[REACTOS]
[reactos.git] / reactos / base / setup / welcome / welcome.c
1 /*
2 * ReactOS applications
3 * Copyright (C) 2001, 2002, 2003 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 /*
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS welcome/autorun application
22 * FILE: subsys/system/welcome/welcome.c
23 * PROGRAMMERS: Eric Kohl
24 * Casper S. Hornstrup (chorns@users.sourceforge.net)
25 *
26 * NOTE:
27 * This utility can be customized by modifying the resources.
28 * Please do NOT change the source code in order to customize this
29 * utility but change the resources!
30 */
31
32 #include <stdarg.h>
33 #include <windef.h>
34 #include <winbase.h>
35 #include <wingdi.h>
36 #include <winuser.h>
37 #include <reactos/version.h>
38 #include <tchar.h>
39 #include <winnls.h>
40
41 #include "resource.h"
42
43 #define LIGHT_BLUE 0x00F7EFD6
44 #define DARK_BLUE 0x008C7B6B
45
46 #define TITLE_WIDTH 480
47 #define TITLE_HEIGHT 93
48
49
50 /* GLOBALS ******************************************************************/
51
52 TCHAR szFrameClass [] = TEXT("WelcomeWindowClass");
53 TCHAR szAppTitle [80];
54
55 HINSTANCE hInstance;
56
57 HWND hwndMain = 0;
58 HWND hwndDefaultTopic = 0;
59
60 HDC hdcMem = 0;
61
62 int nTopic = -1;
63 int nDefaultTopic = -1;
64
65 ULONG ulInnerWidth = TITLE_WIDTH;
66 ULONG ulInnerHeight = (TITLE_WIDTH * 3) / 4;
67 ULONG ulTitleHeight = TITLE_HEIGHT + 3;
68
69 HBITMAP hTitleBitmap = 0;
70 HBITMAP hDefaultTopicBitmap = 0;
71 HBITMAP hTopicBitmap[10];
72 HWND hwndTopicButton[10];
73 HWND hwndCloseButton;
74 HWND hwndCheckButton;
75
76 HFONT hfontTopicButton;
77 HFONT hfontTopicTitle;
78 HFONT hfontTopicDescription;
79 HFONT hfontCheckButton;
80
81 HBRUSH hbrLightBlue;
82 HBRUSH hbrDarkBlue;
83 HBRUSH hbrRightPanel;
84
85 RECT rcTitlePanel;
86 RECT rcLeftPanel;
87 RECT rcRightPanel;
88
89 WNDPROC fnOldBtn;
90
91
92 INT_PTR CALLBACK
93 MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
94
95
96 /* FUNCTIONS ****************************************************************/
97
98 int WINAPI
99 _tWinMain(HINSTANCE hInst,
100 HINSTANCE hPrevInstance,
101 LPTSTR lpszCmdLine,
102 int nCmdShow)
103 {
104 WNDCLASSEX wndclass;
105 MSG msg;
106 int xPos;
107 int yPos;
108 int xWidth;
109 int yHeight;
110 RECT rcWindow;
111 HICON hMainIcon;
112 HMENU hSystemMenu;
113 DWORD dwStyle = WS_OVERLAPPED | WS_CLIPCHILDREN | WS_CLIPSIBLINGS |
114 WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
115 BITMAP BitmapInfo;
116
117 UNREFERENCED_PARAMETER(hPrevInstance);
118 UNREFERENCED_PARAMETER(lpszCmdLine);
119
120 switch (GetUserDefaultUILanguage())
121 {
122 case MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT):
123 SetProcessDefaultLayout(LAYOUT_RTL);
124 break;
125
126 default:
127 break;
128 }
129
130 hInstance = hInst;
131
132 /* Load icons */
133 hMainIcon = LoadIcon (hInstance, MAKEINTRESOURCE(IDI_MAIN));
134
135 /* Register the window class */
136 wndclass.style = CS_HREDRAW | CS_VREDRAW;
137 wndclass.lpfnWndProc = (WNDPROC)MainWndProc;
138 wndclass.cbClsExtra = 0;
139 wndclass.cbWndExtra = 0;
140 wndclass.hInstance = hInstance;
141 wndclass.hIcon = hMainIcon;
142 wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
143 wndclass.hbrBackground = 0;
144 wndclass.lpszMenuName = NULL;
145 wndclass.lpszClassName = szFrameClass;
146
147 wndclass.cbSize = sizeof(WNDCLASSEX);
148 wndclass.hIconSm = 0;
149
150 RegisterClassEx(&wndclass);
151
152 hTitleBitmap = LoadBitmap (hInstance, MAKEINTRESOURCE(IDB_TITLEBITMAP));
153 if (hTitleBitmap != NULL)
154 {
155 GetObject(hTitleBitmap, sizeof(BITMAP), &BitmapInfo);
156 ulInnerWidth = BitmapInfo.bmWidth;
157 ulInnerHeight = (ulInnerWidth * 3) / 4;
158 ulTitleHeight = BitmapInfo.bmHeight + 3;
159 DeleteObject(hTitleBitmap);
160 }
161 ulInnerHeight -= GetSystemMetrics(SM_CYCAPTION);
162
163 rcWindow.top = 0;
164 rcWindow.bottom = ulInnerHeight - 1;
165 rcWindow.left = 0;
166 rcWindow.right = ulInnerWidth - 1;
167
168 AdjustWindowRect(&rcWindow,
169 dwStyle,
170 FALSE);
171 xWidth = rcWindow.right - rcWindow.left;
172 yHeight = rcWindow.bottom - rcWindow.top;
173
174 xPos = (GetSystemMetrics(SM_CXSCREEN) - xWidth) / 2;
175 yPos = (GetSystemMetrics(SM_CYSCREEN) - yHeight) / 2;
176
177 rcTitlePanel.top = 0;
178 rcTitlePanel.bottom = ulTitleHeight;
179 rcTitlePanel.left = 0;
180 rcTitlePanel.right = ulInnerWidth - 1;
181
182 rcLeftPanel.top = rcTitlePanel.bottom;
183 rcLeftPanel.bottom = ulInnerHeight - 1;
184 rcLeftPanel.left = 0;
185 rcLeftPanel.right = ulInnerWidth / 3;
186
187 rcRightPanel.top = rcLeftPanel.top;
188 rcRightPanel.bottom = rcLeftPanel.bottom;
189 rcRightPanel.left = rcLeftPanel.right;
190 rcRightPanel.right = ulInnerWidth - 1;
191
192 if (!LoadString(hInstance, (UINT_PTR)MAKEINTRESOURCE(IDS_APPTITLE), szAppTitle, 80))
193 _tcscpy(szAppTitle, TEXT("ReactOS Welcome"));
194
195 /* Create main window */
196 hwndMain = CreateWindow(szFrameClass,
197 szAppTitle,
198 dwStyle,
199 xPos,
200 yPos,
201 xWidth,
202 yHeight,
203 0,
204 0,
205 hInstance,
206 NULL);
207
208 hSystemMenu = GetSystemMenu(hwndMain, FALSE);
209 if(hSystemMenu)
210 {
211 RemoveMenu(hSystemMenu, SC_SIZE, MF_BYCOMMAND);
212 RemoveMenu(hSystemMenu, SC_MAXIMIZE, MF_BYCOMMAND);
213 }
214
215 ShowWindow(hwndMain, nCmdShow);
216 UpdateWindow(hwndMain);
217
218 while (GetMessage(&msg, NULL, 0, 0) != FALSE)
219 {
220 TranslateMessage(&msg);
221 DispatchMessage(&msg);
222 }
223
224 return(msg.wParam);
225 }
226
227
228 INT_PTR CALLBACK
229 ButtonSubclassWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
230 {
231 LONG i;
232
233 if (uMsg == WM_MOUSEMOVE)
234 {
235 i = GetWindowLongPtr(hWnd, GWL_ID);
236 if (nTopic != i)
237 {
238 nTopic = i;
239 SetFocus(hWnd);
240 InvalidateRect(hwndMain, &rcRightPanel, TRUE);
241 }
242 }
243
244 return(CallWindowProc(fnOldBtn, hWnd, uMsg, wParam, lParam));
245 }
246
247
248 static BOOL
249 RunApplication(int nTopic)
250 {
251 PROCESS_INFORMATION ProcessInfo;
252 STARTUPINFO StartupInfo;
253 TCHAR AppName[256];
254 TCHAR CurrentDir[256];
255 int nLength;
256
257 InvalidateRect(hwndMain, NULL, TRUE);
258
259 GetCurrentDirectory(256, CurrentDir);
260
261 nLength = LoadString(hInstance, IDS_TOPICACTION0 + nTopic, AppName, 256);
262 if (nLength == 0)
263 return TRUE;
264
265 if (!_tcsicmp(AppName, TEXT("<exit>")))
266 return FALSE;
267
268 if (_tcsicmp(AppName, TEXT("explorer.exe")) == 0)
269 {
270 _tcscat(AppName, TEXT(" "));
271 _tcscat(AppName, CurrentDir);
272 }
273
274 ZeroMemory(&StartupInfo, sizeof(StartupInfo));
275 StartupInfo.cb = sizeof(StartupInfo);
276 StartupInfo.lpTitle = TEXT("Test");
277 StartupInfo.dwFlags = STARTF_USESHOWWINDOW;
278 StartupInfo.wShowWindow = SW_SHOWNORMAL;
279
280 CreateProcess(NULL, AppName, NULL, NULL, FALSE, CREATE_NEW_CONSOLE,NULL,
281 CurrentDir,
282 &StartupInfo,
283 &ProcessInfo);
284
285 CloseHandle(ProcessInfo.hProcess);
286 CloseHandle(ProcessInfo.hThread);
287
288 return TRUE;
289 }
290
291
292 static VOID
293 SubclassButton(HWND hWnd)
294 {
295 fnOldBtn = (WNDPROC)SetWindowLongPtr(hWnd, GWL_WNDPROC, (DWORD_PTR)ButtonSubclassWndProc);
296 }
297
298
299 static DWORD
300 GetButtonHeight(HDC hDC,
301 HFONT hFont,
302 LPCTSTR szText,
303 DWORD dwWidth)
304 {
305 HFONT hOldFont;
306 RECT rect;
307
308 rect.left = 0;
309 rect.right = dwWidth - 20;
310 rect.top = 0;
311 rect.bottom = 25;
312
313 hOldFont = (HFONT) SelectObject(hDC, hFont);
314 DrawText(hDC, szText, -1, &rect, DT_TOP | DT_CALCRECT | DT_WORDBREAK);
315 SelectObject(hDC, hOldFont);
316
317 return(rect.bottom-rect.top + 14);
318 }
319
320
321 static LRESULT
322 OnCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
323 {
324 TCHAR szText[80];
325 int i,nLength;
326 HDC ScreenDC;
327 DWORD dwTop;
328 DWORD dwHeight = 0;
329
330 UNREFERENCED_PARAMETER(wParam);
331 UNREFERENCED_PARAMETER(lParam);
332
333 hbrLightBlue = CreateSolidBrush(LIGHT_BLUE);
334 hbrDarkBlue = CreateSolidBrush(DARK_BLUE);
335 hbrRightPanel = CreateSolidBrush(0x00FFFFFF);
336
337 /* Topic title font */
338 hfontTopicTitle = CreateFont(-18,0,0,0,FW_NORMAL,
339 FALSE,FALSE,FALSE,ANSI_CHARSET,
340 OUT_DEFAULT_PRECIS,
341 CLIP_DEFAULT_PRECIS,
342 DEFAULT_QUALITY,
343 FF_DONTCARE,
344 TEXT("Arial"));
345
346 /* Topic description font */
347 hfontTopicDescription = CreateFont(-11,0,0,0,FW_THIN,
348 FALSE,FALSE,FALSE,ANSI_CHARSET,
349 OUT_DEFAULT_PRECIS,
350 CLIP_DEFAULT_PRECIS,
351 DEFAULT_QUALITY,
352 FF_DONTCARE,
353 TEXT("Arial"));
354
355 /* Topic button font */
356 hfontTopicButton = CreateFont(-11,0,0,0,FW_BOLD,
357 FALSE,FALSE,FALSE,ANSI_CHARSET,
358 OUT_DEFAULT_PRECIS,
359 CLIP_DEFAULT_PRECIS,
360 DEFAULT_QUALITY,
361 FF_DONTCARE,
362 TEXT("Arial"));
363
364 /* Load title bitmap */
365 if (hTitleBitmap != 0)
366 hTitleBitmap = LoadBitmap (hInstance, MAKEINTRESOURCE(IDB_TITLEBITMAP));
367
368 /* Load topic bitmaps */
369 hDefaultTopicBitmap = LoadBitmap (hInstance, MAKEINTRESOURCE(IDB_DEFAULTTOPICBITMAP));
370 for (i=0;i < 10; i++)
371 {
372 hTopicBitmap[i] = LoadBitmap (hInstance, MAKEINTRESOURCE(IDB_TOPICBITMAP0+i));
373 }
374
375 ScreenDC = GetWindowDC(hWnd);
376 hdcMem = CreateCompatibleDC (ScreenDC);
377 ReleaseDC(hWnd, ScreenDC);
378
379 /* load and create buttons */
380 dwTop = rcLeftPanel.top;
381 for (i = 0; i < 10; i++)
382 {
383 nLength = LoadString(hInstance, IDS_TOPICBUTTON0 + i, szText, 80);
384 if (nLength > 0)
385 {
386 dwHeight = GetButtonHeight(hdcMem,
387 hfontTopicButton,
388 szText,
389 rcLeftPanel.right - rcLeftPanel.left);
390
391 hwndTopicButton[i] = CreateWindow(TEXT("BUTTON"),
392 szText,
393 WS_CHILDWINDOW | WS_VISIBLE | WS_TABSTOP | BS_MULTILINE | BS_OWNERDRAW,
394 rcLeftPanel.left,
395 dwTop,
396 rcLeftPanel.right - rcLeftPanel.left,
397 dwHeight,
398 hWnd,
399 (HMENU)IntToPtr(i),
400 hInstance,
401 NULL);
402 hwndDefaultTopic = hwndTopicButton[i];
403 nDefaultTopic = i;
404 SubclassButton(hwndTopicButton[i]);
405 SendMessage(hwndTopicButton[i], WM_SETFONT, (WPARAM)hfontTopicButton, MAKELPARAM(TRUE,0));
406 }
407 else
408 {
409 hwndTopicButton[i] = 0;
410 }
411
412 dwTop += dwHeight;
413 }
414
415 /* Create exit button */
416 nLength = LoadString(hInstance, IDS_CLOSETEXT, szText, 80);
417 if (nLength > 0)
418 {
419 hwndCloseButton = CreateWindow(TEXT("BUTTON"),
420 szText,
421 WS_VISIBLE | WS_CHILD | BS_FLAT,
422 rcRightPanel.right - 10 - 57,
423 rcRightPanel.bottom - 10 - 21,
424 57,
425 21,
426 hWnd,
427 (HMENU)IDC_CLOSEBUTTON,
428 hInstance,
429 NULL);
430 hwndDefaultTopic = 0;
431 nDefaultTopic = -1;
432 SendMessage(hwndCloseButton, WM_SETFONT, (WPARAM)hfontTopicButton, MAKELPARAM(TRUE,0));
433 }
434 else
435 {
436 hwndCloseButton = 0;
437 }
438
439 /* Create checkbox */
440 nLength = LoadString(hInstance, IDS_CHECKTEXT,szText,80);
441 if (nLength > 0)
442 {
443 hfontCheckButton = CreateFont(-10,0,0,0,FW_THIN,FALSE,FALSE,FALSE,ANSI_CHARSET,
444 OUT_DEFAULT_PRECIS,
445 CLIP_DEFAULT_PRECIS,
446 DEFAULT_QUALITY,
447 FF_DONTCARE,
448 TEXT("Tahoma"));
449
450 hwndCheckButton = CreateWindow(TEXT("BUTTON"),
451 szText,
452 WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX,
453 rcLeftPanel.left + 8,
454 rcLeftPanel.bottom - 8 - 13,
455 rcLeftPanel.right - rcLeftPanel.left - 16,
456 13,
457 hWnd,
458 (HMENU)IDC_CHECKBUTTON,
459 hInstance,
460 NULL);
461 SendMessage(hwndCheckButton, WM_SETFONT, (WPARAM)hfontCheckButton, MAKELPARAM(TRUE,0));
462 }
463 else
464 {
465 hwndCheckButton = 0;
466 hfontCheckButton = 0;
467 }
468
469 return 0;
470 }
471
472
473 static LRESULT
474 OnCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
475 {
476 UNREFERENCED_PARAMETER(lParam);
477
478 if (LOWORD(wParam) == IDC_CLOSEBUTTON)
479 {
480 DestroyWindow(hWnd);
481 }
482 else if ((LOWORD(wParam) < 10))
483 {
484 if (RunApplication(LOWORD(wParam)) == FALSE)
485 {
486 DestroyWindow(hWnd);
487 }
488 }
489 return 0;
490 }
491
492
493 static VOID
494 PaintBanner(HDC hdc, LPRECT rcPanel)
495 {
496 HBITMAP hOldBitmap;
497 HBRUSH hOldBrush;
498
499 /* Title bitmap */
500 hOldBitmap = (HBITMAP) SelectObject(hdcMem, hTitleBitmap);
501 BitBlt(hdc,
502 rcPanel->left,
503 rcPanel->top,
504 rcPanel->right - rcPanel->left,
505 rcPanel->bottom - 3,
506 hdcMem, 0, 0, SRCCOPY);
507 SelectObject(hdcMem, hOldBitmap);
508
509 /* Dark blue line */
510 hOldBrush = (HBRUSH) SelectObject(hdc, hbrDarkBlue);
511 PatBlt(hdc,
512 rcPanel->left,
513 rcPanel->bottom - 3,
514 rcPanel->right - rcPanel->left,
515 3,
516 PATCOPY);
517
518 SelectObject(hdc, hOldBrush);
519 }
520
521
522 static LRESULT
523 OnPaint(HWND hWnd, WPARAM wParam, LPARAM lParam)
524 {
525 HPEN hPen;
526 HPEN hOldPen;
527 HDC hdc;
528 PAINTSTRUCT ps;
529 HBITMAP hOldBitmap = 0;
530 HBRUSH hOldBrush;
531 HFONT hOldFont;
532 RECT rcTitle, rcDescription;
533 TCHAR szTopicTitle[80];
534 TCHAR szTopicDesc[256];
535 int nLength;
536 BITMAP bmpInfo;
537 TCHAR version[50];
538
539 UNREFERENCED_PARAMETER(wParam);
540 UNREFERENCED_PARAMETER(lParam);
541
542 hdc = BeginPaint(hWnd, &ps);
543
544 /* Banner panel */
545 PaintBanner(hdc, &rcTitlePanel);
546
547 /* Left panel */
548 hOldBrush = (HBRUSH) SelectObject (hdc, hbrLightBlue);
549 PatBlt(hdc,
550 rcLeftPanel.left,
551 rcLeftPanel.top,
552 rcLeftPanel.right - rcLeftPanel.left,
553 rcLeftPanel.bottom - rcLeftPanel.top,
554 PATCOPY);
555 SelectObject(hdc, hOldBrush);
556
557 /* Right panel */
558 hOldBrush = (HBRUSH) SelectObject (hdc, WHITE_BRUSH);
559 PatBlt(hdc,
560 rcRightPanel.left,
561 rcRightPanel.top,
562 rcRightPanel.right - rcRightPanel.left,
563 rcRightPanel.bottom - rcRightPanel.top,
564 PATCOPY);
565 SelectObject(hdc, hOldBrush);
566
567 /* Draw dark verical line */
568 hPen = CreatePen(PS_SOLID, 0, DARK_BLUE);
569 hOldPen = (HPEN) SelectObject(hdc, hPen);
570 MoveToEx(hdc, rcRightPanel.left, rcRightPanel.top, NULL);
571 LineTo(hdc, rcRightPanel.left, rcRightPanel.bottom);
572 SelectObject(hdc, hOldPen);
573 DeleteObject(hPen);
574
575 /* Draw topic bitmap */
576 if ((nTopic == -1) && (hDefaultTopicBitmap != 0))
577 {
578 GetObject(hDefaultTopicBitmap, sizeof(BITMAP), &bmpInfo);
579 hOldBitmap = (HBITMAP) SelectObject (hdcMem, hDefaultTopicBitmap);
580 BitBlt(hdc,
581 rcRightPanel.right - bmpInfo.bmWidth,
582 rcRightPanel.bottom - bmpInfo.bmHeight,
583 bmpInfo.bmWidth,
584 bmpInfo.bmHeight,
585 hdcMem,
586 0,
587 0,
588 SRCCOPY);
589 }
590 else if ((nTopic != -1) && (hTopicBitmap[nTopic] != 0))
591 {
592 GetObject(hTopicBitmap[nTopic], sizeof(BITMAP), &bmpInfo);
593 hOldBitmap = (HBITMAP) SelectObject (hdcMem, hTopicBitmap[nTopic]);
594 BitBlt(hdc,
595 rcRightPanel.right - bmpInfo.bmWidth,
596 rcRightPanel.bottom - bmpInfo.bmHeight,
597 bmpInfo.bmWidth,
598 bmpInfo.bmHeight,
599 hdcMem,
600 0,
601 0,
602 SRCCOPY);
603 }
604
605 if (nTopic == -1)
606 {
607 nLength = LoadString(hInstance, IDS_DEFAULTTOPICTITLE, szTopicTitle, 80);
608 }
609 else
610 {
611 nLength = LoadString(hInstance, IDS_TOPICTITLE0 + nTopic, szTopicTitle, 80);
612 if (nLength == 0)
613 nLength = LoadString(hInstance, IDS_DEFAULTTOPICTITLE, szTopicTitle, 80);
614 }
615
616 if (nTopic == -1)
617 {
618 nLength = LoadString(hInstance, IDS_DEFAULTTOPICDESC, szTopicDesc, 256);
619 }
620 else
621 {
622 nLength = LoadString(hInstance, IDS_TOPICDESC0 + nTopic, szTopicDesc, 256);
623 if (nLength == 0)
624 nLength = LoadString(hInstance, IDS_DEFAULTTOPICDESC, szTopicDesc, 256);
625 }
626
627 SetBkMode(hdc, TRANSPARENT);
628
629 /* Draw version information */
630 wsprintf(version, TEXT("ReactOS %d.%d.%d"),
631 KERNEL_VERSION_MAJOR,
632 KERNEL_VERSION_MINOR,
633 KERNEL_VERSION_PATCH_LEVEL);
634
635 rcTitle.left = rcLeftPanel.left + 8;
636 rcTitle.right = rcLeftPanel.right - 5;
637 rcTitle.top = rcLeftPanel.bottom - 40;
638 rcTitle.bottom = rcLeftPanel.bottom - 5;
639 hOldFont = (HFONT) SelectObject(hdc, hfontTopicDescription);
640 DrawText(hdc, version, -1, &rcTitle, DT_BOTTOM | DT_CALCRECT | DT_SINGLELINE);
641 DrawText(hdc, version, -1, &rcTitle, DT_BOTTOM | DT_SINGLELINE);
642 SelectObject(hdc, hOldFont);
643
644 /* Draw topic title */
645 rcTitle.left = rcRightPanel.left + 12;
646 rcTitle.right = rcRightPanel.right - 8;
647 rcTitle.top = rcRightPanel.top + 8;
648 rcTitle.bottom = rcTitle.top + 57;
649 hOldFont = (HFONT) SelectObject(hdc, hfontTopicTitle);
650 DrawText(hdc, szTopicTitle, -1, &rcTitle, DT_TOP | DT_CALCRECT);
651
652 SetTextColor(hdc, DARK_BLUE);
653 DrawText(hdc, szTopicTitle, -1, &rcTitle, DT_TOP);
654
655 /* Draw topic description */
656 rcDescription.left = rcRightPanel.left + 12;
657 rcDescription.right = rcRightPanel.right - 8;
658 rcDescription.top = rcTitle.bottom + 8;
659 rcDescription.bottom = rcRightPanel.bottom - 20;
660
661 SelectObject(hdc, hfontTopicDescription);
662 SetTextColor(hdc, 0x00000000);
663 DrawText(hdc, szTopicDesc, -1, &rcDescription, DT_TOP | DT_WORDBREAK);
664
665 SetBkMode(hdc, OPAQUE);
666 SelectObject(hdc, hOldFont);
667
668 SelectObject (hdcMem, hOldBrush);
669 SelectObject (hdcMem, hOldBitmap);
670
671 EndPaint(hWnd, &ps);
672
673 return 0;
674 }
675
676
677 static LRESULT
678 OnDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam)
679 {
680 LPDRAWITEMSTRUCT lpDis = (LPDRAWITEMSTRUCT)lParam;
681 HPEN hPen, hOldPen;
682 HBRUSH hOldBrush;
683 TCHAR szText[80];
684 int iBkMode;
685
686 UNREFERENCED_PARAMETER(hWnd);
687 UNREFERENCED_PARAMETER(wParam);
688
689 if (lpDis->hwndItem == hwndCloseButton)
690 {
691 DrawFrameControl(lpDis->hDC,
692 &lpDis->rcItem,
693 DFC_BUTTON,
694 DFCS_BUTTONPUSH | DFCS_FLAT);
695 }
696 else
697 {
698 if (lpDis->CtlID == (ULONG)nTopic)
699 hOldBrush = (HBRUSH) SelectObject(lpDis->hDC, hbrRightPanel);
700 else
701 hOldBrush = (HBRUSH) SelectObject(lpDis->hDC, hbrLightBlue);
702
703 PatBlt(lpDis->hDC,
704 lpDis->rcItem.left,
705 lpDis->rcItem.top,
706 lpDis->rcItem.right,
707 lpDis->rcItem.bottom,
708 PATCOPY);
709 SelectObject(lpDis->hDC, hOldBrush);
710
711 hPen = CreatePen(PS_SOLID, 0, DARK_BLUE);
712 hOldPen = (HPEN) SelectObject(lpDis->hDC, hPen);
713 MoveToEx(lpDis->hDC, lpDis->rcItem.left, lpDis->rcItem.bottom-1, NULL);
714 LineTo(lpDis->hDC, lpDis->rcItem.right, lpDis->rcItem.bottom-1);
715 SelectObject(lpDis->hDC, hOldPen);
716 DeleteObject(hPen);
717
718 InflateRect(&lpDis->rcItem, -10, -4);
719 OffsetRect(&lpDis->rcItem, 0, 1);
720 GetWindowText(lpDis->hwndItem, szText, 80);
721 SetTextColor(lpDis->hDC, 0x00000000);
722 iBkMode = SetBkMode(lpDis->hDC, TRANSPARENT);
723 DrawText(lpDis->hDC, szText, -1, &lpDis->rcItem, DT_TOP | DT_LEFT | DT_WORDBREAK);
724 SetBkMode(lpDis->hDC, iBkMode);
725 }
726
727 return 0;
728 }
729
730
731 static LRESULT
732 OnMouseMove(HWND hWnd, WPARAM wParam, LPARAM lParam)
733 {
734 UNREFERENCED_PARAMETER(wParam);
735 UNREFERENCED_PARAMETER(lParam);
736
737 if (nTopic != -1)
738 {
739 nTopic = -1;
740 SetFocus(hWnd);
741 InvalidateRect(hwndMain, &rcRightPanel, TRUE);
742 }
743
744 return 0;
745 }
746
747
748 static LRESULT
749 OnCtlColorStatic(HWND hWnd, WPARAM wParam, LPARAM lParam)
750 {
751 UNREFERENCED_PARAMETER(hWnd);
752
753 if ((HWND)lParam == hwndCheckButton)
754 {
755 SetBkColor((HDC)wParam, LIGHT_BLUE);
756 return((LRESULT)hbrLightBlue);
757 }
758
759 return 0;
760 }
761
762
763 static LRESULT
764 OnActivate(HWND hWnd, WPARAM wParam, LPARAM lParam)
765 {
766 UNREFERENCED_PARAMETER(hWnd);
767 UNREFERENCED_PARAMETER(wParam);
768 UNREFERENCED_PARAMETER(lParam);
769 nTopic = -1;
770 InvalidateRect(hwndMain, &rcRightPanel, TRUE);
771
772 return(0);
773 }
774
775
776 static LRESULT
777 OnDestroy(HWND hWnd, WPARAM wParam, LPARAM lParam)
778 {
779 int i;
780
781 UNREFERENCED_PARAMETER(hWnd);
782 UNREFERENCED_PARAMETER(wParam);
783 UNREFERENCED_PARAMETER(lParam);
784
785 for (i=0;i<10;i++)
786 {
787 if (hwndTopicButton[i] != 0)
788 DestroyWindow(hwndTopicButton[i]);
789 }
790
791 if (hwndCloseButton != 0)
792 DestroyWindow(hwndCloseButton);
793
794 if (hwndCheckButton != 0)
795 DestroyWindow(hwndCheckButton);
796
797 DeleteDC(hdcMem);
798
799 /* delete bitmaps */
800 DeleteObject(hDefaultTopicBitmap);
801 DeleteObject(hTitleBitmap);
802 for (i=0;i<10;i++)
803 {
804 if (hTopicBitmap[i] != 0)
805 DeleteObject(hTopicBitmap[i]);
806 }
807
808 DeleteObject(hfontTopicTitle);
809 DeleteObject(hfontTopicDescription);
810 DeleteObject(hfontTopicButton);
811
812 if (hfontCheckButton != 0)
813 DeleteObject(hfontCheckButton);
814
815 DeleteObject(hbrLightBlue);
816 DeleteObject(hbrDarkBlue);
817 DeleteObject(hbrRightPanel);
818
819 return 0;
820 }
821
822
823 INT_PTR CALLBACK
824 MainWndProc(HWND hWnd,
825 UINT uMsg,
826 WPARAM wParam,
827 LPARAM lParam)
828 {
829 switch(uMsg)
830 {
831 case WM_CREATE:
832 return(OnCreate(hWnd, wParam, lParam));
833
834 case WM_COMMAND:
835 return(OnCommand(hWnd, wParam, lParam));
836
837 case WM_ACTIVATE:
838 return(OnActivate(hWnd, wParam, lParam));
839
840 case WM_PAINT:
841 return(OnPaint(hWnd, wParam, lParam));
842
843 case WM_DRAWITEM:
844 return(OnDrawItem(hWnd, wParam, lParam));
845
846 case WM_CTLCOLORSTATIC:
847 return(OnCtlColorStatic(hWnd, wParam, lParam));
848
849 case WM_MOUSEMOVE:
850 return(OnMouseMove(hWnd, wParam, lParam));
851
852 case WM_DESTROY:
853 OnDestroy(hWnd, wParam, lParam);
854 PostQuitMessage(0);
855 return(0);
856 }
857
858 return(DefWindowProc(hWnd, uMsg, wParam, lParam));
859 }
860
861 /* EOF */