PageRenderTime 46ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/Samples/Chap14/GrafMenu/GrafMenu.d

http://github.com/AndrejMitrovic/DWinProgramming
D | 340 lines | 240 code | 71 blank | 29 comment | 8 complexity | 859b59085b0b72153169edf920664e5e MD5 | raw file
  1. /+
  2. + Copyright (c) Charles Petzold, 1998.
  3. + Ported to the D Programming Language by Andrej Mitrovic, 2011.
  4. +/
  5. module GrafMenu;
  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 : count, toUTFz;
  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. import resource;
  24. string appName = "GrafMenu";
  25. string description = "Bitmap Menu Demonstration";
  26. HINSTANCE hinst;
  27. extern (Windows)
  28. int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
  29. {
  30. int result;
  31. try
  32. {
  33. Runtime.initialize();
  34. result = myWinMain(hInstance, hPrevInstance, lpCmdLine, iCmdShow);
  35. Runtime.terminate();
  36. }
  37. catch (Throwable o)
  38. {
  39. MessageBox(null, o.toString().toUTF16z, "Error", MB_OK | MB_ICONEXCLAMATION);
  40. result = 0;
  41. }
  42. return result;
  43. }
  44. int myWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
  45. {
  46. hinst = hInstance;
  47. HACCEL hAccel;
  48. HWND hwnd;
  49. MSG msg;
  50. WNDCLASS wndclass;
  51. wndclass.style = CS_HREDRAW | CS_VREDRAW;
  52. wndclass.lpfnWndProc = &WndProc;
  53. wndclass.cbClsExtra = 0;
  54. wndclass.cbWndExtra = 0;
  55. wndclass.hInstance = hInstance;
  56. wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  57. wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  58. wndclass.hbrBackground = cast(HBRUSH) GetStockObject(WHITE_BRUSH);
  59. wndclass.lpszMenuName = appName.toUTF16z;
  60. wndclass.lpszClassName = appName.toUTF16z;
  61. if (!RegisterClass(&wndclass))
  62. {
  63. MessageBox(NULL, "This program requires Windows NT!", appName.toUTF16z, MB_ICONERROR);
  64. return 0;
  65. }
  66. hwnd = CreateWindow(appName.toUTF16z, // window class name
  67. description.toUTF16z, // window caption
  68. WS_OVERLAPPEDWINDOW, // window style
  69. CW_USEDEFAULT, // initial x position
  70. CW_USEDEFAULT, // initial y position
  71. CW_USEDEFAULT, // initial x size
  72. CW_USEDEFAULT, // initial y size
  73. NULL, // parent window handle
  74. NULL, // window menu handle
  75. hInstance, // program instance handle
  76. NULL); // creation parameters
  77. ShowWindow(hwnd, iCmdShow);
  78. UpdateWindow(hwnd);
  79. while (GetMessage(&msg, NULL, 0, 0))
  80. {
  81. TranslateMessage(&msg);
  82. DispatchMessage(&msg);
  83. }
  84. return msg.wParam;
  85. }
  86. extern (Windows)
  87. LRESULT WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) nothrow
  88. {
  89. scope (failure) assert(0);
  90. HMENU hMenu;
  91. static int iCurrentFont = IDM_FONT_COUR;
  92. switch (message)
  93. {
  94. case WM_CREATE:
  95. AddHelpToSys((cast(LPCREATESTRUCT)lParam).hInstance, hwnd);
  96. hMenu = CreateMyMenu((cast(LPCREATESTRUCT)lParam).hInstance);
  97. SetMenu(hwnd, hMenu);
  98. CheckMenuItem(hMenu, iCurrentFont, MF_CHECKED);
  99. return 0;
  100. case WM_SYSCOMMAND:
  101. switch (LOWORD(wParam))
  102. {
  103. case IDM_HELP:
  104. MessageBox(hwnd, "Help not yet implemented!",
  105. appName.toUTF16z, MB_OK | MB_ICONEXCLAMATION);
  106. return 0;
  107. default:
  108. }
  109. break;
  110. case WM_COMMAND:
  111. switch (LOWORD(wParam))
  112. {
  113. case IDM_FILE_NEW:
  114. case IDM_FILE_OPEN:
  115. case IDM_FILE_SAVE:
  116. case IDM_FILE_SAVE_AS:
  117. case IDM_EDIT_UNDO:
  118. case IDM_EDIT_CUT:
  119. case IDM_EDIT_COPY:
  120. case IDM_EDIT_PASTE:
  121. case IDM_EDIT_CLEAR:
  122. MessageBeep(0);
  123. return 0;
  124. case IDM_FONT_COUR:
  125. case IDM_FONT_ARIAL:
  126. case IDM_FONT_TIMES:
  127. hMenu = GetMenu(hwnd);
  128. CheckMenuItem(hMenu, iCurrentFont, MF_UNCHECKED);
  129. iCurrentFont = LOWORD(wParam);
  130. CheckMenuItem(hMenu, iCurrentFont, MF_CHECKED);
  131. return 0;
  132. default:
  133. }
  134. break;
  135. case WM_DESTROY:
  136. DeleteAllBitmaps(hwnd);
  137. PostQuitMessage(0);
  138. return 0;
  139. default:
  140. }
  141. return DefWindowProc(hwnd, message, wParam, lParam);
  142. }
  143. /*----------------------------------------------------
  144. AddHelpToSys: Adds bitmap Help item to system menu
  145. ----------------------------------------------------*/
  146. void AddHelpToSys(HINSTANCE hInstance, HWND hwnd)
  147. {
  148. HBITMAP hBitmap;
  149. HMENU hMenu;
  150. hMenu = GetSystemMenu(hwnd, FALSE);
  151. hBitmap = StretchBitmap(LoadBitmap(hInstance, "BitmapHelp"));
  152. AppendMenu(hMenu, MF_SEPARATOR, 0, NULL);
  153. AppendMenu(hMenu, MF_BITMAP, IDM_HELP, cast(PTSTR)cast(LONG) hBitmap);
  154. }
  155. /*----------------------------------------------
  156. CreateMyMenu: Assembles menu from components
  157. ----------------------------------------------*/
  158. HMENU CreateMyMenu(HINSTANCE hInstance)
  159. {
  160. HBITMAP hBitmap;
  161. HMENU hMenu, hMenuPopup;
  162. int i;
  163. hMenu = CreateMenu();
  164. hMenuPopup = LoadMenu(hInstance, "MenuFile");
  165. hBitmap = StretchBitmap(LoadBitmap(hInstance, "BitmapFile"));
  166. AppendMenu(hMenu, MF_BITMAP | MF_POPUP, cast(int)hMenuPopup, cast(PTSTR)cast(LONG) hBitmap);
  167. hMenuPopup = LoadMenu(hInstance, "MenuEdit");
  168. hBitmap = StretchBitmap(LoadBitmap(hInstance, "BitmapEdit"));
  169. AppendMenu(hMenu, MF_BITMAP | MF_POPUP, cast(int)hMenuPopup, cast(PTSTR)cast(LONG) hBitmap);
  170. hMenuPopup = CreateMenu();
  171. for (i = 0; i < 3; i++)
  172. {
  173. hBitmap = GetBitmapFont(i);
  174. AppendMenu(hMenuPopup, MF_BITMAP, IDM_FONT_COUR + i, cast(PTSTR)cast(LONG) hBitmap);
  175. }
  176. hBitmap = StretchBitmap(LoadBitmap(hInstance, "BitmapFont"));
  177. AppendMenu(hMenu, MF_BITMAP | MF_POPUP, cast(int)hMenuPopup, cast(PTSTR)cast(LONG)hBitmap);
  178. return hMenu;
  179. }
  180. /*----------------------------------------------------
  181. StretchBitmap: Scales bitmap to display resolution
  182. ----------------------------------------------------*/
  183. HBITMAP StretchBitmap(HBITMAP hBitmap1)
  184. {
  185. BITMAP bm1, bm2;
  186. HBITMAP hBitmap2;
  187. HDC hdc, hdcMem1, hdcMem2;
  188. int cxChar, cyChar;
  189. // Get the width and height of a system font character
  190. cxChar = LOWORD(GetDialogBaseUnits());
  191. cyChar = HIWORD(GetDialogBaseUnits());
  192. // Create 2 memory DCs compatible with the display
  193. hdc = CreateIC("DISPLAY", NULL, NULL, NULL);
  194. hdcMem1 = CreateCompatibleDC(hdc);
  195. hdcMem2 = CreateCompatibleDC(hdc);
  196. DeleteDC(hdc);
  197. // Get the dimensions of the bitmap to be stretched
  198. GetObject(hBitmap1, BITMAP.sizeof, cast(PTSTR)&bm1);
  199. // Scale these dimensions based on the system font size
  200. bm2 = bm1;
  201. bm2.bmWidth = (cxChar * bm2.bmWidth) / 4;
  202. bm2.bmHeight = (cyChar * bm2.bmHeight) / 8;
  203. bm2.bmWidthBytes = ((bm2.bmWidth + 15) / 16) * 2;
  204. // Create a new bitmap of larger size
  205. hBitmap2 = CreateBitmapIndirect(&bm2);
  206. // Select the bitmaps in the memory DCs and do a StretchBlt
  207. SelectObject(hdcMem1, hBitmap1);
  208. SelectObject(hdcMem2, hBitmap2);
  209. StretchBlt(hdcMem2, 0, 0, bm2.bmWidth, bm2.bmHeight,
  210. hdcMem1, 0, 0, bm1.bmWidth, bm1.bmHeight, SRCCOPY);
  211. // Clean up
  212. DeleteDC(hdcMem1);
  213. DeleteDC(hdcMem2);
  214. DeleteObject(hBitmap1);
  215. return hBitmap2;
  216. }
  217. /*------------------------------------------------
  218. GetBitmapFont: Creates bitmaps with font names
  219. ------------------------------------------------*/
  220. HBITMAP GetBitmapFont(int i)
  221. {
  222. string[] szFaceName = ["Courier New", "Arial", "Times New Roman"];
  223. HBITMAP hBitmap;
  224. HDC hdc, hdcMem;
  225. HFONT hFont;
  226. SIZE size;
  227. TEXTMETRIC tm; // textmetric maybe?
  228. hdc = CreateIC("DISPLAY", NULL, NULL, NULL);
  229. GetTextMetrics(hdc, &tm);
  230. hdcMem = CreateCompatibleDC(hdc);
  231. hFont = CreateFont(2 * tm.tmHeight, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, szFaceName[i].toUTF16z);
  232. hFont = cast(HFONT)SelectObject(hdcMem, hFont);
  233. GetTextExtentPoint32(hdcMem, szFaceName[i].toUTF16z,
  234. szFaceName[i].count, &size);
  235. hBitmap = CreateBitmap(size.cx, size.cy, 1, 1, NULL);
  236. SelectObject(hdcMem, hBitmap);
  237. TextOut(hdcMem, 0, 0, szFaceName[i].toUTF16z, szFaceName[i].count);
  238. DeleteObject(SelectObject(hdcMem, hFont));
  239. DeleteDC(hdcMem);
  240. DeleteDC(hdc);
  241. return hBitmap;
  242. }
  243. /*-------------------------------------------------------
  244. DeleteAllBitmaps: Deletes all the bitmaps in the menu
  245. -------------------------------------------------------*/
  246. void DeleteAllBitmaps(HWND hwnd)
  247. {
  248. HMENU hMenu;
  249. int i;
  250. MENUITEMINFO mii = MENUITEMINFO(MENUITEMINFO.sizeof, MIIM_SUBMENU | MIIM_TYPE);
  251. // Delete Help bitmap on system menu
  252. hMenu = GetSystemMenu(hwnd, FALSE);
  253. GetMenuItemInfo(hMenu, IDM_HELP, FALSE, &mii);
  254. DeleteObject(cast(HBITMAP)mii.dwTypeData);
  255. // Delete top-level menu bitmaps
  256. hMenu = GetMenu(hwnd);
  257. for (i = 0; i < 3; i++)
  258. {
  259. GetMenuItemInfo(hMenu, i, TRUE, &mii);
  260. DeleteObject(cast(HBITMAP)mii.dwTypeData);
  261. }
  262. // Delete bitmap items on Font menu
  263. hMenu = mii.hSubMenu;;
  264. for (i = 0; i < 3; i++)
  265. {
  266. GetMenuItemInfo(hMenu, i, TRUE, &mii);
  267. DeleteObject(cast(HBITMAP)mii.dwTypeData);
  268. }
  269. }