3 * Copyright (C) 2001, 2002, 2003 ReactOS Team
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.
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.
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.
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 * Hermes Belusca-Maito
28 * This utility can be customized by using localized INI configuration files.
29 * The default strings are stored in the utility's resources.
43 #include <reactos/version.h>
47 #define LIGHT_BLUE RGB(214, 239, 247)
48 #define DARK_BLUE RGB(107, 123, 140)
50 #define TITLE_WIDTH 480
51 #define TITLE_HEIGHT 93
53 /* GLOBALS ******************************************************************/
55 TCHAR szFrameClass
[] = TEXT("WelcomeWindowClass");
61 HWND hWndDefaultTopic
= NULL
;
65 ULONG ulInnerWidth
= TITLE_WIDTH
;
66 ULONG ulInnerHeight
= (TITLE_WIDTH
* 3) / 4;
67 ULONG ulTitleHeight
= TITLE_HEIGHT
+ 3;
69 HBITMAP hTitleBitmap
= NULL
;
70 HBITMAP hDefaultTopicBitmap
= NULL
;
71 HWND hWndCloseButton
= NULL
;
72 HWND hWndCheckButton
= NULL
;
74 /* TODO: Retrieve the preferences from a configuration file */
75 BOOL bDisplayCheckBox
= FALSE
; // FIXME!
76 BOOL bDisplayExitBtn
= TRUE
;
78 #define BUFFER_SIZE 1024
80 #define TOPIC_TITLE_LENGTH 80
81 #define TOPIC_DESC_LENGTH 1024
88 TCHAR szTitle
[TOPIC_TITLE_LENGTH
];
89 TCHAR szDesc
[TOPIC_DESC_LENGTH
];
93 DWORD dwNumberTopics
= 0;
94 PTOPIC
* pTopics
= NULL
;
96 TCHAR szDefaultTitle
[TOPIC_TITLE_LENGTH
];
97 TCHAR szDefaultDesc
[TOPIC_DESC_LENGTH
];
99 INT nTopic
= -1; // Active (focused) topic
100 INT nDefaultTopic
= -1; // Default selected topic
102 HFONT hFontTopicButton
;
103 HFONT hFontTopicTitle
;
104 HFONT hFontTopicDescription
;
105 HFONT hFontCheckButton
;
109 HBRUSH hbrRightPanel
;
119 MainWndProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
);
122 /* FUNCTIONS ****************************************************************/
124 INT
GetLocaleName(LCID Locale
, LPTSTR lpLCData
, SIZE_T cchData
)
128 /* Try to retrieve the locale language name (LOCALE_SNAME is supported on Vista+) */
129 ret
= GetLocaleInfo(Locale
, LOCALE_SNAME
, lpLCData
, cchData
);
130 if (ret
|| (GetLastError() != ERROR_INVALID_FLAGS
))
134 * We failed because LOCALE_SNAME was unrecognized, so try to manually build
135 * a language name in the form xx-YY (WARNING: this method has its limitations).
137 ret
= GetLocaleInfo(Locale
, LOCALE_SISO639LANGNAME
, lpLCData
, cchData
);
141 lpLCData
+= (ret
- 1);
142 cchData
-= (ret
- 1);
146 /* Try to get the second part; we add the '-' separator only if we succeed */
147 ret2
= GetLocaleInfo(Locale
, LOCALE_SISO3166CTRYNAME
, lpLCData
+ 1, cchData
- 1);
150 ret
+= ret2
; // 'ret' already counts '-'.
157 VOID
TranslateEscapes(IN OUT LPTSTR lpString
)
159 LPTSTR pEscape
= NULL
; // Next backslash escape sequence.
161 while (lpString
&& *lpString
)
163 /* Find the next backslash escape sequence */
164 pEscape
= _tcschr(lpString
, _T('\\'));
168 /* Go past the escape backslash */
169 lpString
= pEscape
+ 1;
171 /* Find which sequence it is */
175 // *pEscape = _T('\0'); // Enable if one wants to convert \<NULL> into <NULL>.
176 // lpString = pEscape + 1; // Loop will stop at the next iteration.
179 case _T('n'): case _T('r'):
180 // case _T('\\'): // others?
181 // So far we only need to deal with the newlines.
183 if (*lpString
== _T('n'))
185 else if (*lpString
== _T('r'))
188 memmove(lpString
, lpString
+ 1, (_tcslen(lpString
+ 1) + 1) * sizeof(TCHAR
));
192 /* Unknown escape sequence, ignore it */
200 BOOL
LoadTopicsFromINI(LCID Locale
)
204 TCHAR szBuffer
[LOCALE_NAME_MAX_LENGTH
];
205 TCHAR szIniPath
[MAX_PATH
];
206 LPTSTR lpszSections
= NULL
, lpszSection
= NULL
;
207 PTOPIC pTopic
, *pTopicsTmp
;
209 /* Retrieve the locale name (on which the INI file name is based) */
210 dwRet
= (DWORD
)GetLocaleName(Locale
, szBuffer
, ARRAYSIZE(szBuffer
));
213 /* Fall back to english (US) */
214 StringCchCopy(szBuffer
, ARRAYSIZE(szBuffer
), TEXT("en-US"));
217 /* Build the INI file name */
218 GetCurrentDirectory(ARRAYSIZE(szIniPath
), szIniPath
);
219 StringCchCat(szIniPath
, ARRAYSIZE(szIniPath
), TEXT("\\"));
220 StringCchCat(szIniPath
, ARRAYSIZE(szIniPath
), szBuffer
);
221 StringCchCat(szIniPath
, ARRAYSIZE(szIniPath
), TEXT(".ini"));
223 /* Verify that the file exists, otherwise fall back to english (US) */
224 if (GetFileAttributes(szIniPath
) == INVALID_FILE_ATTRIBUTES
)
226 StringCchCopy(szBuffer
, ARRAYSIZE(szBuffer
), TEXT("en-US"));
228 GetCurrentDirectory(ARRAYSIZE(szIniPath
), szIniPath
);
229 StringCchCat(szIniPath
, ARRAYSIZE(szIniPath
), TEXT("\\"));
230 StringCchCat(szIniPath
, ARRAYSIZE(szIniPath
), szBuffer
);
231 StringCchCat(szIniPath
, ARRAYSIZE(szIniPath
), TEXT(".ini"));
234 /* Verify that the file exists, otherwise fall back to internal (localized) resource */
235 if (GetFileAttributes(szIniPath
) == INVALID_FILE_ATTRIBUTES
)
236 return FALSE
; // TODO: For localized resource, see the general function.
238 /* Try to load the default localized strings */
239 if (!GetPrivateProfileString(TEXT("Defaults"), TEXT("DefaultTopicTitle"), NULL
/* default */,
240 szDefaultTitle
, ARRAYSIZE(szDefaultTitle
), szIniPath
))
244 if (!GetPrivateProfileString(TEXT("Defaults"), TEXT("DefaultTopicDescription"), NULL
/* default */,
245 szDefaultDesc
, ARRAYSIZE(szDefaultDesc
), szIniPath
))
251 TranslateEscapes(szDefaultDesc
);
254 /* Allocate a buffer big enough to hold all the section names */
255 for (dwSize
= BUFFER_SIZE
; ; dwSize
+= BUFFER_SIZE
)
257 lpszSections
= HeapAlloc(GetProcessHeap(), 0, dwSize
* sizeof(TCHAR
));
259 return TRUE
; // FIXME!
260 dwRet
= GetPrivateProfileSectionNames(lpszSections
, dwSize
, szIniPath
);
261 if (dwRet
< dwSize
- 2)
263 HeapFree(GetProcessHeap(), 0, lpszSections
);
269 /* Loop over the sections and load the topics */
270 lpszSection
= lpszSections
;
271 for (; lpszSection
&& *lpszSection
; lpszSection
+= (_tcslen(lpszSection
) + 1))
273 if (_tcsnicmp(lpszSection
, TEXT("Topic"), 5) == 0)
275 /* Allocate (or reallocate) the list of topics */
277 pTopicsTmp
= HeapAlloc(GetProcessHeap(), 0, (dwNumberTopics
+ 1) * sizeof(*pTopics
));
279 pTopicsTmp
= HeapReAlloc(GetProcessHeap(), 0, pTopics
, (dwNumberTopics
+ 1) * sizeof(*pTopics
));
281 break; // Cannot reallocate more
282 pTopics
= pTopicsTmp
;
284 /* Allocate a new topic */
285 pTopic
= HeapAlloc(GetProcessHeap(), 0, sizeof(*pTopic
));
287 break; // Cannot reallocate more
288 pTopics
[dwNumberTopics
++] = pTopic
;
290 /* Retrieve the information */
291 if (!GetPrivateProfileString(lpszSection
, TEXT("Button"), NULL
/* default */,
292 pTopic
->szText
, ARRAYSIZE(pTopic
->szText
), szIniPath
))
296 if (!GetPrivateProfileString(lpszSection
, TEXT("Title"), NULL
/* default */,
297 pTopic
->szTitle
, ARRAYSIZE(pTopic
->szTitle
), szIniPath
))
299 *pTopic
->szTitle
= 0;
301 if (!GetPrivateProfileString(lpszSection
, TEXT("Description"), NULL
/* default */,
302 pTopic
->szDesc
, ARRAYSIZE(pTopic
->szDesc
), szIniPath
))
308 TranslateEscapes(pTopic
->szDesc
);
310 if (!GetPrivateProfileString(lpszSection
, TEXT("Action"), NULL
/* default */,
311 pTopic
->szAction
, ARRAYSIZE(pTopic
->szAction
), szIniPath
))
313 *pTopic
->szAction
= 0;
317 TranslateEscapes(pTopic
->szAction
);
322 HeapFree(GetProcessHeap(), 0, lpszSections
);
327 BOOL
LoadTopics(VOID
)
329 #define MAX_NUMBER_INTERNAL_TOPICS 3
332 PTOPIC pTopic
, *pTopicsTmp
;
338 * First, try to load the default internal (localized) strings.
339 * They can be redefined by the localized INI files.
341 if (!LoadString(hInstance
, IDS_DEFAULTTOPICTITLE
, szDefaultTitle
, ARRAYSIZE(szDefaultTitle
)))
343 if (!LoadString(hInstance
, IDS_DEFAULTTOPICDESC
, szDefaultDesc
, ARRAYSIZE(szDefaultDesc
)))
346 /* Try to load the topics from INI file */
347 if (LoadTopicsFromINI(LOCALE_USER_DEFAULT
))
350 /* We failed, fall back to internal (localized) resource */
351 for (i
= 0; i
< MAX_NUMBER_INTERNAL_TOPICS
; ++i
)
353 /* Allocate (or reallocate) the list of topics */
355 pTopicsTmp
= HeapAlloc(GetProcessHeap(), 0, (dwNumberTopics
+ 1) * sizeof(*pTopics
));
357 pTopicsTmp
= HeapReAlloc(GetProcessHeap(), 0, pTopics
, (dwNumberTopics
+ 1) * sizeof(*pTopics
));
359 break; // Cannot reallocate more
360 pTopics
= pTopicsTmp
;
362 /* Allocate a new topic */
363 pTopic
= HeapAlloc(GetProcessHeap(), 0, sizeof(*pTopic
));
365 break; // Cannot reallocate more
366 pTopics
[dwNumberTopics
++] = pTopic
;
368 /* Retrieve the information */
369 if (!LoadString(hInstance
, IDS_TOPICBUTTON0
+ i
, pTopic
->szText
, ARRAYSIZE(pTopic
->szText
)))
371 if (!LoadString(hInstance
, IDS_TOPICTITLE0
+ i
, pTopic
->szTitle
, ARRAYSIZE(pTopic
->szTitle
)))
372 *pTopic
->szTitle
= 0;
373 if (!LoadString(hInstance
, IDS_TOPICDESC0
+ i
, pTopic
->szDesc
, ARRAYSIZE(pTopic
->szDesc
)))
375 if (!LoadString(hInstance
, IDS_TOPICACTION0
+ i
, pTopic
->szAction
, ARRAYSIZE(pTopic
->szAction
)))
376 *pTopic
->szAction
= 0;
382 VOID
FreeTopics(VOID
)
387 while (dwNumberTopics
--)
389 if (pTopics
[dwNumberTopics
])
390 HeapFree(GetProcessHeap(), 0, pTopics
[dwNumberTopics
]);
392 HeapFree(GetProcessHeap(), 0, pTopics
);
399 ShowLastWin32Error(HWND hWnd
)
401 LPTSTR lpMessageBuffer
= NULL
;
402 DWORD dwError
= GetLastError();
404 if (dwError
== ERROR_SUCCESS
)
407 if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
|
408 FORMAT_MESSAGE_FROM_SYSTEM
|
409 FORMAT_MESSAGE_IGNORE_INSERTS
,
413 (LPTSTR
)&lpMessageBuffer
,
419 MessageBox(hWnd
, lpMessageBuffer
, szAppTitle
, MB_OK
| MB_ICONERROR
);
420 LocalFree(lpMessageBuffer
);
425 _tWinMain(HINSTANCE hInst
,
426 HINSTANCE hPrevInstance
,
437 DWORD dwStyle
= WS_OVERLAPPED
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
|
438 WS_CAPTION
| WS_SYSMENU
| WS_MINIMIZEBOX
;
441 UNREFERENCED_PARAMETER(hPrevInstance
);
442 UNREFERENCED_PARAMETER(lpszCmdLine
);
444 switch (GetUserDefaultUILanguage())
446 case MAKELANGID(LANG_HEBREW
, SUBLANG_DEFAULT
):
447 SetProcessDefaultLayout(LAYOUT_RTL
);
457 hMainIcon
= LoadIcon(hInstance
, MAKEINTRESOURCE(IDI_MAIN
));
459 /* Register the window class */
460 wndclass
.cbSize
= sizeof(WNDCLASSEX
);
461 wndclass
.style
= CS_HREDRAW
| CS_VREDRAW
;
462 wndclass
.lpfnWndProc
= (WNDPROC
)MainWndProc
;
463 wndclass
.cbClsExtra
= 0;
464 wndclass
.cbWndExtra
= 0;
465 wndclass
.hInstance
= hInstance
;
466 wndclass
.hIcon
= hMainIcon
;
467 wndclass
.hIconSm
= NULL
;
468 wndclass
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
469 wndclass
.hbrBackground
= NULL
;
470 wndclass
.lpszMenuName
= NULL
;
471 wndclass
.lpszClassName
= szFrameClass
;
473 RegisterClassEx(&wndclass
);
475 hTitleBitmap
= LoadBitmap(hInstance
, MAKEINTRESOURCE(IDB_TITLEBITMAP
));
476 if (hTitleBitmap
!= NULL
)
478 GetObject(hTitleBitmap
, sizeof(BITMAP
), &BitmapInfo
);
479 ulInnerWidth
= BitmapInfo
.bmWidth
;
480 ulInnerHeight
= (ulInnerWidth
* 3) / 4;
481 ulTitleHeight
= BitmapInfo
.bmHeight
+ 3;
482 DeleteObject(hTitleBitmap
);
484 ulInnerHeight
-= GetSystemMetrics(SM_CYCAPTION
);
487 rcWindow
.bottom
= ulInnerHeight
- 1;
489 rcWindow
.right
= ulInnerWidth
- 1;
491 AdjustWindowRect(&rcWindow
, dwStyle
, FALSE
);
492 xWidth
= rcWindow
.right
- rcWindow
.left
;
493 yHeight
= rcWindow
.bottom
- rcWindow
.top
;
495 xPos
= (GetSystemMetrics(SM_CXSCREEN
) - xWidth
) / 2;
496 yPos
= (GetSystemMetrics(SM_CYSCREEN
) - yHeight
) / 2;
498 rcTitlePanel
.top
= 0;
499 rcTitlePanel
.bottom
= ulTitleHeight
;
500 rcTitlePanel
.left
= 0;
501 rcTitlePanel
.right
= ulInnerWidth
- 1;
503 rcLeftPanel
.top
= rcTitlePanel
.bottom
;
504 rcLeftPanel
.bottom
= ulInnerHeight
- 1;
505 rcLeftPanel
.left
= 0;
506 rcLeftPanel
.right
= ulInnerWidth
/ 3;
508 rcRightPanel
.top
= rcLeftPanel
.top
;
509 rcRightPanel
.bottom
= rcLeftPanel
.bottom
;
510 rcRightPanel
.left
= rcLeftPanel
.right
;
511 rcRightPanel
.right
= ulInnerWidth
- 1;
513 if (!LoadString(hInstance
, IDS_APPTITLE
, szAppTitle
, ARRAYSIZE(szAppTitle
)))
514 StringCchCopy(szAppTitle
, ARRAYSIZE(szAppTitle
), TEXT("ReactOS Welcome"));
518 /* Create main window */
519 hWndMain
= CreateWindow(szFrameClass
,
531 hSystemMenu
= GetSystemMenu(hWndMain
, FALSE
);
534 RemoveMenu(hSystemMenu
, SC_SIZE
, MF_BYCOMMAND
);
535 RemoveMenu(hSystemMenu
, SC_MAXIMIZE
, MF_BYCOMMAND
);
538 ShowWindow(hWndMain
, nCmdShow
);
539 UpdateWindow(hWndMain
);
541 while (GetMessage(&msg
, NULL
, 0, 0) != FALSE
)
543 TranslateMessage(&msg
);
544 DispatchMessage(&msg
);
554 ButtonSubclassWndProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
558 if (uMsg
== WM_MOUSEMOVE
)
560 i
= GetWindowLongPtr(hWnd
, GWL_ID
);
565 InvalidateRect(hWndMain
, &rcRightPanel
, TRUE
);
569 return CallWindowProc(fnOldBtn
, hWnd
, uMsg
, wParam
, lParam
);
574 RunAction(INT nTopic
)
576 // TCHAR CurrentDir[MAX_PATH];
578 TCHAR AppName
[MAX_PATH
];
580 InvalidateRect(hWndMain
, NULL
, TRUE
);
585 // GetCurrentDirectory(ARRAYSIZE(CurrentDir), CurrentDir);
587 StringCchCopy(AppName
, ARRAYSIZE(AppName
), pTopics
[nTopic
]->szAction
);
591 if (!_tcsicmp(AppName
, TEXT("<exit>")))
594 if (!_tcsnicmp(AppName
, TEXT("<msg>"), 5))
596 MessageBox(hWndMain
, AppName
+ 5, TEXT("ReactOS"), MB_OK
| MB_TASKMODAL
);
600 if (_tcsicmp(AppName
, TEXT("explorer.exe")) == 0)
602 // StringCchCat(AppName, ARRAYSIZE(AppName), TEXT(" "));
603 // StringCchCat(AppName, ARRAYSIZE(AppName), CurrentDir);
604 _tcscpy(Parameters
, TEXT("\\"));
611 ShellExecute(NULL
, NULL
, AppName
, Parameters
, NULL
, SW_SHOWDEFAULT
);
618 SubclassButton(HWND hWnd
)
620 fnOldBtn
= (WNDPROC
)SetWindowLongPtr(hWnd
, GWL_WNDPROC
, (DWORD_PTR
)ButtonSubclassWndProc
);
625 GetButtonHeight(HDC hDC
,
634 rect
.right
= dwWidth
- 20;
638 hOldFont
= (HFONT
)SelectObject(hDC
, hFont
);
639 DrawText(hDC
, szText
, -1, &rect
, DT_TOP
| DT_CALCRECT
| DT_WORDBREAK
);
640 SelectObject(hDC
, hOldFont
);
642 return (rect
.bottom
-rect
.top
+ 14);
647 OnCreate(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
656 UNREFERENCED_PARAMETER(wParam
);
657 UNREFERENCED_PARAMETER(lParam
);
659 hbrLightBlue
= CreateSolidBrush(LIGHT_BLUE
);
660 hbrDarkBlue
= CreateSolidBrush(DARK_BLUE
);
661 hbrRightPanel
= CreateSolidBrush(RGB(255, 255, 255));
663 /* Topic title font */
664 hFontTopicTitle
= CreateFont(-18, 0, 0, 0, FW_NORMAL
,
673 /* Topic description font */
674 hFontTopicDescription
= CreateFont(-11, 0, 0, 0, FW_THIN
,
683 /* Topic button font */
684 hFontTopicButton
= CreateFont(-11, 0, 0, 0, FW_BOLD
,
693 /* Load title bitmap */
694 if (hTitleBitmap
!= NULL
)
695 hTitleBitmap
= LoadBitmap(hInstance
, MAKEINTRESOURCE(IDB_TITLEBITMAP
));
697 /* Load topic bitmaps */
698 hDefaultTopicBitmap
= LoadBitmap(hInstance
, MAKEINTRESOURCE(IDB_DEFAULTTOPICBITMAP
));
699 for (i
= 0; i
< dwNumberTopics
; i
++)
701 // FIXME: Not implemented yet!
702 // pTopics[i]->hBitmap = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_TOPICBITMAP0 + i));
703 pTopics
[i
]->hBitmap
= NULL
;
706 ScreenDC
= GetWindowDC(hWnd
);
707 hdcMem
= CreateCompatibleDC(ScreenDC
);
708 ReleaseDC(hWnd
, ScreenDC
);
710 /* Load and create buttons */
711 dwTop
= rcLeftPanel
.top
;
712 for (i
= 0; i
< dwNumberTopics
; i
++)
714 if (*pTopics
[i
]->szText
)
716 dwHeight
= GetButtonHeight(hdcMem
,
719 rcLeftPanel
.right
- rcLeftPanel
.left
);
721 pTopics
[i
]->hWndButton
= CreateWindow(TEXT("BUTTON"),
723 WS_CHILDWINDOW
| WS_VISIBLE
| WS_TABSTOP
| BS_MULTILINE
| BS_OWNERDRAW
,
726 rcLeftPanel
.right
- rcLeftPanel
.left
,
732 hWndDefaultTopic
= pTopics
[i
]->hWndButton
;
734 SubclassButton(pTopics
[i
]->hWndButton
);
735 SendMessage(pTopics
[i
]->hWndButton
, WM_SETFONT
, (WPARAM
)hFontTopicButton
, MAKELPARAM(TRUE
, 0));
739 pTopics
[i
]->hWndButton
= NULL
;
745 /* Create "Exit" button */
748 nLength
= LoadString(hInstance
, IDS_CLOSETEXT
, szText
, ARRAYSIZE(szText
));
751 hWndCloseButton
= CreateWindow(TEXT("BUTTON"),
753 WS_VISIBLE
| WS_CHILD
| BS_FLAT
,
754 rcRightPanel
.right
- 10 - 57,
755 rcRightPanel
.bottom
- 10 - 21,
759 (HMENU
)IDC_CLOSEBUTTON
,
762 hWndDefaultTopic
= NULL
;
764 SendMessage(hWndCloseButton
, WM_SETFONT
, (WPARAM
)hFontTopicButton
, MAKELPARAM(TRUE
, 0));
768 hWndCloseButton
= NULL
;
772 /* Create checkbox */
773 if (bDisplayCheckBox
)
775 nLength
= LoadString(hInstance
, IDS_CHECKTEXT
, szText
, ARRAYSIZE(szText
));
778 hFontCheckButton
= CreateFont(-10, 0, 0, 0, FW_THIN
,
787 hWndCheckButton
= CreateWindow(TEXT("BUTTON"),
789 WS_VISIBLE
| WS_CHILD
| BS_AUTOCHECKBOX
/**/| BS_FLAT
/**/,
790 rcLeftPanel
.left
+ 8,
791 rcLeftPanel
.bottom
- 8 - 13,
792 rcLeftPanel
.right
- rcLeftPanel
.left
- 16,
795 (HMENU
)IDC_CHECKBUTTON
,
798 SendMessage(hWndCheckButton
, WM_SETFONT
, (WPARAM
)hFontCheckButton
, MAKELPARAM(TRUE
, 0));
802 hFontCheckButton
= NULL
;
803 hWndCheckButton
= NULL
;
812 OnCommand(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
814 UNREFERENCED_PARAMETER(lParam
);
816 if (LOWORD(wParam
) == IDC_CLOSEBUTTON
)
820 else if ((LOWORD(wParam
) < dwNumberTopics
))
822 if (RunAction(LOWORD(wParam
)) == FALSE
)
823 DestroyWindow(hWnd
); // Corresponds to a <exit> action.
831 PaintBanner(HDC hdc
, LPRECT rcPanel
)
837 hOldBitmap
= (HBITMAP
)SelectObject(hdcMem
, hTitleBitmap
);
841 rcPanel
->right
- rcPanel
->left
,
843 hdcMem
, 0, 0, SRCCOPY
);
844 SelectObject(hdcMem
, hOldBitmap
);
847 hOldBrush
= (HBRUSH
)SelectObject(hdc
, hbrDarkBlue
);
851 rcPanel
->right
- rcPanel
->left
,
855 SelectObject(hdc
, hOldBrush
);
860 OnPaint(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
866 HBITMAP hOldBitmap
= NULL
;
869 RECT rcTitle
, rcDescription
;
872 LPTSTR lpTitle
= NULL
, lpDesc
= NULL
;
874 UNREFERENCED_PARAMETER(wParam
);
875 UNREFERENCED_PARAMETER(lParam
);
877 hdc
= BeginPaint(hWnd
, &ps
);
880 PaintBanner(hdc
, &rcTitlePanel
);
883 hOldBrush
= (HBRUSH
)SelectObject(hdc
, hbrLightBlue
);
887 rcLeftPanel
.right
- rcLeftPanel
.left
,
888 rcLeftPanel
.bottom
- rcLeftPanel
.top
,
890 SelectObject(hdc
, hOldBrush
);
893 hOldBrush
= (HBRUSH
)SelectObject(hdc
, WHITE_BRUSH
);
897 rcRightPanel
.right
- rcRightPanel
.left
,
898 rcRightPanel
.bottom
- rcRightPanel
.top
,
900 SelectObject(hdc
, hOldBrush
);
902 /* Draw dark vertical line */
903 hPen
= CreatePen(PS_SOLID
, 0, DARK_BLUE
);
904 hOldPen
= (HPEN
)SelectObject(hdc
, hPen
);
905 MoveToEx(hdc
, rcRightPanel
.left
, rcRightPanel
.top
, NULL
);
906 LineTo(hdc
, rcRightPanel
.left
, rcRightPanel
.bottom
);
907 SelectObject(hdc
, hOldPen
);
910 /* Draw topic bitmap */
911 if ((nTopic
== -1) && (hDefaultTopicBitmap
!= NULL
))
913 GetObject(hDefaultTopicBitmap
, sizeof(BITMAP
), &bmpInfo
);
914 hOldBitmap
= (HBITMAP
)SelectObject(hdcMem
, hDefaultTopicBitmap
);
916 rcRightPanel
.right
- bmpInfo
.bmWidth
,
917 rcRightPanel
.bottom
- bmpInfo
.bmHeight
,
925 else if ((nTopic
!= -1) && (pTopics
[nTopic
]->hBitmap
!= NULL
))
927 GetObject(pTopics
[nTopic
]->hBitmap
, sizeof(BITMAP
), &bmpInfo
);
928 hOldBitmap
= (HBITMAP
)SelectObject(hdcMem
, pTopics
[nTopic
]->hBitmap
);
930 rcRightPanel
.right
- bmpInfo
.bmWidth
,
931 rcRightPanel
.bottom
- bmpInfo
.bmHeight
,
942 lpTitle
= szDefaultTitle
;
943 lpDesc
= szDefaultDesc
;
947 lpTitle
= pTopics
[nTopic
]->szTitle
;
948 lpDesc
= pTopics
[nTopic
]->szDesc
;
951 SetBkMode(hdc
, TRANSPARENT
);
953 /* Draw version information */
954 _stprintf(version
, TEXT("ReactOS %d.%d.%d"),
955 KERNEL_VERSION_MAJOR
,
956 KERNEL_VERSION_MINOR
,
957 KERNEL_VERSION_PATCH_LEVEL
);
959 rcTitle
.left
= rcLeftPanel
.left
+ 8;
960 rcTitle
.right
= rcLeftPanel
.right
- 5;
961 rcTitle
.top
= rcLeftPanel
.bottom
- 40;
962 rcTitle
.bottom
= rcLeftPanel
.bottom
- 5;
963 hOldFont
= (HFONT
)SelectObject(hdc
, hFontTopicDescription
);
964 DrawText(hdc
, version
, -1, &rcTitle
, DT_BOTTOM
| DT_CALCRECT
| DT_SINGLELINE
);
965 DrawText(hdc
, version
, -1, &rcTitle
, DT_BOTTOM
| DT_SINGLELINE
);
966 SelectObject(hdc
, hOldFont
);
968 /* Draw topic title */
969 rcTitle
.left
= rcRightPanel
.left
+ 12;
970 rcTitle
.right
= rcRightPanel
.right
- 8;
971 rcTitle
.top
= rcRightPanel
.top
+ 8;
972 rcTitle
.bottom
= rcTitle
.top
+ 57;
973 hOldFont
= (HFONT
)SelectObject(hdc
, hFontTopicTitle
);
974 DrawText(hdc
, lpTitle
, -1, &rcTitle
, DT_TOP
| DT_CALCRECT
);
976 SetTextColor(hdc
, DARK_BLUE
);
977 DrawText(hdc
, lpTitle
, -1, &rcTitle
, DT_TOP
);
979 /* Draw topic description */
980 rcDescription
.left
= rcRightPanel
.left
+ 12;
981 rcDescription
.right
= rcRightPanel
.right
- 8;
982 rcDescription
.top
= rcTitle
.bottom
+ 8;
983 rcDescription
.bottom
= rcRightPanel
.bottom
- 20;
985 SelectObject(hdc
, hFontTopicDescription
);
986 SetTextColor(hdc
, RGB(0, 0, 0));
987 DrawText(hdc
, lpDesc
, -1, &rcDescription
, DT_TOP
| DT_WORDBREAK
);
989 SetBkMode(hdc
, OPAQUE
);
990 SelectObject(hdc
, hOldFont
);
992 SelectObject(hdcMem
, hOldBrush
);
993 SelectObject(hdcMem
, hOldBitmap
);
1002 OnDrawItem(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
1004 LPDRAWITEMSTRUCT lpDis
= (LPDRAWITEMSTRUCT
)lParam
;
1010 UNREFERENCED_PARAMETER(hWnd
);
1011 UNREFERENCED_PARAMETER(wParam
);
1013 if (lpDis
->hwndItem
== hWndCloseButton
)
1015 DrawFrameControl(lpDis
->hDC
,
1018 DFCS_BUTTONPUSH
| DFCS_FLAT
);
1022 if (lpDis
->CtlID
== (ULONG
)nTopic
)
1023 hOldBrush
= (HBRUSH
)SelectObject(lpDis
->hDC
, hbrRightPanel
);
1025 hOldBrush
= (HBRUSH
)SelectObject(lpDis
->hDC
, hbrLightBlue
);
1030 lpDis
->rcItem
.right
,
1031 lpDis
->rcItem
.bottom
,
1033 SelectObject(lpDis
->hDC
, hOldBrush
);
1035 hPen
= CreatePen(PS_SOLID
, 0, DARK_BLUE
);
1036 hOldPen
= (HPEN
)SelectObject(lpDis
->hDC
, hPen
);
1037 MoveToEx(lpDis
->hDC
, lpDis
->rcItem
.left
, lpDis
->rcItem
.bottom
- 1, NULL
);
1038 LineTo(lpDis
->hDC
, lpDis
->rcItem
.right
, lpDis
->rcItem
.bottom
- 1);
1039 SelectObject(lpDis
->hDC
, hOldPen
);
1042 InflateRect(&lpDis
->rcItem
, -10, -4);
1043 OffsetRect(&lpDis
->rcItem
, 0, 1);
1044 GetWindowText(lpDis
->hwndItem
, szText
, ARRAYSIZE(szText
));
1045 SetTextColor(lpDis
->hDC
, RGB(0, 0, 0));
1046 iBkMode
= SetBkMode(lpDis
->hDC
, TRANSPARENT
);
1047 DrawText(lpDis
->hDC
, szText
, -1, &lpDis
->rcItem
, DT_TOP
| DT_LEFT
| DT_WORDBREAK
);
1048 SetBkMode(lpDis
->hDC
, iBkMode
);
1056 OnMouseMove(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
1058 UNREFERENCED_PARAMETER(wParam
);
1059 UNREFERENCED_PARAMETER(lParam
);
1065 InvalidateRect(hWndMain
, &rcRightPanel
, TRUE
);
1073 OnCtlColorStatic(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
1075 UNREFERENCED_PARAMETER(hWnd
);
1077 if ((HWND
)lParam
== hWndCheckButton
)
1079 SetBkColor((HDC
)wParam
, LIGHT_BLUE
);
1080 return (LRESULT
)hbrLightBlue
;
1088 OnActivate(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
1090 UNREFERENCED_PARAMETER(hWnd
);
1091 UNREFERENCED_PARAMETER(wParam
);
1092 UNREFERENCED_PARAMETER(lParam
);
1095 InvalidateRect(hWndMain
, &rcRightPanel
, TRUE
);
1101 OnDestroy(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
1105 UNREFERENCED_PARAMETER(hWnd
);
1106 UNREFERENCED_PARAMETER(wParam
);
1107 UNREFERENCED_PARAMETER(lParam
);
1109 for (i
= 0; i
< dwNumberTopics
; i
++)
1111 if (pTopics
[i
]->hWndButton
!= NULL
)
1112 DestroyWindow(pTopics
[i
]->hWndButton
);
1115 if (hWndCloseButton
!= NULL
)
1116 DestroyWindow(hWndCloseButton
);
1118 if (hWndCheckButton
!= NULL
)
1119 DestroyWindow(hWndCheckButton
);
1123 /* Delete bitmaps */
1124 DeleteObject(hDefaultTopicBitmap
);
1125 DeleteObject(hTitleBitmap
);
1126 for (i
= 0; i
< dwNumberTopics
; i
++)
1128 if (pTopics
[i
]->hBitmap
!= NULL
)
1129 DeleteObject(pTopics
[i
]->hBitmap
);
1132 DeleteObject(hFontTopicTitle
);
1133 DeleteObject(hFontTopicDescription
);
1134 DeleteObject(hFontTopicButton
);
1136 if (hFontCheckButton
!= NULL
)
1137 DeleteObject(hFontCheckButton
);
1139 DeleteObject(hbrLightBlue
);
1140 DeleteObject(hbrDarkBlue
);
1141 DeleteObject(hbrRightPanel
);
1148 MainWndProc(HWND hWnd
,
1156 return OnCreate(hWnd
, wParam
, lParam
);
1159 return OnCommand(hWnd
, wParam
, lParam
);
1162 return OnActivate(hWnd
, wParam
, lParam
);
1165 return OnPaint(hWnd
, wParam
, lParam
);
1168 return OnDrawItem(hWnd
, wParam
, lParam
);
1170 case WM_CTLCOLORSTATIC
:
1171 return OnCtlColorStatic(hWnd
, wParam
, lParam
);
1174 return OnMouseMove(hWnd
, wParam
, lParam
);
1177 OnDestroy(hWnd
, wParam
, lParam
);
1182 return DefWindowProc(hWnd
, uMsg
, wParam
, lParam
);