PageRenderTime 79ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/Samples/Chap15/DibHeads/DibHeads.d

http://github.com/AndrejMitrovic/DWinProgramming
D | 421 lines | 332 code | 72 blank | 17 comment | 22 complexity | 6409571c1fa317d575a950998c990ef7 MD5 | raw file
  1. /+
  2. + Copyright (c) Charles Petzold, 1998.
  3. + Ported to the D Programming Language by Andrej Mitrovic, 2011.
  4. +/
  5. module DibHeads;
  6. import core.memory;
  7. import core.runtime;
  8. import core.thread;
  9. import std.algorithm : min, max;
  10. import std.conv;
  11. import std.math;
  12. import std.range;
  13. import std.string;
  14. import std.utf;
  15. auto toUTF16z(S)(S s)
  16. {
  17. return toUTFz!(const(wchar)*)(s);
  18. }
  19. pragma(lib, "gdi32.lib");
  20. pragma(lib, "comdlg32.lib");
  21. import core.sys.windows.windef;
  22. import core.sys.windows.winuser;
  23. import core.sys.windows.wingdi;
  24. import core.sys.windows.winbase;
  25. import core.sys.windows.commdlg;
  26. import resource;
  27. string appName = "DibHeads";
  28. string description = "DIB Headers";
  29. HINSTANCE hinst;
  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. enum WINVER = 0x0500; // ?
  90. void hwndPrint(A, B, C...)(A hwnd, B szFormat, C values)
  91. {
  92. static if (C.length < 1)
  93. {
  94. string szBuffer = szFormat;
  95. }
  96. else
  97. {
  98. string szBuffer = format(szFormat, values);
  99. }
  100. SendMessage (hwnd, EM_SETSEL, cast(WPARAM) -1, cast(LPARAM) -1);
  101. SendMessage (hwnd, EM_REPLACESEL, FALSE, cast(LPARAM)szBuffer.toUTF16z);
  102. SendMessage (hwnd, EM_SCROLLCARET, 0, 0);
  103. }
  104. void DisplayDibHeaders(HWND hwnd, string szFileName)
  105. {
  106. static string[] szInfoName = ["BITMAPCOREHEADER",
  107. "BITMAPINFOHEADER",
  108. "BITMAPV4HEADER",
  109. "BITMAPV5HEADER"];
  110. static string[] szCompression = ["BI_RGB", "BI_RLE8",
  111. "BI_RLE4",
  112. "BI_BITFIELDS",
  113. "unknown"];
  114. BITMAPCOREHEADER* pbmch;
  115. BITMAPFILEHEADER* pbmfh;
  116. BITMAPV5HEADER* pbmih;
  117. BOOL bSuccess;
  118. DWORD dwFileSize, dwHighSize, dwBytesRead;
  119. HANDLE hFile;
  120. int i;
  121. PBYTE pFile;
  122. TCHAR* szV;
  123. // Display the file name
  124. hwndPrint(hwnd, "File: %s\r\n\r\n", szFileName);
  125. // Open the file
  126. hFile = CreateFile(szFileName.toUTF16z, GENERIC_READ, FILE_SHARE_READ, NULL,
  127. OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  128. if (hFile == INVALID_HANDLE_VALUE)
  129. {
  130. hwndPrint(hwnd, "Cannot open file.\r\n\r\n");
  131. return;
  132. }
  133. // Get the size of the file
  134. dwFileSize = GetFileSize(hFile, &dwHighSize);
  135. if (dwHighSize)
  136. {
  137. hwndPrint(hwnd, "Cannot deal with >4G files.\r\n\r\n");
  138. CloseHandle(hFile);
  139. return;
  140. }
  141. // Allocate memory for the file
  142. pFile = cast(typeof(pFile))GC.malloc(dwFileSize);
  143. if (!pFile)
  144. {
  145. hwndPrint(hwnd, "Cannot allocate memory.\r\n\r\n");
  146. CloseHandle(hFile);
  147. return;
  148. }
  149. // Read the file
  150. SetCursor(LoadCursor(NULL, IDC_WAIT));
  151. ShowCursor(TRUE);
  152. bSuccess = ReadFile(hFile, pFile, dwFileSize, &dwBytesRead, NULL);
  153. ShowCursor(FALSE);
  154. SetCursor(LoadCursor(NULL, IDC_ARROW));
  155. if (!bSuccess || (dwBytesRead != dwFileSize))
  156. {
  157. hwndPrint(hwnd, "Could not read file.\r\n\r\n");
  158. CloseHandle(hFile);
  159. GC.free(pFile);
  160. return;
  161. }
  162. // Close the file
  163. CloseHandle(hFile);
  164. // Display file size
  165. hwndPrint(hwnd, "File size = %s bytes\r\n\r\n", dwFileSize);
  166. // Display BITMAPFILEHEADER structure
  167. pbmfh = cast(BITMAPFILEHEADER*)pFile;
  168. hwndPrint(hwnd, "BITMAPFILEHEADER\r\n");
  169. hwndPrint(hwnd, "\t.bfType = 0x%x\r\n", pbmfh.bfType);
  170. hwndPrint(hwnd, "\t.bfSize = %s\r\n", pbmfh.bfSize);
  171. hwndPrint(hwnd, "\t.bfReserved1 = %s\r\n", pbmfh.bfReserved1);
  172. hwndPrint(hwnd, "\t.bfReserved2 = %s\r\n", pbmfh.bfReserved2);
  173. hwndPrint(hwnd, "\t.bfOffBits = %s\r\n\r\n", pbmfh.bfOffBits);
  174. // Determine which information structure we have
  175. pbmih = cast(BITMAPV5HEADER*)(pFile + BITMAPFILEHEADER.sizeof);
  176. switch (pbmih.bV5Size)
  177. {
  178. case BITMAPCOREHEADER.sizeof:
  179. i = 0;
  180. break;
  181. case BITMAPINFOHEADER.sizeof:
  182. i = 1;
  183. szV = "i"w.dup.ptr;
  184. break;
  185. case BITMAPV4HEADER.sizeof:
  186. i = 2;
  187. szV = "V4"w.dup.ptr;
  188. break;
  189. case BITMAPV5HEADER.sizeof:
  190. i = 3;
  191. szV = "V5"w.dup.ptr;
  192. break;
  193. default:
  194. hwndPrint(hwnd, "Unknown header size of %s.\r\n\r\n", pbmih.bV5Size);
  195. GC.free(pFile);
  196. return;
  197. }
  198. hwndPrint(hwnd, "%s\r\n", szInfoName[i]);
  199. // Display the BITMAPCOREHEADER fields
  200. if (pbmih.bV5Size == BITMAPCOREHEADER.sizeof)
  201. {
  202. pbmch = cast(BITMAPCOREHEADER*)pbmih;
  203. hwndPrint(hwnd, "\t.bcSize = %s\r\n", pbmch.bcSize);
  204. hwndPrint(hwnd, "\t.bcWidth = %s\r\n", pbmch.bcWidth);
  205. hwndPrint(hwnd, "\t.bcHeight = %s\r\n", pbmch.bcHeight);
  206. hwndPrint(hwnd, "\t.bcPlanes = %s\r\n", pbmch.bcPlanes);
  207. hwndPrint(hwnd, "\t.bcBitCount = %s\r\n\r\n", pbmch.bcBitCount);
  208. GC.free(pFile);
  209. return;
  210. }
  211. // Display the BITMAPINFOHEADER fields
  212. hwndPrint(hwnd, "\t.b%sSize = %s\r\n", szV, pbmih.bV5Size);
  213. hwndPrint(hwnd, "\t.b%sWidth = %s\r\n", szV, pbmih.bV5Width);
  214. hwndPrint(hwnd, "\t.b%sHeight = %s\r\n", szV, pbmih.bV5Height);
  215. hwndPrint(hwnd, "\t.b%sPlanes = %s\r\n", szV, pbmih.bV5Planes);
  216. hwndPrint(hwnd, "\t.b%sBitCount = %s\r\n", szV, pbmih.bV5BitCount);
  217. hwndPrint(hwnd, "\t.b%sCompression = %s\r\n", szV,
  218. szCompression [min(4, pbmih.bV5Compression)]);
  219. hwndPrint(hwnd, "\t.b%sSizeImage = %s\r\n", szV, pbmih.bV5SizeImage);
  220. hwndPrint(hwnd, "\t.b%sXPelsPerMeter = %s\r\n", szV,
  221. pbmih.bV5XPelsPerMeter);
  222. hwndPrint(hwnd, "\t.b%sYPelsPerMeter = %s\r\n", szV,
  223. pbmih.bV5YPelsPerMeter);
  224. hwndPrint(hwnd, "\t.b%sClrUsed = %s\r\n", szV, pbmih.bV5ClrUsed);
  225. hwndPrint(hwnd, "\t.b%sClrImportant = %s\r\n\r\n", szV,
  226. pbmih.bV5ClrImportant);
  227. if (pbmih.bV5Size == BITMAPINFOHEADER.sizeof)
  228. {
  229. if (pbmih.bV5Compression == BI_BITFIELDS)
  230. {
  231. hwndPrint(hwnd, "Red Mask = %08x\r\n",
  232. pbmih.bV5RedMask);
  233. hwndPrint(hwnd, "Green Mask = %08x\r\n",
  234. pbmih.bV5GreenMask);
  235. hwndPrint(hwnd, "Blue Mask = %08x\r\n\r\n",
  236. pbmih.bV5BlueMask);
  237. }
  238. GC.free(pFile);
  239. return;
  240. }
  241. // Display additional BITMAPV4HEADER fields
  242. hwndPrint(hwnd, "\t.b%sRedMask = %08x\r\n", szV,
  243. pbmih.bV5RedMask);
  244. hwndPrint(hwnd, "\t.b%sGreenMask = %08x\r\n", szV,
  245. pbmih.bV5GreenMask);
  246. hwndPrint(hwnd, "\t.b%sBlueMask = %08x\r\n", szV,
  247. pbmih.bV5BlueMask);
  248. hwndPrint(hwnd, "\t.b%sAlphaMask = %08x\r\n", szV,
  249. pbmih.bV5AlphaMask);
  250. hwndPrint(hwnd, "\t.b%sCSType = %s\r\n", szV,
  251. pbmih.bV5CSType);
  252. hwndPrint(hwnd, "\t.b%sEndpoints.ciexyzRed.ciexyzX = %08x\r\n", szV,
  253. pbmih.bV5Endpoints.ciexyzRed.ciexyzX);
  254. hwndPrint(hwnd, "\t.b%sEndpoints.ciexyzRed.ciexyzY = %08x\r\n", szV,
  255. pbmih.bV5Endpoints.ciexyzRed.ciexyzY);
  256. hwndPrint(hwnd, "\t.b%sEndpoints.ciexyzRed.ciexyzZ = %08x\r\n", szV,
  257. pbmih.bV5Endpoints.ciexyzRed.ciexyzZ);
  258. hwndPrint(hwnd, "\t.b%sEndpoints.ciexyzGreen.ciexyzX = %08x\r\n", szV,
  259. pbmih.bV5Endpoints.ciexyzGreen.ciexyzX);
  260. hwndPrint(hwnd, "\t.b%sEndpoints.ciexyzGreen.ciexyzY = %08x\r\n", szV,
  261. pbmih.bV5Endpoints.ciexyzGreen.ciexyzY);
  262. hwndPrint(hwnd, "\t.b%sEndpoints.ciexyzGreen.ciexyzZ = %08x\r\n", szV,
  263. pbmih.bV5Endpoints.ciexyzGreen.ciexyzZ);
  264. hwndPrint(hwnd, "\t.b%sEndpoints.ciexyzBlue.ciexyzX = %08x\r\n", szV,
  265. pbmih.bV5Endpoints.ciexyzBlue.ciexyzX);
  266. hwndPrint(hwnd, "\t.b%sEndpoints.ciexyzBlue.ciexyzY = %08x\r\n", szV,
  267. pbmih.bV5Endpoints.ciexyzBlue.ciexyzY);
  268. hwndPrint(hwnd, "\t.b%sEndpoints.ciexyzBlue.ciexyzZ = %08x\r\n", szV,
  269. pbmih.bV5Endpoints.ciexyzBlue.ciexyzZ);
  270. hwndPrint(hwnd, "\t.b%sGammaRed = %08x\r\n", szV,
  271. pbmih.bV5GammaRed);
  272. hwndPrint(hwnd, "\t.b%sGammaGreen = %08x\r\n", szV,
  273. pbmih.bV5GammaGreen);
  274. hwndPrint(hwnd, "\t.b%sGammaBlue = %08x\r\n\r\n", szV,
  275. pbmih.bV5GammaBlue);
  276. if (pbmih.bV5Size == BITMAPV4HEADER.sizeof)
  277. {
  278. GC.free(pFile);
  279. return;
  280. }
  281. // Display additional BITMAPV5HEADER fields
  282. hwndPrint(hwnd, "\t.b%sIntent = %s\r\n", szV, pbmih.bV5Intent);
  283. hwndPrint(hwnd, "\t.b%sProfileData = %s\r\n", szV,
  284. pbmih.bV5ProfileData);
  285. hwndPrint(hwnd, "\t.b%sProfileSize = %s\r\n", szV,
  286. pbmih.bV5ProfileSize);
  287. hwndPrint(hwnd, "\t.b%sReserved = %s\r\n\r\n", szV,
  288. pbmih.bV5Reserved);
  289. GC.free(pFile);
  290. return;
  291. }
  292. __gshared wchar[MAX_PATH] szFileName = 0;
  293. __gshared wchar[MAX_PATH] szTitleName = 0;
  294. extern (Windows)
  295. LRESULT WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) nothrow
  296. {
  297. scope (failure) assert(0);
  298. static HWND hwndEdit;
  299. static OPENFILENAME ofn;
  300. static string szFilter = "Bitmap Files (*.BMP)\0*.bmp\0All Files (*.*)\0*.*\0\0";
  301. switch (message)
  302. {
  303. case WM_CREATE:
  304. hwndEdit = CreateWindow("edit", NULL,
  305. WS_CHILD | WS_VISIBLE | WS_BORDER |
  306. WS_VSCROLL | WS_HSCROLL |
  307. ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY,
  308. 0, 0, 0, 0, hwnd, cast(HMENU) 1,
  309. (cast(LPCREATESTRUCT)lParam).hInstance, NULL);
  310. ofn.hwndOwner = hwnd;
  311. ofn.hInstance = NULL;
  312. ofn.lpstrFilter = szFilter.toUTF16z;
  313. ofn.lpstrCustomFilter = NULL;
  314. ofn.nMaxCustFilter = 0;
  315. ofn.nFilterIndex = 0;
  316. ofn.lpstrFile = szFileName.ptr;
  317. ofn.nMaxFile = MAX_PATH;
  318. ofn.lpstrFileTitle = szTitleName.ptr;
  319. ofn.nMaxFileTitle = MAX_PATH;
  320. ofn.lpstrInitialDir = NULL;
  321. ofn.lpstrTitle = NULL;
  322. ofn.Flags = 0;
  323. ofn.nFileOffset = 0;
  324. ofn.nFileExtension = 0;
  325. ofn.lpstrDefExt = "bmp";
  326. ofn.lCustData = 0;
  327. ofn.lpfnHook = NULL;
  328. ofn.lpTemplateName = NULL;
  329. return 0;
  330. case WM_SIZE:
  331. MoveWindow(hwndEdit, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
  332. return 0;
  333. case WM_COMMAND:
  334. switch (LOWORD(wParam))
  335. {
  336. case IDM_FILE_OPEN:
  337. if (GetOpenFileName(&ofn))
  338. DisplayDibHeaders(hwndEdit, to!string(szFileName[]));
  339. return 0;
  340. default:
  341. }
  342. break;
  343. case WM_DESTROY:
  344. PostQuitMessage(0);
  345. return 0;
  346. default:
  347. }
  348. return DefWindowProc(hwnd, message, wParam, lParam);
  349. }