#include #include "resource.h" // for icon only #define MENUCOLOR 0xD8E9EC int x, y, b = 0; UINT iNumber = 0, Binary = 0, binmask = 0x80000000; BOOL replaying = FALSE, syskey = FALSE; char Buf[1024]; HINSTANCE hInstance; HWND hwnd, hwndHelp, hwndCopy, hwndClear; HBRUSH hBrush; HGLOBAL hGlobal; LPVOID pGlobal; LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); DWORD CalcIt (UINT iFirstNum, int iOperation, UINT iNum) { switch (iOperation) { case '=': return iNum; case '+': return iFirstNum + iNum; case '-': return iFirstNum - iNum; case '*': return iFirstNum * iNum; case '&': return iFirstNum & iNum; case '|': return iFirstNum | iNum; case '^': return iFirstNum ^ iNum; case '<': return iFirstNum << iNum; case '>': return iFirstNum >> iNum; case '/': return iNum ? iFirstNum / iNum: MAXDWORD; case '%': return iNum ? iFirstNum % iNum: MAXDWORD; default : return 0; } } BOOL IsOperator(num) { switch(num) { case '=': return TRUE; case '+': return TRUE; case '-': return TRUE; case '*': return TRUE; case '&': return TRUE; case '|': return TRUE; case '^': return TRUE; case '<': return TRUE; case '>': return TRUE; case '/': return TRUE; case '%': return TRUE; default : return FALSE; } } int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static char szAppName[] = "Programmer's Calc"; MSG msg; WNDCLASS wndclass; hBrush = CreateSolidBrush(MENUCOLOR); wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); wndclass.hbrBackground = hBrush; wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName; if (!RegisterClass(&wndclass)) return 0; hwnd = CreateWindow (szAppName, szAppName, WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, 450,350,370,170, NULL, NULL, hInstance, NULL); ShowWindow(hwnd, iCmdShow); UpdateWindow(hwnd); while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg); DispatchMessage (&msg); } return msg.wParam; } LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { TCHAR szBuffer[36]; static TCHAR cBinary[] = "00000000 00000000 00000000 00000000"; static TCHAR temp[] = "00000000 00000000 00000000 00000000"; int bufSize; HDC hdc; PAINTSTRUCT ps; RECT rect; static BOOL bNewNumber = TRUE; static int iOperation = '='; static iFirstNum; static int Input = 0; //0 for Dec, 1 for Hex, 2 for Char, 3 for Bin UINT bitmask; static DWORD ThisThreadID; switch (message) { case WM_CREATE: memset(Buf, ' ', 1024); hwndHelp = CreateWindow(TEXT("BUTTON"), TEXT("H&elp"), WS_CHILD | WS_VISIBLE, 190, 10, 60, 20, hwnd, (HMENU)192, hInstance, NULL); hwndCopy = CreateWindow(TEXT("BUTTON"), TEXT("C&opy"), WS_CHILD | WS_VISIBLE, 244, 40, 60, 20, hwnd, (HMENU)192, hInstance, NULL); hwndClear = CreateWindow(TEXT("BUTTON"), TEXT("C&lear"), WS_CHILD | WS_VISIBLE, 300, 70, 60, 20, hwnd, (HMENU)192, hInstance, NULL); SetFocus(hwnd); break; case WM_ACTIVATEAPP: if (wParam == FALSE)//being deactivated { SetWindowPos(hwnd, HWND_TOPMOST, 450,350,370,170, SWP_NOMOVE|SWP_NOACTIVATE); BringWindowToTop(hwnd);//new Mar 28, 2005 } else//being activated ThisThreadID = GetWindowThreadProcessId(hwnd, NULL); break; case WM_COMMAND: if ((HWND)(LPARAM)lParam == hwndHelp) SendMessage(hwnd, WM_SYSKEYDOWN, (WPARAM)0x45, 0); // E else if ((HWND)(LPARAM)lParam == hwndCopy) SendMessage(hwnd, WM_SYSKEYDOWN, (WPARAM)0x4F, 0); // O else if ((HWND)(LPARAM)lParam == hwndClear) SendMessage(hwnd, WM_SYSKEYDOWN, (WPARAM)0x4C, 0); // L break; case WM_SYSKEYDOWN: // buttons syskey = TRUE; //fall thru case WM_KEYDOWN: if (syskey) { if (wParam == 0x45) { // &HELP MessageBox(hwnd, "Use Up/Down Arrow keys\nOperators: + - * / % & | ^ < > =\nPress Backspace to remove last number\n", "Help", MB_OK); syskey = FALSE; } else if (wParam == 0x4C) { // C&LEAR replaying = FALSE; iOperation = '='; iNumber = 0; for (x = 0; x <= 34; x++) cBinary[x] = temp[x]; binmask = 0x80000000; Binary = 0; for (x = 0; (x < 1024) && (Buf[x] != ' '); x++) Buf[x] = ' '; b = 0; syskey = FALSE; SetFocus(hwnd); InvalidateRect(hwnd, NULL, FALSE); } else if (wParam == 0x4F) { // C&OPY if (Input == 0) bufSize = wsprintf(szBuffer, TEXT ("%u"), iNumber); else if (Input == 1) bufSize = wsprintf(szBuffer, TEXT ("%X"), iNumber); else if (Input == 2) bufSize = wsprintf(szBuffer, TEXT ("%1C"), iNumber); else if (Input == 3) { strcpy(szBuffer, cBinary); bufSize = 35; } hGlobal = GlobalAlloc(GMEM_MOVEABLE, (bufSize + 1) * sizeof(TCHAR)); pGlobal = (char*)GlobalLock(hGlobal); lstrcpy(pGlobal, szBuffer); GlobalUnlock(hGlobal); OpenClipboard(NULL); EmptyClipboard(); SetClipboardData(CF_TEXT, hGlobal); CloseClipboard(); syskey = FALSE; SetFocus(hwnd); } } if ((wParam == VK_DOWN) && (Input != 3)) Input += 1; else if ((wParam == VK_UP) && (Input != 0)) Input -= 1; if (wParam == VK_BACK) { if(!IsOperator(Buf[b-1])) { if (Input == 1)//hex iNumber /= 16; else if (Input == 0) // dec iNumber /= 10; else if (Input == 2) // char iNumber = 0; } if (b) b--; Buf[b] = ' '; // remove last entered digit } InvalidateRect(hwnd, NULL, FALSE); if (wParam == VK_ESCAPE) SendMessage(hwnd, WM_CLOSE, 0, 0); return 0; case WM_CHAR: if (wParam == VK_RETURN) wParam = '='; else if (Input == 1) wParam = (WPARAM)CharUpper((TCHAR*)wParam); // need to do this here if ((Input == 0) && (isdigit(LOWORD(wParam)))) { // decimal digit if (bNewNumber) { iFirstNum = iNumber; iNumber = 0; } bNewNumber = FALSE; //add new digit if (iNumber <= (MAXDWORD >> 4)) { iNumber = (10 * iNumber) + (wParam - '0'); if ((!replaying) && (b < 1024)) Buf[b] = wParam; if (b < 1024) b++; } } else if ((Input == 1) && (isxdigit (LOWORD (wParam)))) { // hex digit if (bNewNumber) { iFirstNum = iNumber; iNumber = 0; } bNewNumber = FALSE; //add new digit if (iNumber <= (MAXDWORD >> 4)) { iNumber = (16 * iNumber) + (wParam - (isdigit (wParam) ? '0': 'A' - 10)); if ((!replaying) && (b < 1024)) Buf[b] = wParam; if (b < 1024) b++; } } else if (Input == 2) { // ASCII char iNumber = wParam; bNewNumber = TRUE; } else if (Input == 3) { // binary 1 or 0 if ((wParam == '1') || (wParam == '0')) { for (x = 0, y = 1; x < 34; x++, y++) { if ((x == 8) || (x == 17) || (x == 26)) x++; if ((y == 8) || (y == 17) || (y == 26)) y++; cBinary[x] = cBinary[y]; } cBinary[34] = wParam; binmask = 0x80000000; Binary = 0; for (x = 0; x <= 34; x++) { if ((x == 8) || (x == 17) || (x == 26)) x++; if (cBinary[x] == '1') Binary |= binmask; binmask >>= 1; } iNumber = Binary; } } else { // operator if (IsOperator(wParam) == FALSE) { MessageBeep(0); break; } else if (!bNewNumber) iNumber = CalcIt(iFirstNum, iOperation, iNumber); bNewNumber = TRUE; iOperation = LOWORD (wParam); if ((!replaying) && (b < 1024) && (wParam != '=') && (Input < 2)) Buf[b] = wParam; if (b < 1024) b++; } if (Input != 3) { for (x = 0; x < 35; x++) cBinary[x] = temp[x]; bitmask = 1 << 31; for (x = 0; x < 35; x++) { if ((x == 8) || (x == 17) || (x == 26)) x++; if (iNumber & bitmask) cBinary[x] = '1'; bitmask >>= 1; } } InvalidateRect(hwnd, NULL, FALSE); return 0; case WM_PAINT: hdc = BeginPaint (hwnd, &ps); GetClientRect(hwnd, &rect); SetBkColor(hdc, MENUCOLOR); MoveToEx(hdc, 185, 0, NULL); LineTo(hdc, 185, 95); LineTo(hdc, rect.right, 95); TextOut(hdc, 10, 10, TEXT("Dec "), 14); TextOut(hdc, 10, 40, TEXT("Hex "), 14); TextOut(hdc, 10, 70, TEXT("Char "), 14); TextOut(hdc, 10, 100, TEXT("Bin "), 15); TextOut(hdc, 10, 120, Buf, 90); // 90 spaces show szBuffer[0] = iOperation; TextOut(hdc, 68, (10 + (30 * Input)), szBuffer, 1); SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT)); SetTextAlign(hdc, TA_RIGHT); bufSize = wsprintf(szBuffer, TEXT ("%10u"), iNumber); TextOut(hdc, 180, 10, szBuffer, bufSize); bufSize = wsprintf(szBuffer, TEXT ("%8X"), iNumber); TextOut(hdc, 180, 40, szBuffer, bufSize); if ((iNumber > 0x20) && (iNumber < 0xFF)) { szBuffer[0] = iNumber; TextOut(hdc, 180, 70, szBuffer, 1); } else TextOut(hdc, 180, 70, " ", 1); TextOut(hdc, 360, 100, cBinary, 35); SelectObject(hdc, GetStockObject(SYSTEM_FONT)); SetTextAlign(hdc, TA_LEFT); SetBkColor(hdc, 0xFFFFFF); EndPaint (hwnd, &ps); return 0; case WM_DESTROY: DestroyWindow(hwndHelp); DestroyWindow(hwndCopy); DestroyWindow(hwndClear); PostQuitMessage(0); return 0; } return DefWindowProc (hwnd, message, wParam, lParam); }