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 }