PageRenderTime 42ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/Samples/Chap11/HexCalc/HexCalc.d

http://github.com/AndrejMitrovic/DWinProgramming
D | 231 lines | 176 code | 51 blank | 4 comment | 20 complexity | 95a39a42fce5042a6244b4fa5c27e29c MD5 | raw file
  1. /+
  2. + Copyright (c) Charles Petzold, 1998.
  3. + Ported to the D Programming Language by Andrej Mitrovic, 2011.
  4. +/
  5. module HexCalc;
  6. import core.runtime;
  7. import core.thread;
  8. import std.conv;
  9. import std.ascii;
  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. import core.sys.windows.winnt;
  24. import resource;
  25. string appName = "HexCalc";
  26. string description = "Hex Calculator";
  27. enum ID_TIMER = 1;
  28. HINSTANCE hinst;
  29. const MAXDWORD = 0xffffffff;
  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. HWND hwnd;
  51. MSG msg;
  52. WNDCLASS wndclass;
  53. wndclass.style = CS_HREDRAW | CS_VREDRAW;
  54. wndclass.lpfnWndProc = &WndProc;
  55. wndclass.cbClsExtra = 0;
  56. wndclass.cbWndExtra = DLGWINDOWEXTRA; // Note!
  57. wndclass.hInstance = hInstance;
  58. wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  59. wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  60. wndclass.hbrBackground = cast(HBRUSH)(COLOR_BTNFACE + 1);
  61. wndclass.lpszMenuName = NULL;
  62. wndclass.lpszClassName = appName.toUTF16z;
  63. if (!RegisterClass (&wndclass))
  64. {
  65. MessageBox(NULL, "This program requires Windows NT!",
  66. appName.toUTF16z, MB_ICONERROR);
  67. return 0;
  68. }
  69. hwnd = CreateDialog (hInstance, appName.toUTF16z, null, NULL);
  70. ShowWindow (hwnd, iCmdShow);
  71. while (GetMessage (&msg, NULL, 0, 0))
  72. {
  73. TranslateMessage (&msg);
  74. DispatchMessage (&msg);
  75. }
  76. return msg.wParam;
  77. }
  78. void ShowNumber(HWND hwnd, UINT iNumber)
  79. {
  80. TCHAR[20] szBuffer;
  81. auto result = format("%x", iNumber);
  82. SetDlgItemText(hwnd, VK_ESCAPE, result.toUTF16z);
  83. }
  84. DWORD CalcIt(UINT iFirstNum, int iOperation, UINT iNum)
  85. {
  86. switch (iOperation)
  87. {
  88. case '=':
  89. return iNum;
  90. case '+':
  91. return iFirstNum + iNum;
  92. case '-':
  93. return iFirstNum - iNum;
  94. case '*':
  95. return iFirstNum * iNum;
  96. case '&':
  97. return iFirstNum & iNum;
  98. case '|':
  99. return iFirstNum | iNum;
  100. case '^':
  101. return iFirstNum ^ iNum;
  102. case '<':
  103. return iFirstNum << iNum;
  104. case '>':
  105. return iFirstNum >> iNum;
  106. case '/':
  107. return iNum ? iFirstNum / iNum : MAXDWORD;
  108. case '%':
  109. return iNum ? iFirstNum % iNum : MAXDWORD;
  110. default:
  111. return 0;
  112. }
  113. }
  114. extern (Windows)
  115. LRESULT WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) nothrow
  116. {
  117. scope (failure) assert(0);
  118. static BOOL bNewNumber = TRUE;
  119. static int iOperation = '=';
  120. static UINT iNumber, iFirstNum;
  121. HWND hButton;
  122. switch (message)
  123. {
  124. case WM_KEYDOWN: // left arrow --> backspace
  125. if (wParam != VK_LEFT)
  126. break;
  127. wParam = VK_BACK;
  128. goto case WM_CHAR;
  129. case WM_CHAR:
  130. if ((wParam = cast(WPARAM)CharUpper(cast(TCHAR *)wParam)) == VK_RETURN)
  131. wParam = '=';
  132. hButton = GetDlgItem(hwnd, wParam);
  133. if (hButton)
  134. {
  135. SendMessage(hButton, BM_SETSTATE, 1, 0);
  136. Thread.sleep( dur!"msecs"( 100 ) );
  137. SendMessage(hButton, BM_SETSTATE, 0, 0);
  138. }
  139. else
  140. {
  141. MessageBeep(0);
  142. break;
  143. }
  144. goto case WM_COMMAND;
  145. case WM_COMMAND:
  146. SetFocus(hwnd);
  147. if (LOWORD(wParam) == VK_BACK) // backspace
  148. ShowNumber(hwnd, iNumber /= 16);
  149. else if (LOWORD(wParam) == VK_ESCAPE) // escape
  150. ShowNumber(hwnd, iNumber = 0);
  151. else if (isHexDigit(LOWORD(wParam))) // hex digit
  152. {
  153. if (bNewNumber)
  154. {
  155. iFirstNum = iNumber;
  156. iNumber = 0;
  157. }
  158. bNewNumber = FALSE;
  159. if (iNumber <= MAXDWORD >> 4)
  160. ShowNumber(hwnd, iNumber = 16 * iNumber + wParam -
  161. (isDigit(wParam) ? '0' : 'A' - 10));
  162. else
  163. MessageBeep(0);
  164. }
  165. else // operation
  166. {
  167. if (!bNewNumber)
  168. ShowNumber(hwnd, iNumber =
  169. CalcIt(iFirstNum, iOperation, iNumber));
  170. bNewNumber = TRUE;
  171. iOperation = LOWORD(wParam);
  172. }
  173. return 0;
  174. case WM_DESTROY:
  175. PostQuitMessage(0);
  176. return 0;
  177. default:
  178. }
  179. return DefWindowProc(hwnd, message, wParam, lParam);
  180. }