Source code of Windows XP (NT5)
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.

330 lines
9.0 KiB

  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // File: Splash.cpp
  4. // Created: Jan 1996
  5. // By: Ryan Marshall (a-ryanm) and Martin Holladay (a-martih)
  6. //
  7. // Project: Resource Kit Desktop Switcher (MultiDesk)
  8. //
  9. //
  10. // Revision History:
  11. //
  12. //
  13. ////////////////////////////////////////////////////////////////////////////////
  14. #include <windows.h>
  15. #include <windowsx.h>
  16. #include <mmsystem.h>
  17. #include <shlobj.h>
  18. #include <shellapi.h>
  19. #include <stdio.h>
  20. #include "Resource.h"
  21. #include "Splash.h"
  22. //
  23. // Local Prototypes
  24. //
  25. BOOL CALLBACK SplashWndProc(HWND hWnd, UINT nMessage, WPARAM wParam, LPARAM lParam);
  26. BOOL SplashPaint(void);
  27. HPALETTE PaletteFromDS(HDC hDC);
  28. void SplashRealize(HWND hWnd, HDC hTheirDC);
  29. void SplashErase(HDC hDC);
  30. //
  31. // Splash globals
  32. //
  33. #define WM_SPLASHPUMP_TERMINATE 5001
  34. #define TIMER_ID (WM_USER + 5007)
  35. #define TIMEOUT 3000
  36. static const char szSplashClass[] = "Splash";
  37. HBITMAP hSplashBmp = NULL;
  38. BITMAP bmSplashInfo = {0L, 0L, 0L, 0L, 0, 0, NULL};
  39. HINSTANCE hSplashInst = 0;
  40. HWND Splash_hWnd = NULL;
  41. BOOL Splash_bLowRes = TRUE;
  42. BOOL Splash_bNeedPalette = FALSE;
  43. DWORD Splash_dwBitmapHeight = 0;
  44. HBITMAP Splash_hBitmap = NULL;
  45. HBITMAP Splash_hOldBitmap = NULL;
  46. HDC Splash_hImage = NULL;
  47. HPALETTE Splash_hPalette = NULL;
  48. /*------------------------------------------------------------------------*/
  49. /*------------------------------------------------------------------------*/
  50. BOOL CALLBACK SplashWndProc(HWND hWnd, UINT nMessage, WPARAM wParam, LPARAM lParam)
  51. {
  52. UINT nSplashTimer = 0;
  53. switch (nMessage)
  54. {
  55. case WM_NCCREATE:
  56. if ((Splash_hImage = CreateCompatibleDC(NULL)) == NULL)
  57. return FALSE;
  58. if ((Splash_hOldBitmap = SelectBitmap(Splash_hImage, Splash_hBitmap)) == NULL)
  59. return FALSE;
  60. if (Splash_bNeedPalette)
  61. {
  62. if ((Splash_hPalette = PaletteFromDS(Splash_hImage)) == NULL)
  63. return FALSE;
  64. }
  65. return DefWindowProc(hWnd, nMessage, wParam, lParam);
  66. case WM_CREATE:
  67. nSplashTimer = SetTimer(hWnd, TIMER_ID, TIMEOUT, (TIMERPROC) NULL);
  68. if (!nSplashTimer)
  69. PostQuitMessage(1);
  70. ShowWindow(hWnd, SW_SHOWNORMAL);
  71. break;
  72. case WM_PAINT:
  73. SplashPaint();
  74. break;
  75. case WM_ERASEBKGND:
  76. SplashErase((HDC) wParam);
  77. break;
  78. case WM_TIMER:
  79. KillTimer(hWnd, TIMER_ID);
  80. PostQuitMessage(1);
  81. break;
  82. case WM_ENDSESSION:
  83. case WM_CLOSE:
  84. PostQuitMessage(1);
  85. return (DefWindowProc(hWnd, nMessage, wParam, lParam));
  86. case WM_NCDESTROY:
  87. if (Splash_hBitmap) DeleteObject(Splash_hBitmap);
  88. PostThreadMessage(GetCurrentThreadId(), WM_SPLASHPUMP_TERMINATE, 0, 0);
  89. default:
  90. return (DefWindowProc(hWnd, nMessage, wParam, lParam));
  91. }
  92. return FALSE;
  93. }
  94. /*---------------------------------------------------------------------*/
  95. /*---------------------------------------------------------------------*/
  96. BOOL SplashPaint(void)
  97. {
  98. PAINTSTRUCT ps;
  99. HDC hDC;
  100. //
  101. // Paint the Background
  102. //
  103. hDC = BeginPaint(Splash_hWnd, &ps);
  104. SplashRealize(Splash_hWnd, hDC);
  105. SetBkMode(hDC, TRANSPARENT);
  106. EndPaint(Splash_hWnd, &ps);
  107. return TRUE;
  108. }
  109. /*-------------------------------------------------------------------------*/
  110. /*-------------------------------------------------------------------------*/
  111. HPALETTE PaletteFromDS(HDC hDC)
  112. {
  113. DWORD adw[257];
  114. int i;
  115. int n;
  116. n = GetDIBColorTable(hDC, 0, 256, (LPRGBQUAD) &adw[1]);
  117. for (i=1; i<=n; i++)
  118. adw[i] = RGB(GetBValue(adw[i]), GetGValue(adw[i]), GetRValue(adw[i]));
  119. adw[0] = MAKELONG(0x300, n);
  120. return CreatePalette((LPLOGPALETTE) &adw[0]);
  121. }
  122. /*------------------------------------------------------------------------*/
  123. /*------------------------------------------------------------------------*/
  124. void SplashRealize(HWND hWnd, HDC hTheirDC)
  125. {
  126. HDC hDC;
  127. BOOL bRepaint = FALSE;
  128. if (Splash_hPalette)
  129. {
  130. hDC = hTheirDC ? hTheirDC : GetDC(hWnd);
  131. if (hDC)
  132. {
  133. SelectPalette(hDC, Splash_hPalette, FALSE);
  134. bRepaint = (RealizePalette(hDC) > 0);
  135. if (!hTheirDC)
  136. ReleaseDC(hWnd, hDC);
  137. }
  138. }
  139. //RedrawWindow(
  140. // hWnd,
  141. // NULL,
  142. // NULL,
  143. // RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN);
  144. }
  145. /*------------------------------------------------------------------------*/
  146. /*------------------------------------------------------------------------*/
  147. void SplashErase(HDC hDC)
  148. {
  149. RECT rc;
  150. GetClientRect((HWND)hSplashInst, &rc);
  151. SplashRealize(Splash_hWnd, hDC);
  152. BitBlt(hDC, 0, 0, rc.right, rc.bottom, Splash_hImage, 0, 0, SRCCOPY);
  153. }
  154. /*------------------------------------------------------------------------*/
  155. /*------------------------------------------------------------------------*/
  156. INT DoSplashWindow(LPVOID hData)
  157. {
  158. MSG msg;
  159. BOOL bContinue;
  160. WNDCLASS wc;
  161. HDC hDC;
  162. BITMAP Bmp;
  163. RECT rc;
  164. DWORD dwStyle;
  165. hSplashInst = ((PSPLASH_DATA) hData)->hInstance;
  166. //
  167. // Register the class
  168. //
  169. if (!GetClassInfo(hSplashInst, szSplashClass, &wc))
  170. {
  171. wc.style = 0;
  172. wc.lpfnWndProc = (WNDPROC) SplashWndProc;
  173. wc.cbClsExtra = wc.cbWndExtra = 0;
  174. wc.hInstance = hSplashInst;
  175. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  176. wc.hIcon = NULL;
  177. wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
  178. wc.lpszMenuName = NULL;
  179. wc.lpszClassName = szSplashClass;
  180. if (!RegisterClass(&wc))
  181. return FALSE;
  182. }
  183. hDC = GetDC(NULL);
  184. Splash_bLowRes = (GetDeviceCaps(hDC, PLANES) * GetDeviceCaps(hDC, BITSPIXEL)) < 8;
  185. //
  186. // BUGBUG - Comment out lowres = TRUE below
  187. //
  188. //Splash_bLowRes = TRUE; // test low res
  189. Splash_bNeedPalette = (!Splash_bLowRes && (GetDeviceCaps(hDC, RASTERCAPS) & RC_PALETTE));
  190. ReleaseDC(NULL, hDC);
  191. //
  192. // Load the background bitmap
  193. //
  194. Splash_hBitmap = (HBITMAP) LoadImage(
  195. hSplashInst,
  196. MAKEINTRESOURCE(Splash_bLowRes ? IDB_BITMAP_SPLASH : IDB_BITMAP_SPLASH),
  197. IMAGE_BITMAP,
  198. 0,
  199. 0,
  200. LR_CREATEDIBSECTION);
  201. if (!Splash_hBitmap) return FALSE;
  202. //
  203. // Create the window based on the background image
  204. //
  205. GetObject(Splash_hBitmap, sizeof(Bmp), &Bmp);
  206. rc.left = (GetSystemMetrics(SM_CXSCREEN) - Bmp.bmWidth) / 2;
  207. rc.top = (GetSystemMetrics(SM_CYSCREEN) - Bmp.bmHeight) / 3; // intended
  208. rc.right = rc.left + Bmp.bmWidth;
  209. rc.bottom = rc.top + Bmp.bmHeight;
  210. Splash_dwBitmapHeight = Bmp.bmHeight;
  211. dwStyle = WS_POPUP | WS_VISIBLE; // | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
  212. AdjustWindowRect(&rc, dwStyle, FALSE);
  213. Splash_hWnd = CreateWindow(
  214. szSplashClass,
  215. szSplashClass,
  216. dwStyle,
  217. rc.left,
  218. rc.top,
  219. rc.right - rc.left,
  220. rc.bottom - rc.top,
  221. NULL,
  222. NULL,
  223. hSplashInst,
  224. Splash_hBitmap);
  225. if (!Splash_hWnd)
  226. {
  227. if (Splash_hBitmap) DeleteObject(Splash_hBitmap);
  228. return FALSE;
  229. }
  230. /*
  231. //
  232. // Register Window
  233. //
  234. wc.style = CS_HREDRAW | CS_VREDRAW;
  235. wc.lpfnWndProc = (WNDPROC) SplashWndProc;
  236. wc.cbClsExtra = 0;
  237. wc.cbWndExtra = 0;
  238. wc.hInstance = hSplashInst;
  239. wc.hIcon = NULL;
  240. wc.hCursor = LoadCursor(NULL, IDC_WAIT);
  241. wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  242. wc.lpszMenuName = NULL;
  243. wc.lpszClassName = szSplashClass;
  244. if (!RegisterClass(&wc)) return FALSE;
  245. //
  246. // Create Window
  247. //
  248. hWnd = CreateWindowEx(
  249. WS_EX_TOPMOST,
  250. szSplashClass,
  251. szSplashClass,
  252. WS_POPUP | WS_VISIBLE,
  253. CW_USEDEFAULT,
  254. CW_USEDEFAULT,
  255. CW_USEDEFAULT,
  256. CW_USEDEFAULT,
  257. NULL,
  258. (HMENU) NULL,
  259. hSplashInst,
  260. NULL);
  261. if (!hWnd) return FALSE;
  262. */
  263. //
  264. // Pump Messages
  265. //
  266. bContinue = TRUE;
  267. while (bContinue && GetMessage(&msg, Splash_hWnd, 0, 0))
  268. {
  269. TranslateMessage(&msg);
  270. DispatchMessage(&msg);
  271. if (msg.message == WM_SPLASHPUMP_TERMINATE)
  272. bContinue = FALSE;
  273. }
  274. return TRUE;
  275. }