PageRenderTime 46ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/Samples/Chap21/StrProg/StrProg.d

http://github.com/AndrejMitrovic/DWinProgramming
D | 269 lines | 212 code | 53 blank | 4 comment | 14 complexity | eaeefd76a3b2598ce40f0b6e2c6da899 MD5 | raw file
  1. module name;
  2. import core.memory;
  3. import core.runtime;
  4. import core.thread;
  5. import std.conv;
  6. import std.math;
  7. import std.range;
  8. import std.string;
  9. import std.utf;
  10. auto toUTF16z(S)(S s)
  11. {
  12. return toUTFz!(const(wchar)*)(s);
  13. }
  14. pragma(lib, "gdi32.lib");
  15. pragma(lib, "comdlg32.lib");
  16. import core.sys.windows.windef;
  17. import core.sys.windows.winuser;
  18. import core.sys.windows.wingdi;
  19. import core.sys.windows.winbase;
  20. import core.sys.windows.commdlg;
  21. import resource;
  22. import StrLib;
  23. string appName = "StrProg";
  24. string description = "DLL Demonstration Program";
  25. HINSTANCE hinst;
  26. // @BUG@ DMD assumes a module info symbol is always present when importing a module,
  27. // however a DLL doesn't export its moduleinfo symbol, therefore we add a dummy symbol
  28. // here to silence the linker.
  29. extern(C) int D6StrLib12__ModuleInfoZ;
  30. extern (Windows)
  31. int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
  32. {
  33. int result;
  34. try
  35. {
  36. Runtime.initialize();
  37. result = myWinMain(hInstance, hPrevInstance, lpCmdLine, iCmdShow);
  38. Runtime.terminate();
  39. }
  40. catch (Throwable o)
  41. {
  42. MessageBox(null, o.toString().toUTF16z, "Error", MB_OK | MB_ICONEXCLAMATION);
  43. result = 0;
  44. }
  45. return result;
  46. }
  47. int myWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
  48. {
  49. hinst = hInstance;
  50. HACCEL hAccel;
  51. HWND hwnd;
  52. MSG msg;
  53. WNDCLASS wndclass;
  54. wndclass.style = CS_HREDRAW | CS_VREDRAW;
  55. wndclass.lpfnWndProc = &WndProc;
  56. wndclass.cbClsExtra = 0;
  57. wndclass.cbWndExtra = 0;
  58. wndclass.hInstance = hInstance;
  59. wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  60. wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  61. wndclass.hbrBackground = cast(HBRUSH) GetStockObject(WHITE_BRUSH);
  62. wndclass.lpszMenuName = appName.toUTF16z;
  63. wndclass.lpszClassName = appName.toUTF16z;
  64. if (!RegisterClass(&wndclass))
  65. {
  66. MessageBox(NULL, "This program requires Windows NT!", appName.toUTF16z, MB_ICONERROR);
  67. return 0;
  68. }
  69. hwnd = CreateWindow(appName.toUTF16z, // window class name
  70. description.toUTF16z, // window caption
  71. WS_OVERLAPPEDWINDOW, // window style
  72. CW_USEDEFAULT, // initial x position
  73. CW_USEDEFAULT, // initial y position
  74. CW_USEDEFAULT, // initial x size
  75. CW_USEDEFAULT, // initial y size
  76. NULL, // parent window handle
  77. NULL, // window menu handle
  78. hInstance, // program instance handle
  79. NULL); // creation parameters
  80. ShowWindow(hwnd, iCmdShow);
  81. UpdateWindow(hwnd);
  82. while (GetMessage(&msg, NULL, 0, 0))
  83. {
  84. TranslateMessage(&msg);
  85. DispatchMessage(&msg);
  86. }
  87. return msg.wParam;
  88. }
  89. struct CBPARAM
  90. {
  91. HDC hdc;
  92. int xText;
  93. int yText;
  94. int xStart;
  95. int yStart;
  96. int xIncr;
  97. int yIncr;
  98. int xMax;
  99. int yMax;
  100. }
  101. __gshared wchar[MAX_LENGTH] szString = 0;
  102. extern (Windows)
  103. BOOL DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  104. {
  105. switch (message)
  106. {
  107. case WM_INITDIALOG:
  108. SendDlgItemMessage(hDlg, IDC_STRING, EM_LIMITTEXT, MAX_LENGTH, 0);
  109. return TRUE;
  110. case WM_COMMAND:
  111. switch (wParam)
  112. {
  113. case IDOK:
  114. GetDlgItemText(hDlg, IDC_STRING, szString.ptr, MAX_LENGTH);
  115. EndDialog(hDlg, TRUE);
  116. return TRUE;
  117. case IDCANCEL:
  118. EndDialog(hDlg, FALSE);
  119. return TRUE;
  120. default:
  121. }
  122. default:
  123. }
  124. return FALSE;
  125. }
  126. void WriteStrings(string[] strings, CBPARAM pcbp)
  127. {
  128. foreach (str; strings)
  129. {
  130. TextOut(pcbp.hdc, pcbp.xText, pcbp.yText, str.toUTF16z, str.length);
  131. pcbp.yText += pcbp.yIncr;
  132. if (pcbp.yText > pcbp.yMax)
  133. {
  134. pcbp.yText = pcbp.yStart;
  135. if ((pcbp.xText += pcbp.xIncr) > pcbp.xMax)
  136. return;
  137. }
  138. }
  139. }
  140. wstring fromWStringz(const wchar* s)
  141. {
  142. if (s is null)
  143. return null;
  144. wchar* ptr;
  145. for (ptr = cast(wchar*)s; *ptr; ++ptr) {}
  146. return to!wstring(s[0..ptr-s]);
  147. }
  148. extern (Windows)
  149. LRESULT WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) nothrow
  150. {
  151. scope (failure) assert(0);
  152. static HINSTANCE hInst;
  153. static int cxChar, cyChar, cxClient, cyClient;
  154. static UINT iDataChangeMsg;
  155. CBPARAM cbparam;
  156. HDC hdc;
  157. PAINTSTRUCT ps;
  158. TEXTMETRIC tm;
  159. switch (message)
  160. {
  161. case WM_CREATE:
  162. hInst = (cast(LPCREATESTRUCT)lParam).hInstance;
  163. hdc = GetDC(hwnd);
  164. GetTextMetrics(hdc, &tm);
  165. cxChar = cast(int)tm.tmAveCharWidth;
  166. cyChar = cast(int)(tm.tmHeight + tm.tmExternalLeading);
  167. ReleaseDC(hwnd, hdc);
  168. // Register message for notifying instances of data changes
  169. iDataChangeMsg = RegisterWindowMessage("StrProgDataChange");
  170. return 0;
  171. case WM_COMMAND:
  172. switch (wParam)
  173. {
  174. case IDM_ENTER:
  175. if (DialogBox(hInst, "EnterDlg", hwnd, &DlgProc))
  176. {
  177. AddString(to!string(fromWStringz(szString.ptr)));
  178. PostMessage(HWND_BROADCAST, iDataChangeMsg, 0, 0);
  179. }
  180. break;
  181. case IDM_DELETE:
  182. if (DialogBox(hInst, "DeleteDlg", hwnd, &DlgProc))
  183. {
  184. DeleteString(to!string(fromWStringz(szString.ptr)));
  185. PostMessage(HWND_BROADCAST, iDataChangeMsg, 0, 0);
  186. }
  187. break;
  188. default:
  189. }
  190. return 0;
  191. case WM_SIZE:
  192. cxClient = cast(int)LOWORD(lParam);
  193. cyClient = cast(int)HIWORD(lParam);
  194. return 0;
  195. case WM_PAINT:
  196. hdc = BeginPaint(hwnd, &ps);
  197. cbparam.hdc = hdc;
  198. cbparam.xText = cbparam.xStart = cxChar;
  199. cbparam.yText = cbparam.yStart = cyChar;
  200. cbparam.xIncr = cxChar * MAX_LENGTH;
  201. cbparam.yIncr = cyChar;
  202. cbparam.xMax = cbparam.xIncr * (1 + cxClient / cbparam.xIncr);
  203. cbparam.yMax = cyChar * (cyClient / cyChar - 1);
  204. WriteStrings(GetStrings(), cbparam);
  205. EndPaint(hwnd, &ps);
  206. return 0;
  207. case WM_DESTROY:
  208. PostQuitMessage(0);
  209. return 0;
  210. default:
  211. if (message == iDataChangeMsg)
  212. InvalidateRect(hwnd, NULL, TRUE);
  213. break;
  214. }
  215. return DefWindowProc(hwnd, message, wParam, lParam);
  216. }