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.

804 lines
21 KiB

  1. /******************************************************************************
  2. Source File: deskadp.cpp
  3. Main code for the advanced desktop adapter page
  4. Copyright (c) 1997-1998 by Microsoft Corporation
  5. Change History:
  6. 12-16-97 AndreVa - Created It
  7. ******************************************************************************/
  8. #include "deskadp.h"
  9. #define DECL_CRTFREE
  10. #include <crtfree.h>
  11. #include "shfusion.h"
  12. DWORD ApplyNowThd(LPVOID lpThreadParameter);
  13. //
  14. // The function DevicePropertiesW() is implemented in DevMgr.dll; Since we don't have a devmgr.h, we
  15. // explicitly declare it here.
  16. //
  17. typedef int (WINAPI *DEVPROPERTIESW)(
  18. HWND hwndParent,
  19. LPCTSTR MachineName,
  20. LPCTSTR DeviceID,
  21. BOOL ShowDeviceTree
  22. );
  23. // OLE-Registry magic number
  24. // 42071712-76d4-11d1-8b24-00a0c9068ff3
  25. //
  26. GUID g_CLSID_CplExt = { 0x42071712, 0x76d4, 0x11d1,
  27. { 0x8b, 0x24, 0x00, 0xa0, 0xc9, 0x06, 0x8f, 0xf3}
  28. };
  29. DESK_EXTENSION_INTERFACE DeskInterface;
  30. static const DWORD sc_AdapterHelpIds[] =
  31. {
  32. ID_ADP_ADPINFGRP, IDH_DISPLAY_SETTINGS_ADVANCED_ADAPTER_ADAPTER_INFO,
  33. ID_ADP_AI1, IDH_DISPLAY_SETTINGS_ADVANCED_ADAPTER_ADAPTER_INFO,
  34. ID_ADP_AI2, IDH_DISPLAY_SETTINGS_ADVANCED_ADAPTER_ADAPTER_INFO,
  35. ID_ADP_AI3, IDH_DISPLAY_SETTINGS_ADVANCED_ADAPTER_ADAPTER_INFO,
  36. ID_ADP_AI4, IDH_DISPLAY_SETTINGS_ADVANCED_ADAPTER_ADAPTER_INFO,
  37. ID_ADP_AI5, IDH_DISPLAY_SETTINGS_ADVANCED_ADAPTER_ADAPTER_INFO,
  38. ID_ADP_CHIP, IDH_DISPLAY_SETTINGS_ADVANCED_ADAPTER_ADAPTER_INFO,
  39. ID_ADP_DAC, IDH_DISPLAY_SETTINGS_ADVANCED_ADAPTER_ADAPTER_INFO,
  40. ID_ADP_MEM, IDH_DISPLAY_SETTINGS_ADVANCED_ADAPTER_ADAPTER_INFO,
  41. ID_ADP_ADP_STRING, IDH_DISPLAY_SETTINGS_ADVANCED_ADAPTER_ADAPTER_INFO,
  42. ID_ADP_BIOS_INFO, IDH_DISPLAY_SETTINGS_ADVANCED_ADAPTER_ADAPTER_INFO,
  43. ID_ADP_ADPGRP, IDH_DISPLAY_SETTINGS_ADVANCED_ADAPTER_ADAPTER_TYPE,
  44. IDI_ADAPTER, IDH_DISPLAY_SETTINGS_ADVANCED_ADAPTER_ADAPTER_TYPE,
  45. ID_ADP_ADAPTOR, IDH_DISPLAY_SETTINGS_ADVANCED_ADAPTER_ADAPTER_TYPE,
  46. IDC_LIST_ALL, IDH_DISPLAY_SETTINGS_ADVANCED_ADAPTER_LIST_MODES,
  47. IDC_PROPERTIES, IDH_DISPLAY_SETTINGS_ADVANCED_ADAPTER_PROPERTIES,
  48. 0, 0
  49. };
  50. static const DWORD sc_ListAllHelpIds[] =
  51. {
  52. ID_MODE_LIST, IDH_DISPLAY_SETTINGS_ADVANCED_ADAPTER_LISTMODE_DIALOGBOX,
  53. ID_MODE_LISTGRP, IDH_DISPLAY_SETTINGS_ADVANCED_ADAPTER_LISTMODE_DIALOGBOX,
  54. 0, 0
  55. };
  56. ///////////////////////////////////////////////////////////////////////////////
  57. //
  58. // Messagebox wrapper
  59. //
  60. ///////////////////////////////////////////////////////////////////////////////
  61. int
  62. FmtMessageBox(
  63. HWND hwnd,
  64. UINT fuStyle,
  65. DWORD dwTitleID,
  66. DWORD dwTextID)
  67. {
  68. TCHAR Title[256];
  69. TCHAR Text[1500];
  70. LoadString(g_hInst, dwTextID, Text, ARRAYSIZE(Text));
  71. LoadString(g_hInst, dwTitleID, Title, ARRAYSIZE(Title));
  72. return (MessageBox(hwnd, Text, Title, fuStyle));
  73. }
  74. ///////////////////////////////////////////////////////////////////////////////
  75. //
  76. // Main dialog box Windows Proc
  77. //
  78. ///////////////////////////////////////////////////////////////////////////////
  79. INT_PTR
  80. CALLBACK
  81. ListAllModesProc(
  82. HWND hDlg,
  83. UINT uMessage,
  84. WPARAM wParam,
  85. LPARAM lParam
  86. )
  87. {
  88. LPDEVMODEW lpdm, lpdmCur;
  89. HWND hList;
  90. DWORD i;
  91. LRESULT item;
  92. switch (uMessage)
  93. {
  94. case WM_INITDIALOG:
  95. //
  96. // Save the lParam - we will store the new mode here
  97. //
  98. SetWindowLongPtr(hDlg, DWLP_USER, lParam);
  99. lpdmCur = *((LPDEVMODEW *)lParam);
  100. Assert (lpdmCur != NULL);
  101. //
  102. // Build the list of modes to display
  103. //
  104. i = 0;
  105. hList = GetDlgItem(hDlg, ID_MODE_LIST);
  106. while (lpdm = DeskInterface.lpfnEnumAllModes(DeskInterface.pContext, i))
  107. {
  108. TCHAR achFreData[50];
  109. TCHAR achFre[50];
  110. TCHAR achStr[80];
  111. TCHAR achText[120];
  112. DWORD idColor;
  113. DWORD idFreq;
  114. //
  115. // convert bit count to number of colors and make it a string
  116. //
  117. switch (lpdm->dmBitsPerPel)
  118. {
  119. case 32: idColor = IDS_MODE_TRUECOLOR32; break;
  120. case 24: idColor = IDS_MODE_TRUECOLOR24; break;
  121. case 16: idColor = IDS_MODE_16BIT_COLOR; break;
  122. case 15: idColor = IDS_MODE_15BIT_COLOR; break;
  123. case 8: idColor = IDS_MODE_8BIT_COLOR; break;
  124. case 4: idColor = IDS_MODE_4BIT_COLOR; break;
  125. default:
  126. FmtMessageBox(hDlg,
  127. MB_OK | MB_ICONINFORMATION,
  128. IDS_BAD_COLOR,
  129. IDS_BAD_COLOR);
  130. EndDialog(hDlg, -1);
  131. break;
  132. }
  133. if (lpdm->dmDisplayFrequency == 0)
  134. {
  135. FmtMessageBox(hDlg,
  136. MB_OK | MB_ICONINFORMATION,
  137. IDS_BAD_REFRESH,
  138. IDS_BAD_REFRESH);
  139. EndDialog(hDlg, -1);
  140. break;
  141. }
  142. else if (lpdm->dmDisplayFrequency == 1)
  143. {
  144. LoadString(g_hInst, IDS_MODE_REFRESH_DEF, achFre, ARRAYSIZE(achFre));
  145. }
  146. else
  147. {
  148. if (lpdm->dmDisplayFrequency <= 50)
  149. idFreq = IDS_MODE_REFRESH_INT;
  150. else
  151. idFreq = IDS_MODE_REFRESH_HZ;
  152. LoadString(g_hInst, idFreq, achFreData, ARRAYSIZE(achFreData));
  153. wsprintf(achFre, achFreData, lpdm->dmDisplayFrequency);
  154. }
  155. LoadString(g_hInst, idColor, achStr, ARRAYSIZE(achStr));
  156. wsprintf(achText, achStr, lpdm->dmPelsWidth, lpdm->dmPelsHeight, achFre);
  157. item = ListBox_AddString(hList, achText);
  158. if (lpdm == lpdmCur)
  159. ListBox_SetCurSel(hList, item);
  160. ListBox_SetItemData(hList, item, lpdm);
  161. i++;
  162. }
  163. //
  164. // If no modes are available, put up a popup and exit.
  165. //
  166. if (i == 0)
  167. {
  168. EndDialog(hDlg, -1);
  169. }
  170. break;
  171. case WM_COMMAND:
  172. switch (LOWORD(wParam))
  173. {
  174. case ID_MODE_LIST:
  175. if (HIWORD(wParam) != LBN_DBLCLK)
  176. {
  177. return FALSE;
  178. }
  179. //
  180. // fall through, as DBLCLK means select.
  181. //
  182. case IDOK:
  183. //
  184. // Save the mode back
  185. //
  186. item = SendDlgItemMessage(hDlg, ID_MODE_LIST, LB_GETCURSEL, 0, 0);
  187. if ((item != LB_ERR) &&
  188. (lpdm = (LPDEVMODEW) SendDlgItemMessage(hDlg, ID_MODE_LIST, LB_GETITEMDATA, item, 0)))
  189. {
  190. *((LPDEVMODEW *)GetWindowLongPtr(hDlg, DWLP_USER)) = lpdm;
  191. EndDialog(hDlg, TRUE);
  192. break;
  193. }
  194. //
  195. // fall through
  196. //
  197. case IDCANCEL:
  198. EndDialog(hDlg, FALSE);
  199. break;
  200. default:
  201. return FALSE;
  202. }
  203. break;
  204. case WM_HELP:
  205. WinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle,
  206. TEXT("display.hlp"),
  207. HELP_WM_HELP,
  208. (DWORD_PTR)(LPTSTR)sc_ListAllHelpIds);
  209. break;
  210. case WM_CONTEXTMENU:
  211. WinHelp((HWND)wParam,
  212. TEXT("display.hlp"),
  213. HELP_CONTEXTMENU,
  214. (DWORD_PTR)(LPTSTR)sc_ListAllHelpIds);
  215. break;
  216. default:
  217. return FALSE;
  218. }
  219. return TRUE;
  220. }
  221. void Adaptor_OnApply(HWND hDlg)
  222. {
  223. HINSTANCE hInst;
  224. LPDISPLAY_SAVE_SETTINGS lpfnDisplaySaveSettings = NULL;
  225. long lRet = PSNRET_INVALID_NOCHANGEPAGE;
  226. hInst = LoadLibrary(TEXT("desk.cpl"));
  227. if (hInst)
  228. {
  229. lpfnDisplaySaveSettings = (LPDISPLAY_SAVE_SETTINGS)
  230. GetProcAddress(hInst, "DisplaySaveSettings");
  231. if (lpfnDisplaySaveSettings)
  232. {
  233. LONG lSave = lpfnDisplaySaveSettings(DeskInterface.pContext, hDlg);
  234. if (lSave == DISP_CHANGE_SUCCESSFUL)
  235. {
  236. //
  237. // Save the current mode - to restore it in case the user cancels the p. sheet
  238. //
  239. LPDEVMODEW lpdmOnCancel = DeskInterface.lpfnGetSelectedMode(DeskInterface.pContext);
  240. SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)lpdmOnCancel);
  241. lRet = PSNRET_NOERROR;
  242. }
  243. else if (lSave == DISP_CHANGE_RESTART)
  244. {
  245. //
  246. // User wants to reboot system.
  247. //
  248. PropSheet_RestartWindows(GetParent(hDlg));
  249. lRet = PSNRET_NOERROR;
  250. }
  251. }
  252. FreeLibrary(hInst);
  253. }
  254. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, lRet);
  255. }
  256. void Adaptor_OnInitDialog(HWND hDlg)
  257. {
  258. Assert (DeskInterface.cbSize == 0);
  259. //
  260. // Get the CPL extension interfaces from IDataObject.
  261. //
  262. FORMATETC fmte = {(CLIPFORMAT)RegisterClipboardFormat(DESKCPLEXT_INTERFACE),
  263. (DVTARGETDEVICE FAR *) NULL,
  264. DVASPECT_CONTENT,
  265. -1,
  266. TYMED_HGLOBAL};
  267. STGMEDIUM stgm;
  268. HRESULT hres = g_lpdoTarget->GetData(&fmte, &stgm);
  269. if (SUCCEEDED(hres) && stgm.hGlobal)
  270. {
  271. //
  272. // The storage now contains Display device path (\\.\DisplayX) in UNICODE.
  273. //
  274. PDESK_EXTENSION_INTERFACE pInterface =
  275. (PDESK_EXTENSION_INTERFACE) GlobalLock(stgm.hGlobal);
  276. if (pInterface != NULL)
  277. {
  278. RtlCopyMemory(&DeskInterface,
  279. pInterface,
  280. min(pInterface->cbSize,
  281. sizeof(DESK_EXTENSION_INTERFACE)));
  282. GlobalUnlock(stgm.hGlobal);
  283. SendDlgItemMessageW(hDlg, ID_ADP_CHIP, WM_SETTEXT, 0, (LPARAM)&(DeskInterface.Info.ChipType[0]));
  284. SendDlgItemMessageW(hDlg, ID_ADP_DAC, WM_SETTEXT, 0, (LPARAM)&(DeskInterface.Info.DACType[0]));
  285. SendDlgItemMessageW(hDlg, ID_ADP_MEM, WM_SETTEXT, 0, (LPARAM)&(DeskInterface.Info.MemSize[0]));
  286. SendDlgItemMessageW(hDlg, ID_ADP_ADP_STRING, WM_SETTEXT, 0, (LPARAM)&(DeskInterface.Info.AdapString[0]));
  287. SendDlgItemMessageW(hDlg, ID_ADP_BIOS_INFO, WM_SETTEXT, 0, (LPARAM)&(DeskInterface.Info.BiosString[0]));
  288. //
  289. // Save the initial selected mode - to restore it in case the user cancels the p. sheet
  290. //
  291. LPDEVMODEW lpdmOnCancel = DeskInterface.lpfnGetSelectedMode(DeskInterface.pContext);
  292. SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)lpdmOnCancel);
  293. }
  294. ReleaseStgMedium(&stgm);
  295. }
  296. //
  297. // Get device description from IDataObject.
  298. //
  299. LPWSTR pDeviceDescription;
  300. FORMATETC fmte2 = {(CLIPFORMAT)RegisterClipboardFormat(DESKCPLEXT_DISPLAY_NAME),
  301. (DVTARGETDEVICE FAR *) NULL,
  302. DVASPECT_CONTENT,
  303. -1,
  304. TYMED_HGLOBAL};
  305. hres = g_lpdoTarget->GetData(&fmte2, &stgm);
  306. if (SUCCEEDED(hres) && stgm.hGlobal)
  307. {
  308. pDeviceDescription = (LPWSTR) GlobalLock(stgm.hGlobal);
  309. SendDlgItemMessageW(hDlg, ID_ADP_ADAPTOR, WM_SETTEXT, 0, (LPARAM)pDeviceDescription);
  310. GlobalUnlock(stgm.hGlobal);
  311. ReleaseStgMedium(&stgm);
  312. }
  313. //
  314. // Enable/disable the properties button
  315. //
  316. BOOL bEnable = FALSE;
  317. LPWSTR pwDeviceID = NULL;
  318. FORMATETC fmte3 = {(CLIPFORMAT)RegisterClipboardFormat(DESKCPLEXT_DISPLAY_ID),
  319. (DVTARGETDEVICE FAR *)NULL,
  320. DVASPECT_CONTENT,
  321. -1,
  322. TYMED_HGLOBAL};
  323. hres = g_lpdoTarget->GetData(&fmte3, &stgm);
  324. if (SUCCEEDED(hres) && stgm.hGlobal)
  325. {
  326. pwDeviceID = (LPWSTR)GlobalLock(stgm.hGlobal);
  327. bEnable = ((pwDeviceID != NULL) && (*pwDeviceID != L'\0'));
  328. GlobalUnlock(stgm.hGlobal);
  329. ReleaseStgMedium(&stgm);
  330. }
  331. HWND hPropButton = GetDlgItem(hDlg, IDC_PROPERTIES);
  332. if (hPropButton != NULL)
  333. EnableWindow(hPropButton, bEnable);
  334. }
  335. void Adaptor_OnCancel(HWND hDlg)
  336. {
  337. //
  338. // Restore initial mode
  339. //
  340. LPDEVMODEW lpdmOnCancel = (LPDEVMODEW) GetWindowLongPtr(hDlg, DWLP_USER);
  341. DeskInterface.lpfnSetSelectedMode(DeskInterface.pContext, lpdmOnCancel);
  342. }
  343. void Adaptor_OnListAllModes(HWND hDlg)
  344. {
  345. LPDEVMODEW lpdmBefore, lpdmAfter;
  346. lpdmAfter = lpdmBefore = DeskInterface.lpfnGetSelectedMode(DeskInterface.pContext);
  347. if (DialogBoxParam(g_hInst,
  348. MAKEINTRESOURCE(DLG_SET_MODE_LIST),
  349. hDlg,
  350. ListAllModesProc,
  351. (LPARAM) &lpdmAfter) == 1 &&
  352. lpdmAfter && (lpdmAfter != lpdmBefore))
  353. {
  354. //
  355. // If the user selected a new setting, tell the property sheet
  356. // we have outstanding changes. This will enable the Apply button.
  357. //
  358. PropSheet_Changed(GetParent(hDlg), hDlg);
  359. DeskInterface.lpfnSetSelectedMode(DeskInterface.pContext, lpdmAfter);
  360. }
  361. }
  362. void Adaptor_OnProperties(HWND hDlg)
  363. {
  364. // Invoke the device manager property sheets to show the properties of the
  365. // given hardware.
  366. LPWSTR pwDeviceID;
  367. HRESULT hres;
  368. STGMEDIUM stgm;
  369. FORMATETC fmte2 = {(CLIPFORMAT)RegisterClipboardFormat(DESKCPLEXT_DISPLAY_ID),
  370. (DVTARGETDEVICE FAR *) NULL,
  371. DVASPECT_CONTENT,
  372. -1,
  373. TYMED_HGLOBAL};
  374. hres = g_lpdoTarget->GetData(&fmte2, &stgm);
  375. if (SUCCEEDED(hres) && stgm.hGlobal)
  376. {
  377. pwDeviceID = (LPWSTR) GlobalLock(stgm.hGlobal);
  378. HINSTANCE hinstDevMgr = LoadLibrary(TEXT("DEVMGR.DLL"));
  379. if (hinstDevMgr)
  380. {
  381. DEVPROPERTIESW pfnDevPropW =
  382. (DEVPROPERTIESW)GetProcAddress(hinstDevMgr, "DevicePropertiesW");
  383. if (pfnDevPropW)
  384. {
  385. //Display the property sheets for this device.
  386. (*pfnDevPropW)(hDlg, NULL, pwDeviceID, FALSE);
  387. }
  388. FreeLibrary(hinstDevMgr);
  389. }
  390. GlobalUnlock(stgm.hGlobal);
  391. ReleaseStgMedium(&stgm);
  392. }
  393. }
  394. #if TEST_MODE
  395. void Adaptor_OnTestMode(HWND hDlg)
  396. {
  397. //
  398. // Warn the user
  399. //
  400. if (FmtMessageBox(hDlg,
  401. MB_OKCANCEL | MB_ICONINFORMATION,
  402. IDS_TEST_MODE,
  403. IDS_TEST_WARNING) == IDCANCEL) {
  404. return;
  405. }
  406. //
  407. // The user wants to test his new selection. We need to
  408. // create a new desktop with the selected resolution, switch
  409. // to it, and put up a dialog box so he can see if it works with
  410. // his hardware.
  411. //
  412. // All this needs to be done in a separate thread since you can't
  413. // switch a thread with open windows to a new desktop.
  414. //
  415. //
  416. // Create the test thread. It will do the work of creating the desktop
  417. //
  418. //
  419. // Get device name from IDataObject.
  420. //
  421. LPWSTR pDeviceName = NULL;
  422. FORMATETC fmte = {(CLIPFORMAT)RegisterClipboardFormat(DESKCPLEXT_DISPLAY_DEVICE),
  423. (DVTARGETDEVICE FAR *) NULL,
  424. DVASPECT_CONTENT,
  425. -1,
  426. TYMED_HGLOBAL};
  427. STGMEDIUM stgm;
  428. HRESULT hres = g_lpdoTarget->GetData(&fmte, &stgm);
  429. if (SUCCEEDED(hres) && stgm.hGlobal) {
  430. //
  431. // The storage now contains Display device path (\\.\DisplayX) in UNICODE.
  432. //
  433. pDeviceName = (LPWSTR) GlobalLock(stgm.hGlobal);
  434. }
  435. desktopParam.lpdevmode = DeskInterface.lpfnGetSelectedMode(DeskInterface.pContext);
  436. desktopParam.pwszDevice = pDeviceName;
  437. hThread = CreateThread(NULL,
  438. 4096,
  439. ApplyNowThd,
  440. (LPVOID) (&desktopParam),
  441. SYNCHRONIZE | THREAD_QUERY_INFORMATION,
  442. &idThread);
  443. WaitForSingleObject(hThread, INFINITE);
  444. GetExitCodeThread(hThread, &bTest);
  445. //
  446. // clean up memory
  447. //
  448. if (pDeviceName)
  449. {
  450. GlobalUnlock(stgm.hGlobal);
  451. ReleaseStgMedium(&stgm);
  452. }
  453. CloseHandle(hThread);
  454. if (!bTest)
  455. {
  456. FmtMessageBox(hDlg,
  457. MB_ICONEXCLAMATION | MB_OK,
  458. IDS_TEST_MODE,
  459. IDS_TEST_FAILED);
  460. }
  461. SetForegroundWindow(hDlg);
  462. }
  463. #endif
  464. //---------------------------------------------------------------------------
  465. //
  466. // PropertySheeDlgProc()
  467. //
  468. // The dialog procedure for the "Adapter" property sheet page.
  469. //
  470. //---------------------------------------------------------------------------
  471. INT_PTR
  472. CALLBACK
  473. PropertySheeDlgProc(
  474. HWND hDlg,
  475. UINT uMessage,
  476. WPARAM wParam,
  477. LPARAM lParam
  478. )
  479. {
  480. switch (uMessage)
  481. {
  482. case WM_INITDIALOG:
  483. RtlZeroMemory(&DeskInterface, sizeof(DESK_EXTENSION_INTERFACE));
  484. if (!g_lpdoTarget)
  485. {
  486. return FALSE;
  487. }
  488. else
  489. {
  490. Adaptor_OnInitDialog(hDlg);
  491. }
  492. break;
  493. case WM_COMMAND:
  494. if (DeskInterface.cbSize > 0)
  495. {
  496. switch( LOWORD(wParam) )
  497. {
  498. #if TEST_MODE
  499. case IDC_TEST_MODE:
  500. Adaptor_OnTestMode(hDlg);
  501. break;
  502. #endif
  503. case IDC_LIST_ALL:
  504. Adaptor_OnListAllModes(hDlg);
  505. break;
  506. case IDC_PROPERTIES:
  507. Adaptor_OnProperties(hDlg);
  508. break;
  509. default:
  510. return FALSE;
  511. }
  512. }
  513. break;
  514. case WM_NOTIFY:
  515. if (DeskInterface.cbSize > 0)
  516. {
  517. switch (((NMHDR FAR *)lParam)->code)
  518. {
  519. case PSN_APPLY:
  520. Adaptor_OnApply(hDlg);
  521. break;
  522. case PSN_RESET:
  523. Adaptor_OnCancel(hDlg);
  524. break;
  525. default:
  526. return FALSE;
  527. }
  528. }
  529. break;
  530. case WM_HELP:
  531. WinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle,
  532. TEXT("display.hlp"),
  533. HELP_WM_HELP,
  534. (DWORD_PTR)(LPTSTR)sc_AdapterHelpIds);
  535. break;
  536. case WM_CONTEXTMENU:
  537. WinHelp((HWND)wParam,
  538. TEXT("display.hlp"),
  539. HELP_CONTEXTMENU,
  540. (DWORD_PTR)(LPTSTR)sc_AdapterHelpIds);
  541. break;
  542. default:
  543. return FALSE;
  544. }
  545. return TRUE;
  546. }
  547. //
  548. // This functionality has been deprectaed by the new style of testing a video
  549. // settings (apply the changes, bring up a countdown dialog to confirm). If
  550. // need to dipslay a bmp still exists, import TestDisplaySettings from desk.cpl
  551. // via LoadLibrary and GetProcAddress...
  552. //
  553. #if TEST_MODE
  554. /****************************************************************************\
  555. *
  556. * DWORD WINAPI ApplyNowThd(LPVOID lpThreadParameter)
  557. *
  558. * Thread that gets started when the use hits the Apply Now button.
  559. * This thread creates a new desktop with the new video mode, switches to it
  560. * and then displays a dialog box asking if the display looks OK. If the
  561. * user does not respond within the time limit, then 'NO' is assumed to be
  562. * the answer.
  563. *
  564. \****************************************************************************/
  565. DWORD ApplyNowThd(LPVOID lpThreadParameter)
  566. {
  567. PNEW_DESKTOP_PARAM lpDesktopParam = (PNEW_DESKTOP_PARAM) lpThreadParameter;
  568. HDESK hdsk = NULL;
  569. HDESK hdskDefault = NULL;
  570. BOOL bTest = FALSE;
  571. HDC hdc;
  572. //
  573. // HACK:
  574. // We need to make a USER call before calling the desktop stuff so we can
  575. // sure our threads internal data structure are associated with the default
  576. // desktop.
  577. // Otherwise USER has problems closing the desktop with our thread on it.
  578. //
  579. GetSystemMetrics(SM_CXSCREEN);
  580. //
  581. // Create the desktop
  582. //
  583. hdskDefault = GetThreadDesktop(GetCurrentThreadId());
  584. if (hdskDefault != NULL) {
  585. hdsk = CreateDesktopW(L"Display.Cpl Desktop",
  586. lpDesktopParam->pwszDevice,
  587. lpDesktopParam->lpdevmode,
  588. 0,
  589. MAXIMUM_ALLOWED,
  590. NULL);
  591. if (hdsk != NULL) {
  592. //
  593. // use the desktop for this thread
  594. //
  595. if (SetThreadDesktop(hdsk)) {
  596. hdc = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
  597. if (hdc) {
  598. DrawBmp(hdc);
  599. DeleteDC(hdc);
  600. bTest = TRUE;
  601. }
  602. //
  603. // Sleep for some seconds so you have time to look at the screen.
  604. //
  605. Sleep(7000);
  606. }
  607. }
  608. //
  609. // Reset the thread to the right desktop
  610. //
  611. SetThreadDesktop(hdskDefault);
  612. SwitchDesktop(hdskDefault);
  613. //
  614. // Can only close the desktop after we have switched to the new one.
  615. //
  616. if (hdsk != NULL)
  617. CloseDesktop(hdsk);
  618. }
  619. ExitThread((DWORD) bTest);
  620. return 0;
  621. }
  622. #endif