edit.pp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. {
  2. $Id$
  3. Copyright (c) 1999 by Michael van Canneyt and Goran Andersson
  4. Win32 editor example.
  5. }
  6. { Derived from menu.pp
  7. Changes by Goeran Andersson:
  8. 2000.02.24
  9. Handles WM_DrawBkgnd to reduce flicker
  10. Changes to also compile in FPC mode
  11. Changes by Morten Skovrup:
  12. 2000-02-21
  13. Change font
  14. Modified statusbar
  15. Changes by Goeran Andersson:
  16. 2000.02.20
  17. Sends focus to editor
  18. 2000.02.19
  19. Client edge added to editor
  20. Changes to also compile in FPC mode
  21. Handles Edit modify flag
  22. Undo menu item added
  23. Key codes added to edit menu
  24. Undo, Cut, Copy & Paste implemented
  25. WM_Paint sections commented
  26. 1999.08.10
  27. LoadText() added
  28. NewText() added
  29. File selector added
  30. Asks to save file
  31. Empty files works
  32. EditCreate styles corrected
  33. }
  34. Program editdemo;
  35. {$APPTYPE GUI}
  36. Uses
  37. Strings,Windows;
  38. Const
  39. AppName = 'EditDemo';
  40. Type
  41. TFileName = Array[0..Max_Path] Of Char;
  42. Var
  43. AMessage : Msg;
  44. HWindow,HStatus,HEdit : HWnd;
  45. TheFont : HFont;
  46. TheLogFont : TLogFont;
  47. TheColor : DWORD;
  48. FileName : TFileName;
  49. {********************************************************************}
  50. Procedure SetStatusText(Num : Integer; Const Text : string);
  51. var
  52. StatText : array[0..255] of Char;
  53. begin
  54. if Num = 0 then
  55. StatText[0] := ' ' // Add space to text in first item
  56. else
  57. StatText[0] := #9; // Center the rest
  58. StrPCopy(@StatText[1],Text);
  59. SendMessage(HStatus,SB_SETTEXT,WPARAM(Num),LPARAM(@StatText));
  60. end;
  61. {********************************************************************}
  62. Function SelectFile(Var FName:TFileName; Open:Boolean): Boolean;
  63. Const
  64. Filter : PChar = 'Text files (*.txt)'#0'*.txt'#0+
  65. 'All files (*.*)'#0'*.*'#0#0;
  66. Ext : PChar = 'txt';
  67. Var
  68. NameRec : OpenFileName;
  69. Begin
  70. FillChar(NameRec,SizeOf(NameRec),0);
  71. FName[0] := #0;
  72. With NameRec Do
  73. Begin
  74. LStructSize := SizeOf(NameRec);
  75. HWndOwner := HWindow;
  76. LpStrFilter := Filter;
  77. LpStrFile := @FName;
  78. NMaxFile := Max_Path;
  79. Flags := OFN_Explorer Or OFN_HideReadOnly;
  80. If Open Then
  81. Begin
  82. Flags := Flags Or OFN_FileMustExist;
  83. End;
  84. LpStrDefExt := Ext;
  85. End;
  86. If Open Then
  87. SelectFile := GetOpenFileName(@NameRec)
  88. Else
  89. SelectFile := GetSaveFileName(@NameRec);
  90. End;
  91. {********************************************************************}
  92. Procedure SaveText;
  93. Var
  94. Len : Longint;
  95. P : PChar;
  96. F : File;
  97. FName : TFileName;
  98. Begin
  99. If SelectFile(FName,False) Then
  100. Begin
  101. Assign(F,@FName);
  102. Rewrite(F,1);
  103. Len := GetWindowTextLength(HEdit);
  104. GetMem(P,Len+1);
  105. P[Len] := #0;
  106. If Len>0 Then
  107. Begin
  108. GetWindowText(HEdit,P,Len+1);
  109. BlockWrite(F,P^,Len);
  110. End;
  111. Close(F);
  112. FreeMem(P,Len+1);
  113. StrCopy(FileName,FName);
  114. SetStatusText(0,StrPas(FileName));
  115. SetStatusText(1,'');
  116. SendMessage(HEdit,EM_SetModify,0,0);
  117. End;
  118. End;
  119. {********************************************************************}
  120. Procedure AskSave;
  121. Const
  122. BoxType = MB_IconQuestion Or MB_YesNo;
  123. Begin
  124. If SendMessage(HEdit,EM_GetModify,0,0)<>0 Then
  125. Begin
  126. If MessageBox(HWindow,'Save text?','Edited',BoxType)=IdYes Then
  127. Begin
  128. SaveText;
  129. End;
  130. End;
  131. End;
  132. {********************************************************************}
  133. Procedure LoadText;
  134. Var
  135. F : File;
  136. Len : LongInt;
  137. P : PChar;
  138. Begin
  139. AskSave;
  140. If SelectFile(FileName,True) Then
  141. Begin
  142. Assign(F,@FileName);
  143. Reset(F,1);
  144. Len := FileSize(F);
  145. GetMem(P,Len+1);
  146. P[Len] := #0;
  147. If Len>0 Then BlockRead(F,P^,Len);
  148. Close(F);
  149. SetWindowText(HEdit,P);
  150. SendMessage(HEdit,EM_SetModify,0,0);
  151. FreeMem(P,Len+1);
  152. SetStatusText(0,StrPas(FileName));
  153. SetStatusText(1,'');
  154. End;
  155. End;
  156. {********************************************************************}
  157. Procedure NewText;
  158. Const
  159. Empty : PChar = '';
  160. Begin
  161. AskSave;
  162. FileName := 'Unsaved';
  163. SetStatusText(0,StrPas(FileName));
  164. SendMessage(HEdit,WM_SetText,1,LRESULT(Empty));
  165. SendMessage(HEdit,EM_SetModify,0,0);
  166. End;
  167. {********************************************************************}
  168. procedure SelectFont;
  169. var
  170. ChooseFontRec : TChooseFont;
  171. begin
  172. with ChooseFontRec do
  173. begin
  174. lStructSize := SizeOf(ChooseFontRec);
  175. hwndOwner := HWindow;
  176. hDC := 0;
  177. lpLogFont := @TheLogFont;
  178. iPointSize := 0;
  179. Flags := CF_INITTOLOGFONTSTRUCT or CF_SCREENFONTS or CF_EFFECTS;
  180. rgbColors := TheColor;
  181. lCustData := 0;
  182. lpfnHook := nil;
  183. lpTemplateName := nil;
  184. hInstance := 0;
  185. lpszStyle := nil;
  186. nFontType := 0;
  187. nSizeMin := 0;
  188. nSizeMax := 0;
  189. end;
  190. if ChooseFont(@ChooseFontRec) then
  191. begin
  192. DeleteObject(TheFont);
  193. TheColor := ChooseFontRec.rgbColors;
  194. TheFont := CreateFontIndirect(@TheLogFont);
  195. SendMessage(HEdit,WM_SETFONT,WPARAM(TheFont),1);
  196. end;
  197. end;
  198. {********************************************************************}
  199. Function WindowProc (Window:HWnd;AMessage: UINT;WParam:WPARAM; LParam:LPARAM): LRESULT;
  200. stdcall; export;
  201. Var
  202. R : rect;
  203. StatH : LONG;
  204. NrMenu : Longint;
  205. NotiCode : LongInt;
  206. Begin
  207. WindowProc := 0;
  208. Case AMessage Of
  209. wm_Close:
  210. Begin
  211. AskSave;
  212. End;
  213. wm_Destroy:
  214. Begin
  215. PostQuitMessage (0);
  216. Exit;
  217. End;
  218. wm_SetFocus:
  219. Begin
  220. SetFocus(HEdit);
  221. End;
  222. WM_EraseBkgnd:
  223. Begin
  224. Exit(1);
  225. End;
  226. wm_Size:
  227. Begin
  228. GetClientRect(HStatus,@R);
  229. StatH := R.Bottom-R.Top;
  230. GetClientRect(Window,@R);
  231. MoveWindow (HEdit,0,0,R.Right,R.Bottom-StatH,False);
  232. MoveWindow (HStatus,0,R.Bottom-StatH,R.Right,R.Bottom,False);
  233. End;
  234. wm_Command:
  235. Begin
  236. NotiCode := HiWord(WParam);
  237. Case NotiCode of
  238. en_Change : //Editor has changed
  239. Begin
  240. If SendMessage(HEdit,EM_GetModify,0,0)<>0 then
  241. SetStatusText(1,'Modified')
  242. Else
  243. SetStatusText(1,'');
  244. End;
  245. Else
  246. Begin //Menu item
  247. NrMenu := LoWord(WParam);
  248. Case NrMenu Of
  249. 101 : NewText;
  250. 102 : LoadText;
  251. 103 : SaveText;
  252. 104 : PostMessage(Window,WM_Close,0,0);
  253. 201 : SendMessage(HEdit,WM_Undo,0,0);
  254. 202 : SendMessage(HEdit,WM_Cut,0,0);
  255. 203 : SendMessage(HEdit,WM_Copy,0,0);
  256. 204 : SendMessage(HEdit,WM_Paste,0,0);
  257. 301 : SelectFont;
  258. 401 : MessageBox(Window,'Help','Not implemented',
  259. MB_OK Or MB_IconInformation);
  260. End;
  261. End;
  262. End;
  263. End;
  264. wm_CtlColorEdit :
  265. Begin
  266. SetTextColor(WParam,TheColor);
  267. Exit(GetSysColorBrush(COLOR_WINDOW));
  268. End;
  269. End;
  270. WindowProc := DefWindowProc(Window,AMessage,WParam,LParam);
  271. End;
  272. {********************************************************************}
  273. Function WinRegister: Boolean;
  274. Var
  275. WindowClass : WndClass;
  276. Begin
  277. With WindowClass Do
  278. Begin
  279. Style := cs_hRedraw Or cs_vRedraw;
  280. lpfnWndProc := WndProc(@WindowProc);
  281. cbClsExtra := 0;
  282. cbWndExtra := 0;
  283. hInstance := system.MainInstance;
  284. hIcon := LoadIcon (0,idi_Application);
  285. hCursor := LoadCursor (0,idc_Arrow);
  286. hbrBackground := GetStockObject(GRAY_BRUSH);
  287. lpszMenuName := Nil;
  288. lpszClassName := AppName;
  289. End;
  290. WinRegister := RegisterClass (WindowClass)<>0;
  291. End;
  292. {********************************************************************}
  293. Function EditCreate(ParentWindow,Status:HWnd): HWnd;
  294. Const
  295. CS_Start = WS_Child or WS_HScroll or WS_VScroll or ES_MultiLine or ES_Left;
  296. CS_Ex = WS_EX_ClientEdge;
  297. EdiTText : PChar = '';
  298. Var
  299. HEdit : HWND;
  300. R : TRect;
  301. StatH : Word;
  302. Begin
  303. GetClientRect(Status,@R);
  304. StatH := R.Bottom-R.Top;
  305. GetClientRect(ParentWindow,@R);
  306. HEdit := CreateWindowEx (CS_Ex,'EDIT',EditText,CS_Start,0,0,
  307. R.Right-R.Left,R.Bottom-R.Top-StatH,ParentWindow,0,
  308. MainInstance,Nil);
  309. If HEdit<>0 Then
  310. Begin
  311. //Set Courier new as default font
  312. with TheLogFont do
  313. begin
  314. lfHeight := 0; // Default logical height of font
  315. lfWidth := 0; // Default logical average character width
  316. lfEscapement := 0; // angle of escapement
  317. lfOrientation := 0; // base-line orientation angle
  318. lfWeight := FW_NORMAL; // font weight
  319. lfItalic := 0; // italic attribute flag
  320. lfUnderline := 0; // underline attribute flag
  321. lfStrikeOut := 0; // strikeout attribute flag
  322. lfCharSet := DEFAULT_CHARSET; // character set identifier
  323. lfOutPrecision := OUT_DEFAULT_PRECIS; // output precision
  324. lfClipPrecision := CLIP_DEFAULT_PRECIS; // clipping precision
  325. lfQuality := DEFAULT_QUALITY; // output quality
  326. lfPitchAndFamily := DEFAULT_PITCH; // pitch and family
  327. Strcopy(lfFaceName,'Courier New'); // pointer to typeface name string
  328. end;
  329. TheColor := GetSysColor(COLOR_WINDOWTEXT);
  330. TheFont := CreateFontIndirect(@TheLogFont);
  331. SendMessage(HEdit,WM_SETFONT,WPARAM(TheFont),1);
  332. ShowWindow(Hedit,SW_Show);
  333. UpdateWindow(HEdit);
  334. End;
  335. EditCreate := HEdit;
  336. End;
  337. {********************************************************************}
  338. Function WinCreate: HWnd;
  339. Var hWindow : HWnd;
  340. Menu : hMenu;
  341. SubMenu : hMenu;
  342. Begin
  343. hWindow := CreateWindow (AppName,'EditDemo',ws_OverlappedWindow,
  344. cw_UseDefault,cw_UseDefault,cw_UseDefault,
  345. cw_UseDefault,0,0,MainInstance,Nil);
  346. If hWindow<>0 Then
  347. Begin
  348. Menu := CreateMenu;
  349. SubMenu := CreateMenu;
  350. AppendMenu(Submenu,MF_STRING,101,'&New...');
  351. AppendMenu(Submenu,MF_STRING,102,'&Open...');
  352. AppendMenu(Submenu,MF_STRING,103,'&Save...');
  353. AppendMenu(Submenu,MF_SEPARATOR,0,Nil);
  354. AppendMenu(SubMenu,MF_String,104,'E&xit');
  355. AppendMenu(Menu,MF_POPUP,SubMenu,'&File');
  356. SubMenu := CreateMenu;
  357. AppendMenu(SubMenu,MF_String,201,'&Undo'#8'Ctrl+Z');
  358. AppendMenu(Submenu,MF_SEPARATOR,0,Nil);
  359. AppendMenu(SubMenu,MF_String,202,'&Cut'#8'Ctrl+X');
  360. AppendMenu(SubMenu,MF_String,203,'&Copy'#8'Ctrl+C');
  361. AppendMenu(SubMenu,MF_STRING,204,'&Paste'#8'Ctrl+V');
  362. AppendMenu(Menu,MF_POPUP,SubMenu,'&Edit');
  363. SubMenu := CreateMenu;
  364. AppendMenu(SubMenu,MF_String,301,'&Font...');
  365. AppendMenu(Menu,MF_POPUP,SubMenu,'&Options');
  366. AppendMenu(Menu,MF_STRING,401,'&Help');
  367. SetMenu(hWindow,menu);
  368. ShowWindow(hWindow,SW_Show);
  369. UpdateWindow(hWindow);
  370. End;
  371. WinCreate := hWindow;
  372. End;
  373. {********************************************************************}
  374. Function StatusCreate (parent:hwnd): HWnd;
  375. var
  376. AWnd : HWnd;
  377. Edges : array[1..2] of LongInt;
  378. Begin
  379. FileName := 'Unsaved';
  380. AWnd := CreateStatusWindow(WS_CHILD or WS_VISIBLE,FileName,Parent,$7712);
  381. // Create items:
  382. if AWnd <> 0 then
  383. begin
  384. Edges[1] := 400;
  385. Edges[2] := 500;
  386. SendMessage(AWnd,SB_SETPARTS,2,LPARAM(@Edges));
  387. end;
  388. StatusCreate := AWnd;
  389. End;
  390. {********************************************************************}
  391. Begin
  392. If Not WinRegister Then
  393. Begin
  394. MessageBox (0,'Register failed',Nil, mb_Ok);
  395. End
  396. Else
  397. Begin
  398. hWindow := WinCreate;
  399. If longint(hWindow)=0 Then
  400. Begin
  401. MessageBox (0,'WinCreate failed',Nil,MB_OK);
  402. End
  403. Else
  404. Begin
  405. HStatus := statuscreate(hwindow);
  406. HEdit := EditCreate(HWindow,HStatus);
  407. SetFocus(HEdit);
  408. While GetMessage(@AMessage,0,0,0) Do
  409. Begin
  410. TranslateMessage(AMessage);
  411. DispatchMessage(AMessage);
  412. End;
  413. DeleteObject(TheFont);
  414. Halt(AMessage.wParam);
  415. End;
  416. End;
  417. End.
  418. {
  419. $Log$
  420. Revision 1.3 2002-09-07 15:06:35 peter
  421. * old logs removed and tabs fixed
  422. }