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.

876 lines
25 KiB

  1. /******************************************************************************
  2. Source File: deskmon.cpp
  3. Main code for the advanced desktop Monitor page
  4. Copyright (c) 1997-1998 by Microsoft Corporation
  5. Change History:
  6. 12-16-97 AndreVa - Created It
  7. ******************************************************************************/
  8. #include "deskmon.h"
  9. #define DECL_CRTFREE
  10. #include <crtfree.h>
  11. //
  12. // The function DeviceProperties() is implemented in DevMgr.dll; Since we don't have a devmgr.h, we
  13. // explicitly declare it here.
  14. //
  15. typedef int (WINAPI *DEVPROPERTIES)(
  16. HWND hwndParent,
  17. LPCTSTR MachineName,
  18. LPCTSTR DeviceID,
  19. BOOL ShowDeviceTree
  20. );
  21. // OLE-Registry magic number
  22. // 42071713-76d4-11d1-8b24-00a0c9068ff3
  23. //
  24. GUID g_CLSID_CplExt = { 0x42071713, 0x76d4, 0x11d1,
  25. { 0x8b, 0x24, 0x00, 0xa0, 0xc9, 0x06, 0x8f, 0xf3}
  26. };
  27. DESK_EXTENSION_INTERFACE DeskInterface;
  28. static const DWORD sc_MonitorHelpIds[] =
  29. {
  30. IDC_MONITOR_GRP, IDH_DISPLAY_SETTINGS_ADVANCED_MONITOR_TYPE,
  31. IDI_MONITOR, IDH_DISPLAY_SETTINGS_ADVANCED_MONITOR_TYPE,
  32. IDC_MONITORDESC, IDH_DISPLAY_SETTINGS_ADVANCED_MONITOR_TYPE,
  33. IDC_MONITORS_LIST, IDH_DISPLAY_SETTINGS_ADVANCED_MONITOR_MONITORTYPE_LISTBOX,
  34. IDC_PROPERTIES, IDH_DISPLAY_SETTINGS_ADVANCED_MONITOR_PROPERTIES,
  35. IDC_MONSET_GRP, IDH_NOHELP,
  36. IDC_MONSET_FREQSTR, IDH_DISPLAY_SETTINGS_ADVANCED_MONITOR_REFRESH,
  37. IDC_MONSET_FREQ, IDH_DISPLAY_SETTINGS_ADVANCED_MONITOR_REFRESH,
  38. IDC_MONSET_PRUNNING_MODE, IDH_DISPLAY_SETTINGS_ADVANCED_MONITOR_HIDEMODE_CHECKBOX,
  39. IDC_MONSET_PRUNNING_MODE_DESC, IDH_DISPLAY_SETTINGS_ADVANCED_MONITOR_HIDEMODE_CHECKBOX,
  40. 0, 0
  41. };
  42. ///////////////////////////////////////////////////////////////////////////////
  43. //
  44. // Messagebox wrapper
  45. //
  46. ///////////////////////////////////////////////////////////////////////////////
  47. int
  48. FmtMessageBox(
  49. HWND hwnd,
  50. UINT fuStyle,
  51. DWORD dwTitleID,
  52. DWORD dwTextID)
  53. {
  54. TCHAR Title[256];
  55. TCHAR Text[1700];
  56. LoadString(g_hInst, dwTextID, Text, ARRAYSIZE(Text));
  57. LoadString(g_hInst, dwTitleID, Title, ARRAYSIZE(Title));
  58. return (MessageBox(hwnd, Text, Title, fuStyle));
  59. }
  60. // Constructors / destructor
  61. CMonitorPage::CMonitorPage(HWND hDlg)
  62. : m_hDlg(hDlg)
  63. , m_lpdmPrevious(NULL)
  64. , m_bCanBePruned(FALSE)
  65. , m_bIsPruningReadOnly(TRUE)
  66. , m_bIsPruningOn(FALSE)
  67. , m_cMonitors(0)
  68. , m_hMonitorsList(NULL)
  69. , m_lpdmOnCancel(NULL)
  70. , m_bOnCancelIsPruningOn(FALSE)
  71. {
  72. }
  73. void CMonitorPage::OnApply()
  74. {
  75. long lRet = PSNRET_INVALID_NOCHANGEPAGE;
  76. HINSTANCE hInst;
  77. LPDISPLAY_SAVE_SETTINGS lpfnDisplaySaveSettings = NULL;
  78. hInst = LoadLibrary(TEXT("desk.cpl"));
  79. if (hInst)
  80. {
  81. lpfnDisplaySaveSettings = (LPDISPLAY_SAVE_SETTINGS)
  82. GetProcAddress(hInst, "DisplaySaveSettings");
  83. if (lpfnDisplaySaveSettings)
  84. {
  85. long lSave = lpfnDisplaySaveSettings(DeskInterface.pContext, m_hDlg);
  86. LPDEVMODEW lpdmCurrent = DeskInterface.lpfnGetSelectedMode(DeskInterface.pContext);
  87. if (lSave == DISP_CHANGE_SUCCESSFUL)
  88. {
  89. //
  90. // Save the current mode - to restore it in case the user cancels the p. sheet
  91. //
  92. m_lpdmOnCancel = m_lpdmPrevious = lpdmCurrent;
  93. m_bOnCancelIsPruningOn = m_bIsPruningOn;
  94. lRet = PSNRET_NOERROR;
  95. }
  96. else if (lSave == DISP_CHANGE_RESTART)
  97. {
  98. //
  99. // User wants to reboot system.
  100. //
  101. PropSheet_RestartWindows(GetParent(m_hDlg));
  102. lRet = PSNRET_NOERROR;
  103. }
  104. else
  105. {
  106. //
  107. // Keep the apply button active
  108. //
  109. lRet = PSNRET_INVALID_NOCHANGEPAGE;
  110. RefreshFrequenciesList();
  111. BOOL bCanBePruned, bIsPruningReadOnly, bIsPruningOn;
  112. DeskInterface.lpfnGetPruningMode(DeskInterface.pContext,
  113. &bCanBePruned,
  114. &bIsPruningReadOnly,
  115. &bIsPruningOn);
  116. if(m_bIsPruningOn != bIsPruningOn)
  117. InitPruningMode();
  118. }
  119. }
  120. FreeLibrary(hInst);
  121. }
  122. SetWindowLongPtr(m_hDlg, DWLP_MSGRESULT, lRet);
  123. }
  124. void CMonitorPage::OnCancel()
  125. {
  126. if (m_bCanBePruned && !m_bIsPruningReadOnly &&
  127. ((m_bOnCancelIsPruningOn != 0) != (m_bIsPruningOn != 0)))
  128. DeskInterface.lpfnSetPruningMode(DeskInterface.pContext, m_bOnCancelIsPruningOn);
  129. DeskInterface.lpfnSetSelectedMode(DeskInterface.pContext, m_lpdmOnCancel);
  130. };
  131. void CMonitorPage::OnInitDialog()
  132. {
  133. m_hMonitorsList = GetDlgItem(m_hDlg, IDC_MONITORS_LIST);
  134. HWND hSingleMonitor = GetDlgItem(m_hDlg, IDC_MONITORDESC);
  135. ListBox_ResetContent(m_hMonitorsList);
  136. //
  137. // Get the CPL extension interfaces from IDataObject.
  138. //
  139. STGMEDIUM stgmExt;
  140. FORMATETC fmteExt = {(CLIPFORMAT)RegisterClipboardFormat(DESKCPLEXT_INTERFACE),
  141. (DVTARGETDEVICE FAR *) NULL,
  142. DVASPECT_CONTENT,
  143. -1,
  144. TYMED_HGLOBAL};
  145. HRESULT hres = g_lpdoTarget->GetData(&fmteExt, &stgmExt);
  146. if (SUCCEEDED(hres) && stgmExt.hGlobal)
  147. {
  148. //
  149. // The storage now contains Display device path (\\.\DisplayX) in UNICODE.
  150. //
  151. PDESK_EXTENSION_INTERFACE pInterface =
  152. (PDESK_EXTENSION_INTERFACE) GlobalLock(stgmExt.hGlobal);
  153. RtlCopyMemory(&DeskInterface,
  154. pInterface,
  155. min(pInterface->cbSize,
  156. sizeof(DESK_EXTENSION_INTERFACE)));
  157. GlobalUnlock(stgmExt.hGlobal);
  158. ReleaseStgMedium(&stgmExt);
  159. }
  160. //
  161. // Get the adapter devnode.
  162. // The adapter is the parent of all monitors in the device tree.
  163. //
  164. DEVINST devInstAdapter;
  165. BOOL bDevInstAdapter = FALSE;
  166. STGMEDIUM stgmAdpId;
  167. FORMATETC fmteAdpId = {(CLIPFORMAT)RegisterClipboardFormat(DESKCPLEXT_DISPLAY_ID),
  168. (DVTARGETDEVICE FAR *) NULL,
  169. DVASPECT_CONTENT,
  170. -1,
  171. TYMED_HGLOBAL};
  172. hres = g_lpdoTarget->GetData(&fmteAdpId, &stgmAdpId);
  173. if(SUCCEEDED(hres) && stgmAdpId.hGlobal)
  174. {
  175. LPWSTR pwDeviceID = (LPWSTR) GlobalLock(stgmAdpId.hGlobal);
  176. bDevInstAdapter = (CM_Locate_DevNodeW(&devInstAdapter, pwDeviceID, 0) == CR_SUCCESS);
  177. GlobalUnlock(stgmAdpId.hGlobal);
  178. ReleaseStgMedium(&stgmAdpId);
  179. }
  180. //
  181. // Get the adapter device and enum all monitors
  182. //
  183. STGMEDIUM stgmAdpDev;
  184. FORMATETC fmteAdpDev = {(CLIPFORMAT)RegisterClipboardFormat(DESKCPLEXT_DISPLAY_DEVICE),
  185. (DVTARGETDEVICE FAR *) NULL,
  186. DVASPECT_CONTENT,
  187. -1,
  188. TYMED_HGLOBAL};
  189. hres = g_lpdoTarget->GetData(&fmteAdpDev, &stgmAdpDev);
  190. if (SUCCEEDED(hres) && stgmAdpDev.hGlobal)
  191. {
  192. LPWSTR pwDisplayDevice = (LPWSTR)GlobalLock(stgmAdpDev.hGlobal);
  193. LPTSTR pBuffer = pwDisplayDevice;
  194. if(NULL != pBuffer)
  195. {
  196. DISPLAY_DEVICE ddMon;
  197. BOOL bSuccess = FALSE;
  198. int cMonitors = 0;
  199. do
  200. {
  201. ZeroMemory(&ddMon, sizeof(ddMon));
  202. ddMon.cb = sizeof(ddMon);
  203. bSuccess = EnumDisplayDevices(pBuffer, cMonitors, &ddMon, 0);
  204. if (bSuccess)
  205. {
  206. ++cMonitors;
  207. if (ddMon.StateFlags & DISPLAY_DEVICE_ATTACHED)
  208. {
  209. if(0 == m_cMonitors)
  210. SendDlgItemMessage(m_hDlg, IDC_MONITORDESC, WM_SETTEXT, 0, (LPARAM)ddMon.DeviceString);
  211. int nNewItem = ListBox_AddString(m_hMonitorsList, (LPTSTR)ddMon.DeviceString);
  212. if(nNewItem >= 0)
  213. {
  214. ++m_cMonitors;
  215. ListBox_SetItemData(m_hMonitorsList, nNewItem, NULL);
  216. if(bDevInstAdapter)
  217. SaveMonitorInstancePath(devInstAdapter, ddMon.DeviceID, nNewItem);
  218. }
  219. }
  220. }
  221. }
  222. while (bSuccess);
  223. }
  224. GlobalUnlock(stgmAdpDev.hGlobal);
  225. ReleaseStgMedium(&stgmAdpDev);
  226. }
  227. if(m_cMonitors <= 0)
  228. {
  229. TCHAR szDefaultMonitor[MAX_PATH];
  230. LoadString(g_hInst, IDS_DEFAULT_MONITOR, szDefaultMonitor, ARRAYSIZE(szDefaultMonitor));
  231. SendDlgItemMessage(m_hDlg, IDC_MONITORDESC, WM_SETTEXT, 0, (LPARAM)szDefaultMonitor);
  232. EnableWindow(GetDlgItem(m_hDlg, IDC_PROPERTIES), FALSE);
  233. }
  234. else if(m_cMonitors == 1)
  235. {
  236. BOOL bEnable = ((ListBox_GetCount(m_hMonitorsList) >= 1) &&
  237. (NULL != (LPTSTR)ListBox_GetItemData(m_hMonitorsList, 0)));
  238. EnableWindow(GetDlgItem(m_hDlg, IDC_PROPERTIES), bEnable);
  239. }
  240. else
  241. {
  242. ListBox_SetCurSel(m_hMonitorsList, 0);
  243. OnSelMonitorChanged();
  244. }
  245. ShowWindow(((m_cMonitors <= 1) ? m_hMonitorsList : hSingleMonitor), SW_HIDE);
  246. //
  247. // Init the pruning mode check box
  248. //
  249. InitPruningMode();
  250. m_bOnCancelIsPruningOn = m_bIsPruningOn;
  251. //
  252. // Save the current mode - in case the user cancels the p. sheet
  253. //
  254. m_lpdmOnCancel = DeskInterface.lpfnGetSelectedMode(DeskInterface.pContext);
  255. }
  256. void CMonitorPage::OnDestroy()
  257. {
  258. int cMonitors = ListBox_GetCount(m_hMonitorsList);
  259. for(int nMonitor = 0; nMonitor < cMonitors; ++nMonitor)
  260. {
  261. LPTSTR pMonitorInstancePath = (LPTSTR)ListBox_GetItemData(m_hMonitorsList, nMonitor);
  262. if(NULL != pMonitorInstancePath)
  263. LocalFree(pMonitorInstancePath);
  264. }
  265. }
  266. void CMonitorPage::SaveMonitorInstancePath(DEVINST devInstAdapter, LPCTSTR pMonitorID, int nNewItem)
  267. {
  268. DEVINST devInstChild, devInstPrevChild;
  269. TCHAR szBuff[256]; // buffer used to concatenate: HARDWAREID, "\" and DRIVER
  270. // this is what EnumDisplayDevice returns in DeviceID in case of a monitor
  271. ULONG lenBuff; // size of the buffer, in bytes
  272. if (CM_Get_Child(&devInstChild, devInstAdapter, 0) != CR_SUCCESS)
  273. return;
  274. do
  275. {
  276. devInstPrevChild = devInstChild;
  277. //CM_DRP_HARDWAREID
  278. lenBuff = ARRAYSIZE(szBuff) - 2 ; // make sure we have place to append "\"
  279. if (CM_Get_DevNode_Registry_Property(devInstChild,
  280. CM_DRP_HARDWAREID,
  281. NULL,
  282. szBuff,
  283. &lenBuff,
  284. 0) != CR_SUCCESS)
  285. continue;
  286. // "\"
  287. StringCchCat(szBuff, ARRAYSIZE(szBuff), TEXT("\\"));
  288. //CM_DRP_DRIVER
  289. lenBuff = sizeof(szBuff) - lstrlen(szBuff) * sizeof(TCHAR);
  290. if (CM_Get_DevNode_Registry_Property(devInstChild,
  291. CM_DRP_DRIVER,
  292. NULL,
  293. szBuff + lstrlen(szBuff),
  294. &lenBuff,
  295. 0) != CR_SUCCESS)
  296. continue;
  297. if (lstrcmpi(szBuff, pMonitorID) == 0)
  298. {
  299. LPTSTR pMonitorInstancePath = (LPTSTR)LocalAlloc(LPTR, MAX_PATH * sizeof(TCHAR));
  300. if((NULL != pMonitorInstancePath) &&
  301. (CM_Get_Device_ID(devInstChild, pMonitorInstancePath, MAX_PATH, 0) == CR_SUCCESS))
  302. ListBox_SetItemData(m_hMonitorsList, nNewItem, (LPARAM)pMonitorInstancePath);
  303. break;
  304. }
  305. }
  306. while(CM_Get_Sibling(&devInstChild, devInstPrevChild, 0) == CR_SUCCESS);
  307. }
  308. void CMonitorPage::OnSelMonitorChanged()
  309. {
  310. //
  311. // Enable / Disable the Properties button
  312. //
  313. BOOL bEnable = FALSE;
  314. if(ListBox_GetCount(m_hMonitorsList) >= 1)
  315. {
  316. int nCurSel = ListBox_GetCurSel(m_hMonitorsList);
  317. if(nCurSel >= 0)
  318. bEnable = (NULL != (LPTSTR)ListBox_GetItemData(m_hMonitorsList, nCurSel));
  319. }
  320. EnableWindow(GetDlgItem(m_hDlg, IDC_PROPERTIES), bEnable);
  321. }
  322. void CMonitorPage::OnProperties()
  323. {
  324. int nSelMonitor;
  325. if(m_cMonitors <= 0)
  326. nSelMonitor = -1;
  327. else if(m_cMonitors == 1)
  328. nSelMonitor = ((ListBox_GetCount(m_hMonitorsList) >= 1) ? 0 : -1);
  329. else
  330. nSelMonitor = ListBox_GetCurSel(m_hMonitorsList);
  331. if(nSelMonitor < 0)
  332. return;
  333. LPTSTR pMonitorInstancePath = (LPTSTR)ListBox_GetItemData(m_hMonitorsList, nSelMonitor);
  334. if(NULL != pMonitorInstancePath)
  335. {
  336. HINSTANCE hinstDevMgr = LoadLibrary(TEXT("DEVMGR.DLL"));
  337. if (hinstDevMgr)
  338. {
  339. DEVPROPERTIES pfnDevProp = (DEVPROPERTIES)GetProcAddress(hinstDevMgr, "DevicePropertiesW");
  340. if (pfnDevProp)
  341. {
  342. //Display the property sheets for this device.
  343. (*pfnDevProp)(m_hDlg, NULL, pMonitorInstancePath, FALSE);
  344. }
  345. FreeLibrary(hinstDevMgr);
  346. }
  347. }
  348. }
  349. BOOL CMonitorPage::OnSetActive()
  350. {
  351. LPDEVMODEW lpdm;
  352. DWORD item;
  353. LPDEVMODEW lpdmCurrent, lpdmPrevious;
  354. LPDEVMODEW lpdmTmp;
  355. DWORD i = 0;
  356. TCHAR achFre[50];
  357. TCHAR achText[80];
  358. DWORD pos;
  359. HWND hFreq;
  360. InitPruningMode();
  361. //
  362. // Build the list of refresh rates for the currently selected mode.
  363. //
  364. lpdmCurrent = DeskInterface.lpfnGetSelectedMode(DeskInterface.pContext);
  365. hFreq = GetDlgItem(m_hDlg, IDC_MONSET_FREQ);
  366. if (lpdmCurrent == NULL)
  367. return -1;
  368. if (m_lpdmPrevious)
  369. {
  370. if (lpdmCurrent->dmBitsPerPel != m_lpdmPrevious->dmBitsPerPel ||
  371. lpdmCurrent->dmPelsWidth != m_lpdmPrevious->dmPelsWidth ||
  372. lpdmCurrent->dmPelsHeight != m_lpdmPrevious->dmPelsHeight)
  373. {
  374. ComboBox_ResetContent(hFreq);
  375. }
  376. }
  377. m_lpdmPrevious = lpdmCurrent;
  378. while (lpdm = DeskInterface.lpfnEnumAllModes(DeskInterface.pContext, i++)) {
  379. //
  380. // Only show refresh frequencies for current modes.
  381. //
  382. if ((lpdmCurrent->dmBitsPerPel != lpdm->dmBitsPerPel) ||
  383. (lpdmCurrent->dmPelsWidth != lpdm->dmPelsWidth) ||
  384. (lpdmCurrent->dmPelsHeight != lpdm->dmPelsHeight))
  385. continue;
  386. //
  387. // convert bit count to number of colors and make it a string
  388. //
  389. // WARNING should this be 0 ?
  390. if (lpdm->dmDisplayFrequency == 1) {
  391. LoadString(g_hInst, IDS_DEFFREQ, achText, ARRAYSIZE(achText));
  392. }
  393. else {
  394. DWORD idFreq = IDS_FREQ;
  395. if (lpdm->dmDisplayFrequency < 50)
  396. {
  397. idFreq = IDS_INTERLACED;
  398. }
  399. LoadString(g_hInst, idFreq, achFre, ARRAYSIZE(achFre));
  400. StringCchPrintf(achText, ARRAYSIZE(achText), TEXT("%d %s"), lpdm->dmDisplayFrequency, achFre);
  401. }
  402. //
  403. // Insert the string in the right place
  404. //
  405. pos = 0;
  406. while (lpdmTmp = (LPDEVMODEW) ComboBox_GetItemData(hFreq, pos)) {
  407. if ((ULONG_PTR)lpdmTmp != CB_ERR) {
  408. if (lpdmTmp->dmDisplayFrequency == lpdm->dmDisplayFrequency) {
  409. break;
  410. }
  411. if (lpdmTmp->dmDisplayFrequency < lpdm->dmDisplayFrequency) {
  412. pos++;
  413. continue;
  414. }
  415. }
  416. //
  417. // Insert it here
  418. //
  419. item = ComboBox_InsertString(hFreq, pos, achText);
  420. ComboBox_SetItemData(hFreq, item, lpdm);
  421. break;
  422. }
  423. }
  424. //
  425. // Finally, set the right selection
  426. //
  427. pos = 0;
  428. while (lpdmTmp = (LPDEVMODEW) ComboBox_GetItemData(hFreq, pos)) {
  429. if ((ULONG_PTR)lpdmTmp == CB_ERR) {
  430. FmtMessageBox(m_hDlg,
  431. MB_OK | MB_ICONINFORMATION,
  432. IDS_BAD_REFRESH,
  433. IDS_BAD_REFRESH);
  434. return -1;
  435. }
  436. if (lpdmTmp->dmDisplayFrequency == lpdmCurrent->dmDisplayFrequency) {
  437. ComboBox_SetCurSel(hFreq, pos);
  438. break;
  439. }
  440. pos++;
  441. }
  442. return 0;
  443. }
  444. void CMonitorPage::OnFrequencyChanged()
  445. {
  446. DWORD item;
  447. HWND hFreq;
  448. LPDEVMODEW lpdmSelected = NULL, lpdmCurrent = NULL;
  449. //
  450. // Save the mode back
  451. //
  452. hFreq = GetDlgItem(m_hDlg, IDC_MONSET_FREQ);
  453. item = ComboBox_GetCurSel(hFreq);
  454. if (item == LB_ERR)
  455. return;
  456. lpdmCurrent = DeskInterface.lpfnGetSelectedMode(DeskInterface.pContext);
  457. lpdmSelected = (LPDEVMODEW) ComboBox_GetItemData(hFreq, item);
  458. if (lpdmSelected && (lpdmSelected != lpdmCurrent))
  459. DeskInterface.lpfnSetSelectedMode(DeskInterface.pContext, lpdmSelected);
  460. }
  461. void CMonitorPage::OnPruningModeChanged()
  462. {
  463. if (m_bCanBePruned && !m_bIsPruningReadOnly)
  464. {
  465. BOOL bNewIsPruningOn = (BST_UNCHECKED != IsDlgButtonChecked(m_hDlg, IDC_MONSET_PRUNNING_MODE));
  466. if((m_bIsPruningOn != 0) != bNewIsPruningOn)
  467. {
  468. m_bIsPruningOn = bNewIsPruningOn;
  469. DeskInterface.lpfnSetPruningMode(DeskInterface.pContext, m_bIsPruningOn);
  470. RefreshFrequenciesList();
  471. }
  472. }
  473. }
  474. void CMonitorPage::InitPruningMode()
  475. {
  476. m_bCanBePruned = FALSE;
  477. m_bIsPruningReadOnly = TRUE;
  478. m_bIsPruningOn = FALSE;
  479. DeskInterface.lpfnGetPruningMode(DeskInterface.pContext,
  480. &m_bCanBePruned,
  481. &m_bIsPruningReadOnly,
  482. &m_bIsPruningOn);
  483. BOOL bEnable = (m_bCanBePruned && !m_bIsPruningReadOnly);
  484. EnableWindow(GetDlgItem(m_hDlg, IDC_MONSET_PRUNNING_MODE), bEnable);
  485. EnableWindow(GetDlgItem(m_hDlg, IDC_MONSET_PRUNNING_MODE_DESC), bEnable);
  486. BOOL bChecked = (m_bCanBePruned && m_bIsPruningOn);
  487. CheckDlgButton(m_hDlg, IDC_MONSET_PRUNNING_MODE, bChecked);
  488. }
  489. void CMonitorPage::RefreshFrequenciesList()
  490. {
  491. LPDEVMODEW lpdm;
  492. DWORD item;
  493. LPDEVMODEW lpdmCurrent, lpdmPrevious;
  494. LPDEVMODEW lpdmTmp;
  495. DWORD i = 0;
  496. TCHAR achFre[50];
  497. TCHAR achText[80];
  498. DWORD pos;
  499. HWND hFreq;
  500. HWND hwndCurr = GetFocus();
  501. //
  502. // Build the list of refresh rates for the currently selected mode.
  503. //
  504. lpdmCurrent = DeskInterface.lpfnGetSelectedMode(DeskInterface.pContext);
  505. if (lpdmCurrent == NULL)
  506. return;
  507. hFreq = GetDlgItem(m_hDlg, IDC_MONSET_FREQ);
  508. ComboBox_ResetContent(hFreq);
  509. while (lpdm = DeskInterface.lpfnEnumAllModes(DeskInterface.pContext, i++))
  510. {
  511. //
  512. // Only show refresh frequencies for current modes.
  513. //
  514. if ((lpdmCurrent->dmBitsPerPel != lpdm->dmBitsPerPel) ||
  515. (lpdmCurrent->dmPelsWidth != lpdm->dmPelsWidth) ||
  516. (lpdmCurrent->dmPelsHeight != lpdm->dmPelsHeight))
  517. continue;
  518. //
  519. // convert bit count to number of colors and make it a string
  520. //
  521. // WARNING should this be 0 ?
  522. if (lpdm->dmDisplayFrequency == 1)
  523. {
  524. LoadString(g_hInst, IDS_DEFFREQ, achText, ARRAYSIZE(achText));
  525. }
  526. else
  527. {
  528. DWORD idFreq = IDS_FREQ;
  529. if (lpdm->dmDisplayFrequency < 50)
  530. {
  531. idFreq = IDS_INTERLACED;
  532. }
  533. LoadString(g_hInst, idFreq, achFre, ARRAYSIZE(achFre));
  534. StringCchPrintf(achText, ARRAYSIZE(achText), TEXT("%d %s"), lpdm->dmDisplayFrequency, achFre);
  535. }
  536. //
  537. // Insert the string in the right place
  538. //
  539. pos = 0;
  540. while (lpdmTmp = (LPDEVMODEW) ComboBox_GetItemData(hFreq, pos))
  541. {
  542. if ((ULONG_PTR)lpdmTmp != CB_ERR)
  543. {
  544. if (lpdmTmp->dmDisplayFrequency == lpdm->dmDisplayFrequency)
  545. {
  546. break;
  547. }
  548. if (lpdmTmp->dmDisplayFrequency < lpdm->dmDisplayFrequency)
  549. {
  550. pos++;
  551. continue;
  552. }
  553. }
  554. //
  555. // Insert it here
  556. //
  557. item = ComboBox_InsertString(hFreq, pos, achText);
  558. ComboBox_SetItemData(hFreq, item, lpdm);
  559. break;
  560. }
  561. }
  562. //
  563. // Finally, set the right selection
  564. //
  565. pos = 0;
  566. while (lpdmTmp = (LPDEVMODEW) ComboBox_GetItemData(hFreq, pos))
  567. {
  568. if ((ULONG_PTR)lpdmTmp == CB_ERR)
  569. {
  570. FmtMessageBox(m_hDlg,
  571. MB_OK | MB_ICONINFORMATION,
  572. IDS_BAD_REFRESH,
  573. IDS_BAD_REFRESH);
  574. break;
  575. }
  576. if (lpdmTmp->dmDisplayFrequency == lpdmCurrent->dmDisplayFrequency)
  577. {
  578. ComboBox_SetCurSel(hFreq, pos);
  579. break;
  580. }
  581. pos++;
  582. }
  583. if (hwndCurr)
  584. SetFocus(hwndCurr);
  585. return;
  586. }
  587. //---------------------------------------------------------------------------
  588. //
  589. // PropertySheeDlgProc()
  590. //
  591. // The dialog procedure for the "Monitor" property sheet page.
  592. //
  593. //---------------------------------------------------------------------------
  594. INT_PTR
  595. CALLBACK
  596. PropertySheeDlgProc(
  597. HWND hDlg,
  598. UINT uMessage,
  599. WPARAM wParam,
  600. LPARAM lParam
  601. )
  602. {
  603. NMHDR FAR *lpnm;
  604. CMonitorPage * pMonitorPage = (CMonitorPage*)GetWindowLongPtr(hDlg, DWLP_USER);
  605. switch (uMessage)
  606. {
  607. case WM_INITDIALOG:
  608. if (!g_lpdoTarget)
  609. {
  610. return FALSE;
  611. }
  612. else
  613. {
  614. pMonitorPage = new CMonitorPage(hDlg);
  615. if(!pMonitorPage)
  616. return FALSE;
  617. SetWindowLongPtr(hDlg, DWLP_USER, (LPARAM)pMonitorPage);
  618. pMonitorPage->OnInitDialog();
  619. }
  620. break;
  621. case WM_DESTROY:
  622. if (pMonitorPage)
  623. {
  624. pMonitorPage->OnDestroy();
  625. SetWindowLongPtr(hDlg, DWLP_USER, NULL);
  626. delete pMonitorPage;
  627. }
  628. break;
  629. case WM_COMMAND:
  630. switch (GET_WM_COMMAND_ID(wParam, lParam))
  631. {
  632. case IDC_MONSET_FREQ:
  633. switch(GET_WM_COMMAND_CMD(wParam, lParam))
  634. {
  635. case CBN_SELCHANGE:
  636. PropSheet_Changed(GetParent(hDlg), hDlg);
  637. if(pMonitorPage)
  638. pMonitorPage->OnFrequencyChanged();
  639. break;
  640. default:
  641. break;
  642. }
  643. break;
  644. case IDC_PROPERTIES:
  645. if(pMonitorPage)
  646. pMonitorPage->OnProperties();
  647. break;
  648. case IDC_MONSET_PRUNNING_MODE:
  649. PropSheet_Changed(GetParent(hDlg), hDlg);
  650. if(pMonitorPage)
  651. pMonitorPage->OnPruningModeChanged();
  652. break;
  653. case IDC_MONITORS_LIST:
  654. switch(GET_WM_COMMAND_CMD(wParam, lParam))
  655. {
  656. case LBN_SELCHANGE:
  657. if(pMonitorPage)
  658. pMonitorPage->OnSelMonitorChanged();
  659. break;
  660. default:
  661. return FALSE;
  662. }
  663. break;
  664. default:
  665. return FALSE;
  666. }
  667. break;
  668. case WM_NOTIFY:
  669. switch (((NMHDR FAR *)lParam)->code)
  670. {
  671. case PSN_SETACTIVE:
  672. return (pMonitorPage && pMonitorPage->OnSetActive());
  673. case PSN_APPLY:
  674. if(pMonitorPage)
  675. pMonitorPage->OnApply();
  676. break;
  677. case PSN_RESET:
  678. if(pMonitorPage)
  679. pMonitorPage->OnCancel();
  680. break;
  681. default:
  682. return FALSE;
  683. }
  684. break;
  685. case WM_HELP:
  686. WinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle,
  687. TEXT("display.hlp"),
  688. HELP_WM_HELP,
  689. (DWORD_PTR)(LPTSTR)sc_MonitorHelpIds);
  690. break;
  691. case WM_CONTEXTMENU:
  692. WinHelp((HWND)wParam,
  693. TEXT("display.hlp"),
  694. HELP_CONTEXTMENU,
  695. (DWORD_PTR)(LPTSTR)sc_MonitorHelpIds);
  696. break;
  697. default:
  698. return FALSE;
  699. }
  700. return TRUE;
  701. }