Unit1.pas 9.6 KB
Newer Older
cz_012273's avatar
cz_012273 已提交
1 2 3 4 5 6 7 8
unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Memo.Types,
  FMX.Controls.Presentation, FMX.ScrollBox, FMX.Memo, FMX.Layouts, FMX.StdCtrls,
9
  System.IOUtils,FMX.Objects, FMX.Ani, FMX.Effects,system.DateUtils;
cz_012273's avatar
cz_012273 已提交
10 11 12 13 14 15 16 17 18 19

type
  TForm1 = class(TForm)
    ScaledLayout1: TScaledLayout;
    Memo1: TMemo;
    FileNew: TButton;
    FileOpen: TButton;
    FileSave: TButton;
    FileSaveAs: TButton;
    FileExit: TButton;
C
cz_012273 已提交
20
    Label1: TLabel;
C
cz_012273 已提交
21
    Button1: TButton;
22
    Filedelete: TButton;
cz_012273's avatar
cz_012273 已提交
23 24 25 26 27 28

    procedure FileNewClick(Sender: TObject);
    procedure FileOpenClick(Sender: TObject);
    procedure FileSaveClick(Sender: TObject);
    procedure FileSaveAsClick(Sender: TObject);
    procedure FileExitClick(Sender: TObject);
29
    procedure FormShow(Sender: TObject);
cz_012273's avatar
cz_012273 已提交
30
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
C
cz_012273 已提交
31
    procedure Memo1MouseLeave(Sender: TObject);
C
cz_012273 已提交
32
    procedure Button1Click(Sender: TObject);
33 34 35 36
    procedure FiledeleteMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Single);
    procedure FiledeleteMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Single);
cz_012273's avatar
cz_012273 已提交
37 38 39 40 41 42 43 44 45


  private
    { Private declarations }

    procedure ToastConfirm(const AStr: string);
    procedure AniToastFinish(Ani: TObject);
    procedure SetFileName(const FileName: String);
    procedure PerformFileOpen(const AFileName: string);
46 47
    procedure ResultProc(AResult: Boolean; AFileName: string);   //打开参数过程
    procedure ResultProc1(AResult: Boolean; AFileName: string);  //另存参数过程
cz_012273's avatar
cz_012273 已提交
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66


  public
    { Public declarations }

  end;

var
  Form1: TForm1;
  FFileName: string;
  FWantExit: Boolean;
  function GetTextType(const FileName: string): String;

implementation

uses
{$IFDEF ANDROID}
  FMX.Platform.Android,
{$ENDIF}
cz_012273's avatar
cz_012273 已提交
67
  MyDialogs;
cz_012273's avatar
cz_012273 已提交
68 69
type
  TTextFormat=(tfAnsi, tfUnicode, tfUnicodeBigEndian, tfUtf8);
70 71
var
  today : Cardinal;
C
cz_012273 已提交
72

cz_012273's avatar
cz_012273 已提交
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
const
  //TextFormatFlag: array[tfAnsi..tfUtf8] of word=($0000,$FFFE,$FEFF,$EFBB);
  TextFormatFlag: array[tfAnsi..tfUtf8] of word=($0000,$FEFF,$FFFE,$BBEF); //编码标志高低字节互换

{$R *.fmx}
{$R *.LgXhdpiPh.fmx ANDROID}

resourcestring
  sSaveChanges = '是否将未更改保存到 %s?';
  sOverWrite = '%s 已存在。'+#13#10+'要替换它吗?';
  sTitle = '记事本';
  sUntitled = '未命名';
  sColRowInfo = 'Line: %3d   Col: %3d';
  sCommonDlgFileName = '文本文档(*.txt)|*.txt|所有文件(*.*)|*.*';


procedure TForm1.SetFileName(const FileName: String);
begin
  FFileName := System.IOUtils.Tpath.GetSharedDocumentsPath+'/'+FileName+'.txt';
  Caption := Format('%s - %s', [ExtractFileName(FileName), sTitle]);
end;

procedure TForm1.PerformFileOpen(const AFileName: string);
begin
  Memo1.Lines.LoadFromFile(AFileName);
  SetFileName(AFileName);
  Memo1.SetFocus;
  Memo1.text := '';
end;


procedure TForm1.ResultProc(AResult: Boolean; AFileName: string);     //默认参数过程,打开用到
var
  reader: TStreamReader;
107
  TextEncode,s:string;
cz_012273's avatar
cz_012273 已提交
108 109 110 111
begin
  if AResult then
   begin

C
cz_012273 已提交
112
    TextEncode:= GetTextType(AFileName);   //获取文件编码类型
