ComboEdit.pas 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335
  1. unit ComboEdit;
  2. {$J+}
  3. {$WARN UNIT_PLATFORM OFF}
  4. interface
  5. uses Windows, Classes, StdCtrls, Controls, Messages, Forms, Graphics,
  6. Menus, Buttons, Dialogs, Mask,
  7. { SysUtils must overload deprecated FileCtrl (implements SelectDirectory) }
  8. FileCtrl, SysUtils;
  9. const
  10. scAltDown = scAlt + vk_Down;
  11. scCtrlEnter = scCtrl + vk_Return;
  12. DefEditBtnWidth = 25;
  13. resourcestring
  14. SBrowse = 'Browse';
  15. SDefaultFilter = 'All files (*.*)|*.*';
  16. SInvalidFileName = 'Invalid file name - %s';
  17. type
  18. TFileExt = type string;
  19. { TCustomComboEdit }
  20. TCustomComboEdit = class(TCustomMaskEdit)
  21. private
  22. FButton: TButton;
  23. FBtnControl: TWinControl;
  24. FOnButtonClick: TNotifyEvent;
  25. FClickKey: TShortCut;
  26. FReadOnly: Boolean;
  27. FDirectInput: Boolean;
  28. FAlwaysEnable: Boolean;
  29. FAlignment: TAlignment;
  30. procedure SetEditRect;
  31. procedure UpdateBtnBounds;
  32. procedure EditButtonClick(Sender: TObject);
  33. function GetMinHeight: Integer;
  34. function GetTextHeight: Integer;
  35. procedure SetShowCaret;
  36. function GetButtonWidth: Integer;
  37. procedure SetButtonWidth(Value: Integer);
  38. function GetButtonHint: string;
  39. procedure SetButtonHint(const Value: string);
  40. procedure SetDirectInput(Value: Boolean);
  41. procedure SetReadOnly(Value: Boolean);
  42. procedure SetAlignment(Value: TAlignment);
  43. function BtnWidthStored: Boolean;
  44. procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
  45. procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
  46. procedure CMEnter(var Message: TMessage); message CM_ENTER;
  47. procedure CNCtlColor(var Message: TMessage); message CN_CTLCOLOREDIT;
  48. procedure WMSize(var Message: TWMSize); message WM_SIZE;
  49. procedure WMSetFocus(var Message: TMessage); message WM_SETFOCUS;
  50. procedure WMPaste(var Message: TWMPaste); message WM_PASTE;
  51. procedure WMCut(var Message: TWMCut); message WM_CUT;
  52. procedure CMCtl3DChanged(var Message: TMessage); message CM_CTL3DCHANGED;
  53. protected
  54. procedure CreateParams(var Params: TCreateParams); override;
  55. procedure CreateWnd; override;
  56. function EditCanModify: Boolean; override;
  57. function GetReadOnly: Boolean; virtual;
  58. procedure KeyDown(var Key: Word; Shift: TShiftState); override;
  59. procedure KeyPress(var Key: Char); override;
  60. procedure ButtonClick; dynamic;
  61. property Alignment: TAlignment read FAlignment write SetAlignment default taLeftJustify;
  62. property AlwaysEnable: Boolean read FAlwaysEnable write FAlwaysEnable default False;
  63. property Button: TButton read FButton;
  64. property ClickKey: TShortCut read FClickKey write FClickKey
  65. default scAltDown;
  66. property ButtonWidth: Integer read GetButtonWidth write SetButtonWidth
  67. stored BtnWidthStored;
  68. property ButtonHint: string read GetButtonHint write SetButtonHint;
  69. property DirectInput: Boolean read FDirectInput write SetDirectInput default True;
  70. property ReadOnly: Boolean read GetReadOnly write SetReadOnly default False;
  71. property OnButtonClick: TNotifyEvent read FOnButtonClick write FOnButtonClick;
  72. public
  73. constructor Create(AOwner: TComponent); override;
  74. destructor Destroy; override;
  75. procedure DoClick;
  76. procedure SelectAll;
  77. end;
  78. type
  79. TComboEdit = class(TCustomComboEdit)
  80. published
  81. property AutoSelect;
  82. property ButtonHint;
  83. property BorderStyle;
  84. property CharCase;
  85. property ClickKey;
  86. property Color;
  87. property Ctl3D;
  88. property DirectInput;
  89. property DragCursor;
  90. property DragMode;
  91. property EditMask;
  92. property Enabled;
  93. property Font;
  94. property ButtonWidth;
  95. property HideSelection;
  96. property Anchors;
  97. property BiDiMode;
  98. property Constraints;
  99. property DragKind;
  100. property ParentBiDiMode;
  101. property ImeMode;
  102. property ImeName;
  103. property ParentColor;
  104. property ParentCtl3D;
  105. property ParentFont;
  106. property ParentShowHint;
  107. property PopupMenu;
  108. property ReadOnly;
  109. property ShowHint;
  110. property TabOrder;
  111. property TabStop;
  112. property Text;
  113. property Visible;
  114. property OnButtonClick;
  115. property OnChange;
  116. property OnClick;
  117. property OnDblClick;
  118. property OnDragDrop;
  119. property OnDragOver;
  120. property OnEndDrag;
  121. property OnEnter;
  122. property OnExit;
  123. property OnKeyDown;
  124. property OnKeyPress;
  125. property OnKeyUp;
  126. property OnMouseDown;
  127. property OnMouseMove;
  128. property OnMouseUp;
  129. property OnStartDrag;
  130. property OnContextPopup;
  131. property OnEndDock;
  132. property OnStartDock;
  133. end;
  134. { TFileDirEdit }
  135. { The common parent of TFilenameEdit and TDirectoryEdit }
  136. { For internal use only; it's not intended to be used separately }
  137. const
  138. MaxFileLength = SizeOf(TFileName) - 1;
  139. type
  140. TExecOpenDialogEvent = procedure(Sender: TObject; var Name: string;
  141. var Action: Boolean) of object;
  142. TFileDirEdit = class(TCustomComboEdit)
  143. private
  144. FErrMode: Cardinal;
  145. FAcceptFiles: Boolean;
  146. FOnDropFiles: TNotifyEvent;
  147. FOnBeforeDialog: TExecOpenDialogEvent;
  148. FOnAfterDialog: TExecOpenDialogEvent;
  149. procedure SetDragAccept(Value: Boolean);
  150. procedure SetAcceptFiles(Value: Boolean);
  151. procedure WMDropFiles(var Msg: TWMDropFiles); message WM_DROPFILES;
  152. protected
  153. FMultipleDirs: Boolean;
  154. procedure CreateHandle; override;
  155. procedure DestroyWindowHandle; override;
  156. function GetLongName: string; virtual; abstract;
  157. function GetShortName: string; virtual; abstract;
  158. procedure DoAfterDialog(var FileName: string; var Action: Boolean); dynamic;
  159. procedure DoBeforeDialog(var FileName: string; var Action: Boolean); dynamic;
  160. procedure ReceptFileDir(const AFileName: string); virtual; abstract;
  161. procedure ClearFileList; virtual;
  162. procedure DisableSysErrors;
  163. procedure EnableSysErrors;
  164. property MaxLength;
  165. public
  166. constructor Create(AOwner: TComponent); override;
  167. property LongName: string read GetLongName;
  168. property ShortName: string read GetShortName;
  169. published
  170. property AcceptFiles: Boolean read FAcceptFiles write SetAcceptFiles default False;
  171. property OnBeforeDialog: TExecOpenDialogEvent read FOnBeforeDialog
  172. write FOnBeforeDialog;
  173. property OnAfterDialog: TExecOpenDialogEvent read FOnAfterDialog
  174. write FOnAfterDialog;
  175. property OnDropFiles: TNotifyEvent read FOnDropFiles write FOnDropFiles;
  176. property OnButtonClick;
  177. end;
  178. { TFilenameEdit }
  179. TFileDialogKind = (dkOpen, dkSave , dkOpenPicture,
  180. dkSavePicture);
  181. TCreateEditDialogEvent = procedure(Sender: TObject; DialogKind: TFileDialogKind;
  182. var Dialog: TOpenDialog) of object;
  183. TFilenameEdit = class(TFileDirEdit)
  184. private
  185. FDialog: TOpenDialog;
  186. FDialogKind: TFileDialogKind;
  187. FOnCreateEditDialog: TCreateEditDialogEvent;
  188. procedure CreateEditDialog;
  189. function GetFileName: string;
  190. function GetDefaultExt: TFileExt;
  191. function GetFileEditStyle: TFileEditStyle;
  192. function GetFilter: string;
  193. function GetFilterIndex: Integer;
  194. function GetInitialDir: string;
  195. function GetHistoryList: TStrings;
  196. function GetOptions: TOpenOptions;
  197. function GetDialogTitle: string;
  198. function GetDialogFiles: TStrings;
  199. procedure SetDialogKind(Value: TFileDialogKind);
  200. procedure SetFileName(const Value: string);
  201. procedure SetDefaultExt(Value: TFileExt);
  202. procedure SetFileEditStyle(Value: TFileEditStyle);
  203. procedure SetFilter(const Value: string);
  204. procedure SetFilterIndex(Value: Integer);
  205. procedure SetInitialDir(const Value: string);
  206. procedure SetHistoryList(Value: TStrings);
  207. procedure SetOptions(Value: TOpenOptions);
  208. procedure SetDialogTitle(const Value: string);
  209. procedure SetOnCreateEditDialog(Value: TCreateEditDialogEvent);
  210. function IsCustomTitle: Boolean;
  211. function IsCustomFilter: Boolean;
  212. protected
  213. procedure ButtonClick; override;
  214. procedure ReceptFileDir(const AFileName: string); override;
  215. procedure ClearFileList; override;
  216. function GetLongName: string; override;
  217. function GetShortName: string; override;
  218. public
  219. constructor Create(AOwner: TComponent); override;
  220. property Dialog: TOpenDialog read FDialog;
  221. property DialogFiles: TStrings read GetDialogFiles;
  222. published
  223. property DialogKind: TFileDialogKind read FDialogKind write SetDialogKind
  224. default dkOpen;
  225. property DefaultExt: TFileExt read GetDefaultExt write SetDefaultExt;
  226. property FileEditStyle: TFileEditStyle read GetFileEditStyle write SetFileEditStyle
  227. default fsEdit;
  228. property FileName: string read GetFileName write SetFileName stored False;
  229. property Filter: string read GetFilter write SetFilter stored IsCustomFilter;
  230. property FilterIndex: Integer read GetFilterIndex write SetFilterIndex default 1;
  231. property InitialDir: string read GetInitialDir write SetInitialDir;
  232. property HistoryList: TStrings read GetHistoryList write SetHistoryList;
  233. property DialogOptions: TOpenOptions read GetOptions write SetOptions
  234. default [ofHideReadOnly];
  235. property DialogTitle: string read GetDialogTitle write SetDialogTitle
  236. stored IsCustomTitle;
  237. property OnCreateEditDialog: TCreateEditDialogEvent read FOnCreateEditDialog
  238. write SetOnCreateEditDialog;
  239. property AutoSelect;
  240. property ButtonHint;
  241. property BorderStyle;
  242. property CharCase;
  243. property ClickKey;
  244. property Color;
  245. property Ctl3D;
  246. property DirectInput;
  247. property DragCursor;
  248. property DragMode;
  249. property EditMask;
  250. property Enabled;
  251. property Font;
  252. property ButtonWidth;
  253. property HideSelection;
  254. property Anchors;
  255. property BiDiMode;
  256. property Constraints;
  257. property DragKind;
  258. property ParentBiDiMode;
  259. property ImeMode;
  260. property ImeName;
  261. property ParentColor;
  262. property ParentCtl3D;
  263. property ParentFont;
  264. property ParentShowHint;
  265. property PopupMenu;
  266. property ReadOnly;
  267. property ShowHint;
  268. property TabOrder;
  269. property TabStop;
  270. property Text;
  271. property Visible;
  272. property OnChange;
  273. property OnClick;
  274. property OnDblClick;
  275. property OnDragDrop;
  276. property OnDragOver;
  277. property OnEndDrag;
  278. property OnEnter;
  279. property OnExit;
  280. property OnKeyDown;
  281. property OnKeyPress;
  282. property OnKeyUp;
  283. property OnMouseDown;
  284. property OnMouseMove;
  285. property OnMouseUp;
  286. property OnStartDrag;
  287. property OnContextPopup;
  288. property OnEndDock;
  289. property OnStartDock;
  290. end;
  291. { TDirectoryEdit }
  292. TDirectoryEdit = class(TFileDirEdit)
  293. private
  294. FInitialDir: string;
  295. FDialogText: string;
  296. protected
  297. procedure ButtonClick; override;
  298. procedure ReceptFileDir(const AFileName: string); override;
  299. function GetLongName: string; override;
  300. function GetShortName: string; override;
  301. public
  302. constructor Create(AOwner: TComponent); override;
  303. published
  304. property DialogText: string read FDialogText write FDialogText;
  305. property InitialDir: string read FInitialDir write FInitialDir;
  306. property MultipleDirs: Boolean read FMultipleDirs write FMultipleDirs default False;
  307. property AutoSelect;
  308. property ButtonHint;
  309. property BorderStyle;
  310. property CharCase;
  311. property ClickKey;
  312. property Color;
  313. property Ctl3D;
  314. property DirectInput;
  315. property DragCursor;
  316. property DragMode;
  317. property EditMask;
  318. property Enabled;
  319. property Font;
  320. property ButtonWidth;
  321. property HideSelection;
  322. property Anchors;
  323. property BiDiMode;
  324. property Constraints;
  325. property DragKind;
  326. property ParentBiDiMode;
  327. property ImeMode;
  328. property ImeName;
  329. property ParentColor;
  330. property ParentCtl3D;
  331. property ParentFont;
  332. property ParentShowHint;
  333. property PopupMenu;
  334. property ReadOnly;
  335. property ShowHint;
  336. property TabOrder;
  337. property TabStop;
  338. property Text;
  339. property Visible;
  340. property OnChange;
  341. property OnClick;
  342. property OnDblClick;
  343. property OnDragDrop;
  344. property OnDragOver;
  345. property OnEndDrag;
  346. property OnEnter;
  347. property OnExit;
  348. property OnKeyDown;
  349. property OnKeyPress;
  350. property OnKeyUp;
  351. property OnMouseDown;
  352. property OnMouseMove;
  353. property OnMouseUp;
  354. property OnStartDrag;
  355. property OnContextPopup;
  356. property OnEndDock;
  357. property OnStartDock;
  358. end;
  359. EComboEditError = class(Exception);
  360. procedure Register;
  361. implementation
  362. uses
  363. ShellAPI, Consts, ExtDlgs, Variants;
  364. procedure Register;
  365. begin
  366. RegisterComponents('Martin', [TComboEdit, TFilenameEdit, TDirectoryEdit]);
  367. end;
  368. { Utility functions }
  369. type
  370. TCharSet = TSysCharSet;
  371. function ExtractSubstr(const S: string; var Pos: Integer;
  372. const Delims: TCharSet): string;
  373. var
  374. I: Integer;
  375. begin
  376. I := Pos;
  377. while (I <= Length(S)) and not CharInSet(S[I], Delims) do Inc(I);
  378. Result := Copy(S, Pos, I - Pos);
  379. if (I <= Length(S)) and CharInSet(S[I], Delims) then Inc(I);
  380. Pos := I;
  381. end;
  382. function ValidFileName(const FileName: string): Boolean;
  383. function HasAny(const Str, Substr: string): Boolean;
  384. var
  385. I: Integer;
  386. begin
  387. Result := False;
  388. for I := 1 to Length(Substr) do begin
  389. if Pos(Substr[I], Str) > 0 then begin
  390. Result := True;
  391. Break;
  392. end;
  393. end;
  394. end;
  395. begin
  396. Result := (FileName <> '') and (not HasAny(FileName, '<>"[]|'));
  397. if Result then Result := Pos('\', ExtractFileName(FileName)) = 0;
  398. end;
  399. function DirExists(Name: string): Boolean;
  400. var
  401. Code: Integer;
  402. begin
  403. Code := GetFileAttributes(PChar(Name));
  404. Result := (Code <> -1) and (FILE_ATTRIBUTE_DIRECTORY and Code <> 0);
  405. end;
  406. function ShortToLongFileName(const ShortName: string): string;
  407. var
  408. Temp: TWin32FindData;
  409. SearchHandle: THandle;
  410. begin
  411. SearchHandle := FindFirstFile(PChar(ShortName), Temp);
  412. if SearchHandle <> INVALID_HANDLE_VALUE then begin
  413. Result := string(Temp.cFileName);
  414. if Result = '' then Result := string(Temp.cAlternateFileName);
  415. end
  416. else Result := '';
  417. Windows.FindClose(SearchHandle);
  418. end;
  419. function LongToShortFileName(const LongName: string): string;
  420. var
  421. Temp: TWin32FindData;
  422. SearchHandle: THandle;
  423. begin
  424. SearchHandle := FindFirstFile(PChar(LongName), Temp);
  425. if SearchHandle <> INVALID_HANDLE_VALUE then begin
  426. Result := string(Temp.cAlternateFileName);
  427. if Result = '' then Result := string(Temp.cFileName);
  428. end
  429. else Result := '';
  430. Windows.FindClose(SearchHandle);
  431. end;
  432. function ShortToLongPath(const ShortName: string): string;
  433. var
  434. LastSlash: PChar;
  435. TempPathPtr: PChar;
  436. begin
  437. Result := '';
  438. TempPathPtr := PChar(ShortName);
  439. LastSlash := StrRScan(TempPathPtr, '\');
  440. while LastSlash <> nil do begin
  441. Result := '\' + ShortToLongFileName(TempPathPtr) + Result;
  442. if LastSlash <> nil then begin
  443. LastSlash^ := char(0);
  444. LastSlash := StrRScan(TempPathPtr, '\');
  445. end;
  446. end;
  447. Result := TempPathPtr + Result;
  448. end;
  449. function LongToShortPath(const LongName: string): string;
  450. var
  451. LastSlash: PChar;
  452. TempPathPtr: PChar;
  453. begin
  454. Result := '';
  455. TempPathPtr := PChar(LongName);
  456. LastSlash := StrRScan(TempPathPtr, '\');
  457. while LastSlash <> nil do begin
  458. Result := '\' + LongToShortFileName(TempPathPtr) + Result;
  459. if LastSlash <> nil then begin
  460. LastSlash^ := char(0);
  461. LastSlash := StrRScan(TempPathPtr, '\');
  462. end;
  463. end;
  464. Result := TempPathPtr + Result;
  465. end;
  466. { TCustomComboEdit }
  467. constructor TCustomComboEdit.Create(AOwner: TComponent);
  468. begin
  469. inherited Create(AOwner);
  470. ControlStyle := ControlStyle + [csCaptureMouse];
  471. AutoSize := False;
  472. FDirectInput := True;
  473. FClickKey := scCtrlEnter;
  474. FBtnControl := TWinControl.Create(Self);
  475. with FBtnControl do
  476. begin
  477. ControlStyle := ControlStyle + [csReplicatable];
  478. Width := DefEditBtnWidth;
  479. Height := 17;
  480. Visible := True;
  481. Parent := Self;
  482. end;
  483. FButton := TButton.Create(Self);
  484. with FButton do
  485. begin
  486. SetBounds(0, 0, FBtnControl.Width, FBtnControl.Height);
  487. ControlStyle := ControlStyle + [csReplicatable];
  488. ParentShowHint := True;
  489. Caption := '...';
  490. Visible := True;
  491. Parent := FBtnControl;
  492. OnClick := EditButtonClick;
  493. end;
  494. Height := 21;
  495. end;
  496. destructor TCustomComboEdit.Destroy;
  497. begin
  498. FButton.OnClick := nil;
  499. inherited Destroy;
  500. end;
  501. procedure TCustomComboEdit.CreateParams(var Params: TCreateParams);
  502. const
  503. Alignments: array[TAlignment] of Longword = (ES_LEFT, ES_RIGHT, ES_CENTER);
  504. begin
  505. inherited CreateParams(Params);
  506. Params.Style := Params.Style or ES_MULTILINE or WS_CLIPCHILDREN
  507. or Alignments[FAlignment];
  508. end;
  509. procedure TCustomComboEdit.CreateWnd;
  510. begin
  511. inherited CreateWnd;
  512. SetEditRect;
  513. end;
  514. function TCustomComboEdit.EditCanModify: Boolean;
  515. begin
  516. Result := not FReadOnly;
  517. end;
  518. procedure TCustomComboEdit.KeyDown(var Key: Word; Shift: TShiftState);
  519. begin
  520. inherited KeyDown(Key, Shift);
  521. if (FClickKey = ShortCut(Key, Shift)) and (ButtonWidth > 0) then
  522. begin
  523. EditButtonClick(Self);
  524. Key := 0;
  525. end;
  526. end;
  527. procedure TCustomComboEdit.KeyPress(var Key: Char);
  528. var
  529. OrigKey: Char;
  530. begin
  531. if (Key = Char(VK_RETURN)) or (Key = Char(VK_ESCAPE)) or (Key = #10) then
  532. begin
  533. OrigKey := Key;
  534. { must catch and remove this, since is actually multi-line }
  535. GetParentForm(Self).Perform(CM_DIALOGKEY, Byte(Key), 0);
  536. if Key = OrigKey then
  537. begin
  538. inherited KeyPress(Key);
  539. Key := #0;
  540. Exit;
  541. end;
  542. end;
  543. inherited KeyPress(Key);
  544. end;
  545. function TCustomComboEdit.GetButtonWidth: Integer;
  546. begin
  547. Result := FButton.Width;
  548. end;
  549. procedure TCustomComboEdit.SetButtonWidth(Value: Integer);
  550. begin
  551. if ButtonWidth <> Value then
  552. begin
  553. FBtnControl.Visible := Value > 1;
  554. if (csCreating in ControlState) then
  555. begin
  556. FBtnControl.Width := Value;
  557. FButton.Width := Value;
  558. with FButton do
  559. ControlStyle := ControlStyle - [csFixedWidth];
  560. end
  561. else if (Value <> ButtonWidth) and (Value < ClientWidth) then
  562. begin
  563. FButton.Width := Value;
  564. with FButton do
  565. ControlStyle := ControlStyle - [csFixedWidth];
  566. if HandleAllocated then RecreateWnd;
  567. end;
  568. end;
  569. end;
  570. function TCustomComboEdit.GetButtonHint: string;
  571. begin
  572. Result := FButton.Hint;
  573. end;
  574. procedure TCustomComboEdit.SetButtonHint(const Value: string);
  575. begin
  576. FButton.Hint := Value;
  577. end;
  578. procedure TCustomComboEdit.SetEditRect;
  579. var
  580. Loc: TRect;
  581. begin
  582. SetRect(Loc, 0, 0, ClientWidth - FBtnControl.Width - 2, ClientHeight + 1);
  583. SendMessage(Handle, EM_SETRECTNP, 0, LongInt(@Loc));
  584. end;
  585. procedure TCustomComboEdit.UpdateBtnBounds;
  586. var
  587. BtnRect: TRect;
  588. begin
  589. if NewStyleControls then begin
  590. if Ctl3D and (BorderStyle = bsSingle) then
  591. BtnRect := Bounds(Width - FButton.Width - 4, 0,
  592. FButton.Width, Height - 4)
  593. else begin
  594. if BorderStyle = bsSingle then
  595. BtnRect := Bounds(Width - FButton.Width - 2, 2,
  596. FButton.Width, Height - 4)
  597. else
  598. BtnRect := Bounds(Width - FButton.Width, 0,
  599. FButton.Width, Height);
  600. end;
  601. end
  602. else
  603. BtnRect := Bounds(Width - FButton.Width, 0, FButton.Width, Height);
  604. with BtnRect do
  605. FBtnControl.SetBounds(Left, Top, Right - Left, Bottom - Top);
  606. FButton.Height := FBtnControl.Height;
  607. SetEditRect;
  608. end;
  609. procedure TCustomComboEdit.CMCtl3DChanged(var Message: TMessage);
  610. begin
  611. inherited;
  612. UpdateBtnBounds;
  613. end;
  614. procedure TCustomComboEdit.WMSize(var Message: TWMSize);
  615. var
  616. MinHeight: Integer;
  617. begin
  618. inherited;
  619. if not (csLoading in ComponentState) then
  620. begin
  621. MinHeight := GetMinHeight;
  622. { text edit bug: if size to less than MinHeight, then edit ctrl does
  623. not display the text }
  624. if Height < MinHeight then
  625. begin
  626. Height := MinHeight;
  627. Exit;
  628. end;
  629. end;
  630. UpdateBtnBounds;
  631. end;
  632. function TCustomComboEdit.GetTextHeight: Integer;
  633. var
  634. DC: HDC;
  635. SaveFont: HFont;
  636. SysMetrics, Metrics: TTextMetric;
  637. begin
  638. DC := GetDC(0);
  639. try
  640. GetTextMetrics(DC, SysMetrics);
  641. SaveFont := SelectObject(DC, Font.Handle);
  642. GetTextMetrics(DC, Metrics);
  643. SelectObject(DC, SaveFont);
  644. finally
  645. ReleaseDC(0, DC);
  646. end;
  647. if SysMetrics.tmHeight < Metrics.tmHeight then Result := SysMetrics.tmHeight
  648. else Result := Metrics.tmHeight;
  649. end;
  650. function TCustomComboEdit.GetMinHeight: Integer;
  651. var
  652. I: Integer;
  653. begin
  654. I := GetTextHeight;
  655. Result := I + GetSystemMetrics(SM_CYBORDER) * 4 + 1;
  656. end;
  657. procedure TCustomComboEdit.CMFontChanged(var Message: TMessage);
  658. begin
  659. inherited;
  660. if HandleAllocated then SetEditRect;
  661. end;
  662. procedure TCustomComboEdit.CMEnabledChanged(var Message: TMessage);
  663. begin
  664. inherited;
  665. FButton.Enabled := Enabled;
  666. end;
  667. procedure TCustomComboEdit.CMEnter(var Message: TMessage);
  668. begin
  669. if AutoSelect and not (csLButtonDown in ControlState) then SelectAll;
  670. inherited;
  671. end;
  672. procedure TCustomComboEdit.CNCtlColor(var Message: TMessage);
  673. var
  674. TextColor: Longint;
  675. begin
  676. inherited;
  677. if NewStyleControls then begin
  678. TextColor := ColorToRGB(Font.Color);
  679. if not Enabled and (ColorToRGB(Color) <> ColorToRGB(clGrayText)) then
  680. TextColor := ColorToRGB(clGrayText);
  681. SetTextColor(Message.WParam, TextColor);
  682. end;
  683. end;
  684. procedure TCustomComboEdit.WMSetFocus(var Message: TMessage);
  685. begin
  686. inherited;
  687. SetShowCaret;
  688. end;
  689. procedure TCustomComboEdit.SetShowCaret;
  690. const
  691. CaretWidth: array[Boolean] of Byte = (1, 2);
  692. begin
  693. CreateCaret(Handle, 0, CaretWidth[fsBold in Font.Style], GetTextHeight);
  694. ShowCaret(Handle);
  695. end;
  696. procedure TCustomComboEdit.EditButtonClick(Sender: TObject);
  697. begin
  698. if (not FReadOnly) or AlwaysEnable then ButtonClick;
  699. end;
  700. procedure TCustomComboEdit.DoClick;
  701. begin
  702. EditButtonClick(Self);
  703. end;
  704. procedure TCustomComboEdit.ButtonClick;
  705. begin
  706. if Assigned(FOnButtonClick) then FOnButtonClick(Self);
  707. end;
  708. procedure TCustomComboEdit.SelectAll;
  709. begin
  710. if DirectInput then inherited SelectAll;
  711. end;
  712. procedure TCustomComboEdit.SetDirectInput(Value: Boolean);
  713. begin
  714. inherited ReadOnly := not Value or FReadOnly;
  715. FDirectInput := Value;
  716. end;
  717. procedure TCustomComboEdit.WMPaste(var Message: TWMPaste);
  718. begin
  719. if not FDirectInput or ReadOnly then Exit;
  720. inherited;
  721. end;
  722. procedure TCustomComboEdit.WMCut(var Message: TWMCut);
  723. begin
  724. if not FDirectInput or ReadOnly then Exit;
  725. inherited;
  726. end;
  727. function TCustomComboEdit.GetReadOnly: Boolean;
  728. begin
  729. Result := FReadOnly;
  730. end;
  731. procedure TCustomComboEdit.SetReadOnly(Value: Boolean);
  732. begin
  733. if Value <> FReadOnly then begin
  734. FReadOnly := Value;
  735. inherited ReadOnly := Value or not FDirectInput;
  736. end;
  737. end;
  738. procedure TCustomComboEdit.SetAlignment(Value: TAlignment);
  739. begin
  740. if FAlignment <> Value then begin
  741. FAlignment := Value;
  742. RecreateWnd;
  743. end;
  744. end;
  745. function TCustomComboEdit.BtnWidthStored: Boolean;
  746. begin
  747. Result := ButtonWidth <> DefEditBtnWidth;
  748. end;
  749. { TFileDirEdit }
  750. constructor TFileDirEdit.Create(AOwner: TComponent);
  751. begin
  752. inherited Create(AOwner);
  753. OEMConvert := True;
  754. end;
  755. procedure TFileDirEdit.DoBeforeDialog(var FileName: string;
  756. var Action: Boolean);
  757. begin
  758. if Assigned(FOnBeforeDialog) then FOnBeforeDialog(Self, FileName, Action);
  759. end;
  760. procedure TFileDirEdit.DoAfterDialog(var FileName: string;
  761. var Action: Boolean);
  762. begin
  763. if Assigned(FOnAfterDialog) then FOnAfterDialog(Self, FileName, Action);
  764. end;
  765. procedure TFileDirEdit.CreateHandle;
  766. begin
  767. inherited CreateHandle;
  768. if FAcceptFiles then SetDragAccept(True);
  769. end;
  770. procedure TFileDirEdit.DestroyWindowHandle;
  771. begin
  772. SetDragAccept(False);
  773. inherited DestroyWindowHandle;
  774. end;
  775. procedure TFileDirEdit.SetDragAccept(Value: Boolean);
  776. begin
  777. if not (csDesigning in ComponentState) and (Handle <> 0) then
  778. DragAcceptFiles(Handle, Value);
  779. end;
  780. procedure TFileDirEdit.SetAcceptFiles(Value: Boolean);
  781. begin
  782. if FAcceptFiles <> Value then begin
  783. SetDragAccept(Value);
  784. FAcceptFiles := Value;
  785. end;
  786. end;
  787. procedure TFileDirEdit.DisableSysErrors;
  788. begin
  789. FErrMode := SetErrorMode(SEM_NOOPENFILEERRORBOX or SEM_FAILCRITICALERRORS);
  790. end;
  791. procedure TFileDirEdit.EnableSysErrors;
  792. begin
  793. SetErrorMode(FErrMode);
  794. FErrMode := 0;
  795. end;
  796. procedure TFileDirEdit.WMDropFiles(var Msg: TWMDropFiles);
  797. var
  798. AFileName: array[0..255] of Char;
  799. I, Num: Cardinal;
  800. begin
  801. Msg.Result := 0;
  802. try
  803. Num := DragQueryFile(Msg.Drop, $FFFFFFFF, nil, 0);
  804. if Num > 0 then begin
  805. ClearFileList;
  806. for I := 0 to Num - 1 do begin
  807. DragQueryFile(Msg.Drop, I, PChar(@AFileName), Pred(SizeOf(AFileName)));
  808. ReceptFileDir(StrPas(AFileName));
  809. if not FMultipleDirs then Break;
  810. end;
  811. if Assigned(FOnDropFiles) then FOnDropFiles(Self);
  812. end;
  813. finally
  814. DragFinish(Msg.Drop);
  815. end;
  816. end;
  817. procedure TFileDirEdit.ClearFileList;
  818. begin
  819. end;
  820. { TFilenameEdit }
  821. function StrPAlloc(const S: string): PChar;
  822. begin
  823. Result := StrPCopy(StrAlloc(Length(S) + 1), S);
  824. end;
  825. function GetParamStr(P: PChar; var Param: string): PChar;
  826. var
  827. Len: Integer;
  828. Buffer: array[Byte] of Char;
  829. begin
  830. while True do
  831. begin
  832. while (P[0] <> #0) and (P[0] <= ' ') do Inc(P);
  833. if (P[0] = '"') and (P[1] = '"') then Inc(P, 2) else Break;
  834. end;
  835. Len := 0;
  836. while P[0] > ' ' do
  837. if P[0] = '"' then
  838. begin
  839. Inc(P);
  840. while (P[0] <> #0) and (P[0] <> '"') do
  841. begin
  842. Buffer[Len] := P[0];
  843. Inc(Len);
  844. Inc(P);
  845. end;
  846. if P[0] <> #0 then Inc(P);
  847. end else
  848. begin
  849. Buffer[Len] := P[0];
  850. Inc(Len);
  851. Inc(P);
  852. end;
  853. SetString(Param, Buffer, Len);
  854. Result := P;
  855. end;
  856. function ParamCountFromCommandLine(CmdLine: PChar): Integer;
  857. var
  858. S: string;
  859. P: PChar;
  860. begin
  861. P := CmdLine;
  862. Result := 0;
  863. while True do
  864. begin
  865. P := GetParamStr(P, S);
  866. if S = '' then Break;
  867. Inc(Result);
  868. end;
  869. end;
  870. function ParamStrFromCommandLine(CmdLine: PChar; Index: Integer): string;
  871. var
  872. P: PChar;
  873. begin
  874. P := CmdLine;
  875. while True do
  876. begin
  877. P := GetParamStr(P, Result);
  878. if (Index = 0) or (Result = '') then Break;
  879. Dec(Index);
  880. end;
  881. end;
  882. procedure SplitCommandLine(const CmdLine: string; var ExeName,
  883. Params: string);
  884. var
  885. Buffer: PChar;
  886. Cnt, I: Integer;
  887. S: string;
  888. begin
  889. ExeName := '';
  890. Params := '';
  891. Buffer := StrPAlloc(CmdLine);
  892. try
  893. Cnt := ParamCountFromCommandLine(Buffer);
  894. if Cnt > 0 then begin
  895. ExeName := ParamStrFromCommandLine(Buffer, 0);
  896. for I := 1 to Cnt - 1 do begin
  897. S := ParamStrFromCommandLine(Buffer, I);
  898. if Pos(' ', S) > 0 then S := '"' + S + '"';
  899. Params := Params + S;
  900. if I < Cnt - 1 then Params := Params + ' ';
  901. end;
  902. end;
  903. finally
  904. StrDispose(Buffer);
  905. end;
  906. end;
  907. function ClipFilename(const FileName: string): string;
  908. var
  909. Params: string;
  910. begin
  911. if FileExists(FileName) then Result := FileName
  912. else SplitCommandLine(FileName, Result, Params);
  913. end;
  914. function ExtFilename(const FileName: string): string;
  915. begin
  916. if (Pos(' ', FileName) > 0) and (FileName[1] <> '"') then
  917. Result := Format('"%s"', [FileName])
  918. else Result := FileName;
  919. end;
  920. constructor TFilenameEdit.Create(AOwner: TComponent);
  921. begin
  922. inherited Create(AOwner);
  923. CreateEditDialog;
  924. end;
  925. procedure TFilenameEdit.CreateEditDialog;
  926. var
  927. NewDialog: TOpenDialog;
  928. begin
  929. NewDialog := nil;
  930. if Assigned(FOnCreateEditDialog) then
  931. FOnCreateEditDialog(Self, FDialogKind, NewDialog);
  932. if not Assigned(NewDialog) then
  933. case FDialogKind of
  934. dkOpen: NewDialog := TOpenDialog.Create(Self);
  935. dkOpenPicture: NewDialog := TOpenPictureDialog.Create(Self);
  936. dkSavePicture: NewDialog := TSavePictureDialog.Create(Self);
  937. else {dkSave} NewDialog := TSaveDialog.Create(Self);
  938. end;
  939. try
  940. if FDialog <> nil then begin
  941. with NewDialog do begin
  942. DefaultExt := FDialog.DefaultExt;
  943. FileEditStyle := FDialog.FileEditStyle;
  944. FileName := FDialog.FileName;
  945. Filter := FDialog.Filter;
  946. FilterIndex := FDialog.FilterIndex;
  947. InitialDir := FDialog.InitialDir;
  948. HistoryList := FDialog.HistoryList;
  949. Files.Assign(FDialog.Files);
  950. Options := FDialog.Options;
  951. Title := FDialog.Title;
  952. end;
  953. FDialog.Free;
  954. end
  955. else begin
  956. NewDialog.Title := SBrowse;
  957. NewDialog.Filter := SDefaultFilter;
  958. NewDialog.Options := [ofHideReadOnly];
  959. end;
  960. finally
  961. FDialog := NewDialog;
  962. end;
  963. end;
  964. function TFilenameEdit.IsCustomTitle: Boolean;
  965. begin
  966. Result := CompareStr(SBrowse, FDialog.Title) <> 0;
  967. end;
  968. function TFilenameEdit.IsCustomFilter: Boolean;
  969. begin
  970. Result := CompareStr(SDefaultFilter, FDialog.Filter) <> 0;
  971. end;
  972. procedure TFilenameEdit.ButtonClick;
  973. var
  974. Temp: string;
  975. Action: Boolean;
  976. begin
  977. inherited ButtonClick;
  978. Temp := inherited Text;
  979. Action := True;
  980. Temp := ClipFilename(Temp);
  981. DoBeforeDialog(Temp, Action);
  982. if not Action then Exit;
  983. if ValidFileName(Temp) then
  984. try
  985. if DirExists(ExtractFilePath(Temp)) then
  986. SetInitialDir(ExtractFilePath(Temp));
  987. if (ExtractFileName(Temp) = '') or
  988. not ValidFileName(ExtractFileName(Temp)) then Temp := '';
  989. FDialog.FileName := Temp;
  990. except
  991. { ignore any exceptions }
  992. end;
  993. FDialog.HelpContext := Self.HelpContext;
  994. DisableSysErrors;
  995. try
  996. Action := FDialog.Execute;
  997. finally
  998. EnableSysErrors;
  999. end;
  1000. if Action then Temp := FDialog.FileName;
  1001. if CanFocus then SetFocus;
  1002. DoAfterDialog(Temp, Action);
  1003. if Action then begin
  1004. inherited Text := ExtFilename(Temp);
  1005. SetInitialDir(ExtractFilePath(FDialog.FileName));
  1006. end;
  1007. end;
  1008. function TFilenameEdit.GetFileName: string;
  1009. begin
  1010. Result := ClipFilename(inherited Text);
  1011. end;
  1012. procedure TFilenameEdit.SetFileName(const Value: string);
  1013. begin
  1014. if (Value = '') or ValidFileName(ClipFilename(Value)) then begin
  1015. inherited Text := ExtFilename(Value);
  1016. ClearFileList;
  1017. end
  1018. else raise EComboEditError.CreateFmt(SInvalidFilename, [Value]);
  1019. end;
  1020. function TFilenameEdit.GetLongName: string;
  1021. begin
  1022. Result := ShortToLongFileName(FileName);
  1023. end;
  1024. function TFilenameEdit.GetShortName: string;
  1025. begin
  1026. Result := LongToShortFileName(FileName);
  1027. end;
  1028. procedure TFilenameEdit.ClearFileList;
  1029. begin
  1030. FDialog.Files.Clear;
  1031. end;
  1032. procedure TFilenameEdit.ReceptFileDir(const AFileName: string);
  1033. begin
  1034. if FMultipleDirs then begin
  1035. if FDialog.Files.Count = 0 then SetFileName(AFileName);
  1036. FDialog.Files.Add(AFileName);
  1037. end
  1038. else SetFileName(AFileName);
  1039. end;
  1040. function TFilenameEdit.GetDialogFiles: TStrings;
  1041. begin
  1042. Result := FDialog.Files;
  1043. end;
  1044. function TFilenameEdit.GetDefaultExt: TFileExt;
  1045. begin
  1046. Result := FDialog.DefaultExt;
  1047. end;
  1048. function TFilenameEdit.GetFileEditStyle: TFileEditStyle;
  1049. begin
  1050. Result := FDialog.FileEditStyle;
  1051. end;
  1052. function TFilenameEdit.GetFilter: string;
  1053. begin
  1054. Result := FDialog.Filter;
  1055. end;
  1056. function TFilenameEdit.GetFilterIndex: Integer;
  1057. begin
  1058. Result := FDialog.FilterIndex;
  1059. end;
  1060. function TFilenameEdit.GetInitialDir: string;
  1061. begin
  1062. Result := FDialog.InitialDir;
  1063. end;
  1064. function TFilenameEdit.GetHistoryList: TStrings;
  1065. begin
  1066. Result := FDialog.HistoryList;
  1067. end;
  1068. function TFilenameEdit.GetOptions: TOpenOptions;
  1069. begin
  1070. Result := FDialog.Options;
  1071. end;
  1072. function TFilenameEdit.GetDialogTitle: string;
  1073. begin
  1074. Result := FDialog.Title;
  1075. end;
  1076. procedure TFilenameEdit.SetDialogKind(Value: TFileDialogKind);
  1077. begin
  1078. if FDialogKind <> Value then begin
  1079. FDialogKind := Value;
  1080. CreateEditDialog;
  1081. end;
  1082. end;
  1083. procedure TFilenameEdit.SetOnCreateEditDialog(Value: TCreateEditDialogEvent);
  1084. begin
  1085. if @FOnCreateEditDialog <> @Value then
  1086. begin
  1087. FOnCreateEditDialog := Value;
  1088. // to recreate a dialog with every change is stupid way,
  1089. // but its done only once, so it is acceptable
  1090. CreateEditDialog;
  1091. end;
  1092. end;
  1093. procedure TFilenameEdit.SetDefaultExt(Value: TFileExt);
  1094. begin
  1095. FDialog.DefaultExt := Value;
  1096. end;
  1097. procedure TFilenameEdit.SetFileEditStyle(Value: TFileEditStyle);
  1098. begin
  1099. FDialog.FileEditStyle := Value;
  1100. end;
  1101. procedure TFilenameEdit.SetFilter(const Value: string);
  1102. begin
  1103. FDialog.Filter := Value;
  1104. end;
  1105. procedure TFilenameEdit.SetFilterIndex(Value: Integer);
  1106. begin
  1107. FDialog.FilterIndex := Value;
  1108. end;
  1109. procedure TFilenameEdit.SetInitialDir(const Value: string);
  1110. begin
  1111. FDialog.InitialDir := Value;
  1112. end;
  1113. procedure TFilenameEdit.SetHistoryList(Value: TStrings);
  1114. begin
  1115. FDialog.HistoryList := Value;
  1116. end;
  1117. procedure TFilenameEdit.SetOptions(Value: TOpenOptions);
  1118. begin
  1119. if Value <> FDialog.Options then begin
  1120. FDialog.Options := Value;
  1121. FMultipleDirs := ofAllowMultiSelect in FDialog.Options;
  1122. if not FMultipleDirs then ClearFileList;
  1123. end;
  1124. end;
  1125. procedure TFilenameEdit.SetDialogTitle(const Value: string);
  1126. begin
  1127. FDialog.Title := Value;
  1128. end;
  1129. { TDirectoryEdit }
  1130. constructor TDirectoryEdit.Create(AOwner: TComponent);
  1131. begin
  1132. inherited Create(AOwner);
  1133. end;
  1134. procedure TDirectoryEdit.ButtonClick;
  1135. var
  1136. Temp: string;
  1137. Action: Boolean;
  1138. begin
  1139. inherited ButtonClick;
  1140. Temp := Text;
  1141. Action := True;
  1142. DoBeforeDialog(Temp, Action);
  1143. if not Action then Exit;
  1144. if (Temp = '') then begin
  1145. if (InitialDir <> '') then Temp := InitialDir
  1146. else Temp := '\';
  1147. end;
  1148. if not DirExists(Temp) then Temp := '\';
  1149. DisableSysErrors;
  1150. try
  1151. Action := SelectDirectory(FDialogText, '', Temp);
  1152. finally
  1153. EnableSysErrors;
  1154. end;
  1155. if CanFocus then SetFocus;
  1156. DoAfterDialog(Temp, Action);
  1157. if Action then begin
  1158. SelText := '';
  1159. if (Text = '') or not MultipleDirs then Text := Temp
  1160. else Text := Text + ';' + Temp;
  1161. if (Temp <> '') and DirExists(Temp) then InitialDir := Temp;
  1162. end;
  1163. end;
  1164. procedure TDirectoryEdit.ReceptFileDir(const AFileName: string);
  1165. var
  1166. Temp: string;
  1167. begin
  1168. if FileExists(AFileName) then Temp := ExtractFilePath(AFileName)
  1169. else Temp := AFileName;
  1170. if (Text = '') or not MultipleDirs then Text := Temp
  1171. else Text := Text + ';' + Temp;
  1172. end;
  1173. function TDirectoryEdit.GetLongName: string;
  1174. var
  1175. Temp: string;
  1176. Pos: Integer;
  1177. begin
  1178. if not MultipleDirs then Result := ShortToLongPath(Text)
  1179. else begin
  1180. Result := '';
  1181. Pos := 1;
  1182. while Pos <= Length(Text) do begin
  1183. Temp := ShortToLongPath(ExtractSubstr(Text, Pos, [';']));
  1184. if (Result <> '') and (Temp <> '') then Result := Result + ';';
  1185. Result := Result + Temp;
  1186. end;
  1187. end;
  1188. end;
  1189. function TDirectoryEdit.GetShortName: string;
  1190. var
  1191. Temp: string;
  1192. Pos: Integer;
  1193. begin
  1194. if not MultipleDirs then Result := LongToShortPath(Text)
  1195. else begin
  1196. Result := '';
  1197. Pos := 1;
  1198. while Pos <= Length(Text) do begin
  1199. Temp := LongToShortPath(ExtractSubstr(Text, Pos, [';']));
  1200. if (Result <> '') and (Temp <> '') then Result := Result + ';';
  1201. Result := Result + Temp;
  1202. end;
  1203. end;
  1204. end;
  1205. initialization
  1206. end.