deskperf.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 16k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. //
  2. // [Display Troubleshooter Control Panel Extenstion]
  3. //
  4. //
  5. // - Aug.25.1998
  6. //
  7. //    Created by Hideyuki Nagase [hideyukn]
  8. // 
  9. #include    "deskperf.h"
  10. //
  11. // Defines
  12. //
  13. #define ACCELERATION_FULL  0
  14. #define ACCELERATION_NONE  5
  15. #define SLIDER_POS_TO_ACCEL_LEVEL(x) (ACCELERATION_NONE - (x))
  16. #define ACCEL_LEVEL_TO_SLIDER_POS(x) (ACCELERATION_NONE - (x))
  17. #define SZ_ACCELLEVEL TEXT("Acceleration.Level")
  18. //
  19. // Guid for "Troubleshooter" shell extentions
  20. //
  21. GUID g_CLSID_CplExt = { 0xf92e8c40, 0x3d33, 0x11d2,
  22.                         { 0xb1, 0xaa, 0x08, 0x00, 0x36, 0xa7, 0x5b, 0x03}
  23.                       };
  24. //
  25. // Global variables
  26. //
  27. //
  28. // Dos display device name
  29. //
  30. TCHAR gszWinDisplayDevice[MAX_PATH];
  31. //
  32. // NT display device name
  33. //
  34. TCHAR gszNtDisplayDevice[MAX_PATH];
  35. //
  36. // Registry path for current device
  37. //
  38. TCHAR gszRegistryPath[MAX_PATH];
  39. //
  40. // Current acceleration level.
  41. //
  42. DWORD AccelLevel = ACCELERATION_FULL;
  43. //
  44. // Last saved acceleration level.
  45. //
  46. DWORD AccelLevelInReg = ACCELERATION_FULL;
  47. //
  48. // Registry security.
  49. //
  50. BOOL  gbReadOnly = FALSE;
  51. //
  52. // Context-sentitive help
  53. //
  54. static const DWORD sc_PerformanceHelpIds[] =
  55. {
  56.    IDI_MONITOR,             IDH_NOHELP,
  57.    IDC_DESCRIPTION,         IDH_NOHELP,
  58.    IDC_ACCELERATION_SLIDER, IDH_SLIDER_HELP_TOPIC,
  59.    IDC_ACCELERATION_TEXT,   IDH_SLIDER_HELP_TOPIC,
  60.    0, 0
  61. };
  62. void
  63. UpdateGraphicsText(HWND hDlg, DWORD AccelPos)
  64. {
  65.     TCHAR MessageBuffer[200];
  66.     LoadString(g_hInst, IDS_LEVEL0 + AccelPos, MessageBuffer, SIZEOF(MessageBuffer));
  67.     SetDlgItemText(hDlg, IDC_ACCELERATION_TEXT, (LPTSTR) MessageBuffer);
  68. }
  69. BOOL GetDeviceKey(LPCTSTR pszDisplay, LPTSTR pszDeviceKey, int cChars)
  70. {
  71.     DISPLAY_DEVICE DisplayDevice;
  72.     BOOL fFound = FALSE;
  73.     BOOL fSuccess = TRUE;
  74.     int iEnum = 0;
  75.     // Enumerate all the devices in the system.
  76.     while(fSuccess && !fFound)
  77.     {
  78.         ZeroMemory(&DisplayDevice, sizeof(DISPLAY_DEVICE));
  79.         DisplayDevice.cb = sizeof(DISPLAY_DEVICE);
  80.         fSuccess = EnumDisplayDevices(NULL, iEnum, &DisplayDevice, 0);
  81.         if(fSuccess)
  82.         {
  83.             if(0 == lstrcmp(&DisplayDevice.DeviceName[0], pszDisplay))
  84.             {
  85.                 ASSERT(lstrlen(DisplayDevice.DeviceKey) < cChars);
  86.                 fSuccess = (lstrlen(DisplayDevice.DeviceKey) < cChars);
  87.                 if(fSuccess)
  88.                 {
  89.                     lstrcpy(pszDeviceKey, DisplayDevice.DeviceKey);
  90.                     fFound = TRUE;
  91.                 }
  92.             }
  93.             ++iEnum;
  94.         }
  95.     }
  96.     
  97.     return fFound;
  98. }
  99. INT_PTR
  100. CALLBACK
  101. AskDynamicApply(HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
  102. {
  103.     int *pTemp;
  104.     switch (msg)
  105.     {
  106.     case WM_INITDIALOG:
  107.         if ((pTemp = (int *)lp) != NULL)
  108.         {
  109.             SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pTemp);
  110.             CheckDlgButton(hDlg, (*pTemp & DCDSF_DYNA)?
  111.                            IDC_YESDYNA : IDC_NODYNA, BST_CHECKED);
  112.         }
  113.         else
  114.             EndDialog(hDlg, -1);
  115.         break;
  116.     case WM_COMMAND:
  117.         switch (GET_WM_COMMAND_ID(wp, lp))
  118.         {
  119.         case IDOK:
  120.             if ((pTemp = (int *)GetWindowLongPtr(hDlg, DWLP_USER)) != NULL)
  121.             {
  122.                 *pTemp = IsDlgButtonChecked(hDlg, IDC_YESDYNA)? DCDSF_DYNA : 0;
  123.                 if (!IsDlgButtonChecked(hDlg, IDC_SHUTUP))
  124.                     *pTemp |= DCDSF_ASK;
  125.                 SetDisplayCPLPreference(REGSTR_VAL_DYNASETTINGSCHANGE, *pTemp);
  126.             }
  127.             EndDialog(hDlg, TRUE);
  128.             break;
  129.         case IDCANCEL:
  130.             EndDialog(hDlg, FALSE);
  131.             break;
  132.         default:
  133.             return FALSE;
  134.         }
  135.         break;
  136.     default:
  137.         return FALSE;
  138.     }
  139.     return TRUE;
  140. }
  141. BOOL
  142. CALLBACK
  143. PropertySheeDlgProc(
  144.     HWND hDlg,
  145.     UINT uMessage,
  146.     WPARAM wParam,
  147.     LPARAM lParam
  148.     )
  149. {
  150.     switch (uMessage)
  151.     {
  152.     case WM_INITDIALOG:
  153.         if (!g_lpdoTarget)
  154.         {
  155.             return FALSE;
  156.         }
  157.         else
  158.         {
  159.             BOOL bSuccess = FALSE;
  160.             //
  161.             // LATER: Check we are on Terminal Server client or not.
  162.             //
  163.             BOOL bLocalConsole = TRUE;
  164.             if (bLocalConsole)
  165.             {
  166.                 //
  167.                 // Get the display device name from IDataObject.
  168.                 //
  169.                 FORMATETC fmte = {(CLIPFORMAT)RegisterClipboardFormat(DESKCPLEXT_DISPLAY_DEVICE),
  170.                                   (DVTARGETDEVICE FAR *) NULL,
  171.                                   DVASPECT_CONTENT,
  172.                                   -1,
  173.                                   TYMED_HGLOBAL};
  174.                 STGMEDIUM stgm;
  175.                 HRESULT hres = g_lpdoTarget->GetData(&fmte, &stgm);
  176.                 if (SUCCEEDED(hres) && stgm.hGlobal)
  177.                 {
  178.                     //
  179.                     // The storage now contains Display device path (\.DisplayX) in UNICODE.
  180.                     //
  181.                     PWSTR pDisplayDevice = (PWSTR) GlobalLock(stgm.hGlobal);
  182.                     if (pDisplayDevice)
  183.                     {
  184.                         //
  185.                         // Copy the data to local buffer.
  186.                         //
  187.                     #ifdef UNICODE
  188.                         lstrcpy(gszWinDisplayDevice,pDisplayDevice);
  189.                         bSuccess = TRUE;
  190.                     #else
  191.                         bSuccess = (BOOL) WideCharToMultiByte(
  192.                                             CP_ACP,0,
  193.                                             pDisplayDevice,lstrlenW(pDisplayDevice)+1,
  194.                                             gszWinDisplayDevice,MAX_PATH,
  195.                                             NULL,NULL);
  196.                     #endif
  197.                         GlobalUnlock(stgm.hGlobal);
  198.                     }  
  199.                 }
  200.                 //
  201.                 // let's build registry path for its hardware profie.
  202.                 //
  203.                 if (bSuccess)
  204.                 {
  205.                     TCHAR szServicePath[MAX_PATH];
  206.                     bSuccess = FALSE;
  207.                     if(GetDeviceKey(gszWinDisplayDevice, szServicePath, sizeof(szServicePath) / sizeof(TCHAR)))
  208.                     {
  209.                         //
  210.                         // Upcase all character.
  211.                         //
  212.                         TCHAR *psz = szServicePath;
  213.                         while (*psz)
  214.                         {
  215.                             *psz = _totupper(*psz);
  216.                             psz++;
  217.                         }
  218.                         //
  219.                         // Find SYSTEM from service path
  220.                         //
  221.                         psz = _tcsstr(szServicePath,TEXT("\SYSTEM"));
  222.                         //
  223.                         // Skip ''
  224.                         //
  225.                         psz++;
  226.                         lstrcpy(gszRegistryPath,psz);
  227.                         bSuccess = TRUE;
  228.                     }
  229.                 }
  230.                 if (bSuccess)
  231.                 {
  232.                     //
  233.                     // Read currect acceleration level from registry.
  234.                     //
  235.                     HKEY hKeyAccelLevel = NULL;
  236.                     if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  237.                                      gszRegistryPath,
  238.                                      0,
  239.                                      KEY_ALL_ACCESS,
  240.                                      &hKeyAccelLevel) != ERROR_SUCCESS)
  241.                     {
  242.                         if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  243.                                          gszRegistryPath,
  244.                                          0,
  245.                                          KEY_READ,
  246.                                          &hKeyAccelLevel) != ERROR_SUCCESS)
  247.                         {
  248.                             hKeyAccelLevel = NULL;
  249.                         }
  250.                         else
  251.                         {
  252.                             gbReadOnly = TRUE;
  253.                         }
  254.                     }
  255.                     if (hKeyAccelLevel)
  256.                     {
  257.                         DWORD cb = sizeof(AccelLevel);
  258.                         if (RegQueryValueEx(hKeyAccelLevel,
  259.                                             SZ_ACCELLEVEL,
  260.                                             NULL,NULL,
  261.                                             (LPBYTE) &AccelLevel,
  262.                                             &cb) == ERROR_SUCCESS)
  263.                         {
  264.                             //
  265.                             // Update last saved accel level.
  266.                             //
  267.                             AccelLevelInReg = AccelLevel;
  268.                         }
  269.                         else
  270.                         {
  271.                             //
  272.                             // If there is no registry value, assume full acceleration.
  273.                             //
  274.                             AccelLevelInReg = AccelLevel = ACCELERATION_FULL;
  275.                         }
  276.                         RegCloseKey(hKeyAccelLevel);
  277.                         bSuccess = TRUE;
  278.                     }
  279.                 }
  280.             }
  281.             //
  282.             // Setup slider.
  283.             //
  284.             HWND hSlider = GetDlgItem(hDlg, IDC_ACCELERATION_SLIDER);
  285.             //
  286.             // Slider range is between ACCEL_FULL and ACCEL_NONE.
  287.             //
  288.             SendMessage(hSlider, TBM_SETRANGE, (WPARAM)FALSE,
  289.                         MAKELPARAM(ACCELERATION_FULL, ACCELERATION_NONE));
  290.             //
  291.             // Set currect slider position based on currect accel level.
  292.             //
  293.  
  294.             SendMessage(hSlider, TBM_SETPOS, (WPARAM)TRUE,
  295.                         (LPARAM) ACCEL_LEVEL_TO_SLIDER_POS(AccelLevel));
  296.             //
  297.             // Update message based on currect acceleration level.
  298.             //
  299.             UpdateGraphicsText(hDlg, AccelLevel);
  300.             if (!bSuccess || gbReadOnly)
  301.             {
  302.                 // 
  303.                 // Disable slider control
  304.                 //
  305.                 EnableWindow(hSlider, FALSE);
  306.             }
  307.         }
  308.         break;
  309.     case WM_HSCROLL:
  310.         if (GetWindowLongPtr((HWND)lParam, GWLP_ID) == IDC_ACCELERATION_SLIDER)
  311.         {
  312.             //
  313.             // Slider has been moved.
  314.             //
  315.             HWND hSlider = (HWND) lParam;
  316.             //
  317.             // Obtain currect slider position.
  318.             //
  319.             DWORD dwSliderPos = (DWORD) SendMessage(hSlider, TBM_GETPOS, 0, 0L);
  320.             //
  321.             // Convert slider position to accel level.
  322.             //
  323.             DWORD AccelNew = SLIDER_POS_TO_ACCEL_LEVEL(dwSliderPos); 
  324.             //
  325.             // If accleration level has been changed, update description, and
  326.             // enable apply button.
  327.             //
  328.             if (AccelNew != AccelLevel)
  329.             {
  330.                 AccelLevel = AccelNew;
  331.                 UpdateGraphicsText(hDlg, AccelNew);
  332.                 PropSheet_Changed(GetParent(hDlg), hDlg);
  333.             }
  334.         }
  335.         break;
  336.     case WM_NOTIFY:
  337.         if (((NMHDR *)lParam)->code == PSN_APPLY)
  338.         {
  339.             if (AccelLevel != AccelLevelInReg)
  340.             {
  341.                 //
  342.                 // Popup the dialog to ask user to apply it dynamically or not.
  343.                 //
  344.                 int val = GetDynaCDSPreference();
  345.                 BOOL bSuccess = TRUE;
  346.                 if (val & DCDSF_ASK)
  347.                 {
  348.                     switch (DialogBoxParam(g_hInst, 
  349.                                            MAKEINTRESOURCE(DLG_ASKDYNACDS),
  350.                                            hDlg, 
  351.                                            AskDynamicApply, 
  352.                                            (LPARAM)&val))
  353.                     {
  354.                     case 0:         // user cancelled
  355.                     case -1:        // dialog could not be displayed
  356.                         bSuccess = FALSE;
  357.                         break;
  358.                     }
  359.                 }
  360.                 if (bSuccess)
  361.                 {
  362.                     //
  363.                     // AccelLevel has been changed. save it to registry.
  364.                     //
  365.                     HKEY hKeyAccelLevel;
  366.                     if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  367.                                      gszRegistryPath,
  368.                                      0,
  369.                                      KEY_ALL_ACCESS,
  370.                                      &hKeyAccelLevel) == ERROR_SUCCESS)
  371.                     {
  372.                         if (AccelLevel == ACCELERATION_FULL)
  373.                         {
  374.                             //
  375.                             // If acceration is set to ACCELERATION_FULL (default)
  376.                             // remove registry value.
  377.                             //
  378.                             if (RegDeleteValue(hKeyAccelLevel,
  379.                                                SZ_ACCELLEVEL) == ERROR_SUCCESS)
  380.                             {
  381.                                 bSuccess = TRUE;
  382.                             }
  383.                         }
  384.                         else
  385.                         {
  386.                             //
  387.                             // Otherwise, save it to registry.
  388.                             //
  389.                             if (RegSetValueEx(hKeyAccelLevel,
  390.                                               SZ_ACCELLEVEL,
  391.                                               NULL, REG_DWORD,
  392.                                               (LPBYTE) &AccelLevel,
  393.                                               sizeof(AccelLevel)) == ERROR_SUCCESS)
  394.                             {
  395.                                 bSuccess = TRUE;
  396.                             }
  397.                         }
  398.                         RegCloseKey(hKeyAccelLevel);
  399.                     }
  400.                     if (bSuccess)
  401.                     {
  402.                         //
  403.                         // Update last saved data.
  404.                         //
  405.                         AccelLevelInReg = AccelLevel;
  406.                         //
  407.                         // Apply it dynamically or reboot.
  408.                         //
  409.                         if (((val & DCDSF_DYNA) == DCDSF_DYNA))
  410.                         {
  411.                         // Apply it dynamically.
  412.                         // If EnumDisplaySettings was called with EDS_RAWMODE, we need CDS_RAWMODE below.
  413.                         // Otherwise, it's harmless.
  414.                         ChangeDisplaySettings(NULL, CDS_RAWMODE);
  415.                         }
  416.                         else
  417.                         {
  418.                         // User wants to reboot system.
  419.                         PropSheet_RestartWindows(GetParent(hDlg));
  420.                         }
  421.                     }
  422.                     else
  423.                     {
  424.                         //
  425.                         // BUGBUG: Error PopUp ??
  426.                         //
  427.                     }
  428.                 }
  429.             long lRet = (bSuccess ? PSNRET_NOERROR : PSNRET_INVALID_NOCHANGEPAGE);
  430.             SetWindowLongPtr(hDlg, DWLP_MSGRESULT, lRet);
  431.             }
  432.         }
  433.         break;
  434.     case WM_HELP:
  435.         WinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle,
  436.                 TEXT("display.hlp"),
  437.                 HELP_WM_HELP,
  438.                 (DWORD_PTR)(LPTSTR)sc_PerformanceHelpIds);
  439.         break;
  440.     case WM_CONTEXTMENU:
  441.         WinHelp((HWND)wParam,
  442.                 TEXT("display.hlp"),
  443.                 HELP_CONTEXTMENU,
  444.                 (DWORD_PTR)(LPTSTR)sc_PerformanceHelpIds);
  445.         break;
  446.     default:
  447.         return FALSE;
  448.     }
  449.     return TRUE;
  450. }