cz_012273's avatar
cz_012273 已提交
113 114 115 116 117 118 119 120 121 122 123 124 125
    //showmessage(TextEncode);

    if TextEncode='ANSI' then     //注意:字符串比较大小写敏感!
       reader := TStreamReader.Create(AFileName, TEncoding.ansi)
      else if TextEncode='Utf8' then
       reader := TStreamReader.Create(AFileName, TEncoding.utf8)
      else if TextEncode='Unicode' then
       reader := TStreamReader.Create(AFileName, TEncoding.unicode)
      else
       reader := TStreamReader.Create(AFileName, TEncoding.BigEndianUnicode);

      Memo1.Lines.clear; //清空Memo1中原有内容

126
      while not reader.EndOfStream do
cz_012273's avatar
cz_012273 已提交
127 128 129 130 131
      begin
       Memo1.Lines.Add (reader.ReadLine);
      end;

    reader.Free;
132 133
    s:=copy(AFileName,pos('Documents/',AFileName)+10,50);  //取文件名(不带路径)
    label1.text:='当前文件:'+s;
C
cz_012273 已提交
134
    memo1.selstart:=0; //光标放最前面
cz_012273's avatar
cz_012273 已提交
135 136 137 138
   end;
end;

procedure TForm1.ResultProc1(AResult: Boolean; AFileName: string);       //默认参数过程1,另存用到
C
cz_012273 已提交
139 140
var
  s:string;
cz_012273's avatar
cz_012273 已提交
141 142 143 144
begin
  if AResult then
    begin
      Memo1.Lines.SaveToFile(AFileName);
C
cz_012273 已提交
145 146
      s:=copy(AFileName,pos('Documents/',AFileName)+10,50);  //取文件名(不带路径)
      label1.text:='当前文件:'+s;
cz_012273's avatar
cz_012273 已提交
147 148 149 150 151 152 153
    end;
end;

procedure TForm1.FileNewClick(Sender: TObject);        //新建
begin

  SetFileName(sUntitled);
154
  label1.text:='当前文件:'+sUntitled+'.txt';
cz_012273's avatar
cz_012273 已提交
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
  Memo1.Lines.Clear;
  Memo1.text := '';
end;

procedure TForm1.FileOpenClick(Sender: TObject);         //打开
begin

  GetFileOpenDialog(ResultProc);
  {
  case TComponent(Sender).Tag of
    1: GetFileOpenDialog(ResultProc);
    2: GetFileSaveDialog(ResultProc);
    3: GetSelectDirectoryDialog(ResultProc);
  end;
  }

end;

procedure TForm1.FileSaveClick(Sender: TObject);        //保存
begin

  showmessage('当前保存位置及文件名:'+FFileName);

  if FFileName = sUntitled then
    FileSaveAsclick(sender)
  else
  begin
    Memo1.Lines.SaveToFile(FFileName);
    //Memo1.text := '';
  end;
end;

procedure TForm1.FileSaveAsClick(Sender: TObject);           //另存
begin
  GetFileSaveDialog(ResultProc1);  //调用通用对话框
end;

C
cz_012273 已提交
192 193 194 195 196 197 198 199
procedure TForm1.Button1Click(Sender: TObject);              //选择当前行文本内容
var
   Line : integer;
begin
   Memo1.setfocus;
   with Memo1 do
   begin
     Line := CaretPosition.line ;
C
cz_012273 已提交
200
     SelStart := SelStart - CaretPosition.pos ;
201
     if lines.count>0 then SelLength := Length(Lines[Line]) ;  //如不是空文件,选当前行
C
cz_012273 已提交
202 203 204
   end;
end;

205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236

procedure TForm1.FiledeleteMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Single);

begin
  today := MilliSecondOfTheDay(Now);
end;


procedure TForm1.FiledeleteMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Single);
var
  today1:Cardinal;
begin
  today1:= MilliSecondOfTheDay(Now)-today;
  if today1>2000 then
  begin
    if label1.text<>'当前文件:未命名.txt' then
    begin
      showmessage('已删除'+label1.text);
      deletefile(FFileName);
    end;

    SetFileName(sUntitled);
    label1.text:='当前文件:'+sUntitled+'.txt';
    Memo1.Lines.Clear;
    Memo1.text := '';
  end
  else
    showmessage('确认删除文件请长按此按钮!');
end;

cz_012273's avatar
cz_012273 已提交
237 238 239 240 241 242 243 244 245 246 247 248 249
procedure TForm1.FileExitClick(Sender: TObject);      //退出
begin
  Close;
end;


procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);      //按两次退出
begin
{$IFDEF ANDROID}
  if not FWantExit then
  begin
    ToastConfirm('再按一次退出程序.');
    Action := TCloseAction.caNone;
