PageRenderTime 49ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/Samples/Chap11/PopPad3/PopPad3.d

http://github.com/AndrejMitrovic/DWinProgramming
D | 502 lines | 370 code | 115 blank | 17 comment | 52 complexity | 6173ed1367ebef0f50ecec1a450fbe83 MD5 | raw file
  1. /+
  2. + Copyright (c) Charles Petzold, 1998.
  3. + Ported to the D Programming Language by Andrej Mitrovic, 2011.
  4. +/
  5. module PopPad3;
  6. import core.memory;
  7. import core.runtime;
  8. import core.thread;
  9. import std.conv;
  10. import std.math;
  11. import std.range;
  12. import std.string;
  13. import std.utf;
  14. auto toUTF16z(S)(S s)
  15. {
  16. return toUTFz!(const(wchar)*)(s);
  17. }
  18. pragma(lib, "gdi32.lib");
  19. pragma(lib, "comdlg32.lib");
  20. pragma(lib, "winmm.lib");
  21. import core.sys.windows.windef;
  22. import core.sys.windows.winuser;
  23. import core.sys.windows.wingdi;
  24. import core.sys.windows.winbase;
  25. import core.sys.windows.commdlg;
  26. import core.sys.windows.mmsystem;
  27. import PopFile;
  28. import PopFind;
  29. import PopFont;
  30. import resource;
  31. string appName = "PopPad";
  32. string description = "name";
  33. HINSTANCE hinst;
  34. extern (Windows)
  35. int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
  36. {
  37. int result;
  38. try
  39. {
  40. Runtime.initialize();
  41. result = myWinMain(hInstance, hPrevInstance, lpCmdLine, iCmdShow);
  42. Runtime.terminate();
  43. }
  44. catch (Throwable o)
  45. {
  46. MessageBox(null, o.toString().toUTF16z, "Error", MB_OK | MB_ICONEXCLAMATION);
  47. result = 0;
  48. }
  49. return result;
  50. }
  51. int myWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
  52. {
  53. hinst = hInstance;
  54. HACCEL hAccel;
  55. HWND hwnd;
  56. MSG msg;
  57. WNDCLASS wndclass;
  58. wndclass.style = CS_HREDRAW | CS_VREDRAW;
  59. wndclass.lpfnWndProc = &WndProc;
  60. wndclass.cbClsExtra = 0;
  61. wndclass.cbWndExtra = 0;
  62. wndclass.hInstance = hInstance;
  63. wndclass.hIcon = LoadIcon(hInstance, appName.toUTF16z);
  64. wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  65. wndclass.hbrBackground = cast(HBRUSH) GetStockObject(WHITE_BRUSH);
  66. wndclass.lpszMenuName = appName.toUTF16z;
  67. wndclass.lpszClassName = appName.toUTF16z;
  68. if (!RegisterClass(&wndclass))
  69. {
  70. MessageBox(NULL, "This program requires Windows NT!", appName.toUTF16z, MB_ICONERROR);
  71. return 0;
  72. }
  73. hwnd = CreateWindow(appName.toUTF16z, // window class name
  74. description.toUTF16z, // window caption
  75. WS_OVERLAPPEDWINDOW, // window style
  76. CW_USEDEFAULT, // initial x position
  77. CW_USEDEFAULT, // initial y position
  78. CW_USEDEFAULT, // initial x size
  79. CW_USEDEFAULT, // initial y size
  80. NULL, // parent window handle
  81. NULL, // window menu handle
  82. hInstance, // program instance handle
  83. NULL); // creation parameters
  84. ShowWindow(hwnd, iCmdShow);
  85. UpdateWindow(hwnd);
  86. hAccel = LoadAccelerators(hInstance, appName.toUTF16z);
  87. while (GetMessage(&msg, NULL, 0, 0))
  88. {
  89. if (hDlgModeless == NULL || !IsDialogMessage(hDlgModeless, &msg))
  90. {
  91. if (!TranslateAccelerator(hwnd, hAccel, &msg))
  92. {
  93. TranslateMessage(&msg);
  94. DispatchMessage(&msg);
  95. }
  96. }
  97. }
  98. return msg.wParam;
  99. }
  100. enum EDITID = 1;
  101. enum UNTITLED = "(untitled)";
  102. HWND hDlgModeless;
  103. void DoCaption(HWND hwnd, string szTitleName)
  104. {
  105. string szCaption;
  106. szCaption = format("%s - %s", appName, szTitleName.length ? szTitleName : UNTITLED);
  107. SetWindowText(hwnd, szCaption.toUTF16z);
  108. }
  109. void OkMessage(HWND hwnd, string szMessage, string szTitleName)
  110. {
  111. string szBuffer;
  112. szBuffer = format(szMessage, szTitleName.length ? szTitleName : UNTITLED);
  113. MessageBox(hwnd, szBuffer.toUTF16z, appName.toUTF16z, MB_OK | MB_ICONEXCLAMATION);
  114. }
  115. int AskAboutSave(HWND hwnd, string szTitleName)
  116. {
  117. string szBuffer;
  118. int iReturn;
  119. szBuffer = format("Save current changes in %s?", szTitleName.length ? szTitleName : UNTITLED);
  120. iReturn = MessageBox(hwnd, szBuffer.toUTF16z, appName.toUTF16z, MB_YESNOCANCEL | MB_ICONQUESTION);
  121. if (iReturn == IDYES)
  122. if (!SendMessage(hwnd, WM_COMMAND, IDM_FILE_SAVE, 0))
  123. iReturn = IDCANCEL;
  124. return iReturn;
  125. }
  126. wchar[MAX_PATH] szFileName = 0;
  127. wchar[MAX_PATH] szTitleName = 0;
  128. extern (Windows)
  129. LRESULT WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) nothrow
  130. {
  131. scope (failure) assert(0);
  132. static BOOL bNeedSave = FALSE;
  133. static HINSTANCE hInst;
  134. static HWND hwndEdit;
  135. static int iOffset;
  136. static UINT messageFindReplace;
  137. int iSelBeg, iSelEnd, iEnable;
  138. LPFINDREPLACE pfr;
  139. switch (message)
  140. {
  141. case WM_CREATE:
  142. hInst = (cast(LPCREATESTRUCT)lParam).hInstance;
  143. // Create the edit control child window
  144. hwndEdit = CreateWindow("edit", NULL,
  145. WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL |
  146. WS_BORDER | ES_LEFT | ES_MULTILINE |
  147. ES_NOHIDESEL | ES_AUTOHSCROLL | ES_AUTOVSCROLL,
  148. 0, 0, 0, 0,
  149. hwnd, cast(HMENU)EDITID, hInst, NULL);
  150. SendMessage(hwndEdit, EM_LIMITTEXT, 32000, 0L);
  151. // Initialize common dialog box stuff
  152. PopFileInitialize(hwnd);
  153. PopFontInitialize(hwndEdit);
  154. messageFindReplace = RegisterWindowMessage(FINDMSGSTRING.ptr);
  155. DoCaption(hwnd, to!string(fromWStringz(szTitleName.ptr)));
  156. return 0;
  157. case WM_SETFOCUS:
  158. SetFocus(hwndEdit);
  159. return 0;
  160. case WM_SIZE:
  161. MoveWindow(hwndEdit, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
  162. return 0;
  163. case WM_INITMENUPOPUP:
  164. switch (lParam)
  165. {
  166. case 1: // Edit menu
  167. // Enable Undo if edit control can do it
  168. EnableMenuItem(cast(HMENU)wParam, IDM_EDIT_UNDO,
  169. SendMessage(hwndEdit, EM_CANUNDO, 0, 0L) ?
  170. MF_ENABLED : MF_GRAYED);
  171. // Enable Paste if text is in the clipboard
  172. EnableMenuItem(cast(HMENU)wParam, IDM_EDIT_PASTE,
  173. IsClipboardFormatAvailable(CF_TEXT) ?
  174. MF_ENABLED : MF_GRAYED);
  175. // Enable Cut, Copy, and Del if text is selected
  176. SendMessage(hwndEdit, EM_GETSEL, cast(WPARAM)&iSelBeg, cast(LPARAM)&iSelEnd);
  177. iEnable = (iSelBeg != iSelEnd) ? MF_ENABLED : MF_GRAYED;
  178. EnableMenuItem(cast(HMENU)wParam, IDM_EDIT_CUT, iEnable);
  179. EnableMenuItem(cast(HMENU)wParam, IDM_EDIT_COPY, iEnable);
  180. EnableMenuItem(cast(HMENU)wParam, IDM_EDIT_CLEAR, iEnable);
  181. break;
  182. case 2: // Search menu
  183. // Enable Find, Next, and Replace if modeless
  184. // dialogs are not already active
  185. iEnable = hDlgModeless == NULL ?
  186. MF_ENABLED : MF_GRAYED;
  187. EnableMenuItem(cast(HMENU)wParam, IDM_SEARCH_FIND, iEnable);
  188. EnableMenuItem(cast(HMENU)wParam, IDM_SEARCH_NEXT, iEnable);
  189. EnableMenuItem(cast(HMENU)wParam, IDM_SEARCH_REPLACE, iEnable);
  190. break;
  191. default:
  192. }
  193. return 0;
  194. case WM_COMMAND:
  195. // Messages from edit control
  196. if (lParam && LOWORD(wParam) == EDITID)
  197. {
  198. switch (HIWORD(wParam))
  199. {
  200. case EN_UPDATE:
  201. bNeedSave = TRUE;
  202. return 0;
  203. case EN_ERRSPACE:
  204. case EN_MAXTEXT:
  205. MessageBox(hwnd, "Edit control out of space.",
  206. appName.toUTF16z, MB_OK | MB_ICONSTOP);
  207. return 0;
  208. default:
  209. }
  210. break;
  211. }
  212. switch (LOWORD(wParam))
  213. {
  214. // Messages from File menu
  215. case IDM_FILE_NEW:
  216. if (bNeedSave && IDCANCEL == AskAboutSave(hwnd, to!string(fromWStringz(szTitleName.ptr))))
  217. return 0;
  218. SetWindowText(hwndEdit, "\0");
  219. szFileName[0] = 0;
  220. szTitleName[0] = 0;
  221. DoCaption(hwnd, to!string(fromWStringz(szTitleName.ptr)));
  222. bNeedSave = FALSE;
  223. return 0;
  224. case IDM_FILE_OPEN:
  225. if (bNeedSave && IDCANCEL == AskAboutSave(hwnd, to!string(fromWStringz(szTitleName.ptr))))
  226. return 0;
  227. if (PopFileOpenDlg(hwnd, szFileName.ptr, szTitleName.ptr))
  228. {
  229. if (!PopFileRead(hwndEdit, szFileName.ptr))
  230. {
  231. OkMessage(hwnd, "Could not read file %s!", to!string(fromWStringz(szTitleName.ptr)));
  232. szFileName[0] = 0;
  233. szTitleName[0] = 0;
  234. }
  235. }
  236. DoCaption(hwnd, to!string(fromWStringz(szTitleName.ptr)));
  237. bNeedSave = FALSE;
  238. return 0;
  239. case IDM_FILE_SAVE:
  240. if (szFileName[0] != 0)
  241. {
  242. if (PopFileWrite(hwndEdit, szFileName.ptr))
  243. {
  244. bNeedSave = FALSE;
  245. return 1;
  246. }
  247. else
  248. {
  249. OkMessage(hwnd, "Could not write file %s", to!string(fromWStringz(szTitleName.ptr)));
  250. return 0;
  251. }
  252. }
  253. goto case;
  254. case IDM_FILE_SAVE_AS:
  255. if (PopFileSaveDlg(hwnd, szFileName.ptr, szTitleName.ptr))
  256. {
  257. DoCaption(hwnd, to!string(fromWStringz(szTitleName.ptr)));
  258. if (PopFileWrite(hwndEdit, szFileName.ptr))
  259. {
  260. bNeedSave = FALSE;
  261. return 1;
  262. }
  263. else
  264. {
  265. OkMessage(hwnd, "Could not write file %s", to!string(fromWStringz(szTitleName.ptr)));
  266. return 0;
  267. }
  268. }
  269. return 0;
  270. case IDM_FILE_PRINT:
  271. if (!PopPrntPrintFile(hInst, hwnd, hwndEdit, szTitleName.ptr))
  272. OkMessage(hwnd, "Could not print file %s", to!string(fromWStringz(szTitleName.ptr)));
  273. return 0;
  274. case IDM_APP_EXIT:
  275. SendMessage(hwnd, WM_CLOSE, 0, 0);
  276. return 0;
  277. // Messages from Edit menu
  278. case IDM_EDIT_UNDO:
  279. SendMessage(hwndEdit, WM_UNDO, 0, 0);
  280. return 0;
  281. case IDM_EDIT_CUT:
  282. SendMessage(hwndEdit, WM_CUT, 0, 0);
  283. return 0;
  284. case IDM_EDIT_COPY:
  285. SendMessage(hwndEdit, WM_COPY, 0, 0);
  286. return 0;
  287. case IDM_EDIT_PASTE:
  288. SendMessage(hwndEdit, WM_PASTE, 0, 0);
  289. return 0;
  290. case IDM_EDIT_CLEAR:
  291. SendMessage(hwndEdit, WM_CLEAR, 0, 0);
  292. return 0;
  293. case IDM_EDIT_SELECT_ALL:
  294. SendMessage(hwndEdit, EM_SETSEL, 0, -1);
  295. return 0;
  296. // Messages from Search menu
  297. case IDM_SEARCH_FIND:
  298. SendMessage(hwndEdit, EM_GETSEL, 0, cast(LPARAM)&iOffset);
  299. hDlgModeless = PopFindFindDlg(hwnd);
  300. return 0;
  301. case IDM_SEARCH_NEXT:
  302. SendMessage(hwndEdit, EM_GETSEL, 0, cast(LPARAM)&iOffset);
  303. if (PopFindValidFind())
  304. PopFindNextText(hwndEdit, &iOffset);
  305. else
  306. hDlgModeless = PopFindFindDlg(hwnd);
  307. return 0;
  308. case IDM_SEARCH_REPLACE:
  309. SendMessage(hwndEdit, EM_GETSEL, 0, cast(LPARAM)&iOffset);
  310. hDlgModeless = PopFindReplaceDlg(hwnd);
  311. return 0;
  312. case IDM_FORMAT_FONT:
  313. if (PopFontChooseFont(hwnd))
  314. PopFontSetFont(hwndEdit);
  315. return 0;
  316. // Messages from Help menu
  317. case IDM_HELP:
  318. OkMessage(hwnd, "Help not yet implemented!",
  319. "\0");
  320. return 0;
  321. case IDM_APP_ABOUT:
  322. DialogBox(hInst, "AboutBox", hwnd, &AboutDlgProc);
  323. return 0;
  324. default:
  325. }
  326. break;
  327. case WM_CLOSE:
  328. if (!bNeedSave || IDCANCEL != AskAboutSave(hwnd, to!string(fromWStringz(szTitleName.ptr))))
  329. DestroyWindow(hwnd);
  330. return 0;
  331. case WM_QUERYENDSESSION:
  332. if (!bNeedSave || IDCANCEL != AskAboutSave(hwnd, to!string(fromWStringz(szTitleName.ptr))))
  333. return 1;
  334. return 0;
  335. case WM_DESTROY:
  336. PopFontDeinitialize();
  337. PostQuitMessage(0);
  338. return 0;
  339. default:
  340. // Process "Find-Replace" messages
  341. if (message == messageFindReplace)
  342. {
  343. pfr = cast(LPFINDREPLACE)lParam;
  344. if (pfr.Flags & FR_DIALOGTERM)
  345. hDlgModeless = NULL;
  346. if (pfr.Flags & FR_FINDNEXT)
  347. if (!PopFindFindText(hwndEdit, &iOffset, pfr))
  348. OkMessage(hwnd, "Text not found!", "\0");
  349. if (pfr.Flags & FR_REPLACE || pfr.Flags & FR_REPLACEALL)
  350. if (!PopFindReplaceText(hwndEdit, &iOffset, pfr))
  351. OkMessage(hwnd, "Text not found!", "\0");
  352. if (pfr.Flags & FR_REPLACEALL)
  353. {
  354. while (PopFindReplaceText(hwndEdit, &iOffset, pfr))
  355. {
  356. }
  357. }
  358. return 0;
  359. }
  360. break;
  361. }
  362. return DefWindowProc(hwnd, message, wParam, lParam);
  363. }
  364. extern (Windows)
  365. BOOL AboutDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  366. {
  367. switch (message)
  368. {
  369. case WM_INITDIALOG:
  370. return TRUE;
  371. case WM_COMMAND:
  372. switch (LOWORD(wParam))
  373. {
  374. case IDOK:
  375. EndDialog(hDlg, 0);
  376. return TRUE;
  377. default:
  378. }
  379. break;
  380. default:
  381. }
  382. return FALSE;
  383. }
  384. BOOL PopPrntPrintFile(HINSTANCE hInst, HWND hwnd, HWND hwndEdit, PTSTR pstrTitleName)
  385. {
  386. return FALSE;
  387. }