Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

506 lines
11 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation. All rights reserved.
  3. Module Name:
  4. Splash.cpp
  5. Abstract:
  6. Implementation of the splash screen class.
  7. Notes:
  8. ANSI & Unicode via TCHAR - runs on Win9x/NT/2K/XP etc.
  9. History:
  10. 01/30/01 rparsons Created
  11. 01/10/02 rparsons Revised
  12. 01/27/02 rparsons Converted to TCHAR
  13. --*/
  14. #include "splash.h"
  15. /*++
  16. Routine Description:
  17. Constructor - init member variables.
  18. Arguments:
  19. None.
  20. Return Value:
  21. None.
  22. --*/
  23. CSplash::CSplash()
  24. {
  25. m_dwDuration = 0;
  26. m_dwSplashId = 0;
  27. }
  28. /*++
  29. Routine Description:
  30. Does the work of creating the splash screen.
  31. Arguments:
  32. hInstance - Application instance handle.
  33. dwLoColorBitmapId - Low color bitmap identifier.
  34. dwHiColorBitmapId - Hight color bitmap identifier (OPTIONAL).
  35. dwDuration - Amount of time to display the splash screen (milliseconds).
  36. Return Value:
  37. None.
  38. --*/
  39. void
  40. CSplash::Create(
  41. IN HINSTANCE hInstance,
  42. IN DWORD dwLoColorBitmapId,
  43. IN DWORD dwHiColorBitmapId OPTIONAL,
  44. IN DWORD dwDuration
  45. )
  46. {
  47. HDC hDC;
  48. int nBitsInAPixel = 0;
  49. m_hInstance = hInstance;
  50. //
  51. // Get a handle to the display driver context and determine
  52. // the number of bits in a pixel.
  53. //
  54. hDC = GetDC(0);
  55. nBitsInAPixel = GetDeviceCaps(hDC, BITSPIXEL);
  56. ReleaseDC(NULL, hDC);
  57. //
  58. // If there are more than 8 bits in a pixel, and the high color
  59. // bitmap is available, use it. Otherwise, use the low color one.
  60. //
  61. if (nBitsInAPixel > 8 && dwHiColorBitmapId) {
  62. m_dwSplashId = dwHiColorBitmapId;
  63. } else {
  64. m_dwSplashId = dwLoColorBitmapId;
  65. }
  66. m_dwDuration = dwDuration * 1000;
  67. CSplash::InitSplashScreen(hInstance);
  68. CSplash::CreateSplashWindow();
  69. }
  70. /*++
  71. Routine Description:
  72. Sets up the window class struct for splash screen.
  73. Arguments:
  74. hInstance - Application instance handle.
  75. Return Value:
  76. TRUE on success, FALSE otherwise.
  77. --*/
  78. BOOL
  79. CSplash::InitSplashScreen(
  80. IN HINSTANCE hInstance
  81. )
  82. {
  83. WNDCLASS wc;
  84. wc.style = CS_HREDRAW | CS_VREDRAW;
  85. wc.lpfnWndProc = SplashWndProc;
  86. wc.cbClsExtra = 0;
  87. wc.cbWndExtra = 0;
  88. wc.hInstance = hInstance;
  89. wc.hIcon = NULL;
  90. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  91. wc.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
  92. wc.lpszMenuName = NULL;
  93. wc.lpszClassName = _T("SPLASHWIN");
  94. return RegisterClass(&wc);
  95. }
  96. /*++
  97. Routine Description:
  98. Creates the splash screen for the setup app.
  99. Arguments:
  100. None.
  101. Return Value:
  102. TRUE on success, FALSE otherwise.
  103. --*/
  104. BOOL
  105. CSplash::CreateSplashWindow()
  106. {
  107. HBITMAP hBitmap;
  108. BITMAP bm;
  109. RECT rect;
  110. HWND hWnd;
  111. //
  112. // Load the bitmap and fill out a BITMAP structure for it.
  113. //
  114. hBitmap = LoadBitmap(m_hInstance, MAKEINTRESOURCE(m_dwSplashId));
  115. GetObject(hBitmap, sizeof(bm), &bm);
  116. DeleteObject(hBitmap);
  117. GetWindowRect(GetDesktopWindow(), &rect);
  118. //
  119. // Create the splash screen window.
  120. // Specifying WS_EX_TOOLWINDOW keeps us out of the
  121. // taskbar.
  122. //
  123. hWnd = CreateWindowEx(WS_EX_TOOLWINDOW,
  124. _T("SPLASHWIN"),
  125. NULL,
  126. WS_POPUP | WS_BORDER,
  127. (rect.right / 2) - (bm.bmWidth / 2),
  128. (rect.bottom / 2) - (bm.bmHeight / 2),
  129. bm.bmWidth,
  130. bm.bmHeight,
  131. NULL,
  132. NULL,
  133. m_hInstance,
  134. (LPVOID)this);
  135. if (hWnd) {
  136. ShowWindow(hWnd, SW_SHOWNORMAL);
  137. UpdateWindow(hWnd);
  138. }
  139. return (hWnd ? TRUE : FALSE);
  140. }
  141. /*++
  142. Routine Description:
  143. Runs the message loop for the splash screen.
  144. Arguments:
  145. hWnd - Window handle.
  146. uMsg - Windows message.
  147. wParam - Additional message info.
  148. lParam - Additional message info.
  149. Return Value:
  150. TRUE if the message was processed, FALSE otherwise.
  151. --*/
  152. LRESULT
  153. CALLBACK
  154. CSplash::SplashWndProc(
  155. IN HWND hWnd,
  156. IN UINT uMsg,
  157. IN WPARAM wParam,
  158. IN LPARAM lParam
  159. )
  160. {
  161. PAINTSTRUCT ps;
  162. HDC hdc;
  163. CSplash *pThis = (CSplash*)GetWindowLong(hWnd, GWL_USERDATA);
  164. switch (uMsg) {
  165. case WM_CREATE:
  166. {
  167. LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam;
  168. pThis = (CSplash*)(lpcs->lpCreateParams);
  169. SetWindowLong(hWnd, GWL_USERDATA, (LONG)pThis);
  170. //
  171. // Enable the timer - this sets the amount
  172. // of time the screen will be displayed.
  173. //
  174. SetTimer(hWnd, 0, pThis->m_dwDuration, NULL);
  175. break;
  176. }
  177. //
  178. // Handle the palette messages in case another app takes
  179. // over the palette
  180. //
  181. case WM_PALETTECHANGED:
  182. if ((HWND) wParam == hWnd) {
  183. return 0;
  184. }
  185. case WM_QUERYNEWPALETTE:
  186. InvalidateRect(hWnd, NULL, FALSE);
  187. UpdateWindow(hWnd);
  188. return TRUE;
  189. case WM_DESTROY:
  190. PostQuitMessage(0);
  191. break;
  192. case WM_TIMER:
  193. DestroyWindow(hWnd);
  194. break;
  195. case WM_PAINT:
  196. hdc = BeginPaint(hWnd, &ps);
  197. pThis->DisplayBitmap(hWnd, pThis->m_dwSplashId);
  198. EndPaint(hWnd, &ps);
  199. break;
  200. //
  201. // Override this message so Windows doesn't try
  202. // to calculate size for the caption bar and stuff.
  203. //
  204. case WM_NCCALCSIZE:
  205. return 0;
  206. default:
  207. return DefWindowProc(hWnd, uMsg, wParam, lParam);
  208. }
  209. return FALSE;
  210. }
  211. /*++
  212. Routine Description:
  213. Builds a palette with a spectrum of colors.
  214. Arguments:
  215. None.
  216. Return Value:
  217. Handle to a spectrum palette on success
  218. or NULL on failure.
  219. --*/
  220. HPALETTE
  221. CSplash::CreateSpectrumPalette()
  222. {
  223. HPALETTE hPal;
  224. LPLOGPALETTE lplgPal = NULL;
  225. BYTE red, green, blue;
  226. int nCount = 0;
  227. lplgPal = (LPLOGPALETTE)HeapAlloc(GetProcessHeap(),
  228. HEAP_ZERO_MEMORY,
  229. sizeof(LOGPALETTE) +
  230. sizeof(PALETTEENTRY) *
  231. MAXPALETTE);
  232. if (!lplgPal) {
  233. return NULL;
  234. }
  235. //
  236. // Initialize members of the structure
  237. // and build the spectrum of colors.
  238. //
  239. lplgPal->palVersion = PALVERSION;
  240. lplgPal->palNumEntries = MAXPALETTE;
  241. red = green = blue = 0;
  242. for (nCount = 0; nCount < MAXPALETTE; nCount++) {
  243. lplgPal->palPalEntry[nCount].peRed = red;
  244. lplgPal->palPalEntry[nCount].peGreen = green;
  245. lplgPal->palPalEntry[nCount].peBlue = blue;
  246. lplgPal->palPalEntry[nCount].peFlags = 0;
  247. if (!(red += 32)) {
  248. if (!(green += 32)) {
  249. blue += 64;
  250. }
  251. }
  252. }
  253. hPal = CreatePalette(lplgPal);
  254. HeapFree(GetProcessHeap(), 0, lplgPal);
  255. return hPal;
  256. }
  257. /*++
  258. Routine Description:
  259. Builds a palette from an RGBQUAD structure.
  260. Arguments:
  261. rgbqPalette - Array of RGBQUAD structs.
  262. cElements - Number of elements in the array.
  263. Return Value:
  264. Handle to a palette on success or NULL on failure.
  265. --*/
  266. HPALETTE
  267. CSplash::CreatePaletteFromRGBQUAD(
  268. IN LPRGBQUAD rgbqPalette,
  269. IN WORD cElements
  270. )
  271. {
  272. HPALETTE hPal;
  273. LPLOGPALETTE lplgPal = NULL;
  274. int nCount = 0;
  275. lplgPal = (LPLOGPALETTE)HeapAlloc(GetProcessHeap(),
  276. HEAP_ZERO_MEMORY,
  277. sizeof(LOGPALETTE) +
  278. sizeof(PALETTEENTRY) *
  279. cElements);
  280. if (!lplgPal) {
  281. return NULL;
  282. }
  283. //
  284. // Initialize structure members and fill in palette colors.
  285. //
  286. lplgPal->palVersion = PALVERSION;
  287. lplgPal->palNumEntries = cElements;
  288. for (nCount = 0; nCount < cElements; nCount++) {
  289. lplgPal->palPalEntry[nCount].peRed = rgbqPalette[nCount].rgbRed;
  290. lplgPal->palPalEntry[nCount].peGreen = rgbqPalette[nCount].rgbGreen;
  291. lplgPal->palPalEntry[nCount].peBlue = rgbqPalette[nCount].rgbBlue;
  292. lplgPal->palPalEntry[nCount].peFlags = 0;
  293. }
  294. hPal = CreatePalette(lplgPal);
  295. HeapFree(GetProcessHeap(), 0, lplgPal);
  296. return hPal;
  297. }
  298. /*++
  299. Routine Description:
  300. Displays the bitmap in the specified window.
  301. Arguments:
  302. hWnd - Handle to the destination window.
  303. dwResId - Resource identifier for the bitmap.
  304. Return Value:
  305. None.
  306. --*/
  307. void
  308. CSplash::DisplayBitmap(
  309. IN HWND hWnd,
  310. IN DWORD dwResId
  311. )
  312. {
  313. HBITMAP hBitmap;
  314. HPALETTE hPalette;
  315. HDC hdcMemory = NULL, hdcWindow = NULL;
  316. BITMAP bm;
  317. RECT rect;
  318. RGBQUAD rgbq[256];
  319. CSplash *pThis = (CSplash*)GetWindowLong(hWnd, GWL_USERDATA);
  320. GetClientRect(hWnd, &rect);
  321. //
  322. // Load the resource as a DIB section.
  323. //
  324. hBitmap = (HBITMAP)LoadImage(pThis->m_hInstance,
  325. MAKEINTRESOURCE(dwResId),
  326. IMAGE_BITMAP,
  327. 0,
  328. 0,
  329. LR_CREATEDIBSECTION);
  330. GetObject(hBitmap, sizeof(BITMAP), (LPWSTR)&bm);
  331. hdcWindow = GetDC(hWnd);
  332. //
  333. // Create a DC to hold our surface and selct our surface into it.
  334. //
  335. hdcMemory = CreateCompatibleDC(hdcWindow);
  336. SelectObject(hdcMemory, hBitmap);
  337. //
  338. // Retrieve the color table (if there is one) and create a palette
  339. // that reflects it.
  340. //
  341. if (GetDIBColorTable(hdcMemory, 0, 256, rgbq)) {
  342. hPalette = CreatePaletteFromRGBQUAD(rgbq, 256);
  343. } else {
  344. hPalette = CreateSpectrumPalette();
  345. }
  346. //
  347. // Select and realize the palette into our window DC.
  348. //
  349. SelectPalette(hdcWindow, hPalette, FALSE);
  350. RealizePalette(hdcWindow);
  351. //
  352. // Display the bitmap.
  353. //
  354. SetStretchBltMode(hdcWindow, COLORONCOLOR);
  355. StretchBlt(hdcWindow,
  356. 0,
  357. 0,
  358. rect.right,
  359. rect.bottom,
  360. hdcMemory,
  361. 0,
  362. 0,
  363. bm.bmWidth,
  364. bm.bmHeight,
  365. SRCCOPY);
  366. //
  367. // Clean up our objects.
  368. //
  369. DeleteDC(hdcMemory);
  370. DeleteObject(hBitmap);
  371. ReleaseDC(hWnd, hdcWindow);
  372. DeleteObject(hPalette);
  373. }