/Samples/Chap09/Colors1/Colors1.d

http://github.com/AndrejMitrovic/DWinProgramming · D · 323 lines · 238 code · 69 blank · 16 comment · 12 complexity · 1eaf09cfbb47f54b31888dc5ef9e444d MD5 · raw file

  1. /+
  2. + Copyright (c) Charles Petzold, 1998.
  3. + Ported to the D Programming Language by Andrej Mitrovic, 2011.
  4. +/
  5. module Colors1;
  6. import core.runtime;
  7. import core.thread;
  8. import std.algorithm : max, min;
  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. import core.sys.windows.windef;
  20. import core.sys.windows.winuser;
  21. import core.sys.windows.wingdi;
  22. import core.sys.windows.winbase;
  23. int idFocus;
  24. WNDPROC[3] OldScroll;
  25. HINSTANCE hInst;
  26. extern (Windows)
  27. int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
  28. {
  29. int result;
  30. try
  31. {
  32. Runtime.initialize();
  33. result = myWinMain(hInstance, hPrevInstance, lpCmdLine, iCmdShow);
  34. Runtime.terminate();
  35. }
  36. catch (Throwable o)
  37. {
  38. MessageBox(null, o.toString().toUTF16z, "Error", MB_OK | MB_ICONEXCLAMATION);
  39. result = 0;
  40. }
  41. return result;
  42. }
  43. int myWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
  44. {
  45. hInst = hInstance;
  46. string appName = "Colors1";
  47. HWND hwnd;
  48. MSG msg;
  49. WNDCLASS wndclass;
  50. wndclass.style = CS_HREDRAW | CS_VREDRAW;
  51. wndclass.lpfnWndProc = &WndProc;
  52. wndclass.cbClsExtra = 0;
  53. wndclass.cbWndExtra = 0;
  54. wndclass.hInstance = hInstance;
  55. wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  56. wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  57. wndclass.hbrBackground = cast(HBRUSH) GetStockObject(WHITE_BRUSH);
  58. wndclass.lpszMenuName = NULL;
  59. wndclass.lpszClassName = appName.toUTF16z;
  60. if (!RegisterClass(&wndclass))
  61. {
  62. MessageBox(NULL, "This program requires Windows NT!", appName.toUTF16z, MB_ICONERROR);
  63. return 0;
  64. }
  65. hwnd = CreateWindow(appName.toUTF16z, // window class name
  66. "Color Scroll", // window caption
  67. WS_OVERLAPPEDWINDOW, // window style
  68. CW_USEDEFAULT, // initial x position
  69. CW_USEDEFAULT, // initial y position
  70. CW_USEDEFAULT, // initial x size
  71. CW_USEDEFAULT, // initial y size
  72. NULL, // parent window handle
  73. NULL, // window menu handle
  74. hInstance, // program instance handle
  75. NULL); // creation parameters
  76. ShowWindow(hwnd, iCmdShow);
  77. UpdateWindow(hwnd);
  78. while (GetMessage(&msg, NULL, 0, 0))
  79. {
  80. TranslateMessage(&msg);
  81. DispatchMessage(&msg);
  82. }
  83. return msg.wParam;
  84. }
  85. extern (Windows)
  86. LRESULT WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) nothrow
  87. {
  88. scope (failure) assert(0);
  89. static COLORREF[3] crPrim = [RGB(255, 0, 0), RGB(0, 255, 0), RGB(0, 0, 255)];
  90. static HBRUSH[3] hBrush;
  91. static HBRUSH hBrushStatic;
  92. static HWND[3] hwndScroll;
  93. static HWND[3] hwndLabel;
  94. static HWND[3] hwndValue;
  95. static HWND hwndRect;
  96. static int[3] color;
  97. static int cyChar;
  98. static RECT rcColor;
  99. immutable(wchar) *[] szColorLabel =
  100. [
  101. "Red", "Green",
  102. "Blue"
  103. ];
  104. HINSTANCE hInstance;
  105. int i, cxClient, cyClient;
  106. char[] szBuffer;
  107. switch (message)
  108. {
  109. case WM_CREATE:
  110. hInstance = cast(HINSTANCE)GetWindowLongPtr(hwnd, GWL_HINSTANCE);
  111. // Create the white-rectangle window against which the
  112. // scroll bars will be positioned. The child window ID is 9.
  113. hwndRect = CreateWindow("static", NULL,
  114. WS_CHILD | WS_VISIBLE | SS_WHITERECT,
  115. 0, 0, 0, 0,
  116. hwnd, cast(HMENU)9, hInstance, NULL);
  117. for (i = 0; i < 3; i++)
  118. {
  119. // The three scroll bars have IDs 0, 1, and 2, with
  120. // scroll bar ranges from 0 through 255.
  121. hwndScroll[i] = CreateWindow("scrollbar", NULL,
  122. WS_CHILD | WS_VISIBLE |
  123. WS_TABSTOP | SBS_VERT,
  124. 0, 0, 0, 0,
  125. hwnd, cast(HMENU)i, hInstance, NULL);
  126. SetScrollRange(hwndScroll[i], SB_CTL, 0, 255, FALSE);
  127. SetScrollPos(hwndScroll[i], SB_CTL, 0, FALSE);
  128. // The three color-name labels have IDs 3, 4, and 5,
  129. // and text strings "Red", "Green", and "Blue".
  130. hwndLabel[i] = CreateWindow("static", szColorLabel[i],
  131. WS_CHILD | WS_VISIBLE | SS_CENTER,
  132. 0, 0, 0, 0,
  133. hwnd, cast(HMENU)(i + 3),
  134. hInstance, NULL);
  135. // The three color-value text fields have IDs 6, 7,
  136. // and 8, and initial text strings of "0".
  137. hwndValue[i] = CreateWindow("static", "0",
  138. WS_CHILD | WS_VISIBLE | SS_CENTER,
  139. 0, 0, 0, 0,
  140. hwnd, cast(HMENU)(i + 6),
  141. hInstance, NULL);
  142. // override scrollbar's window procedure, keep old one since we'll use it
  143. OldScroll[i] = cast(WNDPROC) SetWindowLongPtr(hwndScroll[i], GWL_WNDPROC, cast(LONG)&ScrollProc);
  144. hBrush[i] = CreateSolidBrush(crPrim[i]);
  145. }
  146. hBrushStatic = CreateSolidBrush(GetSysColor(COLOR_BTNHIGHLIGHT));
  147. cyChar = HIWORD(GetDialogBaseUnits());
  148. return 0;
  149. case WM_SIZE:
  150. cxClient = LOWORD(lParam);
  151. cyClient = HIWORD(lParam);
  152. SetRect(&rcColor, cxClient / 2, 0, cxClient, cyClient);
  153. MoveWindow(hwndRect, 0, 0, cxClient / 2, cyClient, TRUE);
  154. for (i = 0; i < 3; i++)
  155. {
  156. MoveWindow(hwndScroll[i],
  157. (2 * i + 1) * cxClient / 14, 2 * cyChar,
  158. cxClient / 14, cyClient - 4 * cyChar, TRUE);
  159. MoveWindow(hwndLabel[i],
  160. (4 * i + 1) * cxClient / 28, cyChar / 2,
  161. cxClient / 7, cyChar, TRUE);
  162. MoveWindow(hwndValue[i],
  163. (4 * i + 1) * cxClient / 28,
  164. cyClient - 3 * cyChar / 2,
  165. cxClient / 7, cyChar, TRUE);
  166. }
  167. SetFocus(hwnd);
  168. return 0;
  169. case WM_SETFOCUS:
  170. SetFocus(hwndScroll[idFocus]);
  171. return 0;
  172. case WM_VSCROLL:
  173. i = GetWindowLongPtr(cast(HWND)lParam, GWL_ID);
  174. switch (LOWORD(wParam))
  175. {
  176. case SB_PAGEDOWN:
  177. color[i] += 15;
  178. goto case;
  179. // fall through
  180. case SB_LINEDOWN:
  181. color[i] = min(255, color[i] + 1);
  182. break;
  183. case SB_PAGEUP:
  184. color[i] -= 15;
  185. goto case;
  186. // fall through
  187. case SB_LINEUP:
  188. color[i] = max(0, color[i] - 1);
  189. break;
  190. case SB_TOP:
  191. color[i] = 0;
  192. break;
  193. case SB_BOTTOM:
  194. color[i] = 255;
  195. break;
  196. case SB_THUMBPOSITION:
  197. case SB_THUMBTRACK:
  198. color[i] = HIWORD(wParam);
  199. break;
  200. default:
  201. break;
  202. }
  203. SetScrollPos(hwndScroll[i], SB_CTL, color[i], TRUE);
  204. szBuffer = format("%s", color[i]).dup;
  205. SetWindowText(hwndValue[i], szBuffer.toUTF16z);
  206. // This sets the new class background, and deletes the old background brush
  207. DeleteObject(cast(HBRUSH)SetClassLong(hwnd, GCL_HBRBACKGROUND,
  208. cast(LONG)CreateSolidBrush(RGB(to!ubyte (color[0]), to!ubyte (color[1]), to!ubyte (color[2])))));
  209. InvalidateRect(hwnd, &rcColor, TRUE);
  210. return 0;
  211. case WM_CTLCOLORSCROLLBAR:
  212. i = GetWindowLongPtr(cast(HWND)lParam, GWL_ID);
  213. return cast(LRESULT)hBrush[i];
  214. case WM_CTLCOLORSTATIC:
  215. i = GetWindowLongPtr(cast(HWND)lParam, GWL_ID);
  216. if (i >= 3 && i <= 8) // static text controls
  217. {
  218. SetTextColor(cast(HDC)wParam, crPrim[i % 3]);
  219. SetBkColor(cast(HDC)wParam, GetSysColor(COLOR_BTNHIGHLIGHT));
  220. return cast(LRESULT)hBrushStatic;
  221. }
  222. break;
  223. case WM_SYSCOLORCHANGE:
  224. DeleteObject(hBrushStatic);
  225. hBrushStatic = CreateSolidBrush(GetSysColor(COLOR_BTNHIGHLIGHT));
  226. return 0;
  227. case WM_DESTROY:
  228. DeleteObject(cast(HBRUSH)SetClassLong(hwnd, GCL_HBRBACKGROUND, cast(LONG)GetStockObject(WHITE_BRUSH)));
  229. for (i = 0; i < 3; i++)
  230. DeleteObject(hBrush[i]);
  231. DeleteObject(hBrushStatic);
  232. PostQuitMessage(0);
  233. return 0;
  234. default:
  235. }
  236. return DefWindowProc(hwnd, message, wParam, lParam);
  237. }
  238. extern (Windows)
  239. LRESULT ScrollProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  240. {
  241. int id = GetWindowLongPtr(hwnd, GWL_ID);
  242. switch (message)
  243. {
  244. case WM_KEYDOWN:
  245. if (wParam == VK_TAB)
  246. SetFocus(GetDlgItem(GetParent(hwnd), (id + (GetKeyState(VK_SHIFT) < 0 ? 2 : 1)) % 3));
  247. break;
  248. case WM_SETFOCUS:
  249. idFocus = id;
  250. break;
  251. default:
  252. }
  253. return CallWindowProc(OldScroll[id], hwnd, message, wParam, lParam);
  254. }