edit.pp 12 KB

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