#include #include "abstractWatchGUI.h" #include "abstractWatchMode.h" #include "timeWatchMode.h" #include "stopWatchMode.h" #include "binaryWatchGUI.h" #include "digitalWatchGUI.h" #include "analogueWatchGUI.h" #include "demonischClock.h" stopWatch objStopWatch; timeWatch objTimeWatch; analogueWatch objAnalogueWatch; digitalWatch objDigitalWatch; binaryWatch objBinaryWatch; const unsigned short int GUI_ANALOGUE = 0, GUI_DIGITAL = 1, GUI_BINARY = 2; const unsigned short int MODE_TIME = 0, MODE_STOP_WATCH = 1; const unsigned short int SIZE_SMALL = 0, SIZE_NORMAL = 1, SIZE_LARGE = 2, SIZE_MASSIVE = 3; const unsigned short int REPAINT_NONE = 0, REPAINT_TIME = 1, REPAINT_DISPLAY = 2; const unsigned short int numSizeMenu = 4, numGUIMenu = 3, numModeMenu = 2; const unsigned short int SIZE_MENU_REFERENCE[numSizeMenu] = {mItemSizeSmall, mItemSizeNormal, mItemSizeLarge, mItemSizeMassive}; const unsigned short int GUI_MENU_REFERENCE[numGUIMenu] = {mItemGUIAnalogue, mItemGUIDigital, mItemGUIBinary}; const unsigned short int MODE_MENU_REFERENCE[numModeMenu] = {mItemTimeDisplay, mItemStopDisplay}; const unsigned short int SIZE_RATIO[numSizeMenu] = {5, 10, 15, 20}; const char className[] = "demonischClock"; const char APP_TITLE[] = "Demonisch Clock"; const unsigned short int APP_WIDTH = 500; const unsigned short int APP_HEIGHT = 500; unsigned short int gui, mode, size; bool timerActive = false; int handleMenuClick (HWND hwnd, int mItemID); void repaint (HWND hwnd, HDC hdc); void repaintDisplay (HDC hdc); void repaintTime (HDC hdc); int setGUI (HWND hwnd, int newGUI); int setMode (HWND hwnd, int newMode); int setSize (HWND hwnd, int newSize); BOOL CALLBACK digAboutEventListener (HWND hwnd, UINT event, WPARAM object, LPARAM params); LRESULT CALLBACK mainEventListener (HWND hwnd, UINT event, WPARAM object, LPARAM params); int handleMenuClick (HWND hwnd, int mItemID) { for (int i = 0; i < numSizeMenu; i++) { if (mItemID == SIZE_MENU_REFERENCE[i]) { return setSize(hwnd, i); } } for (int i = 0; i < numGUIMenu; i++) { if (mItemID == GUI_MENU_REFERENCE[i]) { return setGUI(hwnd, i); } } for (int i = 0; i < numModeMenu; i++) { if (mItemID == MODE_MENU_REFERENCE[i]) { return setMode(hwnd, i); } } if (mItemID == mItemStopAction && mode == MODE_STOP_WATCH) { objStopWatch.enable(!objStopWatch.isEnabled()); } else if (mItemID == mItemStopReset && mode == MODE_STOP_WATCH) { objStopWatch.reset(); return REPAINT_TIME; } else if (mItemID == mItemHelpAbout) { DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(digAbout), hwnd, digAboutEventListener); } else if (mItemID == mItemFileExit) { DestroyWindow(hwnd); } return REPAINT_NONE; } void repaintScreen (HWND hwnd, HDC hdc) { RECT clientArea; HBRUSH brushBackground = CreateSolidBrush(RGB(255, 255, 255)); HBRUSH brushPrevious = (HBRUSH)SelectObject(hdc, brushBackground); GetClientRect(hwnd, &clientArea); Rectangle(hdc, 0, 0, clientArea.right, clientArea.bottom); SelectObject(hdc, brushPrevious); DeleteObject(brushBackground); repaintDisplay(hdc); } void repaintDisplay (HDC hdc) { if (gui == GUI_ANALOGUE) { objAnalogueWatch.repaintGUI(hdc, SIZE_RATIO[size]); } else if (gui == GUI_DIGITAL) { objDigitalWatch.repaintGUI(hdc, SIZE_RATIO[size]); } else { objBinaryWatch.repaintGUI(hdc, SIZE_RATIO[size]); } repaintTime(hdc); } void repaintTime (HDC hdc) { int hour; int min; int sec; if (mode == MODE_TIME) { hour = objTimeWatch.getHour(); min = objTimeWatch.getMin(); sec = objTimeWatch.getSec(); } else { hour = objStopWatch.getHour(); min = objStopWatch.getMin(); sec = objStopWatch.getSec(); } if (gui == GUI_ANALOGUE) { objAnalogueWatch.repaintTime(hdc, hour, min, sec); } else if (gui == GUI_DIGITAL) { objDigitalWatch.repaintTime(hdc, hour, min, sec); } else { objBinaryWatch.repaintTime(hdc, hour, min, sec); } } int setGUI (HWND hwnd, int newGUI) { if (gui == newGUI) { return REPAINT_NONE; } HMENU menuHandle = GetMenu(hwnd); CheckMenuItem(menuHandle, GUI_MENU_REFERENCE[gui], MF_UNCHECKED); CheckMenuItem(menuHandle, GUI_MENU_REFERENCE[newGUI], MF_CHECKED); gui = newGUI; return REPAINT_DISPLAY; } int setMode (HWND hwnd, int newMode) { if (mode == newMode) { return REPAINT_NONE; } if (gui == GUI_DIGITAL) { objDigitalWatch.resetTime(); } HMENU menuHandle = GetMenu(hwnd); int state; if (newMode == MODE_TIME) { state = MF_GRAYED; } else { state = MF_ENABLED; } EnableMenuItem(menuHandle, mItemStopAction, state); EnableMenuItem(menuHandle, mItemStopReset, state); CheckMenuItem(menuHandle, MODE_MENU_REFERENCE[mode], MF_UNCHECKED); CheckMenuItem(menuHandle, MODE_MENU_REFERENCE[newMode], MF_CHECKED); mode = newMode; return REPAINT_TIME; } int setSize (HWND hwnd, int newSize) { if (size == newSize) { return REPAINT_NONE; } HMENU menuHandle = GetMenu(hwnd); CheckMenuItem(menuHandle, SIZE_MENU_REFERENCE[size], MF_UNCHECKED); CheckMenuItem(menuHandle, SIZE_MENU_REFERENCE[newSize], MF_CHECKED); size = newSize; return REPAINT_DISPLAY; } BOOL CALLBACK digAboutEventListener (HWND handleAbout, UINT event, WPARAM object, LPARAM params) { if (event == WM_COMMAND) { int objectID = LOWORD(object); if (objectID == cmdAboutClose) { EndDialog(handleAbout, 0); } } else if (event == WM_CLOSE) { EndDialog(handleAbout, 0); } else { return false; } return true; } LRESULT CALLBACK mainEventListener (HWND hwnd, UINT event, WPARAM object, LPARAM params) { int repaintType = REPAINT_NONE; if (event == WM_TIMER) { objStopWatch.pulse(); objTimeWatch.pulse(); //Don't need to repaint time if viewing the stop watch and it is disabled if (mode == MODE_TIME || (mode == MODE_STOP_WATCH && objStopWatch.isEnabled())) { repaintType = REPAINT_TIME; } } else if (event == WM_PAINT) { PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); repaintDisplay(hdc); EndPaint(hwnd, &ps); } else if (event == WM_LBUTTONUP) { int x = LOWORD(params); int y = HIWORD(params); int buttonPressed; if (gui == GUI_ANALOGUE) { buttonPressed = objAnalogueWatch.checkMouseClick(x, y); } else if (gui == GUI_DIGITAL) { buttonPressed = objDigitalWatch.checkMouseClick(x, y); } else { buttonPressed = objBinaryWatch.checkMouseClick(x, y); } if (buttonPressed == objBinaryWatch.ACTION_BUTTON && mode == MODE_STOP_WATCH) { objStopWatch.enable(!objStopWatch.isEnabled()); } else if (buttonPressed == objBinaryWatch.RESET_BUTTON && mode == MODE_STOP_WATCH) { objStopWatch.reset(); repaintType = REPAINT_TIME; } else if (buttonPressed == objBinaryWatch.MODE_BUTTON) { if (mode == MODE_TIME) { setMode(hwnd, MODE_STOP_WATCH); } else { setMode(hwnd, MODE_TIME); } repaintType = REPAINT_TIME; } else if (buttonPressed == objBinaryWatch.GUI_BUTTON) { if (gui == GUI_ANALOGUE) { setGUI(hwnd, GUI_DIGITAL); } else if (gui == GUI_DIGITAL) { setGUI(hwnd, GUI_BINARY); } else { setGUI(hwnd, GUI_ANALOGUE); } repaintType = REPAINT_DISPLAY; } } else if (event == WM_CREATE) { int status = SetTimer(hwnd, threadTimer, 1000, NULL); //Start the timer if (status == 0) //Timer did not start { MessageBox(hwnd, "Could not setup the timer required by the clock\nThis programme will now terminate", className, MB_OK | MB_ICONEXCLAMATION); DestroyWindow(hwnd); } else { binaryWatch objBinaryWatch(); digitalWatch objDigitalWatch(); analogueWatch objAnalogueWatch(); timeWatch objTimeWatch(); stopWatch objStopWatch(); gui = GUI_DIGITAL; mode = MODE_TIME; size = SIZE_NORMAL; HMENU menuHandle = GetMenu(hwnd); //Check the default items in the menus so the user knows what is currently selected CheckMenuItem(menuHandle, SIZE_MENU_REFERENCE[size], MF_CHECKED); CheckMenuItem(menuHandle, GUI_MENU_REFERENCE[gui], MF_CHECKED); CheckMenuItem(menuHandle, MODE_MENU_REFERENCE[mode], MF_CHECKED); EnableMenuItem(menuHandle, mItemStopAction, MF_GRAYED); EnableMenuItem(menuHandle, mItemStopReset, MF_GRAYED); timerActive = true; } } else if (event == WM_COMMAND) { repaintType = handleMenuClick(hwnd, LOWORD(object)); } else if (event == WM_CLOSE) { DestroyWindow(hwnd); } else if (event == WM_DESTROY) { //If the timer could not be created for some reason then we don't kill it if (timerActive) { KillTimer(hwnd, threadTimer); } PostQuitMessage(0); } else { return DefWindowProc(hwnd, event, object, params); } if (repaintType != REPAINT_NONE) { HDC hdc = GetDC(hwnd); if (repaintType == REPAINT_TIME) { repaintTime(hdc); } else { repaintScreen(hwnd, hdc); } ReleaseDC(hwnd, hdc); } return 0; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR args, int nCmdShow) { WNDCLASSEX wc; HWND hwnd; MSG Msg; wc.cbSize = sizeof(WNDCLASSEX); wc.style = 0; wc.lpfnWndProc = mainEventListener; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(imgMainIcon)); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(GetStockObject(WHITE_BRUSH)); wc.lpszMenuName = MAKEINTRESOURCE(menuSystem); wc.lpszClassName = className; wc.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(imgMainIcon), IMAGE_ICON, 16, 16, 0); if (!RegisterClassEx(&wc)) { MessageBox(NULL, "Window Registration Failed!", "Error!", MB_OK | MB_ICONEXCLAMATION); return 0; } hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, className, APP_TITLE, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, APP_WIDTH, APP_HEIGHT, NULL, NULL, hInstance, NULL); if (hwnd == NULL) { MessageBox(NULL, "Window Creation Failed!", "Error!", MB_OK | MB_ICONEXCLAMATION); return 0; } ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); while (GetMessage(&Msg, NULL, 0, 0) > 0) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam; }