1 /*-------------------------------------- 2 DIGCLOCK.C -- Digital Clock 3 (c) Charles Petzold, 1998 4 --------------------------------------*/ 5 6 #include <Windows.h> 7 8 #define ID_TIMER 1 9 10 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 11 12 int WINAPI WinMain( __in HINSTANCE hInstance 13 , __in_opt HINSTANCE hPrevInstance 14 , __in LPSTR lpCmdLine 15 , __in int nShowCmd ) 16 { 17 static TCHAR szAppName[] = TEXT("DigClock"); 18 HWND hwnd; 19 MSG msg; 20 WNDCLASS wndclass; 21 22 wndclass.style = CS_HREDRAW | CS_VREDRAW; 23 wndclass.lpfnWndProc = WndProc; 24 wndclass.cbClsExtra = 0; 25 wndclass.cbWndExtra = 0; 26 wndclass.hInstance = hInstance; 27 wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); 28 wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); 29 wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 30 wndclass.lpszMenuName = NULL; 31 wndclass.lpszClassName = szAppName; 32 33 if (!RegisterClass(&wndclass)) 34 { 35 MessageBox(NULL, TEXT("Program requires Windows NT!") 36 , szAppName, MB_ICONERROR); 37 return 0; 38 } 39 40 hwnd = CreateWindow(szAppName, TEXT("Digital Clock") 41 , WS_OVERLAPPEDWINDOW 42 , CW_USEDEFAULT, CW_USEDEFAULT 43 , CW_USEDEFAULT, CW_USEDEFAULT 44 , NULL, NULL, hInstance, NULL); 45 46 ShowWindow(hwnd, nShowCmd); 47 UpdateWindow(hwnd); 48 49 while (GetMessage(&msg, NULL, 0, 0)) 50 { 51 TranslateMessage(&msg); 52 DispatchMessage(&msg); 53 } 54 55 return msg.wParam; 56 } 57 58 void DisplayDigit(HDC hdc, int iNumber) 59 { 60 static BOOL fSevenSegment[10][7] = 61 { 62 1, 1, 1, 0, 1, 1, 1, //0 63 0, 0, 1, 0, 0, 1, 0, //1 64 1, 0, 1, 1, 1, 0, 1, //2 65 1, 0, 1, 1, 0, 1, 1, //3 66 0, 1, 1, 1, 0, 1, 0, //4 67 1, 1, 0, 1, 0, 1, 1, //5 68 1, 1, 0, 1, 1, 1, 1, //6 69 1, 0, 1, 0, 0, 1, 0, //7 70 1, 1, 1, 1, 1, 1, 1, //8 71 1, 1, 1, 1, 0, 1, 1 //9 72 }; 73 74 static POINT ptSegment[7][6] = 75 { 76 7, 6, 11, 2, 31, 2, 35, 6, 31, 10, 11, 10, 77 6, 7, 10, 11, 10, 31, 6, 35, 2, 31, 2, 11, 78 36, 7, 40, 11, 40, 31, 36, 35, 32, 31, 32, 11, 79 7, 36, 11, 32, 31, 32, 35, 36, 31, 40, 11, 40, 80 6, 37, 10, 41, 10, 61, 6, 65, 2, 61, 2, 41, 81 36, 37, 40, 41, 40, 61, 36, 65, 32, 61, 32, 41, 82 7, 66, 11, 62, 31, 62, 35, 66, 31, 70, 11, 70 83 84 }; 85 86 for (int iSeg(0); iSeg != 7; ++iSeg) 87 { 88 if (fSevenSegment[iNumber][iSeg]) 89 Polygon(hdc, ptSegment[iSeg], 6); 90 } 91 } 92 93 void DisplayTwoDigits(HDC hdc, int iNumber, BOOL fSuppress) 94 { 95 if (!fSuppress || (iNumber / 10 != 0)) 96 DisplayDigit(hdc, iNumber / 10); 97 98 OffsetWindowOrgEx(hdc, -42, 0, NULL); 99 DisplayDigit(hdc, iNumber % 10); 100 OffsetWindowOrgEx(hdc, -42, 0, NULL); 101 } 102 103 void DisplayColon(HDC hdc) 104 { 105 POINT ptColon[2][4] = { 2, 21, 6, 17, 10, 21, 6, 25, 106 2, 51, 6, 47, 10, 51, 6, 55 }; 107 108 Polygon(hdc, ptColon[0], 4); 109 Polygon(hdc, ptColon[1], 4); 110 111 OffsetWindowOrgEx(hdc, -12, 0, NULL); 112 } 113 114 void DisplayTime(HDC hdc, BOOL f24Hour, BOOL fSuppress) 115 { 116 SYSTEMTIME st; 117 118 GetLocalTime(&st); 119 120 if (f24Hour) 121 DisplayTwoDigits(hdc, st.wHour, fSuppress); 122 else 123 DisplayTwoDigits(hdc, (st.wHour %= 12) ? st.wHour : 12, fSuppress); 124 125 DisplayColon(hdc); 126 DisplayTwoDigits(hdc, st.wMinute, FALSE); 127 DisplayColon(hdc); 128 DisplayTwoDigits(hdc, st.wSecond, FALSE); 129 } 130 131 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 132 { 133 static BOOL f24Hour, fSuppress; 134 static HBRUSH hBrushRed; 135 static int cxClient, cyClient; 136 HDC hdc; 137 PAINTSTRUCT ps; 138 TCHAR szBuffer[2]; 139 140 switch (message) 141 { 142 case WM_CREATE: 143 hBrushRed = CreateSolidBrush(RGB(255, 0, 0)); 144 SetTimer(hwnd, ID_TIMER, 1000, NULL); 145 146 //fall through 147 case WM_SETTINGCHANGE: 148 GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ITIME, szBuffer, 2); 149 f24Hour = (szBuffer[0] == TEXT('1')); 150 151 GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ITLZERO, szBuffer, 2); 152 fSuppress = (szBuffer[0] == TEXT('0')); 153 154 InvalidateRect(hwnd, NULL, TRUE); 155 return 0; 156 157 case WM_SIZE: 158 cxClient = LOWORD(lParam); 159 cyClient = HIWORD(lParam); 160 return 0; 161 162 case WM_TIMER: 163 InvalidateRect(hwnd, NULL, TRUE); 164 return 0; 165 166 case WM_PAINT: 167 hdc = BeginPaint(hwnd, &ps); 168 169 SetMapMode(hdc, MM_ISOTROPIC); 170 SetWindowExtEx(hdc, 276, 72, NULL); 171 SetViewportExtEx(hdc, cxClient, cyClient, NULL); 172 173 SetWindowOrgEx(hdc, 138, 36, NULL); 174 SetViewportOrgEx(hdc, cxClient / 2, cyClient / 2, NULL); 175 SelectObject(hdc, GetStockObject(NULL_PEN)); 176 SelectObject(hdc, hBrushRed); 177 178 DisplayTime(hdc, f24Hour, fSuppress); 179 180 EndPaint(hwnd, &ps); 181 return 0; 182 183 case WM_DESTROY: 184 KillTimer(hwnd, ID_TIMER); 185 DeleteObject(hBrushRed); 186 PostQuitMessage(0); 187 return 0; 188 } 189 190 return DefWindowProc(hwnd, message, wParam, lParam); 191 }