4 * Copyright 1998 Marcel Baur <mbaur@g26.ethz.ch>
6 * Clock is partially based on
7 * - Program Manager by Ulrich Schmied
8 * - rolex.c by Jim Peterson
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
35 #define INITIAL_WINDOW_SIZE 200
38 CLOCK_GLOBALS Globals;
40 static VOID CLOCK_UpdateMenuCheckmarks(VOID)
42 HMENU hPropertiesMenu;
43 hPropertiesMenu = GetSubMenu(Globals.hMainMenu, 0);
50 CheckMenuRadioItem(hPropertiesMenu, IDM_ANALOG, IDM_DIGITAL, IDM_ANALOG, MF_CHECKED);
51 EnableMenuItem(hPropertiesMenu, IDM_FONT, MF_GRAYED);
56 CheckMenuRadioItem(hPropertiesMenu, IDM_ANALOG, IDM_DIGITAL, IDM_DIGITAL, MF_CHECKED);
57 EnableMenuItem(hPropertiesMenu, IDM_FONT, 0);
60 CheckMenuItem(hPropertiesMenu, IDM_NOTITLE, (Globals.bWithoutTitle ? MF_CHECKED : MF_UNCHECKED));
62 CheckMenuItem(hPropertiesMenu, IDM_ONTOP, (Globals.bAlwaysOnTop ? MF_CHECKED : MF_UNCHECKED));
63 CheckMenuItem(hPropertiesMenu, IDM_SECONDS, (Globals.bSeconds ? MF_CHECKED : MF_UNCHECKED));
64 CheckMenuItem(hPropertiesMenu, IDM_DATE, (Globals.bDate ? MF_CHECKED : MF_UNCHECKED));
67 static VOID CLOCK_UpdateWindowCaption(VOID)
69 CHAR szCaption[MAX_STRING_LEN];
72 /* Set frame caption */
74 chars = GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, NULL, NULL,
75 szCaption, sizeof(szCaption));
78 szCaption[chars++] = ' ';
79 szCaption[chars++] = '-';
80 szCaption[chars++] = ' ';
81 szCaption[chars] = '\0';
84 LoadString(0, IDS_CLOCK, szCaption + chars, sizeof(szCaption) - chars);
85 SetWindowText(Globals.hMainWnd, szCaption);
88 /***********************************************************************
92 static BOOL CLOCK_ResetTimer(void)
94 UINT period; /* milliseconds */
96 KillTimer(Globals.hMainWnd, TIMER_ID);
106 if (!SetTimer (Globals.hMainWnd, TIMER_ID, period, NULL)) {
107 CHAR szApp[MAX_STRING_LEN];
108 LoadString(Globals.hInstance, IDS_CLOCK, szApp, sizeof(szApp));
109 MessageBox(0, "No available timers", szApp, MB_ICONEXCLAMATION | MB_OK);
115 /***********************************************************************
119 static VOID CLOCK_ResetFont(VOID)
122 HDC dc = GetDC(Globals.hMainWnd);
123 newfont = SizeFont(dc, Globals.MaxX, Globals.MaxY, Globals.bSeconds, &Globals.logfont);
125 DeleteObject(Globals.hFont);
126 Globals.hFont = newfont;
129 ReleaseDC(Globals.hMainWnd, dc);
133 /***********************************************************************
137 static VOID CLOCK_ChooseFont(VOID)
141 memset(&cf, 0, sizeof(cf));
142 lf = Globals.logfont;
143 cf.lStructSize = sizeof(cf);
144 cf.hwndOwner = Globals.hMainWnd;
146 cf.Flags = CF_SCREENFONTS | CF_INITTOLOGFONTSTRUCT;
147 if (ChooseFont(&cf)) {
148 Globals.logfont = lf;
153 /***********************************************************************
157 static VOID CLOCK_ToggleTitle(VOID)
159 /* Also shows/hides the menu */
160 LONG style = GetWindowLong(Globals.hMainWnd, GWL_STYLE);
161 if ((Globals.bWithoutTitle = !Globals.bWithoutTitle)) {
162 style = (style & ~WS_OVERLAPPEDWINDOW) | WS_POPUP|WS_THICKFRAME;
163 SetMenu(Globals.hMainWnd, 0);
166 style = (style & ~(WS_POPUP|WS_THICKFRAME)) | WS_OVERLAPPEDWINDOW;
167 SetMenu(Globals.hMainWnd, Globals.hMainMenu);
169 SetWindowLong(Globals.hMainWnd, GWL_STYLE, style);
170 SetWindowPos(Globals.hMainWnd, 0,0,0,0,0,
171 SWP_DRAWFRAME|SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER);
173 CLOCK_UpdateMenuCheckmarks();
174 CLOCK_UpdateWindowCaption();
177 /***********************************************************************
181 static VOID CLOCK_ToggleOnTop(VOID)
183 if ((Globals.bAlwaysOnTop = !Globals.bAlwaysOnTop)) {
184 SetWindowPos(Globals.hMainWnd, HWND_TOPMOST, 0,0,0,0,
185 SWP_NOMOVE|SWP_NOSIZE);
188 SetWindowPos(Globals.hMainWnd, HWND_NOTOPMOST, 0,0,0,0,
189 SWP_NOMOVE|SWP_NOSIZE);
191 CLOCK_UpdateMenuCheckmarks();
193 /***********************************************************************
197 * All handling of main menu events
200 static int CLOCK_MenuCommand (WPARAM wParam)
202 CHAR szApp[MAX_STRING_LEN];
203 CHAR szAppRelease[MAX_STRING_LEN];
205 /* switch to analog */
207 Globals.bAnalog = TRUE;
208 CLOCK_UpdateMenuCheckmarks();
210 InvalidateRect(Globals.hMainWnd, NULL, FALSE);
213 /* switch to digital */
215 Globals.bAnalog = FALSE;
216 CLOCK_UpdateMenuCheckmarks();
219 InvalidateRect(Globals.hMainWnd, NULL, FALSE);
237 /* show or hide seconds */
239 Globals.bSeconds = !Globals.bSeconds;
240 CLOCK_UpdateMenuCheckmarks();
242 if (!Globals.bAnalog)
244 InvalidateRect(Globals.hMainWnd, NULL, FALSE);
247 /* show or hide date */
249 Globals.bDate = !Globals.bDate;
250 CLOCK_UpdateMenuCheckmarks();
251 CLOCK_UpdateWindowCaption();
256 WineLicense(Globals.hMainWnd);
259 /* show warranties */
260 case IDM_NOWARRANTY: {
261 WineWarranty(Globals.hMainWnd);
264 /* show "about" box */
266 LoadString(Globals.hInstance, IDS_CLOCK, szApp, sizeof(szApp));
267 lstrcpy(szAppRelease,szApp);
268 ShellAbout(Globals.hMainWnd, szApp, szAppRelease, 0);
275 /***********************************************************************
279 static VOID CLOCK_Paint(HWND hWnd)
283 HBITMAP bmMem, bmOld;
285 dc = BeginPaint(hWnd, &ps);
287 /* Use an offscreen dc to avoid flicker */
288 dcMem = CreateCompatibleDC(dc);
289 bmMem = CreateCompatibleBitmap(dc, ps.rcPaint.right - ps.rcPaint.left,
290 ps.rcPaint.bottom - ps.rcPaint.top);
292 bmOld = SelectObject(dcMem, bmMem);
294 SetViewportOrgEx(dcMem, -ps.rcPaint.left, -ps.rcPaint.top, NULL);
295 /* Erase the background */
296 FillRect(dcMem, &ps.rcPaint, GetStockObject(LTGRAY_BRUSH));
299 AnalogClock(dcMem, Globals.MaxX, Globals.MaxY, Globals.bSeconds);
301 DigitalClock(dcMem, Globals.MaxX, Globals.MaxY, Globals.bSeconds, Globals.hFont);
303 /* Blit the changes to the screen */
305 ps.rcPaint.left, ps.rcPaint.top,
306 ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top,
308 ps.rcPaint.left, ps.rcPaint.top,
311 SelectObject(dcMem, bmOld);
318 /***********************************************************************
323 static LRESULT WINAPI CLOCK_WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
326 /* L button drag moves the window */
328 LRESULT ret = DefWindowProc (hWnd, msg, wParam, lParam);
334 case WM_NCLBUTTONDBLCLK:
335 case WM_LBUTTONDBLCLK: {
347 Globals.MaxX = LOWORD(lParam);
348 Globals.MaxY = HIWORD(lParam);
354 CLOCK_MenuCommand(wParam);
359 /* Could just invalidate what has changed,
360 * but it doesn't really seem worth the effort
362 InvalidateRect(Globals.hMainWnd, NULL, FALSE);
372 return DefWindowProc (hWnd, msg, wParam, lParam);
378 /***********************************************************************
383 int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show)
388 static const char szClassName[] = "CLClass"; /* To make sure className >= 0x10000 */
389 static const char szWinName[] = "Clock";
392 memset(&Globals.hFont, 0, sizeof (Globals.hFont));
393 Globals.bAnalog = TRUE;
394 Globals.bSeconds = TRUE;
397 class.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
398 class.lpfnWndProc = CLOCK_WndProc;
399 class.cbClsExtra = 0;
400 class.cbWndExtra = 0;
401 class.hInstance = hInstance;
402 class.hIcon = LoadIcon (0, IDI_APPLICATION);
403 class.hCursor = LoadCursor (0, IDC_ARROW);
404 class.hbrBackground = 0;
405 class.lpszMenuName = 0;
406 class.lpszClassName = szClassName;
409 if (!RegisterClass (&class)) return FALSE;
411 Globals.MaxX = Globals.MaxY = INITIAL_WINDOW_SIZE;
412 Globals.hMainWnd = CreateWindow (szClassName, szWinName, WS_OVERLAPPEDWINDOW,
413 CW_USEDEFAULT, CW_USEDEFAULT,
414 Globals.MaxX, Globals.MaxY, 0,
417 if (!CLOCK_ResetTimer())
420 Globals.hMainMenu = LoadMenu(0, MAKEINTRESOURCE(MAIN_MENU));
421 SetMenu(Globals.hMainWnd, Globals.hMainMenu);
422 CLOCK_UpdateMenuCheckmarks();
423 CLOCK_UpdateWindowCaption();
425 ShowWindow (Globals.hMainWnd, show);
426 UpdateWindow (Globals.hMainWnd);
428 while (GetMessage(&msg, 0, 0, 0)) {
429 TranslateMessage(&msg);
430 DispatchMessage(&msg);
433 KillTimer(Globals.hMainWnd, TIMER_ID);
434 DeleteObject(Globals.hFont);