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.

655 lines
19 KiB

  1. /* DBACKP.CPP
  2. **
  3. ** Copyright (C) Microsoft, 1997, All Rights Reserved.
  4. **
  5. ** window class to display a preview of the screen background,
  6. ** complete with rudimentary palette handling and stretching
  7. ** of bitmaps to fit the preview screen.
  8. **
  9. ** this can be replaced with a static bitmap control only
  10. ** if palettes can also be handled by the control.
  11. **
  12. */
  13. #include "stdafx.h"
  14. #include "strsafe.h"
  15. #pragma hdrstop
  16. #define GWW_INFO 0
  17. #define CXYDESKPATTERN 8
  18. BOOL g_bInfoSet = FALSE;
  19. HBITMAP g_hbmPreview = NULL; // the bitmap used for previewing
  20. HBITMAP g_hbmDefault = NULL; // default bitmap
  21. HBITMAP g_hbmWall = NULL; // bitmap image of wallpaper
  22. HDC g_hdcWall = NULL; // memory DC with g_hbmWall selected
  23. HDC g_hdcMemory = NULL; // memory DC
  24. HPALETTE g_hpalWall = NULL; // palette that goes with hbmWall bitmap
  25. HBRUSH g_hbrBack = NULL; // brush for the desktop background
  26. IThumbnail *g_pthumb = NULL; // Html to Bitmap converter
  27. DWORD g_dwWallpaperID = 0; // ID to identify which bitmap we received
  28. #define WM_HTML_BITMAP (WM_USER + 100)
  29. #define WM_ASYNC_BITMAP (WM_HTML_BITMAP + 1)
  30. HPALETTE PaletteFromDS(HDC hdc)
  31. {
  32. DWORD adw[257];
  33. int i,n;
  34. n = GetDIBColorTable(hdc, 0, 256, (LPRGBQUAD)&adw[1]);
  35. adw[0] = MAKELONG(0x300, n);
  36. for (i=1; i<=n; i++)
  37. adw[i] = RGB(GetBValue(adw[i]),GetGValue(adw[i]),GetRValue(adw[i]));
  38. if (n == 0)
  39. return NULL;
  40. else
  41. return CreatePalette((LPLOGPALETTE)&adw[0]);
  42. }
  43. typedef struct{
  44. HWND hwnd;
  45. HBITMAP hbmp;
  46. DWORD id;
  47. WPARAM flags;
  48. TCHAR szFile[MAX_PATH];
  49. } ASYNCWALLPARAM, * PASYNCWALLPARAM;
  50. DWORD CALLBACK UpdateWallProc(LPVOID pv)
  51. {
  52. ASSERT(pv);
  53. PASYNCWALLPARAM pawp = (PASYNCWALLPARAM) pv;
  54. pawp->hbmp = (HBITMAP)LoadImage(NULL, pawp->szFile,
  55. IMAGE_BITMAP, 0, 0,
  56. LR_LOADFROMFILE|LR_CREATEDIBSECTION);
  57. if (pawp->hbmp)
  58. {
  59. // if all is good, then the window will handle cleaning up
  60. if (IsWindow(pawp->hwnd) && PostMessage(pawp->hwnd, WM_ASYNC_BITMAP, 0, (LPARAM)pawp))
  61. return TRUE;
  62. DeleteObject(pawp->hbmp);
  63. }
  64. LocalFree(pawp);
  65. return TRUE;
  66. }
  67. const GUID CLSID_HtmlThumbnailExtractor = {0xeab841a0, 0x9550, 0x11cf, 0x8c, 0x16, 0x0, 0x80, 0x5f, 0x14, 0x8, 0xf3};
  68. DWORD CALLBACK UpdateWallProcHTML(LPVOID pv)
  69. {
  70. if (SUCCEEDED(CoInitialize(NULL)))
  71. {
  72. ASSERT(pv);
  73. if (pv)
  74. {
  75. PASYNCWALLPARAM pawp = (PASYNCWALLPARAM) pv;
  76. IPersistFile *ppf;
  77. HRESULT hr = CoCreateInstance(CLSID_HtmlThumbnailExtractor, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IPersistFile, &ppf));
  78. if (SUCCEEDED(hr))
  79. {
  80. hr = ppf->Load(pawp->szFile, STGM_READ);
  81. if (SUCCEEDED(hr))
  82. {
  83. IExtractImage *pei= NULL;
  84. hr = ppf->QueryInterface(IID_PPV_ARG(IExtractImage, &pei));
  85. if (SUCCEEDED(hr))
  86. {
  87. DWORD dwPriority = 0;
  88. DWORD dwFlags = IEIFLAG_SCREEN | IEIFLAG_OFFLINE;
  89. WCHAR szLocation[MAX_PATH];
  90. SIZEL rgSize = {MON_DX, MON_DY};
  91. hr = pei->GetLocation(szLocation, ARRAYSIZE(szLocation), &dwPriority, &rgSize, SHGetCurColorRes(), &dwFlags);
  92. if (SUCCEEDED(hr))
  93. {
  94. HBITMAP hbm;
  95. hr = pei->Extract(&hbm);
  96. if (SUCCEEDED(hr))
  97. {
  98. if (!SendMessage(pawp->hwnd, WM_HTML_BITMAP, pawp->id, (LPARAM)hbm))
  99. {
  100. DeleteObject(hbm);
  101. }
  102. }
  103. }
  104. pei->Release();
  105. }
  106. }
  107. ppf->Release();
  108. }
  109. LocalFree(pawp);
  110. }
  111. CoUninitialize();
  112. }
  113. return TRUE;
  114. }
  115. void LoadWallpaperAsync(LPCTSTR pszFile, HWND hwnd, DWORD dwID, WPARAM flags, BOOL bHTML)
  116. {
  117. PASYNCWALLPARAM pawp = (PASYNCWALLPARAM) LocalAlloc(LPTR, SIZEOF(ASYNCWALLPARAM));
  118. if (pawp)
  119. {
  120. pawp->hwnd = hwnd;
  121. pawp->flags = flags;
  122. pawp->id = dwID;
  123. if (SUCCEEDED(StringCchCopy(pawp->szFile, ARRAYSIZE(pawp->szFile), pszFile)))
  124. {
  125. if (!bHTML)
  126. {
  127. if (!SHQueueUserWorkItem(UpdateWallProc, pawp, 0, (DWORD_PTR)0, (DWORD_PTR *)NULL, NULL, 0))
  128. {
  129. LocalFree(pawp);
  130. }
  131. }
  132. else
  133. {
  134. if (!SHQueueUserWorkItem(UpdateWallProcHTML, pawp, 0, (DWORD_PTR)0, (DWORD_PTR *)NULL, NULL, 0))
  135. {
  136. LocalFree(pawp);
  137. }
  138. }
  139. }
  140. }
  141. }
  142. void _InitPreview(void)
  143. {
  144. if( g_hbmPreview )
  145. DeleteObject( g_hbmPreview );
  146. g_hbmPreview = LoadMonitorBitmap();
  147. }
  148. void _BuildPattern(void)
  149. {
  150. WCHAR wszBuf[MAX_PATH];
  151. HBITMAP hbmTemp;
  152. COLORREF clrOldBk, clrOldText;
  153. HBRUSH hbr = NULL;
  154. WORD patbits[CXYDESKPATTERN] = {0, 0, 0, 0, 0, 0, 0, 0};
  155. // get rid of old brush if there was one
  156. if (g_hbrBack)
  157. DeleteObject(g_hbrBack);
  158. g_pActiveDesk->GetPattern(wszBuf, ARRAYSIZE(wszBuf), 0);
  159. if (wszBuf[0] != 0L)
  160. {
  161. LPTSTR pszPatternBuf;
  162. #ifndef UNICODE
  163. CHAR szTemp[MAX_PATH];
  164. SHUnicodeToAnsi(wszBuf, szTemp, ARRAYSIZE(szTemp));
  165. pszPatternBuf = szTemp;
  166. #else
  167. pszPatternBuf = wszBuf;
  168. #endif
  169. PatternToWords(pszPatternBuf, patbits);
  170. hbmTemp = CreateBitmap(8, 8, 1, 1, patbits);
  171. if (hbmTemp)
  172. {
  173. g_hbrBack = CreatePatternBrush(hbmTemp);
  174. DeleteObject(hbmTemp);
  175. }
  176. }
  177. else
  178. {
  179. g_hbrBack = CreateSolidBrush(GetSysColor(COLOR_BACKGROUND));
  180. }
  181. if (!g_hbrBack)
  182. {
  183. g_hbrBack = (HBRUSH)GetStockObject(BLACK_BRUSH);
  184. }
  185. clrOldText = SetTextColor(g_hdcMemory, GetSysColor(COLOR_BACKGROUND));
  186. clrOldBk = SetBkColor(g_hdcMemory, GetSysColor(COLOR_WINDOWTEXT));
  187. hbr = (HBRUSH)SelectObject(g_hdcMemory, g_hbrBack);
  188. PatBlt(g_hdcMemory, MON_X, MON_Y, MON_DX, MON_DY, PATCOPY);
  189. SelectObject(g_hdcMemory, hbr);
  190. SetTextColor(g_hdcMemory, clrOldText);
  191. SetBkColor(g_hdcMemory, clrOldBk);
  192. }
  193. void _InitWall(void)
  194. {
  195. if (g_hbmWall)
  196. {
  197. SelectObject(g_hdcWall, g_hbmDefault);
  198. DeleteObject(g_hbmWall);
  199. g_hbmWall = NULL;
  200. if (g_hpalWall)
  201. {
  202. DeleteObject(g_hpalWall);
  203. g_hpalWall = NULL;
  204. }
  205. }
  206. }
  207. void _GetWallpaperAsync(HWND hwnd, WPARAM flags)
  208. {
  209. WCHAR wszWallpaper[INTERNET_MAX_URL_LENGTH];
  210. LPTSTR pszWallpaper;
  211. int cchWallpaper = ARRAYSIZE(wszWallpaper);
  212. g_pActiveDesk->GetWallpaper(wszWallpaper, ARRAYSIZE(wszWallpaper), 0);
  213. #ifndef UNICODE
  214. CHAR szWallpaper[ARRAYSIZE(wszWallpaper)];
  215. SHUnicodeToAnsi(wszWallpaper, szWallpaper, ARRAYSIZE(szWallpaper));
  216. pszWallpaper = szWallpaper;
  217. #else
  218. pszWallpaper = wszWallpaper;
  219. #endif
  220. g_dwWallpaperID++;
  221. if (!*pszWallpaper || !lstrcmpi(pszWallpaper, g_szNone))
  222. return;
  223. {
  224. if (IsNormalWallpaper(pszWallpaper))
  225. {
  226. LoadWallpaperAsync(pszWallpaper, hwnd, g_dwWallpaperID, flags, FALSE);
  227. }
  228. else
  229. {
  230. if(IsWallpaperPicture(pszWallpaper))
  231. {
  232. // This is a picture (GIF, JPG etc.,)
  233. // We need to generate a small HTML file that has this picture
  234. // as the background image.
  235. //
  236. // Compute the filename for the Temporary HTML file.
  237. //
  238. GetTempPath(ARRAYSIZE(wszWallpaper), pszWallpaper);
  239. if (SUCCEEDED(StringCchCat(pszWallpaper, cchWallpaper, PREVIEW_PICTURE_FILENAME)))
  240. {
  241. #ifndef UNICODE
  242. SHAnsiToUnicode(szWallpaper, wszWallpaper, ARRAYSIZE(wszWallpaper));
  243. #endif
  244. //
  245. // Generate the preview picture html file.
  246. //
  247. g_pActiveDesk->GenerateDesktopItemHtml(wszWallpaper, NULL, 0);
  248. }
  249. }
  250. //
  251. // Will cause a WM_HTML_BITMAP to get sent to us.
  252. //
  253. LoadWallpaperAsync(pszWallpaper, hwnd, g_dwWallpaperID, flags, TRUE);
  254. }
  255. }
  256. }
  257. void _DrawWall(HBITMAP hbm, WPARAM flags)
  258. {
  259. int dxWall; // size of wallpaper
  260. int dyWall;
  261. BITMAP bm;
  262. // init the global
  263. g_hbmWall = hbm;
  264. SelectObject(g_hdcWall, g_hbmWall); // bitmap stays in this DC
  265. GetObject(g_hbmWall, sizeof(bm), &bm);
  266. TraceMsg(TF_ALWAYS, "for bitmap %08X we have bpp=%d and planes=%d", g_hbmWall, bm.bmBitsPixel, bm.bmPlanes);
  267. if (GetDeviceCaps(g_hdcMemory, RASTERCAPS) & RC_PALETTE)
  268. {
  269. if (bm.bmBitsPixel * bm.bmPlanes > 8)
  270. g_hpalWall = CreateHalftonePalette(g_hdcMemory);
  271. else if (bm.bmBitsPixel * bm.bmPlanes == 8)
  272. g_hpalWall = PaletteFromDS(g_hdcWall);
  273. else
  274. g_hpalWall = NULL; //!!! assume 1 or 4bpp images dont have palettes
  275. }
  276. GetObject(g_hbmWall, sizeof(bm), &bm);
  277. if(flags & BP_EXTERNALWALL)
  278. {
  279. //For external wallpapers, we ask the image extractor to generate
  280. // bitmaps the size that we want to show (NOT the screen size).
  281. dxWall = MON_DX;
  282. dyWall = MON_DY;
  283. }
  284. else
  285. {
  286. dxWall = MulDiv(bm.bmWidth, MON_DX, GetDeviceCaps(g_hdcMemory, HORZRES));
  287. dyWall = MulDiv(bm.bmHeight, MON_DY, GetDeviceCaps(g_hdcMemory, VERTRES));
  288. }
  289. if (dxWall < 1) dxWall = 1;
  290. if (dyWall < 1) dyWall = 1;
  291. if (g_hpalWall)
  292. {
  293. SelectPalette(g_hdcMemory, g_hpalWall, TRUE);
  294. RealizePalette(g_hdcMemory);
  295. }
  296. IntersectClipRect(g_hdcMemory, MON_X, MON_Y, MON_X + MON_DX, MON_Y + MON_DY);
  297. SetStretchBltMode(g_hdcMemory, COLORONCOLOR);
  298. if (flags & BP_TILE)
  299. {
  300. int i;
  301. StretchBlt(g_hdcMemory, MON_X, MON_Y, dxWall, dyWall,
  302. g_hdcWall, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
  303. for (i = MON_X+dxWall; i < (MON_X + MON_DX); i+= dxWall)
  304. BitBlt(g_hdcMemory, i, MON_Y, dxWall, dyWall, g_hdcMemory, MON_X, MON_Y, SRCCOPY);
  305. for (i = MON_Y; i < (MON_Y + MON_DY); i += dyWall)
  306. BitBlt(g_hdcMemory, MON_X, i, MON_DX, dyWall, g_hdcMemory, MON_X, MON_Y, SRCCOPY);
  307. }
  308. else
  309. {
  310. //We want to stretch the Bitmap to the preview monitor size ONLY for new platforms.
  311. if (flags & BP_STRETCH)
  312. {
  313. //Stretch the bitmap to the whole preview monitor.
  314. dxWall = MON_DX;
  315. dyWall = MON_DY;
  316. }
  317. //Center the bitmap in the preview monitor
  318. StretchBlt(g_hdcMemory, MON_X + (MON_DX - dxWall)/2, MON_Y + (MON_DY - dyWall)/2,
  319. dxWall, dyWall, g_hdcWall, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
  320. }
  321. // restore dc
  322. SelectPalette(g_hdcMemory, (HPALETTE)GetStockObject(DEFAULT_PALETTE), TRUE);
  323. SelectClipRgn(g_hdcMemory, NULL);
  324. }
  325. /*--------------------------------------------------------------------
  326. ** Build the preview bitmap.
  327. **
  328. ** both the pattern and the bitmap are drawn each time, but
  329. ** if the flags dictate the need, new pattern and bitmap
  330. ** globals are built as needed.
  331. **--------------------------------------------------------------------*/
  332. void NEAR PASCAL BuildPreviewBitmap(HWND hwnd, HBITMAP hbmp, WPARAM flags)
  333. {
  334. _InitPreview();
  335. HBITMAP hbmOld = (HBITMAP)SelectObject(g_hdcMemory, g_hbmPreview);
  336. _BuildPattern();
  337. _InitWall();
  338. /*
  339. ** now, position the wallpaper appropriately
  340. */
  341. if (hbmp)
  342. {
  343. // use the one that was passed in
  344. _DrawWall(hbmp, flags);
  345. }
  346. else
  347. {
  348. // this means that we need to set up the stuff
  349. // to get the bmp ASYNC
  350. _GetWallpaperAsync(hwnd, flags);
  351. }
  352. SelectObject(g_hdcMemory, hbmOld);
  353. }
  354. BOOL NEAR PASCAL BP_CreateGlobals(HWND hwnd)
  355. {
  356. HDC hdc;
  357. hdc = GetDC(NULL);
  358. g_hdcWall = CreateCompatibleDC(hdc);
  359. g_hdcMemory = CreateCompatibleDC(hdc);
  360. ReleaseDC(NULL, hdc);
  361. g_hbmPreview = LoadMonitorBitmap();
  362. HBITMAP hbm;
  363. hbm = CreateBitmap(1, 1, 1, 1, NULL);
  364. g_hbmDefault = (HBITMAP)SelectObject(g_hdcMemory, hbm);
  365. SelectObject(g_hdcMemory, g_hbmDefault);
  366. DeleteObject(hbm);
  367. HRESULT hr = E_FAIL;
  368. hr = CoCreateInstance(CLSID_Thumbnail, NULL, CLSCTX_INPROC_SERVER, IID_IThumbnail, (void **)&g_pthumb);
  369. if(SUCCEEDED(hr))
  370. {
  371. g_pthumb->Init(hwnd, WM_HTML_BITMAP);
  372. }
  373. if (!g_hdcWall || !g_hbmPreview || !SUCCEEDED(hr))
  374. return FALSE;
  375. else
  376. return TRUE;
  377. }
  378. void NEAR PASCAL BP_DestroyGlobals(void)
  379. {
  380. if (g_hbmPreview)
  381. {
  382. DeleteObject(g_hbmPreview);
  383. g_hbmPreview = NULL;
  384. }
  385. if (g_hbmWall)
  386. {
  387. SelectObject(g_hdcWall, g_hbmDefault);
  388. DeleteObject(g_hbmWall);
  389. g_hbmWall = NULL;
  390. }
  391. if (g_hpalWall)
  392. {
  393. SelectPalette(g_hdcWall, (HPALETTE)GetStockObject(DEFAULT_PALETTE), TRUE);
  394. DeleteObject(g_hpalWall);
  395. g_hpalWall = NULL;
  396. }
  397. if (g_hdcWall)
  398. {
  399. DeleteDC(g_hdcWall);
  400. g_hdcWall = NULL;
  401. }
  402. if (g_hbrBack)
  403. {
  404. DeleteObject(g_hbrBack);
  405. g_hbrBack = NULL;
  406. }
  407. if (g_hdcMemory)
  408. {
  409. DeleteDC(g_hdcMemory);
  410. g_hdcMemory = NULL;
  411. }
  412. if (g_hbmDefault)
  413. {
  414. DeleteObject(g_hbmDefault);
  415. g_hbmDefault = NULL;
  416. }
  417. if (g_pthumb)
  418. {
  419. g_pthumb->Release();
  420. g_pthumb = NULL;
  421. }
  422. }
  423. void InvalidateBackPrevContents(HWND hwnd)
  424. {
  425. BITMAP bm;
  426. RECT rc;
  427. //
  428. // Only invalidate the "screen" part of the monitor bitmap.
  429. //
  430. GetObject(g_hbmPreview, SIZEOF(bm), &bm);
  431. GetClientRect(hwnd, &rc);
  432. rc.left = ( rc.right - bm.bmWidth ) / 2 + MON_X;
  433. rc.top = ( rc.bottom - bm.bmHeight ) / 2 + MON_Y;
  434. rc.right = rc.left + MON_DX;
  435. rc.bottom = rc.top + MON_DY;
  436. InvalidateRect(hwnd, &rc, FALSE);
  437. }
  438. LRESULT BackPreviewWndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  439. {
  440. PAINTSTRUCT ps;
  441. BITMAP bm;
  442. RECT rc;
  443. HBITMAP hbmOld;
  444. HPALETTE hpalOld;
  445. switch(message)
  446. {
  447. case WM_CREATE:
  448. if (!BP_CreateGlobals(hWnd))
  449. return -1L;
  450. break;
  451. case WM_DESTROY:
  452. MSG msg;
  453. BP_DestroyGlobals();
  454. while (PeekMessage(&msg, hWnd, WM_HTML_BITMAP, WM_ASYNC_BITMAP, PM_REMOVE))
  455. {
  456. if ( msg.lParam )
  457. {
  458. if (msg.message == WM_ASYNC_BITMAP)
  459. {
  460. // clean up these objects
  461. DeleteObject(((PASYNCWALLPARAM)(msg.lParam))->hbmp);
  462. LocalFree((PASYNCWALLPARAM)(msg.lParam));
  463. }
  464. else // WM_HTML_BITMAP
  465. DeleteObject((HBITMAP)msg.lParam);
  466. }
  467. }
  468. break;
  469. case WM_SETBACKINFO:
  470. if (g_hbmPreview)
  471. {
  472. BuildPreviewBitmap(hWnd, NULL, wParam);
  473. g_bInfoSet = TRUE;
  474. InvalidateBackPrevContents(hWnd);
  475. }
  476. break;
  477. case WM_ASYNC_BITMAP:
  478. if (lParam)
  479. {
  480. PASYNCWALLPARAM pawp = (PASYNCWALLPARAM) lParam;
  481. ASSERT(pawp->hbmp);
  482. if (pawp->id == g_dwWallpaperID)
  483. {
  484. BuildPreviewBitmap(hWnd, pawp->hbmp, pawp->flags);
  485. InvalidateBackPrevContents(hWnd);
  486. }
  487. else
  488. {
  489. // clean up this object
  490. DeleteObject(pawp->hbmp);
  491. LocalFree(pawp);
  492. }
  493. }
  494. break;
  495. case WM_HTML_BITMAP:
  496. {
  497. // may come through with NULL if the image extraction failed....
  498. if (wParam == g_dwWallpaperID && lParam)
  499. {
  500. BuildPreviewBitmap(hWnd, (HBITMAP)lParam, BP_EXTERNALWALL);
  501. InvalidateBackPrevContents(hWnd);
  502. // Take ownership of bitmap
  503. return 1;
  504. }
  505. // Bitmap for something no longer selected
  506. return 0;
  507. }
  508. case WM_PALETTECHANGED:
  509. if ((HWND)wParam == hWnd)
  510. break;
  511. //fallthru
  512. case WM_QUERYNEWPALETTE:
  513. if (g_hpalWall)
  514. InvalidateRect(hWnd, NULL, FALSE);
  515. break;
  516. case WM_PAINT:
  517. BeginPaint(hWnd,&ps);
  518. if (g_hbmPreview && g_bInfoSet)
  519. {
  520. hbmOld = (HBITMAP)SelectObject(g_hdcMemory, g_hbmPreview);
  521. if (g_hpalWall)
  522. {
  523. hpalOld = SelectPalette(ps.hdc, g_hpalWall, FALSE);
  524. RealizePalette(ps.hdc);
  525. }
  526. GetObject(g_hbmPreview, sizeof(bm), &bm);
  527. GetClientRect(hWnd, &rc);
  528. rc.left = ( rc.right - bm.bmWidth ) / 2;
  529. rc.top = ( rc.bottom - bm.bmHeight ) / 2;
  530. BitBlt(ps.hdc, rc.left, rc.top, bm.bmWidth, bm.bmHeight, g_hdcMemory,
  531. 0, 0, SRCCOPY);
  532. if (g_hpalWall)
  533. {
  534. SelectPalette(ps.hdc, hpalOld, TRUE);
  535. RealizePalette(ps.hdc);
  536. }
  537. SelectObject(g_hdcMemory, hbmOld);
  538. }
  539. EndPaint(hWnd,&ps);
  540. return 0;
  541. }
  542. return DefWindowProc(hWnd,message,wParam,lParam);
  543. }
  544. BOOL RegisterBackPreviewClass()
  545. {
  546. WNDCLASS wc;
  547. if (!GetClassInfo(HINST_THISDLL, c_szBackgroundPreview2, &wc))
  548. {
  549. wc.style = 0;
  550. wc.lpfnWndProc = BackPreviewWndProc;
  551. wc.cbClsExtra = 0;
  552. wc.cbWndExtra = 0;
  553. wc.hInstance = HINST_THISDLL;
  554. wc.hIcon = NULL;
  555. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  556. wc.hbrBackground = (HBRUSH)(COLOR_3DFACE+1);
  557. wc.lpszMenuName = NULL;
  558. wc.lpszClassName = c_szBackgroundPreview2;
  559. if (!RegisterClass(&wc))
  560. return FALSE;
  561. }
  562. return TRUE;
  563. }