PageRenderTime 65ms CodeModel.GetById 30ms RepoModel.GetById 1ms app.codeStats 0ms

/reactos/base/setup/welcome/welcome.c

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