PageRenderTime 51ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/Samples/Chap15/ShowDib2/Showdib2.d

http://github.com/AndrejMitrovic/DWinProgramming
D | 415 lines | 300 code | 97 blank | 18 comment | 28 complexity | 5a491a7719fbfe55f26b3e3e3f8eb23e MD5 | raw file
  1. /+
  2. + Copyright (c) Charles Petzold, 1998.
  3. + Ported to the D Programming Language by Andrej Mitrovic, 2011.
  4. +/
  5. module Showdib2;
  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. import core.sys.windows.windef;
  21. import core.sys.windows.winuser;
  22. import core.sys.windows.wingdi;
  23. import core.sys.windows.winbase;
  24. import core.sys.windows.commdlg;
  25. import resource;
  26. import DibFile;
  27. string appName = "Showdib2";
  28. string description = "Show DIB #2";
  29. HINSTANCE hinst;
  30. enum GMEM_SHARE = 8192;
  31. extern (Windows)
  32. int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
  33. {
  34. int result;
  35. try
  36. {
  37. Runtime.initialize();
  38. result = myWinMain(hInstance, hPrevInstance, lpCmdLine, iCmdShow);
  39. Runtime.terminate();
  40. }
  41. catch (Throwable o)
  42. {
  43. MessageBox(null, o.toString().toUTF16z, "Error", MB_OK | MB_ICONEXCLAMATION);
  44. result = 0;
  45. }
  46. return result;
  47. }
  48. int myWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
  49. {
  50. hinst = hInstance;
  51. HACCEL hAccel;
  52. HWND hwnd;
  53. MSG msg;
  54. WNDCLASS wndclass;
  55. wndclass.style = CS_HREDRAW | CS_VREDRAW;
  56. wndclass.lpfnWndProc = &WndProc;
  57. wndclass.cbClsExtra = 0;
  58. wndclass.cbWndExtra = 0;
  59. wndclass.hInstance = hInstance;
  60. wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  61. wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  62. wndclass.hbrBackground = cast(HBRUSH) GetStockObject(WHITE_BRUSH);
  63. wndclass.lpszMenuName = appName.toUTF16z;
  64. wndclass.lpszClassName = appName.toUTF16z;
  65. if (!RegisterClass(&wndclass))
  66. {
  67. MessageBox(NULL, "This program requires Windows NT!", appName.toUTF16z, MB_ICONERROR);
  68. return 0;
  69. }
  70. hwnd = CreateWindow(appName.toUTF16z, // window class name
  71. description.toUTF16z, // window caption
  72. WS_OVERLAPPEDWINDOW, // window style
  73. CW_USEDEFAULT, // initial x position
  74. CW_USEDEFAULT, // initial y position
  75. CW_USEDEFAULT, // initial x size
  76. CW_USEDEFAULT, // initial y size
  77. NULL, // parent window handle
  78. NULL, // window menu handle
  79. hInstance, // program instance handle
  80. NULL); // creation parameters
  81. ShowWindow(hwnd, iCmdShow);
  82. UpdateWindow(hwnd);
  83. while (GetMessage(&msg, NULL, 0, 0))
  84. {
  85. TranslateMessage(&msg);
  86. DispatchMessage(&msg);
  87. }
  88. return msg.wParam;
  89. }
  90. int ShowDib(HDC hdc, BITMAPINFO* pbmi, BYTE* pBits, int cxDib, int cyDib,
  91. int cxClient, int cyClient, WORD wShow)
  92. {
  93. switch (wShow)
  94. {
  95. case IDM_SHOW_NORMAL:
  96. return SetDIBitsToDevice(hdc, 0, 0, cxDib, cyDib, 0, 0,
  97. 0, cyDib, pBits, pbmi, DIB_RGB_COLORS);
  98. case IDM_SHOW_CENTER:
  99. return SetDIBitsToDevice(hdc, (cxClient - cxDib) / 2,
  100. (cyClient - cyDib) / 2,
  101. cxDib, cyDib, 0, 0,
  102. 0, cyDib, pBits, pbmi, DIB_RGB_COLORS);
  103. case IDM_SHOW_STRETCH:
  104. SetStretchBltMode(hdc, COLORONCOLOR);
  105. return StretchDIBits(hdc, 0, 0, cxClient, cyClient,
  106. 0, 0, cxDib, cyDib,
  107. pBits, pbmi, DIB_RGB_COLORS, SRCCOPY);
  108. case IDM_SHOW_ISOSTRETCH:
  109. SetStretchBltMode(hdc, COLORONCOLOR);
  110. SetMapMode(hdc, MM_ISOTROPIC);
  111. SetWindowExtEx(hdc, cxDib, cyDib, NULL);
  112. SetViewportExtEx(hdc, cxClient, cyClient, NULL);
  113. SetWindowOrgEx(hdc, cxDib / 2, cyDib / 2, NULL);
  114. SetViewportOrgEx(hdc, cxClient / 2, cyClient / 2, NULL);
  115. return StretchDIBits(hdc, 0, 0, cxDib, cyDib,
  116. 0, 0, cxDib, cyDib,
  117. pBits, pbmi, DIB_RGB_COLORS, SRCCOPY);
  118. default:
  119. }
  120. return 0;
  121. }
  122. __gshared wchar[MAX_PATH] szFileName = 0;
  123. __gshared wchar[MAX_PATH] szTitleName = 0;
  124. extern (Windows)
  125. LRESULT WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) nothrow
  126. {
  127. scope (failure) assert(0);
  128. static BITMAPFILEHEADER* pbmfh;
  129. static BITMAPINFO* pbmi;
  130. static BYTE* pBits;
  131. static DOCINFO di = DOCINFO(DOCINFO.sizeof, "ShowDib2: Printing");
  132. static int cxClient, cyClient, cxDib, cyDib;
  133. static PRINTDLG printdlg = PRINTDLG(PRINTDLG.sizeof);
  134. static WORD wShow = IDM_SHOW_NORMAL;
  135. BOOL bSuccess;
  136. HDC hdc, hdcPrn;
  137. HGLOBAL hGlobal;
  138. HMENU hMenu;
  139. int cxPage, cyPage, iEnable;
  140. PAINTSTRUCT ps;
  141. ubyte* pGlobal;
  142. switch (message)
  143. {
  144. case WM_CREATE:
  145. DibFileInitialize(hwnd);
  146. return 0;
  147. case WM_SIZE:
  148. cxClient = LOWORD(lParam);
  149. cyClient = HIWORD(lParam);
  150. return 0;
  151. case WM_INITMENUPOPUP:
  152. hMenu = GetMenu(hwnd);
  153. if (pbmfh)
  154. iEnable = MF_ENABLED;
  155. else
  156. iEnable = MF_GRAYED;
  157. EnableMenuItem(hMenu, IDM_FILE_SAVE, iEnable);
  158. EnableMenuItem(hMenu, IDM_FILE_PRINT, iEnable);
  159. EnableMenuItem(hMenu, IDM_EDIT_CUT, iEnable);
  160. EnableMenuItem(hMenu, IDM_EDIT_COPY, iEnable);
  161. EnableMenuItem(hMenu, IDM_EDIT_DELETE, iEnable);
  162. return 0;
  163. case WM_COMMAND:
  164. hMenu = GetMenu(hwnd);
  165. switch (LOWORD(wParam))
  166. {
  167. case IDM_FILE_OPEN:
  168. // Show the File Open dialog box
  169. if (!DibFileOpenDlg(hwnd, szFileName.ptr, szTitleName.ptr))
  170. return 0;
  171. // If there's an existing DIB, GC.free the memory
  172. if (pbmfh)
  173. {
  174. GC.free(pbmfh);
  175. pbmfh = NULL;
  176. }
  177. // Load the entire DIB into memory
  178. SetCursor(LoadCursor(NULL, IDC_WAIT));
  179. ShowCursor(TRUE);
  180. pbmfh = DibLoadImage(to!string(szFileName[]));
  181. ShowCursor(FALSE);
  182. SetCursor(LoadCursor(NULL, IDC_ARROW));
  183. // Invalidate the client area for later update
  184. InvalidateRect(hwnd, NULL, TRUE);
  185. if (pbmfh is null)
  186. {
  187. MessageBox(hwnd, "Cannot load DIB file",
  188. appName.toUTF16z, MB_ICONEXCLAMATION | MB_OK);
  189. return 0;
  190. }
  191. // Get pointers to the info structure & the bits
  192. pbmi = cast(BITMAPINFO*)(pbmfh + 1);
  193. pBits = cast(BYTE*)pbmfh + pbmfh.bfOffBits;
  194. // Get the DIB width and height
  195. if (pbmi.bmiHeader.biSize == BITMAPCOREHEADER.sizeof)
  196. {
  197. cxDib = (cast(BITMAPCOREHEADER*)pbmi).bcWidth;
  198. cyDib = (cast(BITMAPCOREHEADER*)pbmi).bcHeight;
  199. }
  200. else
  201. {
  202. cxDib = pbmi.bmiHeader.biWidth;
  203. cyDib = abs(pbmi.bmiHeader.biHeight);
  204. }
  205. return 0;
  206. case IDM_FILE_SAVE:
  207. // Show the File Save dialog box
  208. if (!DibFileSaveDlg(hwnd, szFileName.ptr, szTitleName.ptr))
  209. return 0;
  210. // Save the DIB to a disk file
  211. SetCursor(LoadCursor(NULL, IDC_WAIT));
  212. ShowCursor(TRUE);
  213. bSuccess = DibSaveImage(szFileName.ptr, pbmfh);
  214. ShowCursor(FALSE);
  215. SetCursor(LoadCursor(NULL, IDC_ARROW));
  216. if (!bSuccess)
  217. MessageBox(hwnd, "Cannot save DIB file",
  218. appName.toUTF16z, MB_ICONEXCLAMATION | MB_OK);
  219. return 0;
  220. case IDM_FILE_PRINT:
  221. if (!pbmfh)
  222. return 0;
  223. // Get printer DC
  224. printdlg.Flags = PD_RETURNDC | PD_NOPAGENUMS | PD_NOSELECTION;
  225. if (!PrintDlg(&printdlg))
  226. return 0;
  227. if (NULL == (hdcPrn = printdlg.hDC))
  228. {
  229. MessageBox(hwnd, "Cannot obtain Printer DC",
  230. appName.toUTF16z, MB_ICONEXCLAMATION | MB_OK);
  231. return 0;
  232. }
  233. // Check if the printer can print bitmaps
  234. if (!(RC_BITBLT & GetDeviceCaps(hdcPrn, RASTERCAPS)))
  235. {
  236. DeleteDC(hdcPrn);
  237. MessageBox(hwnd, "Printer cannot print bitmaps",
  238. appName.toUTF16z, MB_ICONEXCLAMATION | MB_OK);
  239. return 0;
  240. }
  241. // Get size of printable area of page
  242. cxPage = GetDeviceCaps(hdcPrn, HORZRES);
  243. cyPage = GetDeviceCaps(hdcPrn, VERTRES);
  244. bSuccess = FALSE;
  245. // Send the DIB to the printer
  246. SetCursor(LoadCursor(NULL, IDC_WAIT));
  247. ShowCursor(TRUE);
  248. if ((StartDoc(hdcPrn, &di) > 0) && (StartPage(hdcPrn) > 0))
  249. {
  250. ShowDib(hdcPrn, pbmi, pBits, cxDib, cyDib,
  251. cxPage, cyPage, wShow);
  252. if (EndPage(hdcPrn) > 0)
  253. {
  254. bSuccess = TRUE;
  255. EndDoc(hdcPrn);
  256. }
  257. }
  258. ShowCursor(FALSE);
  259. SetCursor(LoadCursor(NULL, IDC_ARROW));
  260. DeleteDC(hdcPrn);
  261. if (!bSuccess)
  262. MessageBox(hwnd, "Could not print bitmap",
  263. appName.toUTF16z, MB_ICONEXCLAMATION | MB_OK);
  264. return 0;
  265. case IDM_EDIT_COPY:
  266. case IDM_EDIT_CUT:
  267. if (!pbmfh)
  268. return 0;
  269. // Make a copy of the packed DIB
  270. hGlobal = GlobalAlloc(GHND | GMEM_SHARE, pbmfh.bfSize - BITMAPFILEHEADER.sizeof);
  271. pGlobal = cast(typeof(pGlobal))GlobalLock(hGlobal);
  272. auto newlength = pbmfh.bfSize - BITMAPFILEHEADER.sizeof;
  273. pGlobal[0..newlength] = (cast(BYTE*)pbmfh + BITMAPFILEHEADER.sizeof)[0..newlength];
  274. GlobalUnlock(hGlobal);;
  275. // Transfer it to the clipboard
  276. OpenClipboard(hwnd);
  277. EmptyClipboard();
  278. SetClipboardData(CF_DIB, hGlobal);
  279. CloseClipboard();
  280. if (LOWORD(wParam) == IDM_EDIT_COPY)
  281. return 0;
  282. goto case IDM_EDIT_DELETE;
  283. case IDM_EDIT_DELETE:
  284. if (pbmfh)
  285. {
  286. GC.free(pbmfh);
  287. pbmfh = NULL;
  288. InvalidateRect(hwnd, NULL, TRUE);
  289. }
  290. return 0;
  291. case IDM_SHOW_NORMAL:
  292. case IDM_SHOW_CENTER:
  293. case IDM_SHOW_STRETCH:
  294. case IDM_SHOW_ISOSTRETCH:
  295. CheckMenuItem(hMenu, wShow, MF_UNCHECKED);
  296. wShow = LOWORD(wParam);
  297. CheckMenuItem(hMenu, wShow, MF_CHECKED);
  298. InvalidateRect(hwnd, NULL, TRUE);
  299. return 0;
  300. default:
  301. }
  302. break;
  303. case WM_PAINT:
  304. hdc = BeginPaint(hwnd, &ps);
  305. if (pbmfh)
  306. ShowDib(hdc, pbmi, pBits, cxDib, cyDib,
  307. cxClient, cyClient, wShow);
  308. EndPaint(hwnd, &ps);
  309. return 0;
  310. case WM_DESTROY:
  311. if (pbmfh)
  312. GC.free(pbmfh);
  313. PostQuitMessage(0);
  314. return 0;
  315. default:
  316. }
  317. return DefWindowProc(hwnd, message, wParam, lParam);
  318. }