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