250 251 252 253
  end
  else
    Memo1.Lines.clear;

cz_012273's avatar
cz_012273 已提交
254
  FWantExit := True;
255

cz_012273's avatar
cz_012273 已提交
256 257 258 259 260 261 262 263
{$ENDIF}
end;


procedure TForm1.Formshow(Sender: TObject);       //form1显示
begin

  SetFileName(sUntitled);
264 265
  label1.text:='当前文件:'+sUntitled+'.txt';
  memo1.height:= 473;  //将meno控件恢复到默认高度
266

cz_012273's avatar
cz_012273 已提交
267 268
end;

C
cz_012273 已提交
269

C
cz_012273 已提交
270

C
cz_012273 已提交
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
procedure TForm1.Memo1MouseLeave(Sender: TObject);     //改变memo1高度以适应虚拟键盘
var
  i: Integer;

begin
  i:= Memo1.SelStart;
  //showmessage(inttostr(i));

  if (i>0)and(memo1.height>470) then
  begin
     memo1.height:=370;
     memo1.selstart:=i;
  end;

end;

cz_012273's avatar
cz_012273 已提交
287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321
function WordLoHiExchange(w:Word): word;     //高低位互换
var
hi:word;
lo:word;

begin
 hi:= w shl 8;
 lo:= w shr 8;
 result:= hi or lo
end;


function GetTextType(const FileName: string): String;  //获取编码类型
var
  w: Word;
  b: Byte;
begin
  with TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone) do
    try
      Read(w,2);
      //w:=WordLoHiExchange(w);//因为是以Word数据类型读取,故高低字节互换
      //ShowMessage(IntToStr(w));  //查看word变量值
      if w = TextFormatFlag[tfUnicode] then
        Result := 'Unicode'
      else if w = TextFormatFlag[tfUnicodeBigEndian] then
        Result:= 'UnicodeBigEndian'
      else if w = TextFormatFlag[tfUtf8] then
        Result := 'Utf8'
      else
        Result := 'ANSI';
    finally
      Free;
    end;
end;

C
cz_012273 已提交
322

cz_012273's avatar
cz_012273 已提交
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412

procedure TForm1.AniToastFinish(Ani: TObject);     //按两次退出提示框结束
begin
  with TFloatAnimation(Ani) do
  begin
    Delay := 2;
    Duration := 0.3;
    Inverse := True;
    if (TControl(Parent).Opacity = 1) then
      FMX.Ani.TAnimator.StartAnimation(Parent,'Ani')
    else
      FWantExit := not Inverse;
  end;
end;

procedure TForm1.ToastConfirm(const AStr: string);       //按两次退出提示框

  procedure AniInit(A: TFloatAnimation);          //内部过程
  begin
    with A do
    begin
      Parent := TFmxObject(Owner);
      Name := 'Ani';
      PropertyName := 'Opacity';
      StartValue := 0;
      StopValue := 1;
      Delay := 0;
      Duration := 0;
      Inverse := False;
      OnFinish := AniToastFinish;
      Start;
    end;
  end;

  function Find(ACName: string; ACClass: TComponentClass; AOwner: TComponent): TObject;      //内部函数
  begin
    Result := AOwner.FindComponent(ACName);
    if not Assigned(Result) then
      Result := ACClass.Create(AOwner);
  end;

var
  LR: TRectangle;
begin
  LR := TRectangle(Find('Toast', TRectangle, Self));
  with LR do
  begin
    if (Name = '') then
    begin
      Name := 'Toast';
      XRadius := 1;
      YRadius := 1;
      Stroke.Kind := TBrushKind.None;
      Fill.Color := TAlphaColorRec.Black;
      HitTest := False;

      with TGlowEffect.Create(LR) do
      begin
        Parent := LR;
        GlowColor := TAlphaColorRec.Black;
      end;

      with TText.Create(LR) do
      begin
        Name := 'ShowText';
        Parent := LR;
        Font.Size := 12;
        Align := TAlignLayout.Client;
        Color := TAlphaColorRec.White;
      end;
      Parent := Self;
    end;

    with TText(LR.FindComponent('ShowText')) do
    begin
      Text := AStr;
      LR.Width := Canvas.TextWidth(AStr) + 35;
      LR.Height := Canvas.TextHeight(AStr) + 16;
    end;

    LR.Position.X := (Self.Width - LR.Width ) / 2;
    LR.Position.Y := (Self.Height - LR.Height ) / 1.25;
    LR.Repaint;
    LR.BringToFront;
    AniInit(TFloatAnimation(Find('Ani', TFloatAnimation, LR)));
  end;

end;

end.