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.

237 lines
6.9 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Fake.c
  3. //
  4. // this code gives OEMs a bogus Settings page to patch/modify
  5. //
  6. // OEM display pages patch the snot out of the Settings page
  7. // the problem is that we have changed the setting page, and
  8. // even if the OEM code could deal with our changes, the
  9. // settings page is not even on the same property sheet
  10. // as the extensions.
  11. //
  12. // some OEMs hook the setting page by hooking the TabContol and
  13. // watching for a mouse click to activate the Settings page
  14. // then they modify the page. NOTE they dont patch the page
  15. // if it is activated via the keyboard only the mouse!
  16. //
  17. // some OEM pages find the Setting page by name.
  18. // we have named the real settings page "Settings " and
  19. // the fake page is "Settings"
  20. //
  21. // some OEM pages assume the last page is the Settings page.
  22. // we make sure the fake settings is always last.
  23. //
  24. ///////////////////////////////////////////////////////////////////////////////
  25. #include "priv.h"
  26. #include "winuser.h"
  27. #pragma hdrstop
  28. #include "cplext.h"
  29. #ifndef TCIS_HIDDEN
  30. #define TCIS_HIDDEN 0x0004
  31. #pragma message("using local version of TCIS_HIDDEN")
  32. #endif
  33. #undef MATROX_HACK
  34. /*
  35. * Global stuff
  36. */
  37. static LONG_PTR TabWndProc; // SysTabControl WndProc
  38. static LONG_PTR DlgWndProc; // Dialog WndProc
  39. #ifdef MATROX_HACK
  40. static PROPSHEETHEADER psh; // saved prop sheet header
  41. #endif
  42. /*
  43. * Local Constant Declarations
  44. */
  45. int CALLBACK DeskPropSheetCallback(HWND hDlg, UINT code, LPARAM lParam);
  46. INT_PTR CALLBACK FakeSettingsDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
  47. IThemeUIPages *g_pThemeUI;
  48. ///////////////////////////////////////////////////////////////////////////////
  49. // AddFakeSettingsPage
  50. ///////////////////////////////////////////////////////////////////////////////
  51. void AddFakeSettingsPage(IThemeUIPages *pThemeUI, PROPSHEETHEADER * ppsh)
  52. {
  53. g_pThemeUI = pThemeUI;
  54. PROPSHEETPAGE psp;
  55. HPROPSHEETPAGE hpsp;
  56. ZeroMemory(&psp, sizeof(psp));
  57. psp.dwSize = sizeof(psp);
  58. psp.dwFlags = PSP_DEFAULT;
  59. psp.hInstance = HINST_THISDLL;
  60. psp.pszTemplate = MAKEINTRESOURCE(DLG_FAKE_SETTINGS);
  61. psp.pfnDlgProc = FakeSettingsDlgProc;
  62. psp.lParam = 0L;
  63. //
  64. // some OEMs find the Property sheet by window title
  65. // so make sure we have the title they expect.
  66. //
  67. #ifdef MATROX_HACK
  68. if (ppsh->hwndParent && IsWindowVisible(ppsh->hwndParent))
  69. {
  70. psh = *ppsh;
  71. ppsh->pszCaption = MAKEINTRESOURCE(IDS_DISPLAY_TITLE);
  72. psp.dwFlags |= PSP_PREMATURE;
  73. }
  74. #endif
  75. hpsp = CreatePropertySheetPage(&psp);
  76. if (hpsp)
  77. {
  78. ppsh->phpage[ppsh->nPages++] = hpsp;
  79. ppsh->pfnCallback = DeskPropSheetCallback;
  80. ppsh->dwFlags |= PSH_USECALLBACK;
  81. }
  82. }
  83. ///////////////////////////////////////////////////////////////////////////////
  84. // FakeSettingsDlgProc
  85. ///////////////////////////////////////////////////////////////////////////////
  86. INT_PTR CALLBACK FakeSettingsDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  87. {
  88. if (hDlg && DlgWndProc)
  89. {
  90. if (GetWindowLongPtr(hDlg, GWLP_WNDPROC) != DlgWndProc)
  91. {
  92. SetWindowLongPtr(hDlg, GWLP_WNDPROC, DlgWndProc);
  93. }
  94. if (GetWindowLongPtr(hDlg, DWLP_DLGPROC) != (LONG_PTR)FakeSettingsDlgProc)
  95. {
  96. SetWindowLongPtr(hDlg, DWLP_DLGPROC, (LONG_PTR)FakeSettingsDlgProc);
  97. }
  98. }
  99. switch (message)
  100. {
  101. case WM_INITDIALOG:
  102. return TRUE;
  103. case WM_DESTROY:
  104. break;
  105. case WM_COMMAND:
  106. if (LOWORD(wParam) == IDC_CHANGEDRV)
  107. {
  108. }
  109. break;
  110. }
  111. return FALSE;
  112. }
  113. ///////////////////////////////////////////////////////////////////////////////
  114. // HideFakeSettingsPage
  115. //
  116. // hide the bogus settings page from view so the user cant see it.
  117. //
  118. // this code uses a new TabCtrl item style TCIS_HIDDEN that is only
  119. // in the Win98/NT5/IE4.01 COMMCTRL
  120. //
  121. ///////////////////////////////////////////////////////////////////////////////
  122. void HideFakeSettingsPage(HWND hDlg)
  123. {
  124. HWND hwnd = PropSheet_GetTabControl(hDlg);
  125. if (hwnd)
  126. {
  127. TCITEM tci;
  128. tci.mask = TCIF_STATE;
  129. tci.dwStateMask = TCIS_HIDDEN;
  130. tci.dwState = TCIS_HIDDEN;
  131. TabCtrl_SetItem(hwnd, TabCtrl_GetItemCount(hwnd)-1, &tci);
  132. }
  133. }
  134. ///////////////////////////////////////////////////////////////////////////////
  135. // DeskPropSheetCallback
  136. //
  137. // what this callback does is look for someone subclassing the
  138. // tab control, if we detect this we put the correct WndProc
  139. // back.
  140. //
  141. // we also hide the fake settings page after all the entensions
  142. // have initialized
  143. //
  144. ///////////////////////////////////////////////////////////////////////////////
  145. int CALLBACK DeskPropSheetCallback(HWND hDlg, UINT code, LPARAM lParam)
  146. {
  147. HWND hwnd;
  148. WNDCLASS wc;
  149. switch (code)
  150. {
  151. case PSCB_INITIALIZED:
  152. TraceMsg(TF_GENERAL, "DeskPropSheetCallback: PSCB_INITIALIZED");
  153. hwnd = PropSheet_GetTabControl(hDlg);
  154. if (hwnd && TabWndProc)
  155. {
  156. if (GetWindowLongPtr(hwnd, GWLP_WNDPROC) != TabWndProc)
  157. {
  158. SetWindowLongPtr(hwnd, GWLP_WNDPROC, TabWndProc);
  159. }
  160. }
  161. if (hDlg && DlgWndProc)
  162. {
  163. if (GetWindowLongPtr(hDlg, GWLP_WNDPROC) != DlgWndProc)
  164. {
  165. SetWindowLongPtr(hDlg, GWLP_WNDPROC, DlgWndProc);
  166. }
  167. }
  168. #ifdef MATROX_HACK
  169. //
  170. // restore the caption
  171. //
  172. if (psh.pszCaption)
  173. {
  174. ShowWindow(hDlg, SW_SHOW);
  175. Sleep(10);
  176. PropSheet_SetTitle(hDlg, psh.dwFlags, psh.pszCaption);
  177. PropSheet_SetTitle(GetParent(psh.hwndParent),
  178. PSH_PROPTITLE, MAKEINTRESOURCE(IDS_DISPLAY_TITLE));
  179. psh.pszCaption = 0;
  180. }
  181. #endif
  182. //
  183. // hide the settings page so the user cant see it.
  184. //
  185. HideFakeSettingsPage(hDlg);
  186. break;
  187. case PSCB_PRECREATE:
  188. TraceMsg(TF_GENERAL, "DeskPropSheetCallback: PSCB_PRECREATE");
  189. ZeroMemory(&wc, sizeof(wc));
  190. SHFusionGetClassInfo(NULL, WC_DIALOG, &wc);
  191. DlgWndProc = (LONG_PTR)wc.lpfnWndProc;
  192. ZeroMemory(&wc, sizeof(wc));
  193. SHFusionGetClassInfo(NULL, WC_TABCONTROL, &wc);
  194. TabWndProc = (LONG_PTR)wc.lpfnWndProc;
  195. break;
  196. case PSCB_BUTTONPRESSED:
  197. if ((PSBTN_OK == lParam) || (PSBTN_APPLYNOW == lParam))
  198. {
  199. DWORD dwFlags = ((PSBTN_OK == lParam) ? (TUIAP_WAITFORAPPLY | TUIAP_NONE) : TUIAP_NONE);
  200. if (g_pThemeUI)
  201. {
  202. g_pThemeUI->ApplyPressed(dwFlags);
  203. }
  204. }
  205. break;
  206. }
  207. return 0;
  208. }