PageRenderTime 56ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/Samples/Chap10/PoePoem/PoePoem.d

http://github.com/AndrejMitrovic/DWinProgramming
D | 227 lines | 173 code | 45 blank | 9 comment | 6 complexity | 932b9776e9627f9a86fefbcaa1c59d8a MD5 | raw file
  1. /+
  2. + Copyright (c) Charles Petzold, 1998.
  3. + Ported to the D Programming Language by Andrej Mitrovic, 2011.
  4. +/
  5. module PoePoem;
  6. /+
  7. + The code sample assumes the text resource is ASCII.
  8. + A safer option is to use the import() expression
  9. + or a module ctor for loading text resources.
  10. +/
  11. import core.runtime;
  12. import core.thread;
  13. import std.algorithm : max, min;
  14. import std.conv;
  15. import std.math;
  16. import std.range;
  17. import std.string;
  18. import std.stdio;
  19. import std.utf : count, toUTFz;
  20. auto toUTF16z(S)(S s)
  21. {
  22. return toUTFz!(const(wchar)*)(s);
  23. }
  24. pragma(lib, "gdi32.lib");
  25. import core.sys.windows.windef;
  26. import core.sys.windows.winuser;
  27. import core.sys.windows.wingdi;
  28. import core.sys.windows.winbase;
  29. import resource;
  30. enum ID_TIMER = 1;
  31. HINSTANCE hinst;
  32. extern (Windows)
  33. int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
  34. {
  35. int result;
  36. try
  37. {
  38. Runtime.initialize();
  39. result = myWinMain(hInstance, hPrevInstance, lpCmdLine, iCmdShow);
  40. Runtime.terminate();
  41. }
  42. catch (Throwable o)
  43. {
  44. MessageBox(null, o.toString().toUTF16z, "Error", MB_OK | MB_ICONEXCLAMATION);
  45. result = 0;
  46. }
  47. return result;
  48. }
  49. int myWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
  50. {
  51. TCHAR[16] szAppName;
  52. TCHAR[64] szCaption;
  53. TCHAR[64] szErrMsg;
  54. HWND hwnd;
  55. MSG msg;
  56. WNDCLASS wndclass;
  57. LoadString(hInstance, IDS_APPNAME, szAppName.ptr, szAppName.count);
  58. LoadString(hInstance, IDS_CAPTION, szCaption.ptr, szCaption.count);
  59. wndclass.style = CS_HREDRAW | CS_VREDRAW;
  60. wndclass.lpfnWndProc = &WndProc;
  61. wndclass.cbClsExtra = 0;
  62. wndclass.cbWndExtra = 0;
  63. wndclass.hInstance = hInstance;
  64. wndclass.hIcon = LoadIcon(hInstance, szAppName.ptr);
  65. wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  66. wndclass.hbrBackground = cast(HBRUSH) GetStockObject(WHITE_BRUSH);
  67. wndclass.lpszMenuName = NULL;
  68. wndclass.lpszClassName = szAppName.ptr;
  69. if (!RegisterClass(&wndclass))
  70. {
  71. MessageBox(NULL, "This program requires Windows NT!", szAppName.ptr, MB_ICONERROR);
  72. return 0;
  73. }
  74. hwnd = CreateWindow(szAppName.ptr, // window class name
  75. szCaption.ptr, // window caption
  76. WS_OVERLAPPEDWINDOW, // window style
  77. CW_USEDEFAULT, // initial x position
  78. CW_USEDEFAULT, // initial y position
  79. CW_USEDEFAULT, // initial x size
  80. CW_USEDEFAULT, // initial y size
  81. NULL, // parent window handle
  82. NULL, // window menu handle
  83. hInstance, // program instance handle
  84. NULL); // creation parameters
  85. ShowWindow(hwnd, iCmdShow);
  86. UpdateWindow(hwnd);
  87. while (GetMessage(&msg, NULL, 0, 0))
  88. {
  89. TranslateMessage(&msg);
  90. DispatchMessage(&msg);
  91. }
  92. return msg.wParam;
  93. }
  94. extern (Windows)
  95. LRESULT WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) nothrow
  96. {
  97. scope (failure) assert(0);
  98. static string pText;
  99. static HGLOBAL hResource;
  100. static HWND hScroll;
  101. static int iPosition, cxChar, cyChar, cyClient, iNumLines, xScroll;
  102. HDC hdc;
  103. PAINTSTRUCT ps;
  104. RECT rect;
  105. TEXTMETRIC tm;
  106. switch (message)
  107. {
  108. case WM_CREATE:
  109. hdc = GetDC(hwnd);
  110. GetTextMetrics(hdc, &tm);
  111. cxChar = tm.tmAveCharWidth;
  112. cyChar = tm.tmHeight + tm.tmExternalLeading;
  113. ReleaseDC(hwnd, hdc);
  114. xScroll = GetSystemMetrics(SM_CXVSCROLL);
  115. hScroll = CreateWindow("scrollbar", NULL,
  116. WS_CHILD | WS_VISIBLE | SBS_VERT,
  117. 0, 0, 0, 0,
  118. hwnd, cast(HMENU)1, hinst, NULL);
  119. hResource = LoadResource(hinst, FindResource(hinst, "AnnabelLee", "TEXT"));
  120. pText = to!string(cast(char*)LockResource(hResource));
  121. iNumLines = std.algorithm.count(pText, '\n');
  122. SetScrollRange(hScroll, SB_CTL, 0, iNumLines, FALSE);
  123. SetScrollPos(hScroll, SB_CTL, 0, FALSE);
  124. return 0;
  125. case WM_SIZE:
  126. MoveWindow(hScroll, LOWORD(lParam) - xScroll, 0,
  127. xScroll, cyClient = HIWORD(lParam), TRUE);
  128. SetFocus(hwnd);
  129. return 0;
  130. case WM_SETFOCUS:
  131. SetFocus(hScroll);
  132. return 0;
  133. case WM_VSCROLL:
  134. switch (wParam)
  135. {
  136. case SB_TOP:
  137. iPosition = 0;
  138. break;
  139. case SB_BOTTOM:
  140. iPosition = iNumLines;
  141. break;
  142. case SB_LINEUP:
  143. iPosition -= 1;
  144. break;
  145. case SB_LINEDOWN:
  146. iPosition += 1;
  147. break;
  148. case SB_PAGEUP:
  149. iPosition -= cyClient / cyChar;
  150. break;
  151. case SB_PAGEDOWN:
  152. iPosition += cyClient / cyChar;
  153. break;
  154. case SB_THUMBPOSITION:
  155. iPosition = LOWORD(lParam);
  156. break;
  157. default:
  158. }
  159. iPosition = max(0, min(iPosition, iNumLines));
  160. if (iPosition != GetScrollPos(hScroll, SB_CTL))
  161. {
  162. SetScrollPos(hScroll, SB_CTL, iPosition, TRUE);
  163. InvalidateRect(hwnd, NULL, TRUE);
  164. }
  165. return 0;
  166. case WM_PAINT:
  167. hdc = BeginPaint(hwnd, &ps);
  168. scope(exit) EndPaint(hwnd, &ps);
  169. pText = to!string(cast(char*)LockResource(hResource));
  170. GetClientRect(hwnd, &rect);
  171. rect.left += cxChar;
  172. rect.top += cyChar * (1 - iPosition);
  173. DrawText(hdc, pText.toUTF16z, -1, &rect, DT_EXTERNALLEADING);
  174. return 0;
  175. case WM_DESTROY:
  176. FreeResource(hResource);
  177. PostQuitMessage(0);
  178. return 0;
  179. default:
  180. }
  181. return DefWindowProc(hwnd, message, wParam, lParam);
  182. }