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.

635 lines
22 KiB

  1. #include "priv.h"
  2. #include "CoverWnd.h"
  3. #include <ginarcid.h>
  4. #undef IDB_BACKGROUND_24
  5. #define IDB_BACKGROUND_24 0x3812
  6. #undef IDB_FLAG_24
  7. #define IDB_FLAG_24 0x3813
  8. const TCHAR g_szWindowClassName[] = TEXT("CoverWindowClass");
  9. const TCHAR g_szPleaseWaitName[] = TEXT("PleaseWaitWindowClass");
  10. #define CHUNK_SIZE 20
  11. #define IDT_KILLYOURSELF 1
  12. #define IDT_UPDATE 2
  13. #define WM_DESTORYYOURSELF (WM_USER + 0)
  14. void DimPixels(ULONG* pulSrc, int cLen, int Amount)
  15. {
  16. for (int i = cLen - 1; i >= 0; i--)
  17. {
  18. ULONG ulR = GetRValue(*pulSrc);
  19. ULONG ulG = GetGValue(*pulSrc);
  20. ULONG ulB = GetBValue(*pulSrc);
  21. ULONG ulGray = (54 * ulR + 183 * ulG + 19 * ulB) >> 8;
  22. ULONG ulTemp = ulGray * (0xff - Amount);
  23. ulR = (ulR * Amount + ulTemp) >> 8;
  24. ulG = (ulG * Amount + ulTemp) >> 8;
  25. ulB = (ulB * Amount + ulTemp) >> 8;
  26. *pulSrc = (*pulSrc & 0xff000000) | RGB(ulR, ulG, ulB);
  27. pulSrc++;
  28. }
  29. }
  30. LRESULT CALLBACK PleaseWaitWndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lParam)
  31. {
  32. switch ( msg )
  33. {
  34. case WM_CREATE:
  35. {
  36. CREATESTRUCT* pCS = (CREATESTRUCT*)lParam;
  37. SetWindowLongPtr( hwnd, GWLP_USERDATA, (LPARAM) pCS->lpCreateParams );
  38. HBITMAP hbmBackground = (HBITMAP) pCS->lpCreateParams;
  39. BITMAP bm;
  40. if ( GetObject( hbmBackground, sizeof(bm), &bm ) )
  41. {
  42. RECT rc;
  43. HWND hwndParent = GetParent( hwnd );
  44. GetClientRect( hwndParent, &rc );
  45. POINT pt = {0,0};
  46. HMONITOR hmon = MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY);
  47. if (hmon)
  48. {
  49. MONITORINFO mi = {sizeof(mi)};
  50. GetMonitorInfo(hmon, &mi);
  51. rc = mi.rcMonitor;
  52. MapWindowPoints(HWND_DESKTOP, hwndParent, (LPPOINT)&rc, 2);
  53. }
  54. // Center dialog in the center of the virtual screen
  55. int x = ( rc.right - rc.left - bm.bmWidth ) / 2;
  56. int y = ( rc.bottom - rc.top - bm.bmHeight ) / 2;
  57. SetWindowPos( hwnd, NULL, x, y, bm.bmWidth, bm.bmHeight, SWP_NOZORDER | SWP_NOACTIVATE );
  58. }
  59. }
  60. return TRUE;
  61. case WM_PAINT:
  62. {
  63. HBITMAP hbmBackground = (HBITMAP) GetWindowLongPtr( hwnd, GWLP_USERDATA );
  64. PAINTSTRUCT ps;
  65. HDC hdc = BeginPaint( hwnd, &ps );
  66. BITMAP bm;
  67. if ( hbmBackground )
  68. {
  69. DWORD dwLayout = SetLayout(hdc, LAYOUT_BITMAPORIENTATIONPRESERVED);
  70. if ( GetObject( hbmBackground, sizeof(bm), &bm ) )
  71. {
  72. HDC hdcBackground = CreateCompatibleDC( hdc );
  73. if (hdcBackground)
  74. {
  75. HBITMAP hbmOld = (HBITMAP) SelectObject( hdcBackground, hbmBackground );
  76. BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcBackground, 0, 0, SRCCOPY);
  77. SelectObject( hdcBackground, hbmOld );
  78. DeleteDC( hdcBackground );
  79. }
  80. }
  81. SetLayout(hdc, dwLayout);
  82. // Don't draw more the once, no one will be on top of us
  83. DeleteObject(hbmBackground);
  84. SetWindowLongPtr( hwnd, GWLP_USERDATA, NULL );
  85. HFONT hfntSelected = NULL;
  86. HFONT hfntButton = NULL;
  87. HINSTANCE hMsGina = LoadLibrary( L"msgina.dll" );
  88. if ( hMsGina )
  89. {
  90. CHAR szPixelSize[ 32 ];
  91. if (LoadStringA(hMsGina,
  92. IDS_TURNOFF_TITLE_FACESIZE,
  93. szPixelSize,
  94. ARRAYSIZE(szPixelSize)) != 0)
  95. {
  96. LOGFONT logFont = { 0 };
  97. logFont.lfHeight = -MulDiv(atoi(szPixelSize), GetDeviceCaps(hdc, LOGPIXELSY), 72);
  98. if (LoadString(hMsGina,
  99. IDS_TURNOFF_TITLE_FACENAME,
  100. logFont.lfFaceName,
  101. LF_FACESIZE) != 0)
  102. {
  103. logFont.lfWeight = FW_BOLD;
  104. logFont.lfQuality = DEFAULT_QUALITY;
  105. hfntButton = CreateFontIndirect(&logFont);
  106. hfntSelected = static_cast<HFONT>(SelectObject(hdc, hfntButton));
  107. }
  108. }
  109. }
  110. COLORREF colorButtonText = RGB(255, 255, 255);
  111. COLORREF colorText = SetTextColor(hdc, colorButtonText);
  112. int iBkMode = SetBkMode(hdc, TRANSPARENT);
  113. WCHAR szText[MAX_PATH];
  114. szText[0] = 0;
  115. LoadString((HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), IDS_PLEASEWAIT, szText, ARRAYSIZE(szText));
  116. RECT rcText;
  117. RECT rcClient;
  118. RECT rc;
  119. TBOOL(GetClientRect( hwnd, &rcClient ));
  120. TBOOL(CopyRect(&rcText, &rcClient));
  121. DWORD dwFlags = DT_HIDEPREFIX | (IS_MIRRORING_ENABLED() ? DT_RTLREADING : 0);
  122. int iPixelHeight = DrawText( hdc, szText, -1, &rcText, DT_CALCRECT | dwFlags);
  123. TBOOL(CopyRect(&rc, &rcClient));
  124. TBOOL(InflateRect(&rc, -((rc.right - rc.left - (rcText.right - rcText.left)) / 2), -((rc.bottom - rc.top - iPixelHeight) / 2)));
  125. (int)DrawText(hdc, szText, -1, &rc, dwFlags );
  126. (int)SetBkMode(hdc, iBkMode);
  127. (COLORREF)SetTextColor(hdc, colorText);
  128. if ( hfntButton )
  129. {
  130. (HGDIOBJ)SelectObject(hdc, hfntSelected);
  131. DeleteObject( hfntButton );
  132. }
  133. }
  134. EndPaint( hwnd, &ps );
  135. }
  136. break;
  137. case WM_ERASEBKGND:
  138. return TRUE;
  139. default:
  140. return DefWindowProc( hwnd, msg, wp, lParam );
  141. break;
  142. }
  143. return 0;
  144. }
  145. CDimmedWindow::CDimmedWindow (HINSTANCE hInstance) :
  146. _lReferenceCount(1),
  147. _hInstance(hInstance)
  148. {
  149. WNDCLASSEX wndClassEx;
  150. ZeroMemory(&wndClassEx, sizeof(wndClassEx));
  151. wndClassEx.cbSize = sizeof(wndClassEx);
  152. wndClassEx.lpfnWndProc = WndProc;
  153. wndClassEx.hInstance = hInstance;
  154. wndClassEx.lpszClassName = g_szWindowClassName;
  155. wndClassEx.hCursor = LoadCursor(NULL, IDC_WAIT);
  156. _atom = RegisterClassEx(&wndClassEx);
  157. wndClassEx.lpszClassName = g_szPleaseWaitName;
  158. wndClassEx.lpfnWndProc = PleaseWaitWndProc;
  159. _atomPleaseWait = RegisterClassEx(&wndClassEx);
  160. }
  161. CDimmedWindow::~CDimmedWindow (void)
  162. {
  163. if (_hwnd)
  164. {
  165. PostMessage(_hwnd, WM_DESTORYYOURSELF, 0, 0);
  166. }
  167. if (_atom != 0)
  168. {
  169. TBOOL(UnregisterClass(MAKEINTRESOURCE(_atom), _hInstance));
  170. }
  171. if (_atomPleaseWait != 0 )
  172. {
  173. TBOOL(UnregisterClass(MAKEINTRESOURCE(_atomPleaseWait), _hInstance));
  174. }
  175. }
  176. ULONG CDimmedWindow::AddRef (void)
  177. {
  178. return(InterlockedIncrement(&_lReferenceCount));
  179. }
  180. ULONG CDimmedWindow::Release (void)
  181. {
  182. LONG lReferenceCount;
  183. lReferenceCount = InterlockedDecrement(&_lReferenceCount);
  184. ASSERTMSG(lReferenceCount >= 0, "Reference count negative or zero in CDimmedWindow::Release");
  185. if (lReferenceCount == 0)
  186. {
  187. delete this;
  188. }
  189. return(lReferenceCount);
  190. }
  191. DWORD CDimmedWindow::WorkerThread(IN void *pv)
  192. {
  193. ASSERT(pv);
  194. HWND hwnd = NULL;
  195. CDimmedWindow* pDimmedWindow = (CDimmedWindow*)pv;
  196. BOOL fScreenReader;
  197. bool fNoDebuggerPresent, fNoScreenReaderPresent;
  198. BOOL fUserTurnedOffWindow = SHRegGetBoolUSValue(SZ_THEMES, L"NoCoverWindow", FALSE, FALSE); // Needed for perf testing
  199. fNoDebuggerPresent = !IsDebuggerPresent();
  200. fNoScreenReaderPresent = ((SystemParametersInfo(SPI_GETSCREENREADER, 0, &fScreenReader, 0) == FALSE) || (fScreenReader == FALSE));
  201. if (fNoDebuggerPresent &&
  202. fNoScreenReaderPresent &&
  203. !fUserTurnedOffWindow)
  204. {
  205. int xVirtualScreen = GetSystemMetrics(SM_XVIRTUALSCREEN);
  206. int yVirtualScreen = GetSystemMetrics(SM_YVIRTUALSCREEN);
  207. int cxVirtualScreen = GetSystemMetrics(SM_CXVIRTUALSCREEN);
  208. int cyVirtualScreen = GetSystemMetrics(SM_CYVIRTUALSCREEN);
  209. HWND hwnd = CreateWindowEx(WS_EX_TOPMOST,
  210. g_szWindowClassName,
  211. NULL,
  212. WS_POPUP | WS_CLIPCHILDREN,
  213. xVirtualScreen, yVirtualScreen,
  214. cxVirtualScreen, cyVirtualScreen,
  215. NULL, NULL, pDimmedWindow->_hInstance, NULL);
  216. if (hwnd != NULL)
  217. {
  218. bool fDimmed;
  219. HBITMAP hbmBackground = NULL;
  220. fDimmed = false;
  221. (BOOL)ShowWindow(hwnd, SW_SHOW);
  222. TBOOL(SetForegroundWindow(hwnd));
  223. (BOOL)EnableWindow(hwnd, FALSE);
  224. SetTimer(hwnd, IDT_KILLYOURSELF, pDimmedWindow->_ulKillTimer, NULL);
  225. // Now create bitmap with background image and the windows flag
  226. HINSTANCE hShell32 = LoadLibrary( L"shell32.dll" );
  227. if ( NULL != hShell32 )
  228. {
  229. hbmBackground = (HBITMAP) LoadImage( hShell32, MAKEINTRESOURCE( IDB_BACKGROUND_24 ), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE );
  230. if (hbmBackground)
  231. {
  232. HDC hdcMem1 = CreateCompatibleDC(NULL);
  233. if (hdcMem1)
  234. {
  235. HDC hdcMem2 = CreateCompatibleDC(NULL);
  236. if (hdcMem2)
  237. {
  238. HBITMAP hbmFlag = (HBITMAP) LoadImage( hShell32, MAKEINTRESOURCE( IDB_FLAG_24 ), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE );
  239. if (hbmFlag)
  240. {
  241. HBITMAP hbmOld1 = (HBITMAP)SelectObject(hdcMem1, hbmBackground);
  242. HBITMAP hbmOld2 = (HBITMAP)SelectObject(hdcMem2, hbmFlag);
  243. BITMAP bm1;
  244. if (GetObject(hbmBackground, sizeof(bm1), &bm1))
  245. {
  246. BITMAP bm2;
  247. if (GetObject(hbmFlag, sizeof(bm2), &bm2))
  248. {
  249. BitBlt(hdcMem1, bm1.bmWidth - bm2.bmWidth - 8, 0, bm2.bmWidth, bm2.bmHeight, hdcMem2, 0, 0, SRCCOPY);
  250. }
  251. }
  252. SelectObject(hdcMem1, hbmOld1);
  253. SelectObject(hdcMem2, hbmOld2);
  254. DeleteObject(hbmFlag);
  255. }
  256. DeleteDC(hdcMem2);
  257. }
  258. DeleteDC(hdcMem1);
  259. }
  260. }
  261. FreeLibrary( hShell32 );
  262. }
  263. HWND hwndPleaseWait = CreateWindowEx( 0
  264. , g_szPleaseWaitName
  265. , NULL
  266. , WS_CHILD | WS_VISIBLE | WS_BORDER
  267. , 0
  268. , 0
  269. , 100
  270. , 100
  271. , hwnd
  272. , NULL
  273. , pDimmedWindow->_hInstance
  274. , hbmBackground // the window is responsible for freeing it.
  275. );
  276. if ( NULL == hwndPleaseWait )
  277. {
  278. DeleteObject( hbmBackground );
  279. }
  280. pDimmedWindow->_hwnd = hwnd;
  281. // This Release matches the addref during ::Create to guarantee that the object does not die before the HWND
  282. // is created.
  283. pDimmedWindow->Release();
  284. MSG msg;
  285. while (GetMessage(&msg, NULL, 0, 0))
  286. {
  287. TranslateMessage(&msg);
  288. DispatchMessage(&msg);
  289. if ((msg.message == WM_DESTORYYOURSELF) && (msg.hwnd == hwnd))
  290. {
  291. break;
  292. }
  293. }
  294. }
  295. }
  296. return (hwnd == NULL ? E_FAIL : S_OK);
  297. }
  298. HRESULT CDimmedWindow::Create (UINT ulKillTimer)
  299. {
  300. BOOL fSucceeded = FALSE;
  301. if (!_hwnd)
  302. {
  303. _ulKillTimer = ulKillTimer;
  304. AddRef();
  305. fSucceeded = SHCreateThread(CDimmedWindow::WorkerThread, (void *)this, CTF_INSIST, NULL);
  306. if (!fSucceeded)
  307. {
  308. Release();
  309. }
  310. }
  311. return fSucceeded ? S_OK : E_FAIL;
  312. }
  313. typedef struct
  314. {
  315. HDC hdcDimmed;
  316. HBITMAP hbmDimmed;
  317. HBITMAP hbmOldDimmed;
  318. HDC hdcTemp;
  319. HBITMAP hbmTemp;
  320. HBITMAP hbmOldTemp;
  321. ULONG* pulSrc;
  322. int idxSaturation;
  323. int idxChunk;
  324. int idxProgress;
  325. } DIMMEDWINDOWDATA;
  326. LRESULT CALLBACK CDimmedWindow::WndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  327. {
  328. LRESULT lResult = 0;
  329. DIMMEDWINDOWDATA *pData;
  330. pData = (DIMMEDWINDOWDATA *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
  331. switch (uMsg)
  332. {
  333. case WM_CREATE:
  334. {
  335. CREATESTRUCT* pCS = (CREATESTRUCT*)lParam;
  336. if (pCS)
  337. {
  338. pData = new DIMMEDWINDOWDATA;
  339. if (pData)
  340. {
  341. SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pData);
  342. // On remote session we don't gray out the screen, yeah :-)
  343. if (!GetSystemMetrics(SM_REMOTESESSION))
  344. {
  345. HDC hdcWindow = GetDC(hwnd);
  346. if (hdcWindow != NULL )
  347. {
  348. pData->hdcDimmed = CreateCompatibleDC(hdcWindow);
  349. if (pData->hdcDimmed)
  350. {
  351. BITMAPINFO bmi;
  352. ZeroMemory(&bmi, sizeof(bmi));
  353. bmi.bmiHeader.biSize = sizeof(bmi);
  354. bmi.bmiHeader.biWidth = pCS->cx;
  355. bmi.bmiHeader.biHeight = pCS->cy;
  356. bmi.bmiHeader.biPlanes = 1;
  357. bmi.bmiHeader.biBitCount = 32;
  358. bmi.bmiHeader.biCompression = BI_RGB;
  359. bmi.bmiHeader.biSizeImage = 0;
  360. pData->hbmDimmed = CreateDIBSection(pData->hdcDimmed, &bmi, DIB_RGB_COLORS, (LPVOID*)&pData->pulSrc, NULL, 0);
  361. if (pData->hbmDimmed != NULL)
  362. {
  363. pData->hbmOldDimmed = (HBITMAP) SelectObject(pData->hdcDimmed, pData->hbmDimmed);
  364. pData->idxSaturation = 8;
  365. pData->idxChunk = pCS->cy / CHUNK_SIZE;
  366. }
  367. else
  368. {
  369. DeleteDC(pData->hdcDimmed);
  370. pData->hdcDimmed = NULL;
  371. }
  372. }
  373. pData->hdcTemp = CreateCompatibleDC(hdcWindow);
  374. if (pData->hdcTemp)
  375. {
  376. pData->hbmTemp = CreateCompatibleBitmap(hdcWindow, pCS->cx, pCS->cy);
  377. if (pData->hbmTemp)
  378. {
  379. pData->hbmOldTemp = (HBITMAP) SelectObject(pData->hdcTemp, pData->hbmTemp);
  380. }
  381. else
  382. {
  383. DeleteDC(pData->hdcTemp);
  384. pData->hdcTemp = NULL;
  385. }
  386. }
  387. ReleaseDC(hwnd, hdcWindow);
  388. }
  389. }
  390. if (pData->hdcDimmed)
  391. {
  392. SetTimer(hwnd, IDT_UPDATE, 30, NULL);
  393. }
  394. }
  395. }
  396. break;
  397. }
  398. case WM_DESTORYYOURSELF:
  399. {
  400. DestroyWindow(hwnd);
  401. break;
  402. }
  403. case WM_DESTROY:
  404. {
  405. if (pData)
  406. {
  407. SetWindowLongPtr(hwnd, GWLP_USERDATA, NULL);
  408. KillTimer(hwnd, IDT_UPDATE);
  409. KillTimer(hwnd, IDT_KILLYOURSELF);
  410. if (pData->hdcDimmed)
  411. {
  412. SelectObject(pData->hdcDimmed, pData->hbmOldDimmed);
  413. DeleteDC(pData->hdcDimmed);
  414. pData->hdcDimmed = NULL;
  415. }
  416. if (pData->hbmDimmed)
  417. {
  418. DeleteObject(pData->hbmDimmed);
  419. pData->hbmDimmed = NULL;
  420. }
  421. if (pData->hdcTemp)
  422. {
  423. SelectObject(pData->hdcTemp, pData->hbmOldTemp);
  424. DeleteDC(pData->hdcTemp);
  425. pData->hdcTemp = NULL;
  426. }
  427. if (pData->hbmTemp)
  428. {
  429. DeleteObject(pData->hbmTemp);
  430. pData->hbmTemp = NULL;
  431. }
  432. delete pData;
  433. }
  434. break;
  435. }
  436. case WM_TIMER:
  437. if (pData)
  438. {
  439. BOOL fDestroyBitmaps = FALSE;
  440. if (wParam == IDT_KILLYOURSELF)
  441. {
  442. ShowWindow(hwnd, SW_HIDE);
  443. fDestroyBitmaps = TRUE;
  444. }
  445. else if (pData->hdcDimmed && pData->hbmDimmed)
  446. {
  447. HDC hdcWindow = GetDC(hwnd);
  448. BITMAP bm;
  449. GetObject(pData->hbmDimmed, sizeof(BITMAP), &bm);
  450. if (pData->idxChunk >= 0 )
  451. {
  452. //
  453. // In the first couple of passes, we slowly collect the screen
  454. // into our bitmap. We do this because Blt-ing the whole thing
  455. // causes the system to hang. By doing it this way, we continue
  456. // to pump messages, the UI stays responsive and it keeps the
  457. // mouse alive.
  458. //
  459. int y = pData->idxChunk * CHUNK_SIZE;
  460. if (pData->hdcTemp)
  461. {
  462. BitBlt(pData->hdcTemp, 0, y, bm.bmWidth, CHUNK_SIZE, hdcWindow, 0, y, SRCCOPY);
  463. BitBlt(pData->hdcDimmed, 0, y, bm.bmWidth, CHUNK_SIZE, pData->hdcTemp, 0, y, SRCCOPY);
  464. }
  465. else
  466. {
  467. BitBlt(pData->hdcDimmed, 0, y, bm.bmWidth, CHUNK_SIZE, hdcWindow, 0, y, SRCCOPY);
  468. }
  469. pData->idxChunk--;
  470. if (pData->idxChunk < 0)
  471. {
  472. //
  473. // We're done getting the bitmap, now reset the timer
  474. // so we slowly fade to grey.
  475. //
  476. SetTimer(hwnd, IDT_UPDATE, 250, NULL);
  477. pData->idxSaturation = 16;
  478. }
  479. }
  480. else
  481. {
  482. //
  483. // In these passes, we are making the image more and more grey and
  484. // then Blt-ing the result to the screen.
  485. //
  486. DimPixels(pData->pulSrc, bm.bmWidth * bm.bmHeight, 0xd5);
  487. BitBlt(hdcWindow, 0, 0, bm.bmWidth, bm.bmHeight, pData->hdcDimmed, 0, 0, SRCCOPY);
  488. pData->idxSaturation--;
  489. if (pData->idxSaturation <= 0) // when we hit zero, kill the timer.
  490. {
  491. KillTimer(hwnd, IDT_UPDATE);
  492. fDestroyBitmaps = TRUE;
  493. }
  494. }
  495. }
  496. if (fDestroyBitmaps)
  497. {
  498. if (pData->hdcDimmed)
  499. {
  500. SelectObject(pData->hdcDimmed, pData->hbmOldDimmed);
  501. DeleteDC(pData->hdcDimmed);
  502. pData->hdcDimmed = NULL;
  503. }
  504. if (pData->hbmDimmed)
  505. {
  506. DeleteObject(pData->hbmDimmed);
  507. pData->hbmDimmed = NULL;
  508. }
  509. if (pData->hdcTemp)
  510. {
  511. SelectObject(pData->hdcTemp, pData->hbmOldTemp);
  512. DeleteDC(pData->hdcTemp);
  513. pData->hdcTemp = NULL;
  514. }
  515. if (pData->hbmTemp)
  516. {
  517. DeleteObject(pData->hbmTemp);
  518. pData->hbmTemp = NULL;
  519. }
  520. }
  521. }
  522. break;
  523. case WM_WINDOWPOSCHANGING:
  524. {
  525. LPWINDOWPOS pwp = (LPWINDOWPOS) lParam;
  526. pwp->flags |= SWP_NOSIZE | SWP_NOMOVE;
  527. }
  528. break;
  529. case WM_PAINT:
  530. {
  531. HDC hdcPaint;
  532. PAINTSTRUCT ps;
  533. hdcPaint = BeginPaint(hwnd, &ps);
  534. TBOOL(EndPaint(hwnd, &ps));
  535. lResult = 0;
  536. break;
  537. }
  538. default:
  539. lResult = DefWindowProc(hwnd, uMsg, wParam, lParam);
  540. break;
  541. }
  542. return(lResult);
  543. }