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.

5683 lines
140 KiB

  1. /**++
  2. Copyright (c) 1990-1995 Microsoft Corporation
  3. Module Name:
  4. apilayer.c
  5. Abstract:
  6. This module contains functions for the common UI api layer. this layer
  7. managed all property sheet page handles, create, destroy and inter-page
  8. communications.
  9. Author:
  10. 28-Dec-1995 Thu 16:02:12 created -by- Daniel Chou (danielc)
  11. [Environment:]
  12. NT Windows - Common Printer Driver UI DLL
  13. [Notes:]
  14. Revision History:
  15. --*/
  16. #include "precomp.h"
  17. #pragma hdrstop
  18. #define DBG_CPSUIFILENAME DbgApilayer
  19. #define DBG_PAGEDLGPROC 0x00000001
  20. #define DBG_SHOWPAGE 0x00000002
  21. #define DBG_DEL_PROC 0x00000004
  22. #define DBG_GET_PAGE 0x00000008
  23. #define DBG_ADD_CPSUIPAGE 0x00000010
  24. #define DBG_ADD_PSPAGE 0x00000020
  25. #define DBG_ADDCOMPAGE 0x00000040
  26. #define DBG_ADD_CPSUI 0x00000080
  27. #define DBG_PFNCOMPROPSHEET 0x00000100
  28. #define DBG_GETSETREG 0x00000200
  29. #define DBG_DOCOMPROPSHEET 0x00000400
  30. #define DBG_DO_CPSUI 0x00000800
  31. #define DBG_CALLPFN 0x00001000
  32. #define DBG_SETHSTARTPAGE 0x00002000
  33. #define DBG_PAGE_PROC 0x00004000
  34. #define DBG_TCMPROC 0x00008000
  35. #define DBG_TABTABLE 0x00010000
  36. #define DBG_INSPAGE 0x00020000
  37. #define DBG_PSPCB 0x00040000
  38. #define DBG_DMPUBHIDEBITS 0x00080000
  39. #define DBG_APPLYDOC 0x00100000
  40. #define DBG_GET_PAGEHWND 0x00200000
  41. #define DBG_GET_TABWND 0x00400000
  42. #define DBG_ALWAYS_APPLYNOW 0x80000000
  43. #define DBG_IGNORE_PSN_APPLY 0x40000000
  44. DEFINE_DBGVAR(0);
  45. #define REGDPF_TVPAGE 0x00000001
  46. #define REGDPF_EXPAND_OPTIONS 0x00000002
  47. #define REGDPF_STD_P1 0x00000004
  48. #define REGDPF_MASK 0x00000007
  49. #define REGDPF_DEFAULT 0x00000000
  50. extern HINSTANCE hInstDLL;
  51. extern HANDLE hCPSUIMutex;
  52. extern CPSUIHANDLETABLE CPSUIHandleTable;
  53. extern DWORD TlsIndex;
  54. static const WCHAR szCPSUIRegKey[] = L"Software\\Microsoft\\ComPstUI";
  55. static const WCHAR szDocPropKeyName[] = L"DocPropFlags";
  56. #if DBG
  57. LPSTR pszCPSFUNC[] = { "CPSFUNC_ADD_HPROPSHEETPAGE",
  58. "CPSFUNC_ADD_PROPSHEETPAGE",
  59. "CPSFUNC_ADD_PCOMPROPSHEETUIA",
  60. "CPSFUNC_ADD_PCOMPROPSHEETUIW",
  61. "CPSFUNC_ADD_PFNPROPSHEETUIA",
  62. "CPSFUNC_ADD_PFNPROPSHEETUIW",
  63. "CPSFUNC_DELETE_HCOMPROPSHEET",
  64. "CPSFUNC_SET_HSTARTPAGE",
  65. "CPSFUNC_GET_PAGECOUNT",
  66. "CPSFUNC_SET_RESULT",
  67. "CPSFUNC_GET_HPSUIPAGES",
  68. "CPSFUNC_LOAD_CPSUI_STRINGA",
  69. "CPSFUNC_LOAD_CPSUI_STRINGW",
  70. "CPSFUNC_LOAD_CPSUI_ICON",
  71. "CPSFUNC_GET_PFNPROPSHEETUI_ICON",
  72. "CPSFUNC_ADD_PROPSHEETPAGEA",
  73. "CPSFUNC_INSERT_PSUIPAGEA",
  74. "CPSFUNC_INSERT_PSUIPAGEW",
  75. "CPSFUNC_SET_PSUIPAGE_TITLEA",
  76. "CPSFUNC_SET_PSUIPAGE_TITLEW",
  77. "CPSFUNC_SET_PSUIPAGE_ICON",
  78. "CPSFUNC_SET_DATABLOCK",
  79. "CPSFUNC_QUERY_DATABLOCK",
  80. "CPSFUNC_SET_DMPUB_HIDEBITS",
  81. "CPSFUNC_IGNORE_CPSUI_PSN_APPLY",
  82. "CPSFUNC_DO_APPLY_CPSUI",
  83. "CPSFUNC_SET_FUSION_CONTEXT"
  84. };
  85. LPSTR pszPFNReason[] = { "PROPSHEETUI_REASON_INIT",
  86. "PROPSHEETUI_REASON_GET_INFO_HEADER",
  87. "PROPSHEETUI_REASON_DESTROY",
  88. "PROPSHEETUI_REASON_SET_RESULT",
  89. "PROPSHEETUI_REASON_GET_ICON" };
  90. LPSTR pszTabMode[] = { "TAB_MODE_INIT",
  91. "TAB_MODE_FIND",
  92. "TAB_MODE_INSERT",
  93. "TAB_MODE_DELETE",
  94. "TAB_MODE_DELETE_ALL" };
  95. LPSTR pszInsType[] = { "PSUIPAGEINSERT_GROUP_PARENT",
  96. "PSUIPAGEINSERT_PCOMPROPSHEETUI",
  97. "PSUIPAGEINSERT_PFNPROPSHEETUI",
  98. "PSUIPAGEINSERT_PROPSHEETPAGE",
  99. "PSUIPAGEINSERT_HPROPSHEETPAGE",
  100. "PSUIPAGEINSERT_DLL" };
  101. #define DBG_SHOW_CPSUIPAGE(pPage, Level) \
  102. { \
  103. CPSUIDBG(DBG_SHOWPAGE, ("\n\n------ Show Current Page from %08lx, Level=%ld-------", \
  104. pPage, Level)); \
  105. \
  106. DbgShowCPSUIPage(pPage, Level); \
  107. }
  108. #define DBG_SHOW_PTCI(psz, w, ptci) Show_ptci(psz, w, ptci)
  109. VOID
  110. DbgShowCPSUIPage(
  111. PCPSUIPAGE pPage,
  112. LONG Level
  113. )
  114. {
  115. while (pPage) {
  116. if (pPage->Flags & CPF_PARENT) {
  117. if (pPage->Flags & CPF_ROOT) {
  118. CPSUIDBG(DBG_SHOWPAGE, ("%02ld!%08lx:%08lx: ROOT - Flags=%08lx, hDlg=%08lx, cPage=%ld/%ld, pStartPage=%08lx",
  119. Level,
  120. pPage, pPage->hPage, pPage->Flags,
  121. pPage->RootInfo.hDlg,
  122. (DWORD)pPage->RootInfo.cCPSUIPage,
  123. (DWORD)pPage->RootInfo.cPage,
  124. pPage->RootInfo.pStartPage));
  125. } else if (pPage->Flags & CPF_PFNPROPSHEETUI) {
  126. CPSUIDBG(DBG_SHOWPAGE,
  127. ("%02ld!%08lx:%08lx: PFN - Flags=%08lx, pfnPSUI=%08lx, UserData=%08lx, Result=%ld",
  128. Level, pPage, pPage->hPage, pPage->Flags,
  129. pPage->pfnInfo.pfnPSUI, (DWORD)pPage->pfnInfo.UserData,
  130. pPage->pfnInfo.Result));
  131. } else if (pPage->Flags & CPF_COMPROPSHEETUI) {
  132. CPSUIDBG(DBG_SHOWPAGE, ("%02ld!%08lx:%08lx: CPSUI - Flags=%08lx, pTVWnd=%08lx, lParam=%08lx, TV=%ld, Std1=%ld, Std2=%ld",
  133. Level,
  134. pPage, pPage->hPage, pPage->Flags,
  135. pPage->CPSUIInfo.pTVWnd, pPage->CPSUIInfo.Result,
  136. (DWORD)pPage->CPSUIInfo.TVPageIdx,
  137. (DWORD)pPage->CPSUIInfo.StdPageIdx1,
  138. (DWORD)pPage->CPSUIInfo.StdPageIdx2));
  139. } else if (pPage->Flags & CPF_USER_GROUP) {
  140. CPSUIDBG(DBG_SHOWPAGE, ("%02ld!%08lx:%08lx: GROUP_PARENT - Flags=%08lx",
  141. Level, pPage, pPage->hPage, pPage->Flags));
  142. } else {
  143. CPSUIDBG(DBG_SHOWPAGE, ("%02ld!%08lx:%08lx: UNKNOWN - Flags=%08lx",
  144. Level, pPage, pPage->hPage, pPage->Flags));
  145. }
  146. DbgShowCPSUIPage(pPage->pChild, Level + 1);
  147. } else {
  148. CPSUIDBG(DBG_SHOWPAGE, ("%02ld!%08lx:%08lx: %ws - Flags=%08lx, hDlg=%08lx, DlgProc=%08lx",
  149. (LONG)Level,
  150. pPage, pPage->hPage,
  151. (pPage->Flags & CPF_CALLER_HPSPAGE) ? L"USER_HPAGE" :
  152. L"PROPSHEETPAGE",
  153. pPage->Flags,
  154. pPage->hPageInfo.hDlg, pPage->hPageInfo.DlgProc));
  155. }
  156. pPage = pPage->pNext;
  157. }
  158. }
  159. VOID
  160. Show_ptci(
  161. LPSTR pszHeader,
  162. WPARAM wParam,
  163. TC_ITEM *ptci
  164. )
  165. {
  166. if (ptci) {
  167. if (pszHeader) {
  168. CPSUIDBG(DBG_TCMPROC, ("%hs", pszHeader));
  169. }
  170. CPSUIDBG(DBG_TCMPROC, (" IdxItem=%ld", wParam));
  171. CPSUIDBG(DBG_TCMPROC, (" Mask=%08lx", ptci->mask));
  172. if ((ptci->mask & TCIF_TEXT) &&
  173. (ptci->pszText)) {
  174. CPSUIDBG(DBG_TCMPROC, (" pszText=%ws", ptci->pszText));
  175. }
  176. CPSUIDBG(DBG_TCMPROC, (" cchTextMax=%ld", ptci->cchTextMax));
  177. CPSUIDBG(DBG_TCMPROC, (" iImage=%ld", ptci->iImage));
  178. }
  179. }
  180. VOID
  181. SHOW_TABWND(
  182. LPWSTR pName,
  183. PTABTABLE pTabTable
  184. )
  185. {
  186. WORD w;
  187. PTABINFO pTI = pTabTable->TabInfo;
  188. for (w = 0; w < pTabTable->cTab; w++, pTI++) {
  189. WORD Idx = pTI->HandleIdx;
  190. PCPSUIPAGE pPage;
  191. if (((Idx = pTI->HandleIdx) != 0xFFFF) &&
  192. (pPage = HANDLETABLE_GetCPSUIPage(WORD_2_HANDLE(Idx)))) {
  193. TC_ITEM tci;
  194. WCHAR wBuf[80];
  195. tci.mask = TCIF_TEXT;
  196. tci.pszText = wBuf;
  197. tci.cchTextMax = sizeof(wBuf) / sizeof(WCHAR);
  198. if (!SendMessage(pTabTable->hWndTab,
  199. TCM_GETITEMW,
  200. (WPARAM)w,
  201. (LPARAM)(TC_ITEM FAR *)&tci)) {
  202. wsprintf(wBuf, L"FAILED TabName");
  203. }
  204. CPSUIDBG(DBG_GET_TABWND,
  205. (" %ws: %2ld/%2ld=[%20ws] hDlg=%08lx, DlgProc=%08lx, hIdx=%04lx, hDlg=%08lx, pPage=%08lx",
  206. pName, w, pTI->OrgInsIdx, wBuf, pPage->hPageInfo.hDlg,
  207. pPage->hPageInfo.DlgProc, Idx, pTI->hDlg, pPage));
  208. HANDLETABLE_UnGetCPSUIPage(pPage);
  209. }
  210. }
  211. }
  212. #else
  213. #define DBG_SHOW_CPSUIPAGE(pPage, Level)
  214. #define DBG_SHOW_PTCI(psz, w, ptci)
  215. #define SHOW_TABWND(pName, pTabTable)
  216. #endif
  217. BOOL
  218. GetPageActivationContext(
  219. PCPSUIPAGE pCPSUIPage,
  220. HANDLE *phActCtx
  221. )
  222. {
  223. BOOL bRet = FALSE;
  224. if (phActCtx) {
  225. //
  226. // climb up in the hierarchy to the first parent page which has an
  227. // activation context properly set.
  228. //
  229. while (pCPSUIPage && INVALID_HANDLE_VALUE == pCPSUIPage->hActCtx) {
  230. pCPSUIPage = pCPSUIPage->pParent;
  231. }
  232. if (pCPSUIPage) {
  233. //
  234. // we found a parent with an activation context properly set.
  235. // return success.
  236. //
  237. *phActCtx = pCPSUIPage->hActCtx;
  238. bRet = TRUE;
  239. }
  240. }
  241. return bRet;
  242. }
  243. DWORD
  244. FilterException(
  245. HANDLE hPage,
  246. LPEXCEPTION_POINTERS pExceptionPtr
  247. )
  248. /*++
  249. Routine Description:
  250. Arguments:
  251. Return Value:
  252. Author:
  253. 13-Feb-1996 Tue 09:36:00 created -by- Daniel Chou (danielc)
  254. Revision History:
  255. --*/
  256. {
  257. HWND hWnd = NULL;
  258. PCPSUIPAGE pPage;
  259. PCPSUIPAGE pRootPage = NULL;
  260. LPSTR pFormat;
  261. LPSTR pMsg = NULL;
  262. CHAR Buf[2048];
  263. UINT i;
  264. UINT IDSLast;
  265. //
  266. // Buffer is long enough, reserve MAX_PATH characters for LoadString() and wsprintf()
  267. //
  268. if ((pPage = HANDLETABLE_GetCPSUIPage(hPage)) &&
  269. (pRootPage = HANDLETABLE_GetRootPage(pPage)) &&
  270. (hWnd = pPage->RootInfo.hDlg)) {
  271. IDSLast = IDS_INT_CPSUI_AV4;
  272. i = GetWindowTextA(pPage->RootInfo.hDlg, Buf, COUNT_ARRAY(Buf) - MAX_PATH);
  273. } else {
  274. IDSLast = IDS_INT_CPSUI_AV3;
  275. i = GetModuleFileNameA(NULL, Buf, COUNT_ARRAY(Buf) - MAX_PATH);
  276. }
  277. pMsg = &Buf[++i];
  278. i += LoadStringA(hInstDLL, IDS_INT_CPSUI_AV1, &Buf[i], COUNT_ARRAY(Buf)-i);
  279. i += wsprintfA(&Buf[i], " 0x%lx ",
  280. pExceptionPtr->ExceptionRecord->ExceptionAddress);
  281. i += LoadStringA(hInstDLL, IDS_INT_CPSUI_AV2, &Buf[i], COUNT_ARRAY(Buf)-i);
  282. i += wsprintfA(&Buf[i], " 0x%08lx",
  283. pExceptionPtr->ExceptionRecord->ExceptionCode);
  284. i += LoadStringA(hInstDLL, IDSLast, &Buf[i], COUNT_ARRAY(Buf)-i);
  285. HANDLETABLE_UnGetCPSUIPage(pPage);
  286. HANDLETABLE_UnGetCPSUIPage(pRootPage);
  287. CPSUIERR((Buf));
  288. CPSUIERR((pMsg));
  289. MessageBoxA(hWnd, pMsg, Buf, MB_ICONSTOP | MB_OK);
  290. return(EXCEPTION_EXECUTE_HANDLER);
  291. }
  292. LONG
  293. DoTabTable(
  294. UINT Mode,
  295. PTABTABLE pTabTable,
  296. SHORT Idx,
  297. SHORT OrgInsIdx
  298. )
  299. /*++
  300. Routine Description:
  301. Arguments:
  302. Return Value:
  303. Author:
  304. 12-Feb-1996 Mon 18:18:56 created -by- Daniel Chou (danielc)
  305. Revision History:
  306. --*/
  307. {
  308. PTABINFO pTI;
  309. PTABINFO pTmp;
  310. UINT cTab;
  311. UINT i;
  312. SHORT CurIdx;
  313. SHORT OldIdx;
  314. SHORT RetIdx;
  315. pTI =
  316. pTmp = pTabTable->TabInfo;
  317. cTab = (UINT)pTabTable->cTab;
  318. RetIdx = -1;
  319. switch (Mode) {
  320. case TAB_MODE_FIND:
  321. CPSUIDBG(DBG_TABTABLE, ("TAB_MODE_FIND: Index=%ld, cTab=%ld", Idx, cTab));
  322. if ((Idx >= 0) && (Idx < (SHORT)cTab)) {
  323. for (i = 0; i < cTab; i++, pTI++) {
  324. CPSUIDBG(DBG_TABTABLE,
  325. (" i=%2ld, Idx=%2ld, cTab=%2ld, OrgIdx=%2ld",
  326. i, Idx, cTab, pTI->OrgInsIdx));
  327. if (pTI->OrgInsIdx == Idx) {
  328. RetIdx = (SHORT)i;
  329. CPSUIDBG(DBG_TABTABLE, (" FOUND: RetIdx=%ld", RetIdx));
  330. break;
  331. }
  332. }
  333. }
  334. break;
  335. case TAB_MODE_DELETE_ALL:
  336. FillMemory(pTI, sizeof(pTabTable->TabInfo), 0xFF);
  337. pTabTable->cTab = 0;
  338. pTabTable->CurSel =
  339. pTabTable->InsIdx =
  340. pTabTable->HandleIdx = 0xFFFF;
  341. pTabTable->cPostSetCurSel = 0;
  342. pTabTable->iPostSetCurSel = -1;
  343. RetIdx = MAXPROPPAGES;
  344. break;
  345. case TAB_MODE_DELETE:
  346. //
  347. // Delete the pTabTable->TabInfo[].OrgInsIdx = Idx, reduced every
  348. // TabInfo[] which is > Idx by one, if pTabTable->TabInfo[] == Idx
  349. // then overwrite that entry
  350. //
  351. if (Idx < (SHORT)cTab) {
  352. //
  353. // Remove the one which match to the Idx
  354. //
  355. for (i = 0; i < cTab; i++, pTI++) {
  356. if ((CurIdx = pTI->OrgInsIdx) == Idx) {
  357. RetIdx = Idx;
  358. } else {
  359. if (CurIdx > Idx) {
  360. --CurIdx;
  361. }
  362. pTmp->OrgInsIdx = CurIdx;
  363. pTmp->HandleIdx = pTI->HandleIdx;
  364. ++pTmp;
  365. }
  366. }
  367. if (RetIdx >= 0) {
  368. RetIdx = (SHORT)(--(pTabTable->cTab));
  369. pTmp->OrgInsIdx =
  370. pTmp->HandleIdx = 0xFFFF;
  371. }
  372. }
  373. break;
  374. case TAB_MODE_INSERT:
  375. //
  376. // Make room for the Idx location, move everything right one space
  377. // from the Idx, for every pTabTable->TabInfo[].OrgInsIdx if it is
  378. // greater or eqaul to OrgInsIdx then add it by one, then set the
  379. // pTabTable->TabInfo[Idx].OrgInsIdx = OrgInsIdx
  380. //
  381. CurIdx = (SHORT)cTab;
  382. pTI += cTab;
  383. if (Idx > CurIdx) {
  384. Idx = CurIdx;
  385. }
  386. do {
  387. if (CurIdx == Idx) {
  388. pTI->OrgInsIdx = OrgInsIdx;
  389. pTI->HandleIdx = 0xFFFF;
  390. } else {
  391. if (CurIdx > Idx) {
  392. *pTI = *(pTI - 1);
  393. }
  394. if (pTI->OrgInsIdx >= OrgInsIdx) {
  395. ++pTI->OrgInsIdx;
  396. }
  397. }
  398. pTI--;
  399. } while (CurIdx--);
  400. RetIdx = (SHORT)(++(pTabTable->cTab));
  401. break;
  402. }
  403. CPSUIDBG(DBG_TABTABLE,
  404. ("%hs(0x%lx, %ld, %ld)=%ld",
  405. pszTabMode[Mode], pTabTable, (LONG)Idx, (LONG)OrgInsIdx,
  406. (LONG)RetIdx));
  407. return((LONG)RetIdx);
  408. }
  409. BOOL
  410. CALLBACK
  411. NO_PSN_APPLY_PROC(
  412. HWND hDlg,
  413. UINT Msg,
  414. WPARAM wParam,
  415. LPARAM lParam
  416. )
  417. {
  418. #define pNMHdr ((NMHDR *)lParam)
  419. #define pPN ((PSHNOTIFY *)lParam)
  420. DLGPROC OldDlgProc;
  421. if (OldDlgProc = (DLGPROC)GetProp(hDlg, CPSUIPROP_WNDPROC)) {
  422. switch (Msg) {
  423. case WM_NOTIFY:
  424. if (pNMHdr->code == PSN_APPLY) {
  425. //
  426. // Ignore it
  427. //
  428. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, 0);
  429. CPSUIDBG(DBG_GET_TABWND,
  430. ("!!IGNORE NO_PSN_APPLY_PROC(%ld, PSN_APPLY %08lx (%08lx), %ld (%ld), %ld, %ld), hDlg=%08lx",
  431. wParam,
  432. pNMHdr->hwndFrom, GetParent(hDlg),
  433. pNMHdr->idFrom, GetWindowLongPtr(GetParent(hDlg), GWLP_ID),
  434. pNMHdr->code, pPN->lParam, hDlg));
  435. return(TRUE);
  436. }
  437. break;
  438. case WM_DESTROY:
  439. RemoveProp(hDlg, CPSUIPROP_WNDPROC);
  440. SetWindowLongPtr(hDlg, DWLP_DLGPROC, (LPARAM)OldDlgProc);
  441. CPSUIDBG(DBG_GET_TABWND,
  442. ("!! NO_PSN_APPLY_PROC(WM_DESTORY): hDlg=%08lx, Change DlgProc back to %08lx",
  443. hDlg, OldDlgProc));
  444. break;
  445. }
  446. return((BOOL)CallWindowProc((WNDPROC)OldDlgProc,
  447. hDlg,
  448. Msg,
  449. wParam,
  450. lParam));
  451. }
  452. return(TRUE);
  453. #undef pPN
  454. #undef pNMHdr
  455. }
  456. BOOL
  457. CALLBACK
  458. SetIgnorePSNApplyProc(
  459. PCPSUIPAGE pPage
  460. )
  461. /*++
  462. Routine Description:
  463. Arguments:
  464. Return Value:
  465. Author:
  466. 04-Feb-1998 Wed 22:51:57 created -by- Daniel Chou (danielc)
  467. Revision History:
  468. --*/
  469. {
  470. HWND hDlg;
  471. DLGPROC OldDlgProc;
  472. BOOL Ok = FALSE;
  473. if (hDlg = pPage->hPageInfo.hDlg) {
  474. if (pPage->Flags & CPF_NO_PSN_APPLY) {
  475. //
  476. // Following will prevent us to set it more than once
  477. //
  478. if ((!(pPage->Flags & CPF_DLGPROC_CHANGED)) &&
  479. (OldDlgProc = (DLGPROC)GetWindowLongPtr(hDlg, DWLP_DLGPROC)) &&
  480. (OldDlgProc != (DLGPROC)NO_PSN_APPLY_PROC) &&
  481. (!GetProp(hDlg, CPSUIPROP_WNDPROC)) &&
  482. (SetProp(hDlg, CPSUIPROP_WNDPROC, (HANDLE)OldDlgProc)) &&
  483. (SetWindowLongPtr(hDlg,
  484. DWLP_DLGPROC,
  485. (LPARAM)NO_PSN_APPLY_PROC))) {
  486. Ok = TRUE;
  487. pPage->Flags |= CPF_DLGPROC_CHANGED;
  488. CPSUIDBG(DBG_GET_TABWND,
  489. ("SetIgnorePSNApplyProc: pPage=%08lx, DlgProc: %08lx --> NO_PSN_APPLY_PROC",
  490. pPage, OldDlgProc));
  491. }
  492. } else {
  493. if ((pPage->Flags & CPF_DLGPROC_CHANGED) &&
  494. (OldDlgProc = (DLGPROC)GetProp(hDlg, CPSUIPROP_WNDPROC)) &&
  495. (SetWindowLongPtr(hDlg, DWLP_DLGPROC, (LPARAM)OldDlgProc))) {
  496. Ok = TRUE;
  497. pPage->Flags &= ~CPF_DLGPROC_CHANGED;
  498. RemoveProp(hDlg, CPSUIPROP_WNDPROC);
  499. CPSUIDBG(DBG_GET_TABWND,
  500. ("SetIgnorePSNApplyProc: pPage=%08lx, DlgProc: NO_PSN_APPLY_PROC --> %08lx",
  501. pPage, OldDlgProc));
  502. }
  503. }
  504. } else {
  505. CPSUIDBG(DBG_GET_TABWND,
  506. ("SetIgnorePSNApplyProc: pPage=%08lx, hDlg=NULL", pPage));
  507. }
  508. if (!Ok) {
  509. CPSUIDBG(DBG_GET_TABWND,
  510. ("SetIgnorePSNApplyProc: hDlg=%08lx, pPage=%08lx, Handle=%08lx, FAILED",
  511. hDlg, pPage, pPage->hCPSUIPage));
  512. }
  513. return(Ok);
  514. }
  515. LRESULT
  516. CALLBACK
  517. TabCtrlWndProc(
  518. HWND hWnd,
  519. UINT Msg,
  520. WPARAM wParam,
  521. LPARAM lParam
  522. )
  523. {
  524. PTABTABLE pTabTable;
  525. LRESULT Result = 0;
  526. WORD Idx;
  527. if ((pTabTable = (PTABTABLE)GetProp(hWnd, CPSUIPROP_TABTABLE)) &&
  528. (!IsBadWritePtr(pTabTable, sizeof(TABTABLE))) &&
  529. (pTabTable->pTabTable == pTabTable)) {
  530. NULL;
  531. } else {
  532. pTabTable = NULL;
  533. CPSUIERR(("TabCtrlWndProc: pTabTable=%08lx, BadPtr=%ld",
  534. pTabTable, IsBadWritePtr(pTabTable, sizeof(TABTABLE))));
  535. }
  536. CPSUIDBGBLK(
  537. {
  538. if (Msg >= TCM_FIRST) {
  539. switch (Msg) {
  540. case TCM_GETCURSEL:
  541. CPSUIDBG(DBG_TCMPROC, ("TCM_GETCURSEL"));
  542. break;
  543. case TCM_HITTEST:
  544. CPSUIDBG(DBG_TCMPROC, ("TCM_HITTEST"));
  545. break;
  546. case TCM_DELETEITEM:
  547. CPSUIDBG(DBG_TCMPROC, ("TCM_DELETEITEM"));
  548. break;
  549. case TCM_GETITEMRECT:
  550. CPSUIDBG(DBG_TCMPROC, ("TCM_GETITEMRECT"));
  551. break;
  552. case TCM_GETITEMA:
  553. CPSUIDBG(DBG_TCMPROC, ("TCM_GETITEMA"));
  554. break;
  555. case TCM_GETITEMW:
  556. CPSUIDBG(DBG_TCMPROC, ("TCM_GETITEMW"));
  557. break;
  558. case TCM_SETITEMA:
  559. CPSUIDBG(DBG_TCMPROC, ("TCM_SETITEMA"));
  560. break;
  561. case TCM_SETITEMW:
  562. CPSUIDBG(DBG_TCMPROC, ("TCM_SETITEMW"));
  563. break;
  564. case TCM_SETCURSEL:
  565. CPSUIDBG(DBG_TCMPROC, ("TCM_SETCURSEL"));
  566. break;
  567. case TCM_INSERTITEMA:
  568. CPSUIDBG(DBG_TCMPROC, ("TCM_INSERTITEMA"));
  569. break;
  570. case TCM_INSERTITEMW:
  571. CPSUIDBG(DBG_TCMPROC, ("TCM_INSERTITEMW"));
  572. break;
  573. case TCM_DELETEALLITEMS:
  574. CPSUIDBG(DBG_TCMPROC, ("TCM_DELETEALLITEMS"));
  575. break;
  576. default:
  577. CPSUIDBG(DBG_TCMPROC, ("TCM_FIRST + %ld", Msg - TCM_FIRST));
  578. break;
  579. }
  580. }
  581. })
  582. if (pTabTable) {
  583. TC_ITEM *ptci;
  584. WPARAM OldwParam;
  585. WORD wIdx;
  586. BOOL CallOldProc;
  587. ptci = (TC_ITEM *)lParam;
  588. OldwParam = wParam;
  589. CallOldProc = TRUE;
  590. switch (Msg) {
  591. //
  592. // These are TAB_MODE_INSERT after call
  593. //
  594. case TCM_INSERTITEMA:
  595. case TCM_INSERTITEMW:
  596. DBG_SHOW_PTCI("!!BEFORE!!", wParam, ptci);
  597. if (pTabTable->cTab >= MAXPROPPAGES) {
  598. CPSUIERR(("Too may TABs=%ld, can not add any more.",
  599. pTabTable->cTab));
  600. return(-1);
  601. }
  602. if (OldwParam > pTabTable->cTab) {
  603. OldwParam = (WPARAM)pTabTable->cTab;
  604. }
  605. if ((wIdx = pTabTable->InsIdx) > pTabTable->cTab) {
  606. wIdx = pTabTable->cTab;
  607. }
  608. wParam = (WPARAM)wIdx;
  609. break;
  610. //
  611. // These are TAB_MODE_FIND after call
  612. //
  613. case TCM_GETCURSEL:
  614. case TCM_HITTEST:
  615. ptci = NULL;
  616. if ((Result = CallWindowProc(pTabTable->WndProc,
  617. hWnd,
  618. Msg,
  619. wParam,
  620. lParam)) >= 0) {
  621. if ((Msg == TCM_GETCURSEL) &&
  622. (pTabTable->CurSel != (WORD)Result) &&
  623. (!(pTabTable->TabInfo[Result].hDlg))) {
  624. CPSUIDBG(DBG_GET_TABWND, ("!! TCM_GETCURSEL: PostMessage(TCM_SETCURSEL=%ld, CurSel=%ld) to Get hDlg/DlgProc",
  625. Result, pTabTable->CurSel));
  626. CPSUIDBG(DBG_GET_TABWND,
  627. ("TCM_GETCURSEL: MAP TabInfo[%ld]=%d, Handle=%08lx, hDlg=%08lx",
  628. Result, pTabTable->TabInfo[Result].OrgInsIdx,
  629. pTabTable->TabInfo[Result].HandleIdx,
  630. pTabTable->TabInfo[Result].hDlg));
  631. pTabTable->cPostSetCurSel = COUNT_POSTSETCURSEL;
  632. pTabTable->iPostSetCurSel = (SHORT)Result;
  633. PostMessage(hWnd, TCM_SETCURSEL, Result, 0);
  634. }
  635. Result = (LONG)pTabTable->TabInfo[Result].OrgInsIdx;
  636. }
  637. CallOldProc = FALSE;
  638. break;
  639. //
  640. // These are TAB_MODE_FIND before call, and return TRUE/FALSE
  641. //
  642. case TCM_DELETEITEM:
  643. case TCM_GETITEMRECT:
  644. ptci = NULL;
  645. case TCM_GETITEMA:
  646. case TCM_GETITEMW:
  647. case TCM_SETITEMA:
  648. case TCM_SETITEMW:
  649. DBG_SHOW_PTCI("!!BEFORE!!", wParam, ptci);
  650. if ((Result = DoTabTable(TAB_MODE_FIND,
  651. pTabTable,
  652. (SHORT)wParam,
  653. 0)) >= 0) {
  654. wParam = (WPARAM)Result;
  655. } else {
  656. CallOldProc = FALSE;
  657. }
  658. break;
  659. //
  660. // These are TAB_MODE_FIND before call, and return Index
  661. //
  662. case TCM_SETCURSEL:
  663. ptci = NULL;
  664. DBG_SHOW_PTCI("!!BEFORE!!", wParam, ptci);
  665. CPSUIDBG(DBG_GET_TABWND, ("SETCURSEL: %ld --> %ld, CurSel=%ld",
  666. wParam, DoTabTable(TAB_MODE_FIND, pTabTable, (SHORT)wParam, 0),
  667. pTabTable->CurSel));
  668. if ((Result = DoTabTable(TAB_MODE_FIND,
  669. pTabTable,
  670. (SHORT)wParam,
  671. 0)) >= 0) {
  672. wParam = (WPARAM)Result;
  673. } else {
  674. CallOldProc = FALSE;
  675. }
  676. break;
  677. //
  678. // These are no item index passed
  679. //
  680. default:
  681. ptci = NULL;
  682. break;
  683. }
  684. if (CallOldProc) {
  685. Result = CallWindowProc(pTabTable->WndProc,
  686. hWnd,
  687. Msg,
  688. wParam,
  689. lParam);
  690. DBG_SHOW_PTCI("!!AFTER!!", wParam, ptci);
  691. }
  692. switch (Msg) {
  693. case TCM_DELETEALLITEMS:
  694. if (Result) {
  695. DoTabTable(TAB_MODE_DELETE_ALL, pTabTable, 0, 0);
  696. }
  697. break;
  698. case TCM_DELETEITEM:
  699. if (Result) {
  700. DoTabTable(TAB_MODE_DELETE, pTabTable, (SHORT)OldwParam, 0);
  701. CPSUIDBG(DBG_GET_TABWND,
  702. ("DeleteItem: Result=%ld, OldwParam=%u, Count=%ld",
  703. Result, OldwParam, pTabTable->cTab));
  704. SHOW_TABWND(L"TCM_DELETEITEM", pTabTable);
  705. }
  706. break;
  707. case TCM_GETITEMA:
  708. case TCM_GETITEMW:
  709. if (pTabTable->iPostSetCurSel >= 0) {
  710. pTabTable->cPostSetCurSel = COUNT_POSTSETCURSEL;
  711. PostMessage(hWnd,
  712. TCM_SETCURSEL,
  713. (WPARAM)pTabTable->iPostSetCurSel,
  714. 0);
  715. }
  716. break;
  717. case TCM_INSERTITEMA:
  718. case TCM_INSERTITEMW:
  719. if (Result >= 0) {
  720. DoTabTable(TAB_MODE_INSERT,
  721. pTabTable,
  722. (SHORT)Result,
  723. (SHORT)OldwParam);
  724. pTabTable->TabInfo[Result].HandleIdx = pTabTable->HandleIdx;
  725. CPSUIDBG(DBG_GET_TABWND,
  726. ("InsertItem: OldwParam=%ld, Result=%ld, Count=%ld, Handle=%08lx",
  727. OldwParam, Result, pTabTable->cTab,
  728. WORD_2_HANDLE(pTabTable->HandleIdx)));
  729. SHOW_TABWND(L"TCM_INSERTITEM", pTabTable);
  730. }
  731. //
  732. // Reset to the maximum
  733. //
  734. pTabTable->InsIdx =
  735. pTabTable->HandleIdx = 0xFFFF;
  736. break;
  737. case TCM_SETCURSEL:
  738. if (Result >= 0) {
  739. PCPSUIPAGE pPage;
  740. HWND hDlg;
  741. DLGPROC DlgProc;
  742. PTABINFO pTI;
  743. //
  744. // Invert the return value from tab table
  745. //
  746. pTI = &(pTabTable->TabInfo[wParam]);
  747. CPSUIDBG(DBG_GET_TABWND, ("SETCURSEL: Result:OldSel=%ld --> %ld, CurSel=%ld",
  748. Result, pTabTable->TabInfo[Result].OrgInsIdx, wParam));
  749. pTabTable->CurSel = (WORD)wParam;
  750. if (!pTI->hDlg) {
  751. Idx = pTI->HandleIdx;
  752. if (hDlg = (HWND)SendMessage(pTabTable->hPSDlg,
  753. PSM_GETCURRENTPAGEHWND,
  754. (WPARAM)0,
  755. (LPARAM)0)) {
  756. UINT i = (UINT)pTabTable->cTab;
  757. PTABINFO pTIChk = pTabTable->TabInfo;
  758. //
  759. // Find out if we already has this hDlg, if we do
  760. // then we are in trouble, since it cannot have two
  761. // Tab Pages with same hDlg
  762. //
  763. while (i--) {
  764. if (pTIChk->hDlg == hDlg) {
  765. CPSUIASSERT(0, "SetCurSel: Table.hDlg already exist in TabInfo[%ld]",
  766. pTIChk->hDlg != hDlg, UIntToPtr(pTabTable->cTab - i - 1));
  767. hDlg = NULL;
  768. break;
  769. } else {
  770. pTIChk++;
  771. }
  772. }
  773. }
  774. if ((hDlg) &&
  775. (DlgProc = (DLGPROC)GetWindowLongPtr(hDlg,
  776. DWLP_DLGPROC)) &&
  777. (pPage =
  778. HANDLETABLE_GetCPSUIPage(WORD_2_HANDLE(Idx)))) {
  779. pTabTable->cPostSetCurSel = 0;
  780. pTabTable->iPostSetCurSel = -1;
  781. CPSUIDBG(DBG_GET_TABWND,
  782. ("SETCURSEL(%08lx): TabInfo[%u]: Handle=%08lx, hDlg=%08lx (%08lx), DlgProc=%08lx --> %08lx",
  783. pTabTable->hPSDlg,
  784. wParam, WORD_2_HANDLE(Idx),
  785. pPage->hPageInfo.hDlg, hDlg,
  786. pPage->hPageInfo.DlgProc, DlgProc));
  787. pTI->hDlg =
  788. pPage->hPageInfo.hDlg = hDlg;
  789. pPage->hPageInfo.DlgProc = DlgProc;
  790. pPage->Flags |= CPF_ACTIVATED;
  791. if ((pPage->Flags & (CPF_NO_PSN_APPLY |
  792. CPF_DLGPROC_CHANGED)) ==
  793. CPF_NO_PSN_APPLY) {
  794. SetIgnorePSNApplyProc(pPage);
  795. }
  796. HANDLETABLE_UnGetCPSUIPage(pPage);
  797. SHOW_TABWND(L"TCM_SETCURSEL", pTabTable);
  798. } else if (pTabTable->cPostSetCurSel) {
  799. --(pTabTable->cPostSetCurSel);
  800. CPSUIDBG(DBG_GET_TABWND,
  801. ("!! FAILED: (Dlg=%08lx, DlgProc=%08lx, pPage=%08lx), PostMessage(TCM_SETCURSEL=%ld)",
  802. hDlg, DlgProc, pPage, pTI->OrgInsIdx));
  803. PostMessage(hWnd,
  804. TCM_SETCURSEL,
  805. (WPARAM)pTI->OrgInsIdx,
  806. 0);
  807. } else {
  808. pTabTable->iPostSetCurSel = (SHORT)pTI->OrgInsIdx;
  809. }
  810. } else {
  811. pTabTable->cPostSetCurSel = 0;
  812. pTabTable->iPostSetCurSel = -1;
  813. }
  814. Result = (LONG)pTabTable->TabInfo[Result].OrgInsIdx;
  815. CPSUIDBG(DBG_TCMPROC, ("TCM_SETCURSEL: MAP TabInfo[%ld]=%d (%08lx)",
  816. Result, pTabTable->TabInfo[Result].OrgInsIdx,
  817. WORD_2_HANDLE(pTabTable->TabInfo[Result].HandleIdx)));
  818. }
  819. break;
  820. case TCM_GETITEMCOUNT:
  821. if (Result != (LONG)pTabTable->cTab) {
  822. CPSUIERR(("TCM_GETITEMCOUNT=%ld is not equal to cTab=%ld",
  823. Result, (LONG)pTabTable->cTab));
  824. }
  825. break;
  826. case WM_DESTROY:
  827. SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LPARAM)pTabTable->WndProc);
  828. RemoveProp(hWnd, CPSUIPROP_TABTABLE);
  829. break;
  830. }
  831. if (Msg >= TCM_FIRST) {
  832. CPSUIDBG(DBG_TCMPROC, ("!! Result=%ld !!\n", Result));
  833. }
  834. }
  835. return(Result);
  836. }
  837. LONG_PTR
  838. SetPSUIPageTitle(
  839. PCPSUIPAGE pRootPage,
  840. PCPSUIPAGE pPage,
  841. LPWSTR pTitle,
  842. BOOL AnsiCall
  843. )
  844. /*++
  845. Routine Description:
  846. Arguments:
  847. Return Value:
  848. Author:
  849. 21-Feb-1996 Wed 14:16:17 created -by- Daniel Chou (danielc)
  850. Revision History:
  851. --*/
  852. {
  853. HWND hWndTab;
  854. INSPAGEIDXINFO InsPageIdxInfo;
  855. if ((pTitle) &&
  856. (InsPageIdxInfo.pCPSUIPage = pPage) &&
  857. (pRootPage->RootInfo.hDlg) &&
  858. (!(pPage->Flags & CPF_PARENT)) &&
  859. (pPage->hPage) &&
  860. (InsPageIdxInfo.pTabTable = pRootPage->RootInfo.pTabTable) &&
  861. (hWndTab = pRootPage->RootInfo.pTabTable->hWndTab)) {
  862. //
  863. // The property sheet already displayed
  864. //
  865. EnumCPSUIPagesSeq(pRootPage,
  866. pRootPage,
  867. SetInsPageIdxProc,
  868. (LPARAM)&InsPageIdxInfo);
  869. if (InsPageIdxInfo.pCPSUIPage == NULL) {
  870. TC_ITEM tcItem;
  871. tcItem.mask = TCIF_TEXT;
  872. tcItem.pszText = pTitle;
  873. if (SendMessage(hWndTab,
  874. (AnsiCall) ? TCM_SETITEMA : TCM_SETITEMW,
  875. (WPARAM)GET_REAL_INSIDX(InsPageIdxInfo.pTabTable),
  876. (LPARAM)(TC_ITEM FAR*)&tcItem)) {
  877. return(1);
  878. }
  879. }
  880. }
  881. return(0);
  882. }
  883. LONG_PTR
  884. SetPSUIPageIcon(
  885. PCPSUIPAGE pRootPage,
  886. PCPSUIPAGE pPage,
  887. HICON hIcon
  888. )
  889. /*++
  890. Routine Description:
  891. Arguments:
  892. Return Value:
  893. Author:
  894. 21-Feb-1996 Wed 14:16:17 created -by- Daniel Chou (danielc)
  895. Revision History:
  896. --*/
  897. {
  898. HWND hWndTab;
  899. INSPAGEIDXINFO InsPageIdxInfo;
  900. while ((pPage) && (pPage->Flags & CPF_PARENT)) {
  901. pPage = pPage->pChild;
  902. }
  903. if ((InsPageIdxInfo.pCPSUIPage = pPage) &&
  904. (pRootPage->RootInfo.hDlg) &&
  905. (!(pPage->Flags & CPF_PARENT)) &&
  906. (pPage->hPage) &&
  907. (InsPageIdxInfo.pTabTable = pRootPage->RootInfo.pTabTable) &&
  908. (hWndTab = pRootPage->RootInfo.pTabTable->hWndTab)) {
  909. //
  910. // The property sheet already displayed
  911. //
  912. EnumCPSUIPagesSeq(pRootPage,
  913. pRootPage,
  914. SetInsPageIdxProc,
  915. (LPARAM)&InsPageIdxInfo);
  916. if (InsPageIdxInfo.pCPSUIPage == NULL) {
  917. HIMAGELIST himi;
  918. TC_ITEM tcItem;
  919. UINT InsIdx;
  920. InsIdx = (UINT)GET_REAL_INSIDX(InsPageIdxInfo.pTabTable);
  921. himi = TabCtrl_GetImageList(hWndTab);
  922. if (pPage->hPageInfo.hIcon) {
  923. //
  924. // Replace the Image ID icon
  925. //
  926. if (!himi) {
  927. CPSUIERR(("SetPSUIPageIcon: No Image List in Tab Control"));
  928. return(0);
  929. }
  930. tcItem.mask = TCIF_IMAGE;
  931. if (SendMessage(hWndTab,
  932. TCM_GETITEMW,
  933. (WPARAM)InsIdx,
  934. (LPARAM)(TC_ITEM FAR*)&tcItem)) {
  935. if (hIcon) {
  936. tcItem.iImage = ImageList_ReplaceIcon(himi,
  937. tcItem.iImage,
  938. hIcon);
  939. } else {
  940. //
  941. // We need to remove this from image list
  942. //
  943. ImageList_Remove(himi, tcItem.iImage);
  944. tcItem.iImage = -1;
  945. }
  946. } else {
  947. tcItem.iImage = -1;
  948. }
  949. } else {
  950. //
  951. // Add new icon to the image list only if hIcon is not NULL
  952. //
  953. //
  954. if (hIcon) {
  955. if (!himi) {
  956. if (!(himi = ImageList_Create(16,
  957. 16,
  958. ILC_COLOR4 | ILC_MASK,
  959. 16,
  960. 16))) {
  961. CPSUIERR(("SetPSUIPageIcon: Create Tab Contrl Image List FAILED"));
  962. return(0);
  963. }
  964. if (SendMessage(hWndTab,
  965. TCM_SETIMAGELIST,
  966. 0,
  967. (LPARAM)himi)) {
  968. CPSUIERR(("SetPSUIPageIcon: ?Has Previous Image list"));
  969. }
  970. }
  971. tcItem.iImage = ImageList_AddIcon(himi, hIcon);
  972. } else {
  973. //
  974. // nothing to do
  975. //
  976. return(1);
  977. }
  978. }
  979. pPage->hPageInfo.hIcon = hIcon;
  980. tcItem.mask = TCIF_IMAGE;
  981. if (SendMessage(hWndTab,
  982. TCM_SETITEMW,
  983. (WPARAM)InsIdx,
  984. (LPARAM)(TC_ITEM FAR*)&tcItem)) {
  985. return(1);
  986. }
  987. }
  988. }
  989. return(0);
  990. }
  991. UINT
  992. CALLBACK
  993. PropSheetProc(
  994. HWND hWnd,
  995. UINT Msg,
  996. LPARAM lParam
  997. )
  998. {
  999. HWND hWndTab;
  1000. if (hWnd) {
  1001. PTABTABLE pTabTable;
  1002. HANDLE hRootPage;
  1003. PCPSUIPAGE pRootPage;
  1004. HWND hWndTab;
  1005. WORD Idx;
  1006. LOCK_CPSUI_HANDLETABLE();
  1007. Idx = TLSVALUE_2_IDX(TlsGetValue(TlsIndex));
  1008. hRootPage = WORD_2_HANDLE(Idx);
  1009. CPSUIDBG(DBG_PAGE_PROC, ("ProcessID=%ld, ThreadID=%ld [TIsValue=%08lx]",
  1010. GetCurrentProcessId(), GetCurrentThreadId(),
  1011. TlsGetValue(TlsIndex)));
  1012. if (pRootPage = HANDLETABLE_GetCPSUIPage(hRootPage)) {
  1013. if ((pRootPage->Flags & CPF_ROOT) &&
  1014. (pRootPage->RootInfo.hDlg = hWnd) &&
  1015. (pTabTable = pRootPage->RootInfo.pTabTable) &&
  1016. (pTabTable->hWndTab == NULL) &&
  1017. (pTabTable->hWndTab = hWndTab =
  1018. PropSheet_GetTabControl(hWnd))) {
  1019. //
  1020. // Done and remembered so reset it back to 0
  1021. //
  1022. CPSUIDBG(DBG_PAGE_PROC,
  1023. ("PropSheetProc: hDlg RootPage=%08lx", hWnd));
  1024. pTabTable->hPSDlg = hWnd;
  1025. pTabTable->WndProc = (WNDPROC)GetWindowLongPtr(hWndTab,
  1026. GWLP_WNDPROC);
  1027. SetProp(hWndTab, CPSUIPROP_TABTABLE, (HANDLE)pTabTable);
  1028. SetWindowLongPtr(hWndTab, GWLP_WNDPROC, (LPARAM)TabCtrlWndProc);
  1029. }
  1030. HANDLETABLE_UnGetCPSUIPage(pRootPage);
  1031. } else {
  1032. CPSUIERR(("PropSheetProc(): Invalid pRootPage=%08lx ???", pRootPage));
  1033. }
  1034. UNLOCK_CPSUI_HANDLETABLE();
  1035. }
  1036. CPSUIDBG(DBG_PAGE_PROC,
  1037. ("hWnd=%08lx, Msg=%ld, lParam=%08lx", hWnd, Msg, lParam));
  1038. return(0);
  1039. }
  1040. UINT
  1041. CALLBACK
  1042. CPSUIPSPCallBack(
  1043. HWND hWnd,
  1044. UINT Msg,
  1045. LPPROPSHEETPAGE pPSPage
  1046. )
  1047. /*++
  1048. Routine Description:
  1049. This function trap user supplied PropSheetPageProc callback function to
  1050. fixed up our PROPSHEETPAGE structure's lParam, pfnCallback, pfnDlgProc and
  1051. dwSize.
  1052. Arguments:
  1053. Return Value:
  1054. Author:
  1055. 28-Jun-1996 Fri 12:49:48 created -by- Daniel Chou (danielc)
  1056. Revision History:
  1057. --*/
  1058. {
  1059. ULONG_PTR ulCookie = 0;
  1060. BOOL bCtxActivated = FALSE;
  1061. HANDLE hActCtx = INVALID_HANDLE_VALUE;
  1062. if (Msg == PSPCB_CREATE) {
  1063. PCPSUIPAGE pCPSUIPage;
  1064. DLGPROC DlgProc;
  1065. LPFNPSPCALLBACK pspCB;
  1066. DWORD dwSize;
  1067. UINT Result;
  1068. pCPSUIPage = (PCPSUIPAGE)pPSPage->lParam;
  1069. DlgProc = pPSPage->pfnDlgProc;
  1070. pspCB = pPSPage->pfnCallback;
  1071. dwSize = pPSPage->dwSize;
  1072. CPSUIDBG(DBG_PAGEDLGPROC,
  1073. ("PSPCB_CREATE(1): pCPSUIPage=%08lx, DlgProc=%08lx, lParam=%08lx, pspCB=%08lx, Size=%ld",
  1074. pCPSUIPage, pPSPage->pfnDlgProc,
  1075. pPSPage->lParam, pPSPage->pfnCallback, pPSPage->dwSize));
  1076. //
  1077. // fixed up user's pfnDlgProc, lParam, pfnCallback, dwSize
  1078. //
  1079. pPSPage->pfnDlgProc = pCPSUIPage->hPageInfo.DlgProc;
  1080. pPSPage->lParam = pCPSUIPage->hPageInfo.lParam;
  1081. pPSPage->pfnCallback = pCPSUIPage->hPageInfo.pspCB;
  1082. pPSPage->dwSize = pCPSUIPage->hPageInfo.dwSize;
  1083. CPSUIDBG(DBG_PSPCB,
  1084. ("CPSUIPSPCallBack(hWnd=%08lx, Msg=%ld, pPSPage=%08lx)",
  1085. hWnd, Msg, pPSPage));
  1086. try {
  1087. if (GetPageActivationContext(pCPSUIPage, &hActCtx)) {
  1088. bCtxActivated = ActivateActCtx(hActCtx, &ulCookie);
  1089. }
  1090. __try {
  1091. Result = pPSPage->pfnCallback(hWnd, Msg, pPSPage);
  1092. }
  1093. __finally {
  1094. //
  1095. // we need to deactivate the context, no matter what!
  1096. //
  1097. if (bCtxActivated) {
  1098. DeactivateActCtx(0, ulCookie);
  1099. }
  1100. }
  1101. } except (FilterException(pCPSUIPage->hCPSUIPage,
  1102. GetExceptionInformation())) {
  1103. Result = 0;
  1104. }
  1105. //
  1106. // save back if user change it
  1107. //
  1108. pCPSUIPage->hPageInfo.DlgProc = pPSPage->pfnDlgProc;
  1109. pCPSUIPage->hPageInfo.lParam = pPSPage->lParam;
  1110. pCPSUIPage->hPageInfo.pspCB = pPSPage->pfnCallback;
  1111. CPSUIDBG(DBG_PAGEDLGPROC,
  1112. ("PSPCB_CREATE(2): pCPSUIPage=%08lx, DlgProc=%08lx, lParam=%08lx, pspCB=%08lx, Size=%ld",
  1113. pCPSUIPage, pPSPage->pfnDlgProc,
  1114. pPSPage->lParam, pPSPage->pfnCallback, pPSPage->dwSize));
  1115. //
  1116. // Now put in original content at this call
  1117. //
  1118. pPSPage->pfnDlgProc = DlgProc;
  1119. pPSPage->lParam = (LPARAM)pCPSUIPage;
  1120. pPSPage->pfnCallback = pspCB;
  1121. pPSPage->dwSize = dwSize;
  1122. CPSUIDBG(DBG_PAGEDLGPROC,
  1123. ("PSPCB_CREATE(3): pCPSUIPage=%08lx, DlgProc=%08lx, lParam=%08lx, pspCB=%08lx, Size=%ld",
  1124. pCPSUIPage, pPSPage->pfnDlgProc,
  1125. pPSPage->lParam, pPSPage->pfnCallback, pPSPage->dwSize));
  1126. return(Result);
  1127. } else {
  1128. CPSUIERR(("CPSUIPSPCallBack: Invalid Msg=%u passed, return 0", Msg));
  1129. return(0);
  1130. }
  1131. }
  1132. INT_PTR
  1133. CALLBACK
  1134. CPSUIPageDlgProc(
  1135. HWND hDlg,
  1136. UINT Msg,
  1137. WPARAM wParam,
  1138. LPARAM lParam
  1139. )
  1140. /*++
  1141. Routine Description:
  1142. This function trap for each property sheet page activation for remember
  1143. its hDlg and handle to the property sheet, after we trap the WM_INITDIALOG
  1144. we will release the trap DlgProc.
  1145. Arguments:
  1146. Return Value:
  1147. Author:
  1148. 28-Jun-1995 Wed 17:00:44 created -by- Daniel Chou (danielc)
  1149. Revision History:
  1150. Add original dwSize, pfnCallback trap
  1151. --*/
  1152. {
  1153. ULONG_PTR ulCookie = 0;
  1154. BOOL bCtxActivated = FALSE;
  1155. HANDLE hActCtx = INVALID_HANDLE_VALUE;
  1156. if (Msg == WM_INITDIALOG) {
  1157. LPPROPSHEETPAGE pPSPage;
  1158. PCPSUIPAGE pCPSUIPage;
  1159. PCPSUIPAGE pRootPage;
  1160. LONG Result;
  1161. pPSPage = (LPPROPSHEETPAGE)lParam;
  1162. pRootPage =
  1163. pCPSUIPage = (PCPSUIPAGE)pPSPage->lParam;
  1164. while (pRootPage->pParent) {
  1165. pRootPage = pRootPage->pParent;
  1166. }
  1167. CPSUIASSERT(0, "CPSUIPageDlgProc: No ROOT Page=%08lx",
  1168. (pRootPage->Flags & CPF_ROOT), pRootPage);
  1169. if (pRootPage->Flags & CPF_ROOT) {
  1170. if (pRootPage->RootInfo.hDlg) {
  1171. CPSUIDBG(DBG_PAGEDLGPROC,
  1172. ("CPSUIPageDlgProc: Already has a hDlg in ROOT=%08lx",
  1173. pRootPage->RootInfo.hDlg));
  1174. } else {
  1175. pRootPage->RootInfo.hDlg = GetParent(hDlg);
  1176. }
  1177. }
  1178. //
  1179. // Fixed up user's DlgProc, lParam, pfnCallBack and dwSize and remember
  1180. // this hDlg. After we call the WM_INITDIALOG, we will not reset it
  1181. // back since we will already trap it and will not need any more of
  1182. // these information, the pfnCallback for the PSPCB_RELEASE will go to
  1183. // the user supplied callback directly if one exist.
  1184. //
  1185. pPSPage->pfnDlgProc = pCPSUIPage->hPageInfo.DlgProc;
  1186. pPSPage->lParam = pCPSUIPage->hPageInfo.lParam;
  1187. pPSPage->pfnCallback = pCPSUIPage->hPageInfo.pspCB;
  1188. pPSPage->dwSize = pCPSUIPage->hPageInfo.dwSize;
  1189. pCPSUIPage->hPageInfo.hDlg = hDlg;
  1190. pCPSUIPage->Flags |= CPF_ACTIVATED;
  1191. CPSUIDBG(DBG_PAGEDLGPROC,
  1192. ("CPSUIPageDlgProc: WM_INITDIALOG: hDlg=%08lx, pCPSUIPage=%08lx, DlgProc=%08lx, lParam=%08lx, pspCB=%08lx, Size=%ld",
  1193. hDlg, pCPSUIPage, pPSPage->pfnDlgProc,
  1194. pPSPage->lParam, pPSPage->pfnCallback, pPSPage->dwSize));
  1195. SetWindowLongPtr(hDlg, DWLP_DLGPROC, (LPARAM)pPSPage->pfnDlgProc);
  1196. try {
  1197. if (GetPageActivationContext(pCPSUIPage, &hActCtx)) {
  1198. bCtxActivated = ActivateActCtx(hActCtx, &ulCookie);
  1199. }
  1200. __try {
  1201. Result = pPSPage->pfnDlgProc(hDlg, Msg, wParam, lParam) ? TRUE : FALSE;
  1202. }
  1203. __finally {
  1204. //
  1205. // we need to deactivate the context, no matter what!
  1206. //
  1207. if (bCtxActivated) {
  1208. DeactivateActCtx(0, ulCookie);
  1209. }
  1210. }
  1211. } except (FilterException(pRootPage->hCPSUIPage,
  1212. GetExceptionInformation())) {
  1213. Result = FALSE;
  1214. }
  1215. return(Result);
  1216. }
  1217. return(FALSE);
  1218. }
  1219. BOOL
  1220. EnumCPSUIPagesSeq(
  1221. PCPSUIPAGE pRootPage,
  1222. PCPSUIPAGE pCPSUIPage,
  1223. CPSUIPAGEENUMPROC CPSUIPageEnumProc,
  1224. LPARAM lParam
  1225. )
  1226. /*++
  1227. Routine Description:
  1228. This function enumerate pCPSUIPage and all its children includes header
  1229. page of children. The enumeration always enumerate in the order of
  1230. Parent first then the children in the sequence of tree.
  1231. Arguments:
  1232. pCPSUIPage - The starting parent page to be enumberated
  1233. CPSUIPageEnumProc - The caller supplied function for each enumberated
  1234. page, this fucntion return FALSE to stop enumeration.
  1235. lParam - a 32-bit parameter passed to the caller supplied
  1236. enumeration funciton
  1237. Return Value:
  1238. BOOLEAN
  1239. Author:
  1240. 29-Dec-1995 Fri 15:25:01 created -by- Daniel Chou (danielc)
  1241. Revision History:
  1242. --*/
  1243. {
  1244. BOOL Ok = TRUE;
  1245. //
  1246. // now enumerate the parent
  1247. //
  1248. LOCK_CPSUI_HANDLETABLE();
  1249. if (CPSUIPageEnumProc(pRootPage, pCPSUIPage, lParam)) {
  1250. if (pCPSUIPage->Flags & CPF_PARENT) {
  1251. //
  1252. // If this a parent then enum all its children first
  1253. //
  1254. PCPSUIPAGE pCurPage = pCPSUIPage->pChild;
  1255. PCPSUIPAGE pNext;
  1256. while (pCurPage) {
  1257. pNext = pCurPage->pNext;
  1258. if (!EnumCPSUIPagesSeq(pRootPage,
  1259. pCurPage,
  1260. CPSUIPageEnumProc,
  1261. lParam)) {
  1262. Ok = FALSE;
  1263. break;
  1264. }
  1265. pCurPage = pNext;
  1266. }
  1267. }
  1268. } else {
  1269. Ok = FALSE;
  1270. }
  1271. UNLOCK_CPSUI_HANDLETABLE();
  1272. return(Ok);
  1273. }
  1274. BOOL
  1275. EnumCPSUIPages(
  1276. PCPSUIPAGE pRootPage,
  1277. PCPSUIPAGE pCPSUIPage,
  1278. CPSUIPAGEENUMPROC CPSUIPageEnumProc,
  1279. LPARAM lParam
  1280. )
  1281. /*++
  1282. Routine Description:
  1283. This function enumerate pCPSUIPage and all its children includes header
  1284. page of children. The enumeration always enumerate in the order of
  1285. children first then the parent.
  1286. Arguments:
  1287. pCPSUIPage - The starting parent page to be enumberated
  1288. CPSUIPageEnumProc - The caller supplied function for each enumberated
  1289. page, this fucntion return FALSE to stop enumeration.
  1290. lParam - a 32-bit parameter passed to the caller supplied
  1291. enumeration funciton
  1292. Return Value:
  1293. BOOLEAN
  1294. Author:
  1295. 29-Dec-1995 Fri 15:25:01 created -by- Daniel Chou (danielc)
  1296. Revision History:
  1297. --*/
  1298. {
  1299. BOOL Ok = TRUE;
  1300. LOCK_CPSUI_HANDLETABLE();
  1301. if (pCPSUIPage->Flags & CPF_PARENT) {
  1302. //
  1303. // If this a parent then enum all its children first
  1304. //
  1305. PCPSUIPAGE pCurPage = pCPSUIPage->pChild;
  1306. PCPSUIPAGE pNext;
  1307. while (pCurPage) {
  1308. pNext = pCurPage->pNext;
  1309. if (!EnumCPSUIPages(pRootPage,
  1310. pCurPage,
  1311. CPSUIPageEnumProc,
  1312. lParam)) {
  1313. Ok = FALSE;
  1314. break;
  1315. }
  1316. pCurPage = pNext;
  1317. }
  1318. }
  1319. //
  1320. // now enumerate the parent
  1321. //
  1322. if (Ok) {
  1323. Ok = CPSUIPageEnumProc(pRootPage, pCPSUIPage, lParam);
  1324. }
  1325. UNLOCK_CPSUI_HANDLETABLE();
  1326. return(Ok);
  1327. }
  1328. LONG
  1329. CallpfnPSUI(
  1330. PCPSUIPAGE pCPSUIPage,
  1331. WORD Reason,
  1332. LPARAM lParam
  1333. )
  1334. /*++
  1335. Routine Description:
  1336. Arguments:
  1337. Return Value:
  1338. Author:
  1339. 31-Jan-1996 Wed 14:27:21 created -by- Daniel Chou (danielc)
  1340. Revision History:
  1341. --*/
  1342. {
  1343. ULONG_PTR ulCookie = 0;
  1344. BOOL bCtxActivated = FALSE;
  1345. HANDLE hActCtx = INVALID_HANDLE_VALUE;
  1346. LONG Result = 0;
  1347. DWORD dwErr = ERROR_SUCCESS;
  1348. HANDLETABLE_LockCPSUIPage(pCPSUIPage);
  1349. CPSUIDBG(DBG_CALLPFN, ("\n@ CallpfnPSUI(%08lx, %hs, %08lx)", pCPSUIPage,
  1350. (Reason <= MAX_PROPSHEETUI_REASON_INDEX) ?
  1351. pszPFNReason[Reason] : "??? Unknown Reason",
  1352. (Reason == PROPSHEETUI_REASON_SET_RESULT) ?
  1353. ((PSETRESULT_INFO)lParam)->Result : lParam));
  1354. CPSUIASSERT(0, "CallpfnPSUI() Invalid Reason=%08lx",
  1355. (Reason <= MAX_PROPSHEETUI_REASON_INDEX), Reason);
  1356. if ((pCPSUIPage) &&
  1357. (pCPSUIPage->Flags & CPF_PFNPROPSHEETUI) &&
  1358. (pCPSUIPage->hCPSUIPage) &&
  1359. (pCPSUIPage->pfnInfo.pfnPSUI)) {
  1360. PCPSUIPAGE pRootPage;
  1361. PROPSHEETUI_INFO PSUIInfo;
  1362. ZeroMemory(&PSUIInfo, sizeof(PSUIInfo));
  1363. PSUIInfo.cbSize = sizeof(PROPSHEETUI_INFO);
  1364. PSUIInfo.Version = PROPSHEETUI_INFO_VERSION;
  1365. PSUIInfo.Flags = (pCPSUIPage->Flags & CPF_ANSI_CALL) ?
  1366. 0 : PSUIINFO_UNICODE;
  1367. PSUIInfo.hComPropSheet = pCPSUIPage->hCPSUIPage;
  1368. PSUIInfo.pfnComPropSheet = CPSUICallBack;
  1369. if ((PSUIInfo.Reason = Reason) == PROPSHEETUI_REASON_INIT) {
  1370. pCPSUIPage->pfnInfo.lParamInit =
  1371. PSUIInfo.lParamInit = lParam;
  1372. PSUIInfo.UserData = 0;
  1373. PSUIInfo.Result = 0;
  1374. } else {
  1375. PSUIInfo.lParamInit = pCPSUIPage->pfnInfo.lParamInit;
  1376. PSUIInfo.UserData = pCPSUIPage->pfnInfo.UserData;
  1377. PSUIInfo.Result = pCPSUIPage->pfnInfo.Result;
  1378. }
  1379. CPSUIDBG(DBG_CALLPFN, ("CallpfnCPSUI: cbSize=%ld", (DWORD)PSUIInfo.cbSize));
  1380. CPSUIDBG(DBG_CALLPFN, (" Version=%04lx", (DWORD)PSUIInfo.Version));
  1381. CPSUIDBG(DBG_CALLPFN, (" Reason=%ld", (DWORD)PSUIInfo.Reason));
  1382. CPSUIDBG(DBG_CALLPFN, (" Flags=%08lx", (DWORD)PSUIInfo.Flags));
  1383. CPSUIDBG(DBG_CALLPFN, (" hComPropSheet=%08lx", PSUIInfo.hComPropSheet));
  1384. CPSUIDBG(DBG_CALLPFN, (" pfnComPropSheet=%08lx", PSUIInfo.pfnComPropSheet));
  1385. CPSUIDBG(DBG_CALLPFN, (" Result=%08lx", PSUIInfo.Result));
  1386. CPSUIDBG(DBG_CALLPFN, (" UserData=%08lx", PSUIInfo.UserData));
  1387. try {
  1388. if (GetPageActivationContext(pCPSUIPage, &hActCtx)) {
  1389. bCtxActivated = ActivateActCtx(hActCtx, &ulCookie);
  1390. }
  1391. __try {
  1392. Result = pCPSUIPage->pfnInfo.pfnPSUI(&PSUIInfo, lParam);
  1393. }
  1394. __finally {
  1395. //
  1396. // we need to deactivate the context, no matter what!
  1397. //
  1398. if (bCtxActivated) {
  1399. DeactivateActCtx(0, ulCookie);
  1400. }
  1401. }
  1402. } except (FilterException(pCPSUIPage->hCPSUIPage,
  1403. GetExceptionInformation())) {
  1404. Result = -1;
  1405. }
  1406. if (Result <= 0) {
  1407. //
  1408. // Something has failed. Save the last error here.
  1409. //
  1410. dwErr = GetLastError();
  1411. }
  1412. //
  1413. // Save the new UserData and Result
  1414. //
  1415. pCPSUIPage->pfnInfo.UserData = PSUIInfo.UserData;
  1416. pCPSUIPage->pfnInfo.Result = PSUIInfo.Result;
  1417. //
  1418. // If this is the first pfnPropSheetUI() added and it passed a pResult
  1419. // to the CommonPropertySheetUI() then set the result for it too.
  1420. //
  1421. if ((pRootPage = pCPSUIPage->pParent) &&
  1422. (pRootPage->Flags & CPF_ROOT) &&
  1423. (pRootPage->RootInfo.pResult)) {
  1424. *(pRootPage->RootInfo.pResult) = (DWORD)PSUIInfo.Result;
  1425. }
  1426. CPSUIDBG(DBG_CALLPFN, ("---------CallpfnCPSUI()=%ld----------", Result));
  1427. CPSUIDBG(DBG_CALLPFN, (" New Result=%08lx%ws", PSUIInfo.Result,
  1428. ((pRootPage) && (pRootPage->Flags & CPF_ROOT) &&
  1429. (pRootPage->RootInfo.pResult)) ? L" (== *pResult)" : L""));
  1430. CPSUIDBG(DBG_CALLPFN, (" New UserData=%08lx\n", PSUIInfo.UserData));
  1431. } else {
  1432. CPSUIERR(("CallpfnPSUI(): Invalid pCPSUIPage=%08lx", pCPSUIPage));
  1433. }
  1434. HANDLETABLE_UnLockCPSUIPage(pCPSUIPage);
  1435. if (ERROR_SUCCESS != dwErr) {
  1436. //
  1437. // Set the preserved last error.
  1438. //
  1439. SetLastError(dwErr);
  1440. }
  1441. return(Result);
  1442. }
  1443. HICON
  1444. pfnGetIcon(
  1445. PCPSUIPAGE pPage,
  1446. LPARAM lParam
  1447. )
  1448. /*++
  1449. Routine Description:
  1450. This function return the hIcon for the pfnPropSheetUI()
  1451. Arguments:
  1452. pPage - The page has CPF_PFNPROPSHEETUI flag set
  1453. lParam - LOWORD(lParam) = cxIcon
  1454. HIWORD(lParam) = cyIcon
  1455. Return Value:
  1456. Author:
  1457. 11-Feb-1996 Sun 12:18:39 created -by- Daniel Chou (danielc)
  1458. Revision History:
  1459. --*/
  1460. {
  1461. PCPSUIPAGE pChild;
  1462. PTVWND pTVWnd;
  1463. POPTITEM pItem;
  1464. PROPSHEETUI_GETICON_INFO PSUIGetIconInfo;
  1465. PSUIGetIconInfo.cbSize = sizeof(PSUIGetIconInfo);
  1466. PSUIGetIconInfo.Flags = 0;
  1467. if (!(PSUIGetIconInfo.cxIcon = LOWORD(lParam))) {
  1468. PSUIGetIconInfo.cxIcon = (WORD)GetSystemMetrics(SM_CXICON);
  1469. }
  1470. if (!(PSUIGetIconInfo.cyIcon = HIWORD(lParam))) {
  1471. PSUIGetIconInfo.cyIcon = (WORD)GetSystemMetrics(SM_CYICON);
  1472. }
  1473. PSUIGetIconInfo.hIcon = NULL;
  1474. //
  1475. // If this is the PFNPROPSHEETUI and it got only one child which is the
  1476. // COMPROPSHEETUI then we can return the Icon for the COMPROPSHEETUI
  1477. // internally
  1478. //
  1479. //
  1480. // Skip to last PFNPROPSHEETUI in the chain
  1481. //
  1482. LOCK_CPSUI_HANDLETABLE();
  1483. while ((pPage->Flags & CPF_PFNPROPSHEETUI) &&
  1484. (pChild = pPage->pChild) &&
  1485. (pChild->Flags & CPF_PFNPROPSHEETUI) &&
  1486. (pChild->pNext == NULL)) {
  1487. pPage = pChild;
  1488. }
  1489. if ((pPage->Flags & CPF_PFNPROPSHEETUI) &&
  1490. (pChild = pPage->pChild) &&
  1491. (pChild->Flags & CPF_COMPROPSHEETUI) &&
  1492. (pChild->pNext == NULL) &&
  1493. (pTVWnd = pChild->CPSUIInfo.pTVWnd) &&
  1494. (pItem = PIDX_INTOPTITEM(pTVWnd, INTIDX_TVROOT)) &&
  1495. (PSUIGetIconInfo.hIcon = MergeIcon(_OI_HINST(pItem),
  1496. GETSELICONID(pItem),
  1497. MK_INTICONID(0, 0),
  1498. (UINT)PSUIGetIconInfo.cxIcon,
  1499. (UINT)PSUIGetIconInfo.cyIcon))) {
  1500. UNLOCK_CPSUI_HANDLETABLE();
  1501. } else {
  1502. UNLOCK_CPSUI_HANDLETABLE();
  1503. CallpfnPSUI(pPage,
  1504. PROPSHEETUI_REASON_GET_ICON,
  1505. (LPARAM)&PSUIGetIconInfo);
  1506. }
  1507. return(PSUIGetIconInfo.hIcon);
  1508. }
  1509. LONG_PTR
  1510. pfnSetResult(
  1511. HANDLE hPage,
  1512. ULONG_PTR Result
  1513. )
  1514. /*++
  1515. Routine Description:
  1516. This function set the result to the pPage's parent page which has
  1517. CPF_PFNPROPSHEETUI bit set
  1518. Arguments:
  1519. Return Value:
  1520. Author:
  1521. 04-Feb-1996 Sun 00:48:40 created -by- Daniel Chou (danielc)
  1522. Revision History:
  1523. --*/
  1524. {
  1525. PCPSUIPAGE pPage;
  1526. PCPSUIPAGE pParent;
  1527. SETRESULT_INFO SRInfo;
  1528. if (!(pPage = HANDLETABLE_GetCPSUIPage(hPage))) {
  1529. CPSUIERR(("pfnSetResult(): Invalid hPage=%08lx", hPage));
  1530. return(-1);
  1531. }
  1532. SRInfo.cbSize = sizeof(SRInfo);
  1533. SRInfo.wReserved = 0;
  1534. SRInfo.Result = Result;
  1535. Result = 0;
  1536. //
  1537. // Finding its Parent first
  1538. //
  1539. HANDLETABLE_UnGetCPSUIPage(pPage);
  1540. LOCK_CPSUI_HANDLETABLE();
  1541. while ((pPage) && (pParent = pPage->pParent)) {
  1542. if (pParent->Flags & CPF_PFNPROPSHEETUI) {
  1543. BOOL bRet;
  1544. SRInfo.hSetResult = pPage->hCPSUIPage;
  1545. ++Result;
  1546. //
  1547. // We did not unlock the handletable, so if called switch to other
  1548. // thread and callback here then dead lock will occurred
  1549. //
  1550. bRet = (BOOL)(CallpfnPSUI(pParent,
  1551. PROPSHEETUI_REASON_SET_RESULT,
  1552. (LPARAM)&SRInfo) <= 0);
  1553. if (bRet) {
  1554. break;
  1555. }
  1556. }
  1557. pPage = pParent;
  1558. }
  1559. UNLOCK_CPSUI_HANDLETABLE();
  1560. return(Result);
  1561. }
  1562. LONG_PTR
  1563. SethStartPage(
  1564. PCPSUIPAGE pRootPage,
  1565. PCPSUIPAGE pPage,
  1566. LONG Index
  1567. )
  1568. /*++
  1569. Routine Description:
  1570. This function find the index (lParam) page from the pPage
  1571. Arguments:
  1572. Return Value:
  1573. Author:
  1574. 06-Feb-1996 Tue 05:33:11 created -by- Daniel Chou (danielc)
  1575. Revision History:
  1576. --*/
  1577. {
  1578. LONG Result;
  1579. if (!pPage) {
  1580. CPSUIERR(("SethStartPage(NULL): Invalid Page to set"));
  1581. return(0);
  1582. } else if (pRootPage->Flags & CPF_DONE_PROPSHEET) {
  1583. CPSUIERR(("*Cannot Set StartPage now, Flags=%08lx*", pRootPage->Flags));
  1584. return(0);
  1585. }
  1586. if (pPage->Flags & CPF_PARENT) {
  1587. Result = Index;
  1588. if (pPage->Flags & CPF_COMPROPSHEETUI) {
  1589. switch (Result) {
  1590. case SSP_TVPAGE:
  1591. if ((Result = pPage->CPSUIInfo.TVPageIdx) == PAGEIDX_NONE) {
  1592. Result = pPage->CPSUIInfo.StdPageIdx1;
  1593. }
  1594. break;
  1595. case SSP_STDPAGE1:
  1596. Result = pPage->CPSUIInfo.StdPageIdx1;
  1597. break;
  1598. case SSP_STDPAGE2:
  1599. Result = pPage->CPSUIInfo.StdPageIdx2;
  1600. break;
  1601. default:
  1602. break;
  1603. }
  1604. }
  1605. if (Result >= 0) {
  1606. pPage = pPage->pChild;
  1607. while ((pPage) && (Result--) && (pPage->pNext)) {
  1608. pPage = pPage->pNext;
  1609. }
  1610. } else {
  1611. Result = 0;
  1612. }
  1613. } else {
  1614. Result = -1;
  1615. }
  1616. CPSUIDBG(DBG_SETHSTARTPAGE, ("SethStartPage: Result=%ld, pPage=%08lx",
  1617. (LONG)Result, pPage));
  1618. if ((Result == -1) && (pPage)) {
  1619. pRootPage->RootInfo.pStartPage = pPage;
  1620. Result = 1;
  1621. if ((pRootPage->Flags & CPF_SHOW_PROPSHEET) &&
  1622. (pRootPage->RootInfo.hDlg)) {
  1623. PropSheet_SetCurSel(pRootPage->RootInfo.hDlg,
  1624. pPage->hPage,
  1625. 0);
  1626. }
  1627. } else {
  1628. Result = 0;
  1629. CPSUIERR(("SethStartPage: INVALID Index=%ld for pPage=%08lx",
  1630. Index, pPage));
  1631. }
  1632. return(Result);
  1633. }
  1634. BOOL
  1635. CALLBACK
  1636. SetPageProcInfo(
  1637. PCPSUIPAGE pRootPage,
  1638. PCPSUIPAGE pCPSUIPage,
  1639. LPARAM lParam
  1640. )
  1641. /*++
  1642. Routine Description:
  1643. Arguments:
  1644. Return Value:
  1645. Author:
  1646. 29-Jan-1996 Mon 16:28:48 created -by- Daniel Chou (danielc)
  1647. Revision History:
  1648. --*/
  1649. {
  1650. #define pPageProcInfo ((PPAGEPROCINFO)lParam)
  1651. if ((!(pCPSUIPage->Flags & CPF_PARENT)) &&
  1652. (pCPSUIPage->hPage)) {
  1653. PTABTABLE pTabTable;
  1654. WORD i;
  1655. if ((i = pPageProcInfo->iPage) < pPageProcInfo->cPage) {
  1656. if (pPageProcInfo->phPage) {
  1657. pPageProcInfo->phPage[i] = pCPSUIPage->hPage;
  1658. }
  1659. if (pPageProcInfo->pHandle) {
  1660. pPageProcInfo->pHandle[i] = pCPSUIPage->hCPSUIPage;
  1661. }
  1662. if (pTabTable = pPageProcInfo->pTabTable) {
  1663. pTabTable->cTab++;
  1664. pTabTable->TabInfo[i].hDlg = NULL;
  1665. pTabTable->TabInfo[i].OrgInsIdx = i;
  1666. pTabTable->TabInfo[i].HandleIdx =
  1667. HANDLE_2_IDX(pCPSUIPage->hCPSUIPage);
  1668. }
  1669. pPageProcInfo->iPage++;
  1670. } else {
  1671. return(FALSE);
  1672. }
  1673. }
  1674. return(TRUE);
  1675. #undef pPageProcInfo
  1676. }
  1677. BOOL
  1678. CALLBACK
  1679. SetInsPageIdxProc(
  1680. PCPSUIPAGE pRootPage,
  1681. PCPSUIPAGE pCPSUIPage,
  1682. LPARAM lParam
  1683. )
  1684. /*++
  1685. Routine Description:
  1686. Arguments:
  1687. Return Value:
  1688. Author:
  1689. 14-Feb-1996 Wed 23:07:51 created -by- Daniel Chou (danielc)
  1690. Revision History:
  1691. --*/
  1692. {
  1693. PINSPAGEIDXINFO pInsPageIdxInfo = (PINSPAGEIDXINFO)lParam;
  1694. if (pCPSUIPage->Flags & CPF_ROOT) {
  1695. pInsPageIdxInfo->pTabTable->InsIdx = 0;
  1696. } else if ((!(pCPSUIPage->Flags & CPF_PARENT)) &&
  1697. (pCPSUIPage->hPage)) {
  1698. if (pInsPageIdxInfo->pCPSUIPage == pCPSUIPage) {
  1699. pInsPageIdxInfo->pCPSUIPage = NULL;
  1700. return(FALSE);
  1701. } else {
  1702. ++(pInsPageIdxInfo->pTabTable->InsIdx);
  1703. }
  1704. }
  1705. return(TRUE);
  1706. }
  1707. BOOL
  1708. CALLBACK
  1709. DeleteCPSUIPageProc(
  1710. PCPSUIPAGE pRootPage,
  1711. PCPSUIPAGE pCPSUIPage,
  1712. LPARAM lParam
  1713. )
  1714. /*++
  1715. Routine Description:
  1716. This function is the enumeration proc for each of page need to be deleted
  1717. Arguments:
  1718. pCPSUIPage - Pointer to the page currently enumerated and need to be
  1719. deleted.
  1720. lParam - Pointer to the DWORD to be accumerate the total property
  1721. sheet pages deleted.
  1722. Return Value:
  1723. BOOLEAN
  1724. Author:
  1725. 29-Dec-1995 Fri 13:43:26 created -by- Daniel Chou (danielc)
  1726. Revision History:
  1727. --*/
  1728. {
  1729. DWORD dw;
  1730. //
  1731. // Delete the Page, link sibling prev/next together
  1732. //
  1733. if (pCPSUIPage->pNext) {
  1734. pCPSUIPage->pNext->pPrev = pCPSUIPage->pPrev;
  1735. }
  1736. if (pCPSUIPage->pPrev) {
  1737. pCPSUIPage->pPrev->pNext = pCPSUIPage->pNext;
  1738. }
  1739. CPSUIDBG(DBG_DEL_PROC,
  1740. ("DeleteCPSUIPage: Delete pCPSUIPage=%08lx, hCPSUIPage=%08lx, cPage=%ld",
  1741. pCPSUIPage, pCPSUIPage->hCPSUIPage, pRootPage->RootInfo.cPage));
  1742. if ((pCPSUIPage->pParent) &&
  1743. (pCPSUIPage->pParent->pChild == pCPSUIPage)) {
  1744. //
  1745. // We are deleting the first child of the parent, set the next sibling
  1746. // to be its first child.
  1747. //
  1748. CPSUIDBG(DBG_DEL_PROC, ("DeleteCPSUIPage: Delete First child, link head"));
  1749. CPSUIASSERT(0, "DeleteCPSUIPageProc: First Child (%08lx) has pPrev",
  1750. pCPSUIPage->pPrev == NULL, pCPSUIPage);
  1751. pCPSUIPage->pParent->pChild = pCPSUIPage->pNext;
  1752. }
  1753. CPSUIASSERT(0, "DeleteCPSUIPageProc: Parent (%08lx) still has children",
  1754. ((pCPSUIPage->Flags & CPF_PARENT) == 0) ||
  1755. (pCPSUIPage->pChild == NULL), pCPSUIPage);
  1756. if (pCPSUIPage->Flags & CPF_PARENT) {
  1757. //
  1758. // Clean up the COMPROPSHEETUI stuff if PTVWND exists
  1759. //
  1760. if (pCPSUIPage->Flags & CPF_PFNPROPSHEETUI) {
  1761. CPSUIDBG(DBG_DEL_PROC,
  1762. ("DeleteCPSUIPage: Destroy CPF_PFNPROPSHEETUI=%08lx",
  1763. pCPSUIPage));
  1764. CallpfnPSUI(pCPSUIPage,
  1765. PROPSHEETUI_REASON_DESTROY,
  1766. (LPARAM)(pRootPage->Flags & CPF_DONE_PROPSHEET));
  1767. if ((pCPSUIPage->Flags & CPF_DLL) &&
  1768. (pCPSUIPage->pfnInfo.hInst)) {
  1769. CPSUIDBG(DBG_DEL_PROC, ("DeleteProc(%08lx): FreeLibrary(%08lx)",
  1770. pCPSUIPage, pCPSUIPage->pfnInfo.hInst));
  1771. FreeLibrary(pCPSUIPage->pfnInfo.hInst);
  1772. }
  1773. } else if ((pCPSUIPage->Flags & CPF_COMPROPSHEETUI) &&
  1774. (pCPSUIPage->CPSUIInfo.pTVWnd)) {
  1775. CPSUIDBG(DBG_DEL_PROC,
  1776. ("DeleteCPSUIPage: CPF_CPSUI=%08lx, CleanUp/Free pTVWnd=%08lx",
  1777. pCPSUIPage->CPSUIInfo.pTVWnd));
  1778. CleanUpTVWND(pCPSUIPage->CPSUIInfo.pTVWnd);
  1779. LocalFree((HLOCAL)pCPSUIPage->CPSUIInfo.pTVWnd);
  1780. }
  1781. } else {
  1782. //
  1783. // Do any end processing needed for this page
  1784. //
  1785. if (pCPSUIPage->hPage) {
  1786. if (!(pRootPage->Flags & CPF_DONE_PROPSHEET)) {
  1787. if (pRootPage->RootInfo.hDlg) {
  1788. //
  1789. // The Property sheet already displayed
  1790. //
  1791. CPSUIDBG(DBG_DEL_PROC,
  1792. ("DeleteCPSUIPage: REMOVE hPage=%08lx", pCPSUIPage->hPage));
  1793. PropSheet_RemovePage(pRootPage->RootInfo.hDlg,
  1794. 0,
  1795. pCPSUIPage->hPage);
  1796. } else {
  1797. CPSUIDBG(DBG_DEL_PROC,
  1798. ("DeleteCPSUIPage: DESTROY hPage=%08lx", pCPSUIPage->hPage));
  1799. DestroyPropertySheetPage(pCPSUIPage->hPage);
  1800. }
  1801. }
  1802. pRootPage->RootInfo.cPage--;
  1803. if (lParam) {
  1804. ++(*(LPDWORD)lParam);
  1805. }
  1806. } else if (!(pCPSUIPage->Flags & CPF_CALL_TV_DIRECT)) {
  1807. CPSUIWARN(("DeleteCPSUIPageProc: CHILD (%08lx) but hPage=NULL",
  1808. pCPSUIPage));
  1809. }
  1810. CPSUIDBG(DBG_DEL_PROC, ("DeleteCPSUIPage: Delete pCPSUIPage, cPage=%ld",
  1811. pRootPage->RootInfo.cPage));
  1812. }
  1813. //
  1814. // Remove it from the handle table
  1815. //
  1816. if (HANDLETABLE_DeleteHandle(pCPSUIPage->hCPSUIPage)) {
  1817. if ((pCPSUIPage != pRootPage) &&
  1818. (pRootPage->RootInfo.pStartPage == pCPSUIPage)) {
  1819. pRootPage->RootInfo.pStartPage = NULL;
  1820. }
  1821. }
  1822. return(TRUE);
  1823. }
  1824. PCPSUIPAGE
  1825. AddCPSUIPage(
  1826. PCPSUIPAGE pParent,
  1827. HANDLE hInsert,
  1828. BYTE Mode
  1829. )
  1830. /*++
  1831. Routine Description:
  1832. This function add a new CPSUIPAGE to the pParent page. If pParent is NULL
  1833. then it create ROOT page. The new page always added as last child of the
  1834. pParent.
  1835. Arguments:
  1836. pParent - Pointer to the CPSUIPAGE which will be new child's parent
  1837. hInsert - Handle to the children page will insert at. The meaning of
  1838. hInsert depends on the Mode passed. if pParent is NULL
  1839. then hInsert is ignored
  1840. Mode - Mode of insertion, it can be one of the following
  1841. INSPSUIPAGE_MODE_BEFORE
  1842. Insert pages before the common property sheet page
  1843. handle specified by hInsert
  1844. INSPSUIPAGE_MODE_AFTER
  1845. Insert pages after the common property sheet page
  1846. handle specified by hInsert
  1847. INSPSUIPAGE_MODE_FIRST_CHILD
  1848. Insert pages as the first child of hComPropSheet
  1849. parent handle.
  1850. INSPSUIPAGE_MODE_LAST_CHILD
  1851. Insert pages as the last child of hComPropSheet
  1852. parent handle.
  1853. INSPSUIPAGE_MODE_INDEX
  1854. Insert pages as a zero base child index of its
  1855. parent handle specified by hComPropSheet.
  1856. The hInsert is the zero based index special handle
  1857. that must generated by HINSPSUIPAGE_INDEX(Index)
  1858. macro.
  1859. Return Value:
  1860. PCPSUIPAGE, if function sucessful, when this function sucessed, it also
  1861. return the hChild handle in hCPSUIPage field. It return NULL if this
  1862. function failed.
  1863. Author:
  1864. 02-Jan-1996 Tue 13:49:34 created -by- Daniel Chou (danielc)
  1865. Revision History:
  1866. --*/
  1867. {
  1868. HANDLE hChild;
  1869. PCPSUIPAGE pChild;
  1870. if (!(pChild = (PCPSUIPAGE)LocalAlloc(LPTR, sizeof(CPSUIPAGE)))) {
  1871. CPSUIERR(("AddCPSUIPage: LocalAlloc(CPSUIPAGE) failed"));
  1872. return(NULL);
  1873. }
  1874. LOCK_CPSUI_HANDLETABLE();
  1875. if (hChild = HANDLETABLE_AddCPSUIPage(pChild)) {
  1876. pChild->ID = CPSUIPAGE_ID;
  1877. pChild->hCPSUIPage = hChild;
  1878. pChild->hActCtx = INVALID_HANDLE_VALUE;
  1879. pChild->pParent = pParent;
  1880. if (pParent) {
  1881. PCPSUIPAGE pCurPage;
  1882. BOOL Ok = FALSE;
  1883. //
  1884. // Either insert first, or this is the first child
  1885. //
  1886. if ((!(pCurPage = pParent->pChild)) ||
  1887. (Mode == INSPSUIPAGE_MODE_FIRST_CHILD) ||
  1888. ((Mode == INSPSUIPAGE_MODE_INDEX) &&
  1889. (!HINSPSUIPAGE_2_IDX(hInsert)))) {
  1890. //
  1891. // Insert as first child, link to the first one first
  1892. //
  1893. //
  1894. if (pChild->pNext = pCurPage) {
  1895. pCurPage->pPrev = pChild;
  1896. }
  1897. pParent->pChild = pChild;
  1898. Ok = TRUE;
  1899. } else {
  1900. PCPSUIPAGE pNext;
  1901. UINT i = 0xFFFF;
  1902. switch (Mode) {
  1903. case INSPSUIPAGE_MODE_INDEX:
  1904. i = HINSPSUIPAGE_2_IDX(hInsert);
  1905. case INSPSUIPAGE_MODE_LAST_CHILD:
  1906. while ((i--) && (pCurPage)) {
  1907. if ((!i) || (!(pCurPage->pNext))) {
  1908. Ok = TRUE;
  1909. break;
  1910. }
  1911. pCurPage = pCurPage->pNext;
  1912. }
  1913. break;
  1914. case INSPSUIPAGE_MODE_BEFORE:
  1915. while (pCurPage) {
  1916. if ((pNext = pCurPage->pNext) &&
  1917. (pNext->hCPSUIPage == hInsert)) {
  1918. Ok = TRUE;
  1919. break;
  1920. }
  1921. pCurPage = pNext;
  1922. }
  1923. break;
  1924. case INSPSUIPAGE_MODE_AFTER:
  1925. while (pCurPage) {
  1926. if (pCurPage->hCPSUIPage == hInsert) {
  1927. Ok = TRUE;
  1928. break;
  1929. }
  1930. pCurPage = pCurPage->pNext;
  1931. }
  1932. break;
  1933. default:
  1934. CPSUIERR(("Invalid inseert Mode = %u passed", Mode));
  1935. break;
  1936. }
  1937. if (Ok) {
  1938. pChild->pPrev = pCurPage;
  1939. if (pChild->pNext = pCurPage->pNext) {
  1940. pCurPage->pNext->pPrev = pChild;
  1941. }
  1942. pCurPage->pNext = pChild;
  1943. } else {
  1944. //
  1945. // We never insert after
  1946. //
  1947. CPSUIERR(("AddCPSUIPage: Cannot Insert Page: Mode=%ld, hInsert=%08lx, pParent=%08lx",
  1948. Mode, hInsert, pParent));
  1949. HANDLETABLE_UnGetCPSUIPage(pChild);
  1950. HANDLETABLE_DeleteHandle(hChild);
  1951. pChild = NULL;
  1952. }
  1953. }
  1954. } else {
  1955. //
  1956. // This is the ROOT page
  1957. //
  1958. CPSUIDBG(DBG_ADD_CPSUIPAGE,
  1959. ("AddCPSUIPage: Add %08lx as ROOT PAGE", pChild));
  1960. pChild->Flags |= (CPF_ROOT | CPF_PARENT);
  1961. }
  1962. } else {
  1963. CPSUIERR(("AddCPSUIPage: HANDLETABLE_AddCPSUIPage(pChild=%08lx) failed",
  1964. pChild));
  1965. LocalFree((HLOCAL)pChild);
  1966. pChild = NULL;
  1967. }
  1968. UNLOCK_CPSUI_HANDLETABLE();
  1969. return(pChild);
  1970. }
  1971. BOOL
  1972. AddPropSheetPage(
  1973. PCPSUIPAGE pRootPage,
  1974. PCPSUIPAGE pCPSUIPage,
  1975. LPPROPSHEETPAGE pPSPage,
  1976. HPROPSHEETPAGE hPSPage
  1977. )
  1978. /*++
  1979. Routine Description:
  1980. Add this PROPSHEETPAGE page to the property sheet dialog box and associate
  1981. with the pCPSUIPage
  1982. Arguments:
  1983. pRootPage - Pointer to the root page of CPSUIPAGE which this data
  1984. instance is associated with.
  1985. pCPSUIPage - Pointer to the CPSUIPAGE which the pPropSheetPage will
  1986. be associated with.
  1987. pPSPage - Pointer to the PROPSHEETPAGE data structure of the page to
  1988. be added, if this is NULL then hPSPage will be used
  1989. hPSPage - Handle to PROPSHEETPAGE created by the caller to be added
  1990. Return Value:
  1991. Author:
  1992. 03-Jan-1996 Wed 13:28:31 created -by- Daniel Chou (danielc)
  1993. Revision History:
  1994. 17-Dec-1997 Wed 16:21:52 updated -by- Daniel Chou (danielc)
  1995. Unlock the handle table when we display the direct treeview page, this
  1996. is done because when handle table is locked, any other thread in the
  1997. current process cannot display anymore cpsui pages.
  1998. --*/
  1999. {
  2000. PROPSHEETPAGE psp;
  2001. HANDLE hActCtx = INVALID_HANDLE_VALUE;
  2002. BOOL Ok = TRUE;
  2003. LOCK_CPSUI_HANDLETABLE();
  2004. if (pRootPage->RootInfo.cPage >= MAXPROPPAGES) {
  2005. CPSUIASSERT(0, "AddPropSheetPage: Too many pages=%08lx", FALSE,
  2006. pRootPage->RootInfo.cPage);
  2007. Ok = FALSE;
  2008. } else if (pPSPage) {
  2009. LPBYTE pData;
  2010. PPSPINFO pPSPInfo;
  2011. DWORD dwSize;
  2012. //
  2013. // Create a local copy of the PROPSHEETPAGE and add in our own PSPINFO
  2014. // at end of the structure.
  2015. //
  2016. dwSize = pPSPage->dwSize;
  2017. if (pData = (LPBYTE)LocalAlloc(LPTR, dwSize + sizeof(PSPINFO))) {
  2018. CopyMemory(pData, pPSPage, dwSize);
  2019. pPSPage = (LPPROPSHEETPAGE)pData;
  2020. pPSPInfo = (PPSPINFO)(pData + dwSize);
  2021. pPSPInfo->cbSize = sizeof(PSPINFO);
  2022. pPSPInfo->wReserved = 0;
  2023. pPSPInfo->hComPropSheet = pCPSUIPage->pParent->hCPSUIPage;
  2024. pPSPInfo->hCPSUIPage = pCPSUIPage->hCPSUIPage;
  2025. pPSPInfo->pfnComPropSheet = CPSUICallBack;
  2026. CPSUIDBG(DBG_PAGEDLGPROC,
  2027. ("AddPropSheetPage: pCPSUIPage=%08lx, DlgProc=%08lx, lParam=%08lx, pspCB=%08lx, Size=%ld",
  2028. pCPSUIPage, pPSPage->pfnDlgProc,
  2029. pPSPage->lParam, pPSPage->pfnCallback, pPSPage->dwSize));
  2030. pCPSUIPage->hPageInfo.DlgProc = pPSPage->pfnDlgProc;
  2031. pCPSUIPage->hPageInfo.lParam = pPSPage->lParam;
  2032. pCPSUIPage->hPageInfo.pspCB = pPSPage->pfnCallback;
  2033. pCPSUIPage->hPageInfo.dwSize = dwSize;
  2034. pPSPage->pfnCallback = CPSUIPSPCallBack;
  2035. pPSPage->pfnDlgProc = CPSUIPageDlgProc;
  2036. pPSPage->lParam = (LPARAM)pCPSUIPage;
  2037. pPSPage->dwSize = dwSize + sizeof(PSPINFO);
  2038. if (pCPSUIPage->Flags & CPF_CALL_TV_DIRECT) {
  2039. CPSUIDBG(DBG_ADD_PSPAGE,
  2040. ("AddPropSheetPage(CPF_CALL_TV_DIRECT): cPage=%ld",
  2041. pRootPage->RootInfo.cPage));
  2042. //
  2043. // We will
  2044. UNLOCK_CPSUI_HANDLETABLE();
  2045. if (DialogBoxParam(hInstDLL,
  2046. pPSPage->pszTemplate,
  2047. pRootPage->RootInfo.hDlg,
  2048. CPSUIPageDlgProc,
  2049. (LPARAM)pPSPage) == -1) {
  2050. CPSUIERR(("DialogBoxParam(CALL_TV_DIRECT), hDlg=%08lx, Template=%08lx, FAILED",
  2051. pRootPage->RootInfo.hDlg, pPSPage->pszTemplate));
  2052. }
  2053. return(FALSE);
  2054. } else {
  2055. CPSUIDBG(DBG_ADD_PSPAGE, ("AddPropSheetPage: Add PROPSHEETPAGE=%08lx",
  2056. pPSPage));
  2057. if (pPSPage->dwSize <= PROPSHEETPAGE_V2_SIZE) {
  2058. //
  2059. // the passed in PROPSHEETPAGE structure is version 2 or less
  2060. // which means it doesn't have fusion activation context at all
  2061. // let's thunk to the latest version (V3) so we can provide
  2062. // proper activation context.
  2063. //
  2064. ZeroMemory(&psp, sizeof(psp));
  2065. // first copy the data from the passed in page
  2066. CopyMemory(&psp, pPSPage, pPSPage->dwSize);
  2067. // set the new size (V3) and set pPSPage to point to psp
  2068. psp.dwSize = sizeof(psp);
  2069. pPSPage = &psp;
  2070. }
  2071. if (0 == (pPSPage->dwFlags & PSP_USEFUSIONCONTEXT)) {
  2072. if ((ULONG)(ULONG_PTR)pPSPage->pszTemplate >= DP_STD_RESERVED_START &&
  2073. (ULONG)(ULONG_PTR)pPSPage->pszTemplate <= DP_STD_TREEVIEWPAGE) {
  2074. // if the page is standard page or treeview page, we'll force to context
  2075. // to V6
  2076. pPSPage->dwFlags |= PSP_USEFUSIONCONTEXT;
  2077. pPSPage->hActCtx = g_hActCtx;
  2078. } else if (GetPageActivationContext(pCPSUIPage, &hActCtx)) {
  2079. // if the caller did not provide an activation context explicitly
  2080. // then we set the activation context from the compstui handle (if any)
  2081. // by climbing up the hierarchy until we find a page with a proper
  2082. // activation context set.
  2083. pPSPage->dwFlags |= PSP_USEFUSIONCONTEXT;
  2084. pPSPage->hActCtx = hActCtx;
  2085. }
  2086. }
  2087. if (pCPSUIPage->Flags & CPF_ANSI_CALL) {
  2088. hPSPage = SHNoFusionCreatePropertySheetPageA((LPPROPSHEETPAGEA)pPSPage);
  2089. } else {
  2090. hPSPage = SHNoFusionCreatePropertySheetPageW(pPSPage);
  2091. }
  2092. if (!hPSPage) {
  2093. CPSUIASSERT(0, "AddPropSheetPage: CreatePropertySheetPage(%08lx) failed",
  2094. FALSE, pPSPage);
  2095. Ok = FALSE;
  2096. }
  2097. }
  2098. LocalFree((HLOCAL)pData);
  2099. } else {
  2100. Ok = FALSE;
  2101. CPSUIASSERT(0, "AddPropSheetPage: Allocate %08lx bytes failed",
  2102. FALSE, ULongToPtr(pPSPage->dwSize));
  2103. }
  2104. } else if (hPSPage) {
  2105. CPSUIDBG(DBG_ADD_PSPAGE, ("AddPropSheetPage: Add *HPROPSHEETPAGE*=%08lx",
  2106. hPSPage));
  2107. pCPSUIPage->Flags |= CPF_CALLER_HPSPAGE;
  2108. } else {
  2109. Ok = FALSE;
  2110. CPSUIASSERT(0, "AddPropSheetPage: hPSPage = NULL", FALSE, 0);
  2111. }
  2112. if (Ok) {
  2113. pCPSUIPage->hPage = hPSPage;
  2114. if (pRootPage->RootInfo.hDlg) {
  2115. INSPAGEIDXINFO InsPageIdxInfo;
  2116. //
  2117. // The property sheet already displayed
  2118. //
  2119. if (InsPageIdxInfo.pTabTable = pRootPage->RootInfo.pTabTable) {
  2120. InsPageIdxInfo.pCPSUIPage = pCPSUIPage;
  2121. EnumCPSUIPagesSeq(pRootPage,
  2122. pRootPage,
  2123. SetInsPageIdxProc,
  2124. (LPARAM)&InsPageIdxInfo);
  2125. }
  2126. CPSUIDBG(DBG_ADD_PSPAGE,
  2127. ("AddPropSheetPage: PropSheet_AddPage(%08lx) INSERT Index=%u / %u",
  2128. hPSPage, (UINT)InsPageIdxInfo.pTabTable->InsIdx,
  2129. (UINT)pRootPage->RootInfo.cPage));
  2130. InsPageIdxInfo.pTabTable->HandleIdx =
  2131. HANDLE_2_IDX(pCPSUIPage->hCPSUIPage);
  2132. if (!PropSheet_AddPage(pRootPage->RootInfo.hDlg, hPSPage)) {
  2133. Ok = FALSE;
  2134. CPSUIASSERT(0, "AddPropSheetPage: PropSheet_AddPage(%08lx) failed",
  2135. FALSE, hPSPage);
  2136. }
  2137. }
  2138. }
  2139. if (Ok) {
  2140. pRootPage->RootInfo.cPage++;
  2141. CPSUIDBG(DBG_ADD_PSPAGE, ("AddPropSheetPage: cPage=%ld",
  2142. pRootPage->RootInfo.cPage));
  2143. } else {
  2144. CPSUIERR(("AddPropSheetPage: FAILED"));
  2145. if (pCPSUIPage->hPage) {
  2146. DestroyPropertySheetPage(pCPSUIPage->hPage);
  2147. pCPSUIPage->hPage = NULL;
  2148. }
  2149. }
  2150. UNLOCK_CPSUI_HANDLETABLE();
  2151. return(Ok);
  2152. }
  2153. LONG
  2154. AddComPropSheetPage(
  2155. PCPSUIPAGE pCPSUIPage,
  2156. UINT PageIdx
  2157. )
  2158. /*++
  2159. Routine Description:
  2160. This function add the common property sheet UI standard pages to the
  2161. hParent Page passed.
  2162. Arguments:
  2163. pCPSUIPage - pointer to the parent page which child will be added for the
  2164. common UI
  2165. PageIdx - Page index to be added. (zero based)
  2166. Return Value:
  2167. LONG result, if <= 0 then error occurred, > 0 if sucessful
  2168. Author:
  2169. 24-Jan-1996 Wed 17:58:15 created -by- Daniel Chou (danielc)
  2170. Revision History:
  2171. --*/
  2172. {
  2173. PTVWND pTVWnd;
  2174. PMYDLGPAGE pCurMyDP;
  2175. PROPSHEETPAGE psp;
  2176. LONG Result;
  2177. WORD DlgTemplateID;
  2178. WCHAR Buf[MAX_RES_STR_CHARS];
  2179. pTVWnd = pCPSUIPage->CPSUIInfo.pTVWnd;
  2180. pCurMyDP = pTVWnd->pMyDlgPage + PageIdx;
  2181. pCurMyDP->pTVWnd = (LPVOID)pTVWnd;
  2182. pCurMyDP->PageIdx = (BYTE)PageIdx;
  2183. //
  2184. // Set default User data for the callback
  2185. //
  2186. pCurMyDP->CPSUIUserData = pTVWnd->pCPSUI->UserData;
  2187. if (pCurMyDP->DlgPage.cbSize != sizeof(DLGPAGE)) {
  2188. return(ERR_CPSUI_INVALID_DLGPAGE_CBSIZE);
  2189. }
  2190. psp.dwSize = sizeof(PROPSHEETPAGE);
  2191. psp.dwFlags = 0;
  2192. //
  2193. // psp.dwFlags = (pTVWnd->Flags & TWF_HAS_HELPFILE) ? PSP_HASHELP : 0;
  2194. //
  2195. psp.lParam = (LPARAM)pCurMyDP;
  2196. if (pCurMyDP->DlgPage.Flags & DPF_USE_HDLGTEMPLATE) {
  2197. psp.pResource = pCurMyDP->DlgPage.hDlgTemplate;
  2198. psp.dwFlags |= PSP_DLGINDIRECT;
  2199. DlgTemplateID = 0;
  2200. } else {
  2201. DlgTemplateID = pCurMyDP->DlgPage.DlgTemplateID;
  2202. psp.pszTemplate = MAKEINTRESOURCE(DlgTemplateID);
  2203. }
  2204. psp.pfnDlgProc = PropPageProc;
  2205. psp.hInstance = hInstDLL;
  2206. switch (DlgTemplateID) {
  2207. case DP_STD_INT_TVPAGE:
  2208. case DP_STD_TREEVIEWPAGE:
  2209. CPSUIDBG(DBG_ADDCOMPAGE, ("AddComPropSheetPage: Add TVPage"));
  2210. if (pTVWnd->TVPageIdx == PAGEIDX_NONE) {
  2211. pCPSUIPage->CPSUIInfo.TVPageIdx = (LONG)PageIdx;
  2212. pTVWnd->TVPageIdx = (BYTE)PageIdx;
  2213. psp.pfnDlgProc = TreeViewProc;
  2214. } else {
  2215. return(ERR_CPSUI_MORE_THAN_ONE_TVPAGE);
  2216. }
  2217. break;
  2218. case DP_STD_DOCPROPPAGE1:
  2219. CPSUIDBG(DBG_ADDCOMPAGE, ("AddComPropSheetPage: Add StdPage 1"));
  2220. if (pTVWnd->cDMPub > 0) {
  2221. if (pTVWnd->StdPageIdx1 == PAGEIDX_NONE) {
  2222. pCPSUIPage->CPSUIInfo.StdPageIdx1 = (LONG)PageIdx;
  2223. pTVWnd->StdPageIdx1 = (BYTE)PageIdx;
  2224. } else {
  2225. return(ERR_CPSUI_MORE_THAN_ONE_STDPAGE);
  2226. }
  2227. } else {
  2228. //
  2229. // This page got nothing
  2230. //
  2231. return(0);
  2232. }
  2233. break;
  2234. case DP_STD_DOCPROPPAGE2:
  2235. CPSUIDBG(DBG_ADDCOMPAGE, ("AddComPropSheetPage: Add StdPage 2"));
  2236. if (pTVWnd->cDMPub > 0) {
  2237. if (pTVWnd->StdPageIdx2 == PAGEIDX_NONE) {
  2238. pCPSUIPage->CPSUIInfo.StdPageIdx2= (LONG)PageIdx;
  2239. pTVWnd->StdPageIdx2 = (BYTE)PageIdx;
  2240. } else {
  2241. return(ERR_CPSUI_MORE_THAN_ONE_STDPAGE);
  2242. }
  2243. } else {
  2244. //
  2245. // This page got nothing
  2246. //
  2247. return(0);
  2248. }
  2249. break;
  2250. default:
  2251. psp.hInstance = pTVWnd->hInstCaller;
  2252. break;
  2253. }
  2254. //
  2255. // If we have error counting the page items or the page got not item then
  2256. // return it now
  2257. //
  2258. if ((Result = CountPropPageItems(pTVWnd, (BYTE)PageIdx)) <= 0) {
  2259. return(Result);
  2260. }
  2261. if (pCurMyDP->DlgPage.Flags & DPF_ICONID_AS_HICON) {
  2262. psp.dwFlags |= PSP_USEHICON;
  2263. psp.hIcon = (HICON)pCurMyDP->DlgPage.IconID;
  2264. } else if (psp.hIcon = GETICON16(pTVWnd->hInstCaller,
  2265. pCurMyDP->DlgPage.IconID)) {
  2266. psp.dwFlags |= PSP_USEHICON;
  2267. pCurMyDP->hIcon = psp.hIcon;
  2268. }
  2269. Buf[0] = L'\0';
  2270. if (pCPSUIPage->Flags & CPF_CALL_TV_DIRECT) {
  2271. ComposeStrData(pTVWnd->hInstCaller,
  2272. (WORD)(GBF_PREFIX_OK |
  2273. GBF_INT_NO_PREFIX |
  2274. ((pTVWnd->Flags & TWF_ANSI_CALL) ?
  2275. GBF_ANSI_CALL : 0)),
  2276. Buf,
  2277. COUNT_ARRAY(Buf),
  2278. IDS_INT_CPSUI_ADVDOCOPTION,
  2279. pTVWnd->ComPropSheetUI.pOptItemName,
  2280. 0,
  2281. 0);
  2282. } else {
  2283. GetStringBuffer(pTVWnd->hInstCaller,
  2284. (WORD)(GBF_PREFIX_OK |
  2285. GBF_INT_NO_PREFIX |
  2286. ((pTVWnd->Flags & TWF_ANSI_CALL) ?
  2287. GBF_ANSI_CALL : 0)),
  2288. L'\0',
  2289. pCurMyDP->DlgPage.pTabName,
  2290. Buf,
  2291. COUNT_ARRAY(Buf));
  2292. }
  2293. if (Buf[0] != L'\0') {
  2294. psp.pszTitle = (LPTSTR)Buf;
  2295. psp.dwFlags |= PSP_USETITLE;
  2296. }
  2297. //
  2298. // Internally we always translate to the UNICODE
  2299. //
  2300. if (CPSUICallBack(pCPSUIPage->hCPSUIPage,
  2301. CPSFUNC_ADD_PROPSHEETPAGEW,
  2302. (LPARAM)&psp,
  2303. (LPARAM)0L)) {
  2304. return(1);
  2305. } else {
  2306. switch (DlgTemplateID) {
  2307. case DP_STD_INT_TVPAGE:
  2308. case DP_STD_TREEVIEWPAGE:
  2309. pCPSUIPage->CPSUIInfo.TVPageIdx = PAGEIDX_NONE;
  2310. pTVWnd->TVPageIdx = PAGEIDX_NONE;
  2311. break;
  2312. case DP_STD_DOCPROPPAGE1:
  2313. pCPSUIPage->CPSUIInfo.StdPageIdx1 = PAGEIDX_NONE;
  2314. pTVWnd->StdPageIdx1 = PAGEIDX_NONE;
  2315. break;
  2316. case DP_STD_DOCPROPPAGE2:
  2317. pCPSUIPage->CPSUIInfo.StdPageIdx2 = PAGEIDX_NONE;
  2318. pTVWnd->StdPageIdx2 = PAGEIDX_NONE;
  2319. break;
  2320. }
  2321. if (!(pCPSUIPage->Flags & CPF_CALL_TV_DIRECT)) {
  2322. CPSUIERR(("AddComPropSheetPage() FAILED, IdxPage=%ld", PageIdx));
  2323. }
  2324. return(ERR_CPSUI_CREATEPROPPAGE_FAILED);
  2325. }
  2326. }
  2327. LONG
  2328. AddComPropSheetUI(
  2329. PCPSUIPAGE pRootPage,
  2330. PCPSUIPAGE pCPSUIPage,
  2331. PCOMPROPSHEETUI pCPSUI
  2332. )
  2333. /*++
  2334. Routine Description:
  2335. This is the main entry point to the common UI
  2336. Arguments:
  2337. pRootPage - Pointer to the CPSUIPAGE data structure of ROOT
  2338. pCPSUIPage - Pointer to the CPSUIPAGE which represent the hCPSUIPage
  2339. pCPSUI - Pointer to the COMPROPSHEETUI data structure to specified
  2340. how to add common UI pages.
  2341. Return Value:
  2342. LONG
  2343. <=0: Error occurred (Error Code of ERR_CPSUI_xxxx)
  2344. >0: Total Pages added
  2345. Author:
  2346. 24-Jan-1996 Wed 16:54:30 created -by- Daniel Chou (danielc)
  2347. Revision History:
  2348. --*/
  2349. {
  2350. PTVWND pTVWnd = NULL;
  2351. UINT cPage = 0;
  2352. LONG Result = 0;
  2353. DWORD DMPubHideBits;
  2354. DWORD CPF_FlagsOr;
  2355. if ((!pCPSUI) ||
  2356. (pCPSUI->cbSize < sizeof(COMPROPSHEETUI))) {
  2357. Result = ERR_CPSUI_INVALID_PDATA;
  2358. } else if (!pCPSUI->hInstCaller) {
  2359. Result = ERR_CPSUI_NULL_HINST;
  2360. } else if (!pCPSUI->cOptItem) {
  2361. Result = ERR_CPSUI_ZERO_OPTITEM;
  2362. } else if (!pCPSUI->pOptItem) {
  2363. Result = ERR_CPSUI_NULL_POPTITEM;
  2364. } else if (!(pTVWnd = (PTVWND)LocalAlloc(LPTR,
  2365. sizeof(TVWND) + sizeof(OIDATA) *
  2366. pCPSUI->cOptItem))) {
  2367. Result = ERR_CPSUI_ALLOCMEM_FAILED;
  2368. } else {
  2369. if (pCPSUIPage->Flags & CPF_ANSI_CALL) {
  2370. pTVWnd->Flags |= TWF_ANSI_CALL;
  2371. }
  2372. if (pCPSUI->Flags & CPSUIF_UPDATE_PERMISSION) {
  2373. pTVWnd->Flags |= TWF_CAN_UPDATE;
  2374. }
  2375. //
  2376. // Now convert the pCPSUI to the local buffer
  2377. //
  2378. Result = GetCurCPSUI(pTVWnd, (POIDATA)(pTVWnd + 1), pCPSUI);
  2379. pTVWnd->pCPSUI = pCPSUI;
  2380. pCPSUI = &(pTVWnd->ComPropSheetUI);
  2381. pTVWnd->hCPSUIPage = pCPSUIPage->hCPSUIPage;
  2382. pTVWnd->pRootFlags = (LPDWORD)&(pRootPage->Flags);
  2383. pTVWnd->hInstCaller = pCPSUI->hInstCaller;
  2384. pTVWnd->pLastItem = pCPSUI->pOptItem + pCPSUI->cOptItem - 1;
  2385. pTVWnd->ActiveDlgPage =
  2386. pTVWnd->TVPageIdx =
  2387. pTVWnd->StdPageIdx1 =
  2388. pTVWnd->StdPageIdx2 = PAGEIDX_NONE;
  2389. if (!pCPSUI->pCallerName) {
  2390. pCPSUI->pCallerName = (LPTSTR)IDS_CPSUI_NO_NAME;
  2391. }
  2392. if (!pCPSUI->pOptItemName) {
  2393. pCPSUI->pOptItemName = (LPTSTR)IDS_CPSUI_NO_NAME;
  2394. }
  2395. pCPSUIPage->CPSUIInfo.pTVWnd = pTVWnd;
  2396. pCPSUIPage->CPSUIInfo.TVPageIdx = PAGEIDX_NONE;
  2397. pCPSUIPage->CPSUIInfo.StdPageIdx1= PAGEIDX_NONE;
  2398. pCPSUIPage->CPSUIInfo.StdPageIdx2= PAGEIDX_NONE;
  2399. }
  2400. //
  2401. // Remember this one in the page
  2402. //
  2403. DMPubHideBits = pRootPage->RootInfo.DMPubHideBits;
  2404. switch ((ULONG_PTR)pCPSUI->pDlgPage) {
  2405. case (ULONG_PTR)CPSUI_PDLGPAGE_PRINTERPROP:
  2406. CPF_FlagsOr = CPF_PRINTERPROP;
  2407. DMPubHideBits = 0;
  2408. break;
  2409. case (ULONG_PTR)CPSUI_PDLGPAGE_DOCPROP:
  2410. CPF_FlagsOr = CPF_DOCPROP;
  2411. break;
  2412. case (ULONG_PTR)CPSUI_PDLGPAGE_ADVDOCPROP:
  2413. CPF_FlagsOr = CPF_ADVDOCPROP;
  2414. break;
  2415. default:
  2416. DMPubHideBits =
  2417. CPF_FlagsOr = 0;
  2418. break;
  2419. }
  2420. if ((Result >= 0) &&
  2421. ((Result = AddIntOptItem(pTVWnd)) >= 0) &&
  2422. ((Result = SetpMyDlgPage(pTVWnd, pRootPage->RootInfo.cPage)) > 0) &&
  2423. ((Result = ValidatepOptItem(pTVWnd, DMPubHideBits)) >= 0)) {
  2424. UINT iPage = 0;
  2425. //
  2426. // Go through each page and add them to the property sheet if the
  2427. // page got item
  2428. //
  2429. while ((iPage < (UINT)pTVWnd->cInitMyDlgPage) && (Result >= 0)) {
  2430. if ((Result = AddComPropSheetPage(pCPSUIPage, iPage++)) > 0) {
  2431. ++cPage;
  2432. }
  2433. }
  2434. if ((cPage == 0) && (pTVWnd->Flags & TWF_HAS_ADVANCED_PUSH)) {
  2435. //
  2436. // If the advance is via push button but we did not add any pages
  2437. // then we need to add the advanced page as default
  2438. //
  2439. pTVWnd->Flags &= ~TWF_HAS_ADVANCED_PUSH;
  2440. pTVWnd->Flags |= TWF_ADVDOCPROP;
  2441. if ((Result = AddComPropSheetPage(pCPSUIPage, iPage++)) > 0) {
  2442. ++cPage;
  2443. }
  2444. } else {
  2445. pTVWnd->cInitMyDlgPage = (BYTE)iPage;
  2446. }
  2447. }
  2448. if (Result >= 0) {
  2449. pCPSUIPage->Flags |= CPF_FlagsOr;
  2450. pRootPage->Flags |= CPF_FlagsOr | CPF_HAS_CPSUI;
  2451. pRootPage->RootInfo.cCPSUIPage += (WORD)cPage;
  2452. CPSUIDBG(DBG_ADD_CPSUI, ("\nAddComPropSheetUI: TV=%ld, P1=%ld, p2=%ld, pTVWnd->Flags=%08lx, %08lx->RootFlags=%08lx, (%08lx)",
  2453. pTVWnd->TVPageIdx, pTVWnd->StdPageIdx1,
  2454. pTVWnd->StdPageIdx2, pTVWnd->Flags,
  2455. pRootPage, pRootPage->Flags,
  2456. pCPSUI->pDlgPage));
  2457. return((LONG)cPage);
  2458. } else {
  2459. CPSUIERR(("AddComPropSheetUI() Failed = %ld", Result));
  2460. return(Result);
  2461. }
  2462. }
  2463. LONG_PTR
  2464. InsertPSUIPage(
  2465. PCPSUIPAGE pRootPage,
  2466. PCPSUIPAGE pParentPage,
  2467. HANDLE hInsert,
  2468. PINSERTPSUIPAGE_INFO pInsPageInfo,
  2469. BOOL AnsiCall
  2470. )
  2471. /*++
  2472. Routine Description:
  2473. Arguments:
  2474. Return Value:
  2475. Author:
  2476. 14-Feb-1996 Wed 14:03:20 created -by- Daniel Chou (danielc)
  2477. Revision History:
  2478. --*/
  2479. {
  2480. BOOL bCtxActivated = FALSE;
  2481. ULONG_PTR ulCookie = 0;
  2482. HANDLE hActCtx = INVALID_HANDLE_VALUE;
  2483. WCHAR wszDLLName[MAX_PATH];
  2484. PCPSUIPAGE pCPSUIPage;
  2485. INSERTPSUIPAGE_INFO IPInfo;
  2486. LONG cPage;
  2487. BOOL Ok = FALSE;
  2488. DWORD dwErr = ERROR_SUCCESS;
  2489. if (!pInsPageInfo) {
  2490. CPSUIERR(("InsertPSUIPage: Pass a NULL pInsPageInfo"));
  2491. return(0);
  2492. } else if (pInsPageInfo->cbSize < sizeof(INSERTPSUIPAGE_INFO)) {
  2493. CPSUIERR(("InsertPSUIPage: Invalid cbSize=%u in pInsPageInfo",
  2494. pInsPageInfo->cbSize));
  2495. return(0);
  2496. }
  2497. //
  2498. // Make a local copy
  2499. //
  2500. IPInfo = *pInsPageInfo;
  2501. if (IPInfo.Type > MAX_PSUIPAGEINSERT_INDEX) {
  2502. CPSUIERR(("InsertPSUIPage: Invalid Type=%u in pInsPageInfo",
  2503. IPInfo.Type));
  2504. return(0);
  2505. } else if ((IPInfo.Type != PSUIPAGEINSERT_GROUP_PARENT) &&
  2506. (IPInfo.dwData1 == 0)) {
  2507. CPSUIERR(("InsertPSUIPage: dwData1 is NULL in pInsPageInfo"));
  2508. return(0);
  2509. }
  2510. CPSUIDBG(DBG_INSPAGE,
  2511. ("InsertPSUIPage: Type=%hs, Mode=%u, hInsert=%08lx, pInsPageInfo=%08lx%hs",
  2512. pszInsType[IPInfo.Type], IPInfo.Mode, hInsert, pInsPageInfo,
  2513. (AnsiCall) ? " (ANSI)" : ""));
  2514. if (!(pCPSUIPage = AddCPSUIPage(pParentPage, hInsert, IPInfo.Mode))) {
  2515. CPSUIERR(("InsertPSUIPage: AddCPSUIPage() failed"));
  2516. return(0);
  2517. }
  2518. if (AnsiCall) {
  2519. pCPSUIPage->Flags |= CPF_ANSI_CALL;
  2520. }
  2521. switch (IPInfo.Type) {
  2522. case PSUIPAGEINSERT_GROUP_PARENT:
  2523. //
  2524. // Nothing to do except setting the flags
  2525. //
  2526. Ok = TRUE;
  2527. pCPSUIPage->Flags |= CPF_PARENT | CPF_USER_GROUP;
  2528. break;
  2529. case PSUIPAGEINSERT_PCOMPROPSHEETUI:
  2530. pCPSUIPage->Flags |= (CPF_PARENT | CPF_COMPROPSHEETUI);
  2531. //
  2532. // 20-Jul-1996 Sat 07:58:34 updated -by- Daniel Chou (danielc)
  2533. // Set dwData2 to cPage if sucessful, and dwData=ERR_CPSUI_xxx if
  2534. // failed
  2535. //
  2536. // This are cases that we want to add 0 page, so only negative value
  2537. // is falure return.
  2538. //
  2539. if ((cPage = AddComPropSheetUI(pRootPage,
  2540. pCPSUIPage,
  2541. (PCOMPROPSHEETUI)IPInfo.dwData1)) >= 0) {
  2542. Ok = TRUE;
  2543. }
  2544. pInsPageInfo->dwData2 = (ULONG_PTR)cPage;
  2545. break;
  2546. case PSUIPAGEINSERT_DLL:
  2547. pCPSUIPage->Flags |= (CPF_PARENT | CPF_DLL | CPF_PFNPROPSHEETUI);
  2548. if (AnsiCall) {
  2549. CPSUIDBG(DBG_INSPAGE, ("Loading DLL: %hs", IPInfo.dwData1));
  2550. } else {
  2551. CPSUIDBG(DBG_INSPAGE, ("Loading DLL: %ws", IPInfo.dwData1));
  2552. }
  2553. CPSUIDBG(DBG_INSPAGE, ("Get pfnPropSheetU() = %hs", IPInfo.dwData2));
  2554. if (AnsiCall)
  2555. {
  2556. // convert from ANSI to UNICODE
  2557. SHAnsiToUnicode((LPCSTR)IPInfo.dwData1, wszDLLName, ARRAYSIZE(wszDLLName));
  2558. }
  2559. else
  2560. {
  2561. // just copy the UNICODE name into the buffer
  2562. SHUnicodeToUnicode((LPCWSTR)IPInfo.dwData1, wszDLLName, ARRAYSIZE(wszDLLName));
  2563. }
  2564. //
  2565. // this is a third party DLL and we don't know if it is fusion aware
  2566. // or not, so we just try if there is an external manifest file or
  2567. // a manifest embedded in the resources.
  2568. //
  2569. if (SUCCEEDED(CreateActivationContextFromExecutable(wszDLLName, &hActCtx)))
  2570. {
  2571. // compstui page takes the ownership of the activation context handle.
  2572. pCPSUIPage->hActCtx = hActCtx;
  2573. // activate the context prior loading the DLL and calling into it.
  2574. bCtxActivated = ActivateActCtx(pCPSUIPage->hActCtx, &ulCookie);
  2575. }
  2576. __try {
  2577. if ((pCPSUIPage->pfnInfo.hInst = LoadLibraryW(wszDLLName)) &&
  2578. (IPInfo.dwData2) &&
  2579. (pCPSUIPage->pfnInfo.pfnPSUI = (PFNPROPSHEETUI)
  2580. GetProcAddress(pCPSUIPage->pfnInfo.hInst,
  2581. (LPCSTR)IPInfo.dwData2))) {
  2582. pCPSUIPage->pfnInfo.lParamInit = IPInfo.dwData3;
  2583. pCPSUIPage->pfnInfo.Result = 0;
  2584. Ok = (BOOL)((CallpfnPSUI(pCPSUIPage,
  2585. PROPSHEETUI_REASON_INIT,
  2586. (LPARAM)IPInfo.dwData3) > 0) &&
  2587. (pCPSUIPage->pChild));
  2588. }
  2589. }
  2590. __finally {
  2591. if (bCtxActivated) {
  2592. //
  2593. // we need to deactivate the context, no matter what!
  2594. //
  2595. DeactivateActCtx(0, ulCookie);
  2596. }
  2597. }
  2598. break;
  2599. case PSUIPAGEINSERT_PFNPROPSHEETUI:
  2600. pCPSUIPage->Flags |= (CPF_PARENT | CPF_PFNPROPSHEETUI);
  2601. pCPSUIPage->pfnInfo.pfnPSUI = (PFNPROPSHEETUI)IPInfo.dwData1;
  2602. pCPSUIPage->pfnInfo.lParamInit = IPInfo.dwData2;
  2603. pCPSUIPage->pfnInfo.Result = 0;
  2604. //
  2605. // If this function successful and it got any pages then
  2606. // we returned ok, else failed it.
  2607. //
  2608. Ok = (BOOL)((CallpfnPSUI(pCPSUIPage,
  2609. PROPSHEETUI_REASON_INIT,
  2610. (LPARAM)IPInfo.dwData2) > 0) &&
  2611. (pCPSUIPage->pChild));
  2612. break;
  2613. case PSUIPAGEINSERT_PROPSHEETPAGE:
  2614. //
  2615. // This is set only if we are calling Treeview Page with a seperate
  2616. // dialog box, when calling direct with DialogBoxParam() with treeview
  2617. // at return of AddPropSheetPage() the treeview dialog box already
  2618. // done, so there is no need for error
  2619. //
  2620. pCPSUIPage->Flags |= (pParentPage->Flags & CPF_CALL_TV_DIRECT);
  2621. Ok = AddPropSheetPage(pRootPage,
  2622. pCPSUIPage,
  2623. (LPPROPSHEETPAGE)IPInfo.dwData1,
  2624. NULL);
  2625. break;
  2626. case PSUIPAGEINSERT_HPROPSHEETPAGE:
  2627. Ok = AddPropSheetPage(pRootPage,
  2628. pCPSUIPage,
  2629. NULL,
  2630. (HPROPSHEETPAGE)IPInfo.dwData1);
  2631. break;
  2632. }
  2633. if (!Ok) {
  2634. //
  2635. // Save the last error.
  2636. //
  2637. dwErr = GetLastError();
  2638. }
  2639. HANDLETABLE_UnGetCPSUIPage(pCPSUIPage);
  2640. if (Ok) {
  2641. DBG_SHOW_CPSUIPAGE(pRootPage, 0);
  2642. return((ULONG_PTR)pCPSUIPage->hCPSUIPage);
  2643. } else {
  2644. EnumCPSUIPages(pRootPage, pCPSUIPage, DeleteCPSUIPageProc, 0L);
  2645. if (!(pCPSUIPage->Flags & CPF_CALL_TV_DIRECT)) {
  2646. CPSUIERR(("InsertPSUIPage(): Insertion of %hs failed",
  2647. pszInsType[IPInfo.Type]));
  2648. }
  2649. SetLastError(dwErr);
  2650. return(0);
  2651. }
  2652. }
  2653. LONG
  2654. CALLBACK
  2655. IgnorePSNApplyProc(
  2656. PCPSUIPAGE pRootPage,
  2657. PCPSUIPAGE pCPSUIPage,
  2658. LPARAM lParam
  2659. )
  2660. /*++
  2661. Routine Description:
  2662. This function send the APPLYNOW message to the CPSUIPAGE's page
  2663. Arguments:
  2664. Return Value:
  2665. FALSE - Apply done by not successful, the callee need more user changes
  2666. TRUE - Apply done with sucessful
  2667. Author:
  2668. 17-Nov-1997 Mon 13:38:18 created -by- Daniel Chou (danielc)
  2669. Revision History:
  2670. --*/
  2671. {
  2672. if (!(pCPSUIPage->Flags & CPF_PARENT)) {
  2673. DWORD Flags = pCPSUIPage->Flags;
  2674. if (lParam) {
  2675. pCPSUIPage->Flags |= CPF_NO_PSN_APPLY;
  2676. } else {
  2677. pCPSUIPage->Flags &= ~CPF_NO_PSN_APPLY;
  2678. }
  2679. if ((pCPSUIPage->Flags & CPF_ACTIVATED) &&
  2680. (Flags ^ (pCPSUIPage->Flags & CPF_NO_PSN_APPLY))) {
  2681. SetIgnorePSNApplyProc(pCPSUIPage);
  2682. }
  2683. CPSUIDBG(DBG_GET_TABWND,
  2684. ("IgnorePSNApplyProc(%u): pPage=%08lx, Handle=%08lx",
  2685. (pCPSUIPage->Flags & CPF_NO_PSN_APPLY) ? 1 : 0,
  2686. pCPSUIPage, pCPSUIPage->hCPSUIPage));
  2687. }
  2688. return(TRUE);
  2689. }
  2690. LONG
  2691. CALLBACK
  2692. ApplyCPSUIProc(
  2693. PCPSUIPAGE pRootPage,
  2694. PCPSUIPAGE pCPSUIPage,
  2695. LPARAM lParam
  2696. )
  2697. /*++
  2698. Routine Description:
  2699. This function send the APPLYNOW message to the CPSUIPAGE's page
  2700. Arguments:
  2701. Return Value:
  2702. FALSE - Apply done by not successful, the callee need more user changes
  2703. TRUE - Apply done with sucessful
  2704. Author:
  2705. 17-Nov-1997 Mon 13:38:18 created -by- Daniel Chou (danielc)
  2706. Revision History:
  2707. --*/
  2708. {
  2709. HWND hDlg;
  2710. DLGPROC DlgProc;
  2711. if ((!(pCPSUIPage->Flags & CPF_PARENT)) &&
  2712. (hDlg = pCPSUIPage->hPageInfo.hDlg) &&
  2713. (DlgProc = pCPSUIPage->hPageInfo.DlgProc)) {
  2714. PCPSUIPAGE pParent;
  2715. PTVWND pTVWnd = NULL;
  2716. PSHNOTIFY PN;
  2717. PN.hdr.hwndFrom = pRootPage->RootInfo.hDlg;
  2718. PN.hdr.idFrom = (UINT)GetWindowLongPtr(PN.hdr.hwndFrom, GWLP_ID);
  2719. PN.hdr.code = PSN_APPLY;
  2720. PN.lParam = (lParam & APPLYCPSUI_OK_CANCEL_BUTTON) ? 1 : 0;
  2721. CPSUIDBG(DBG_GET_TABWND,
  2722. ("*ApplyCPSUIProc(PSN_APPLY): Page=%08lx, Handle=%08lx, hDlg=%08lx, DlgPorc=%08lx",
  2723. pCPSUIPage, pCPSUIPage->hCPSUIPage, hDlg, DlgProc));
  2724. if ((pParent = pCPSUIPage->pParent) &&
  2725. ((pParent->Flags & (CPF_PARENT | CPF_COMPROPSHEETUI)) ==
  2726. (CPF_PARENT | CPF_COMPROPSHEETUI)) &&
  2727. (pTVWnd = pParent->CPSUIInfo.pTVWnd)) {
  2728. if (lParam & APPLYCPSUI_NO_NEWDEF) {
  2729. pTVWnd->Flags |= TWF_APPLY_NO_NEWDEF;
  2730. } else {
  2731. pTVWnd->Flags &= ~TWF_APPLY_NO_NEWDEF;
  2732. }
  2733. CPSUIDBG(DBG_GET_TABWND,
  2734. ("* APPLY ComPropSheetUI, pParent=%08lx: APPLY_NO_NEWDEF=%ld",
  2735. pParent->hCPSUIPage, (pTVWnd->Flags & TWF_APPLY_NO_NEWDEF) ? 1 : 0));
  2736. }
  2737. if (CallWindowProc((WNDPROC)DlgProc,
  2738. hDlg,
  2739. WM_NOTIFY,
  2740. (WPARAM)PN.hdr.idFrom,
  2741. (LPARAM)&PN)) {
  2742. CPSUIDBG(DBG_GET_TABWND,
  2743. ("*ApplyCPSUIProc(PSN_APPLY): Return=%ld",
  2744. GetWindowLongPtr(hDlg, DWLP_MSGRESULT)));
  2745. switch (GetWindowLongPtr(hDlg, DWLP_MSGRESULT)) {
  2746. case PSNRET_INVALID:
  2747. case PSNRET_INVALID_NOCHANGEPAGE:
  2748. PostMessage(pRootPage->RootInfo.hDlg,
  2749. PSM_SETCURSEL,
  2750. (WPARAM)0,
  2751. (LPARAM)pCPSUIPage->hPage);
  2752. return(FALSE);
  2753. case PSNRET_NOERROR:
  2754. default:
  2755. break;
  2756. }
  2757. }
  2758. if (pTVWnd) {
  2759. pTVWnd->Flags &= ~TWF_APPLY_NO_NEWDEF;
  2760. }
  2761. }
  2762. return(TRUE);
  2763. }
  2764. LONG_PTR
  2765. CALLBACK
  2766. CPSUICallBack(
  2767. HANDLE hComPropSheet,
  2768. UINT Function,
  2769. LPARAM lParam1,
  2770. LPARAM lParam2
  2771. )
  2772. /*++
  2773. Routine Description:
  2774. Arguments:
  2775. Return Value:
  2776. Author:
  2777. 29-Dec-1995 Fri 11:36:27 created -by- Daniel Chou (danielc)
  2778. Revision History:
  2779. --*/
  2780. {
  2781. PCPSUIPAGE pParentPage;
  2782. PCPSUIPAGE pRootPage = NULL;
  2783. PMYDATABLOCK pMyDB;
  2784. PCPSUIDATABLOCK pCPSUIDB;
  2785. HCURSOR hCursor;
  2786. DWORD Count = 0;
  2787. LONG_PTR Result = 0;
  2788. DWORD dwErr = ERROR_SUCCESS;
  2789. //
  2790. // Compstui.dll should not set the wait cursor, it is the
  2791. // responsibility of the top level caller to display any
  2792. // progress UI if applicable. SteveKi 12/06/97
  2793. //
  2794. #if 0
  2795. hCursor = SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_WAIT)));
  2796. #endif
  2797. CPSUIDBG(DBG_PFNCOMPROPSHEET,
  2798. ("*CPSUICallBack(%08lx, %hs, %08lx, %08lx)",
  2799. hComPropSheet,
  2800. (Function <= MAX_CPSFUNC_INDEX) ? pszCPSFUNC[Function] :
  2801. "??? Unknown Function",
  2802. lParam1, lParam2));
  2803. if ((pParentPage = HANDLETABLE_GetCPSUIPage(hComPropSheet)) &&
  2804. ((pParentPage->Flags & CPF_PARENT) ||
  2805. (pParentPage->pChild)) &&
  2806. (pRootPage = HANDLETABLE_GetRootPage(pParentPage))) {
  2807. PCPSUIPAGE pChildPage = NULL;
  2808. PAGEPROCINFO PageProcInfo;
  2809. INSERTPSUIPAGE_INFO IPInfo;
  2810. switch (Function) {
  2811. case CPSFUNC_INSERT_PSUIPAGEA:
  2812. case CPSFUNC_INSERT_PSUIPAGEW:
  2813. Result = InsertPSUIPage(pRootPage,
  2814. pParentPage,
  2815. (HANDLE)lParam1,
  2816. (PINSERTPSUIPAGE_INFO)lParam2,
  2817. Function == CPSFUNC_INSERT_PSUIPAGEA);
  2818. break;
  2819. case CPSFUNC_ADD_HPROPSHEETPAGE:
  2820. case CPSFUNC_ADD_PROPSHEETPAGEA:
  2821. case CPSFUNC_ADD_PROPSHEETPAGEW:
  2822. case CPSFUNC_ADD_PFNPROPSHEETUIA:
  2823. case CPSFUNC_ADD_PFNPROPSHEETUIW:
  2824. case CPSFUNC_ADD_PCOMPROPSHEETUIA:
  2825. case CPSFUNC_ADD_PCOMPROPSHEETUIW:
  2826. IPInfo.cbSize = sizeof(IPInfo);
  2827. IPInfo.Mode = INSPSUIPAGE_MODE_LAST_CHILD;
  2828. IPInfo.dwData1 = (ULONG_PTR)lParam1;
  2829. IPInfo.dwData2 = (ULONG_PTR)lParam2;
  2830. IPInfo.dwData3 = 0;
  2831. switch (Function) {
  2832. case CPSFUNC_ADD_HPROPSHEETPAGE:
  2833. IPInfo.Type = PSUIPAGEINSERT_HPROPSHEETPAGE;
  2834. break;
  2835. case CPSFUNC_ADD_PROPSHEETPAGEA: IPInfo.dwData3 = 1;
  2836. case CPSFUNC_ADD_PROPSHEETPAGEW:
  2837. Result = 0;
  2838. IPInfo.Type = PSUIPAGEINSERT_PROPSHEETPAGE;
  2839. break;
  2840. case CPSFUNC_ADD_PCOMPROPSHEETUIA: IPInfo.dwData3 = 1;
  2841. case CPSFUNC_ADD_PCOMPROPSHEETUIW:
  2842. IPInfo.Type = PSUIPAGEINSERT_PCOMPROPSHEETUI;
  2843. break;
  2844. case CPSFUNC_ADD_PFNPROPSHEETUIA: IPInfo.dwData3 = 1;
  2845. case CPSFUNC_ADD_PFNPROPSHEETUIW:
  2846. IPInfo.Type = PSUIPAGEINSERT_PFNPROPSHEETUI;
  2847. break;
  2848. }
  2849. Result = InsertPSUIPage(pRootPage,
  2850. pParentPage,
  2851. NULL,
  2852. &IPInfo,
  2853. (BOOL)IPInfo.dwData3);
  2854. if (!Result) {
  2855. //
  2856. // Save the last error.
  2857. //
  2858. dwErr = GetLastError();
  2859. }
  2860. //
  2861. // 20-Jul-1996 Sat 07:58:34 updated -by- Daniel Chou (danielc)
  2862. // Set dwData2 to cPage if sucessful, and dwData=ERR_CPSUI_xxx if
  2863. // failed
  2864. //
  2865. if ((IPInfo.Type == PSUIPAGEINSERT_PCOMPROPSHEETUI) &&
  2866. (lParam2)) {
  2867. *(LPDWORD)lParam2 = (DWORD)IPInfo.dwData2;
  2868. }
  2869. break;
  2870. case CPSFUNC_GET_PAGECOUNT:
  2871. PageProcInfo.pTabTable = NULL;
  2872. PageProcInfo.pHandle = NULL;
  2873. PageProcInfo.phPage = NULL;
  2874. PageProcInfo.iPage = 0;
  2875. PageProcInfo.cPage = (WORD)pRootPage->RootInfo.cPage;
  2876. EnumCPSUIPagesSeq(pRootPage,
  2877. pParentPage,
  2878. SetPageProcInfo,
  2879. (LPARAM)&PageProcInfo);
  2880. Result = (LONG_PTR)PageProcInfo.iPage;
  2881. break;
  2882. case CPSFUNC_GET_HPSUIPAGES:
  2883. if (((LONG)lParam2 > 0) &&
  2884. (PageProcInfo.pHandle = (HANDLE *)lParam1) &&
  2885. (PageProcInfo.cPage = (WORD)lParam2)) {
  2886. PageProcInfo.iPage = 0;
  2887. PageProcInfo.phPage = NULL;
  2888. PageProcInfo.pTabTable = NULL;
  2889. EnumCPSUIPagesSeq(pRootPage,
  2890. pParentPage,
  2891. SetPageProcInfo,
  2892. (LPARAM)&PageProcInfo);
  2893. Result = (LONG_PTR)PageProcInfo.iPage;
  2894. }
  2895. break;
  2896. case CPSFUNC_LOAD_CPSUI_STRINGA:
  2897. case CPSFUNC_LOAD_CPSUI_STRINGW:
  2898. Result = (LONG_PTR)LoadCPSUIString((LPTSTR)lParam1,
  2899. LOWORD(lParam2),
  2900. HIWORD(lParam2),
  2901. Function ==
  2902. CPSFUNC_LOAD_CPSUI_STRINGA);
  2903. break;
  2904. case CPSFUNC_LOAD_CPSUI_ICON:
  2905. if (((LONG)lParam1 >= IDI_CPSUI_ICONID_FIRST) &&
  2906. ((LONG)lParam1 <= IDI_CPSUI_ICONID_LAST)) {
  2907. Result = lParam1;
  2908. if (!(lParam1 = (LONG)LOWORD(lParam2))) {
  2909. lParam1 = (LONG)GetSystemMetrics(SM_CXICON);
  2910. }
  2911. if (!(lParam2 = (LONG)HIWORD(lParam2))) {
  2912. lParam2 = (LONG)GetSystemMetrics(SM_CYICON);
  2913. }
  2914. Result = (LONG_PTR)LoadImage(hInstDLL,
  2915. MAKEINTRESOURCE(Result),
  2916. IMAGE_ICON,
  2917. (INT)lParam1,
  2918. (INT)lParam2,
  2919. 0);
  2920. } else {
  2921. Result = 0;
  2922. }
  2923. break;
  2924. case CPSFUNC_SET_RESULT:
  2925. Result = pfnSetResult((lParam1) ? (HANDLE)lParam1 : hComPropSheet,
  2926. (ULONG_PTR)lParam2);
  2927. break;
  2928. case CPSFUNC_SET_FUSION_CONTEXT:
  2929. // check to release the current activation context (if any)
  2930. if (pParentPage->hActCtx && pParentPage->hActCtx != INVALID_HANDLE_VALUE) {
  2931. ReleaseActCtx(pParentPage->hActCtx);
  2932. pParentPage->hActCtx = INVALID_HANDLE_VALUE;
  2933. }
  2934. // attach the new passed in fusion activation context to the compstui page
  2935. pParentPage->hActCtx = (HANDLE)lParam1;
  2936. // check to addref the passed in activation context handle
  2937. if (pParentPage->hActCtx && pParentPage->hActCtx != INVALID_HANDLE_VALUE) {
  2938. AddRefActCtx(pParentPage->hActCtx);
  2939. }
  2940. // indicate success
  2941. Result = 1;
  2942. break;
  2943. case CPSFUNC_SET_HSTARTPAGE:
  2944. //
  2945. // Assume OK first
  2946. //
  2947. Result = 0xFFFF;
  2948. if (pRootPage->Flags & CPF_SHOW_PROPSHEET) {
  2949. break;
  2950. } else if (!lParam1) {
  2951. if (lParam2) {
  2952. pRootPage->Flags |= CPF_PSZ_PSTARTPAGE;
  2953. pRootPage->RootInfo.pStartPage = (PCPSUIPAGE)lParam2;
  2954. Result = lParam2;
  2955. }
  2956. break;
  2957. }
  2958. //
  2959. // Fall through
  2960. //
  2961. case CPSFUNC_DELETE_HCOMPROPSHEET:
  2962. case CPSFUNC_GET_PFNPROPSHEETUI_ICON:
  2963. case CPSFUNC_SET_PSUIPAGE_TITLEA:
  2964. case CPSFUNC_SET_PSUIPAGE_TITLEW:
  2965. case CPSFUNC_SET_PSUIPAGE_ICON:
  2966. case CPSFUNC_IGNORE_CPSUI_PSN_APPLY:
  2967. case CPSFUNC_DO_APPLY_CPSUI:
  2968. if ((lParam1) &&
  2969. (pChildPage = HANDLETABLE_GetCPSUIPage((HANDLE)lParam1)) &&
  2970. (HANDLETABLE_IsChildPage(pChildPage, pParentPage))) {
  2971. switch (Function) {
  2972. case CPSFUNC_SET_HSTARTPAGE:
  2973. Result = SethStartPage(pRootPage,
  2974. pChildPage,
  2975. (LONG)lParam2);
  2976. break;
  2977. case CPSFUNC_DELETE_HCOMPROPSHEET:
  2978. HANDLETABLE_UnGetCPSUIPage(pChildPage);
  2979. EnumCPSUIPages(pRootPage,
  2980. pChildPage,
  2981. DeleteCPSUIPageProc,
  2982. (LPARAM)&Count);
  2983. Result = (LONG_PTR)Count;
  2984. pChildPage = NULL;
  2985. break;
  2986. case CPSFUNC_GET_PFNPROPSHEETUI_ICON:
  2987. Result = (LONG_PTR)pfnGetIcon(pChildPage, lParam2);
  2988. break;
  2989. case CPSFUNC_SET_PSUIPAGE_TITLEA:
  2990. case CPSFUNC_SET_PSUIPAGE_TITLEW:
  2991. Result = SetPSUIPageTitle(pRootPage,
  2992. pChildPage,
  2993. (LPWSTR)lParam2,
  2994. Function ==
  2995. CPSFUNC_SET_PSUIPAGE_TITLEA);
  2996. break;
  2997. case CPSFUNC_SET_PSUIPAGE_ICON:
  2998. Result = SetPSUIPageIcon(pRootPage,
  2999. pChildPage,
  3000. (HICON)lParam2);
  3001. break;
  3002. case CPSFUNC_IGNORE_CPSUI_PSN_APPLY:
  3003. CPSUIDBG(DBG_GET_TABWND,
  3004. ("*\n\nCPSFUNC_IGNORE_CPSUI_PSN_APPLY: Page=%08lx, lParam2=%08lx, hDlg=%08lx\n",
  3005. pChildPage, lParam2, pRootPage->RootInfo.hDlg));
  3006. if (EnumCPSUIPagesSeq(pRootPage,
  3007. pChildPage,
  3008. IgnorePSNApplyProc,
  3009. lParam2)) {
  3010. Result = 1;
  3011. }
  3012. break;
  3013. case CPSFUNC_DO_APPLY_CPSUI:
  3014. if ((pRootPage->Flags & CPF_SHOW_PROPSHEET) &&
  3015. (pRootPage->RootInfo.hDlg)) {
  3016. CPSUIDBG(DBG_GET_TABWND,
  3017. ("*\n\nCPSFUNC_DO_APPLY_CPSUI: Page=%08lx, lParam2=%08lx, hDlg=%08lx\n",
  3018. pChildPage, lParam2, pRootPage->RootInfo.hDlg));
  3019. if (EnumCPSUIPagesSeq(pRootPage,
  3020. pChildPage,
  3021. ApplyCPSUIProc,
  3022. lParam2)) {
  3023. Result = 1;
  3024. }
  3025. }
  3026. break;
  3027. }
  3028. }
  3029. HANDLETABLE_UnGetCPSUIPage(pChildPage);
  3030. break;
  3031. case CPSFUNC_SET_DATABLOCK:
  3032. LOCK_CPSUI_HANDLETABLE();
  3033. if ((pCPSUIDB = (PCPSUIDATABLOCK)lParam1) &&
  3034. (lParam2) &&
  3035. (pCPSUIDB->cbData) &&
  3036. (pCPSUIDB->pbData) &&
  3037. (pMyDB = (PMYDATABLOCK)LocalAlloc(LPTR,
  3038. SIZE_DB(pCPSUIDB->cbData)))) {
  3039. PMYDATABLOCK pPrevDB = NULL;
  3040. PMYDATABLOCK pCurDB = pRootPage->RootInfo.pMyDB;
  3041. //
  3042. // Try to find the old ID and delete it
  3043. //
  3044. while (pCurDB) {
  3045. if (pCurDB->ID == (DWORD)lParam2) {
  3046. if (pPrevDB) {
  3047. pPrevDB->pNext = pCurDB->pNext;
  3048. } else {
  3049. //
  3050. // This is the first one
  3051. //
  3052. pRootPage->RootInfo.pMyDB = pCurDB->pNext;
  3053. }
  3054. CPSUIDBG(DBG_PFNCOMPROPSHEET,
  3055. ("SET_DATABLOCK()=Free ID=%08lx, pCurDB=%08lx (%ld)",
  3056. pCurDB->ID, pCurDB, pCurDB->cb));
  3057. LocalFree((HLOCAL)pCurDB);
  3058. pCurDB = NULL;
  3059. } else {
  3060. pPrevDB = pCurDB;
  3061. pCurDB = pCurDB->pNext;
  3062. }
  3063. }
  3064. //
  3065. // Insert to the front
  3066. //
  3067. pMyDB->pNext = pRootPage->RootInfo.pMyDB;
  3068. pMyDB->ID = (DWORD)lParam2;
  3069. pMyDB->cb = pCPSUIDB->cbData;
  3070. pRootPage->RootInfo.pMyDB = pMyDB;
  3071. Result = (LONG_PTR)pCPSUIDB->cbData;
  3072. CopyMemory((LPBYTE)(pMyDB + 1),
  3073. pCPSUIDB->pbData,
  3074. LODWORD(Result));
  3075. }
  3076. UNLOCK_CPSUI_HANDLETABLE();
  3077. break;
  3078. case CPSFUNC_QUERY_DATABLOCK:
  3079. LOCK_CPSUI_HANDLETABLE();
  3080. if (pMyDB = pRootPage->RootInfo.pMyDB) {
  3081. while (pMyDB) {
  3082. if (pMyDB->ID == (DWORD)lParam2) {
  3083. break;
  3084. } else {
  3085. pMyDB = pMyDB->pNext;
  3086. }
  3087. }
  3088. if (pMyDB) {
  3089. Result = (LONG_PTR)pMyDB->cb;
  3090. //
  3091. // Only do it if has a pointer and buffer count is
  3092. // not zero or the pointer is not NULL
  3093. //
  3094. if ((pCPSUIDB = (PCPSUIDATABLOCK)lParam1) &&
  3095. (pCPSUIDB->cbData) &&
  3096. (pCPSUIDB->pbData)) {
  3097. //
  3098. // Limit to total bytes to copy = min(lParam2, Result)
  3099. //
  3100. if ((LONG_PTR)Result > (LONG_PTR)pCPSUIDB->cbData) {
  3101. Result = (LONG_PTR)pCPSUIDB->cbData;
  3102. }
  3103. CopyMemory(pCPSUIDB->pbData,
  3104. (LPBYTE)(pMyDB + 1),
  3105. LODWORD(Result));
  3106. }
  3107. }
  3108. }
  3109. UNLOCK_CPSUI_HANDLETABLE();
  3110. break;
  3111. case CPSFUNC_SET_DMPUB_HIDEBITS:
  3112. //
  3113. // Only do it when these page is not register yet
  3114. //
  3115. if (!(pRootPage->Flags & (CPF_DOCPROP | CPF_ADVDOCPROP))) {
  3116. (DWORD)lParam1 &= ~((DWORD)0xFFFFFFFF << DMPUB_LAST);
  3117. pRootPage->RootInfo.DMPubHideBits = (DWORD)(Result = lParam1);
  3118. }
  3119. break;
  3120. default:
  3121. CPSUIERR(("CPSUICallBack(%ld) Unknown function index", Function));
  3122. Result = (ULONG_PTR)-1;
  3123. break;
  3124. }
  3125. }
  3126. HANDLETABLE_UnGetCPSUIPage(pParentPage);
  3127. HANDLETABLE_UnGetCPSUIPage(pRootPage);
  3128. //
  3129. // Compstui.dll should not set the wait cursor, it is the
  3130. // responsibility of the top level caller to display any
  3131. // progress UI if applicable. SteveKi 12/06/97
  3132. //
  3133. #if 0
  3134. SetCursor(hCursor);
  3135. #endif
  3136. CPSUIDBG(DBG_PFNCOMPROPSHEET, ("CPSUICallBack()=%08lx", Result));
  3137. if (dwErr != ERROR_SUCCESS) {
  3138. //
  3139. // Set the last error if preserved.
  3140. //
  3141. SetLastError(dwErr);
  3142. }
  3143. return(Result);
  3144. }
  3145. DWORD
  3146. GetSetCurUserReg(
  3147. HKEY *phRegKey,
  3148. PTVWND pTVWnd,
  3149. LPDWORD pdw
  3150. )
  3151. /*++
  3152. Routine Description:
  3153. Arguments:
  3154. Return Value:
  3155. Author:
  3156. 30-Jan-1996 Tue 13:36:59 created -by- Daniel Chou (danielc)
  3157. Revision History:
  3158. --*/
  3159. {
  3160. POPTITEM pItem;
  3161. DWORD dw = 0;
  3162. if (*phRegKey) {
  3163. if (pTVWnd->ActiveDlgPage == pTVWnd->TVPageIdx) {
  3164. dw = REGDPF_TVPAGE;
  3165. } else if (pTVWnd->ActiveDlgPage == 0) {
  3166. dw = REGDPF_STD_P1;
  3167. } else {
  3168. dw = 0;
  3169. }
  3170. if ((pTVWnd->IntTVOptIdx) &&
  3171. (pItem = PIDX_INTOPTITEM(pTVWnd, pTVWnd->IntTVOptIdx)) &&
  3172. (!(pItem->Flags & OPTIF_COLLAPSE))) {
  3173. dw |= REGDPF_EXPAND_OPTIONS;
  3174. }
  3175. if (dw != *pdw) {
  3176. CPSUIDBG(DBG_GETSETREG, ("GetSetCurUserReg(): Set New DW=%08lx", dw));
  3177. RegSetValueEx(*phRegKey,
  3178. szDocPropKeyName,
  3179. 0,
  3180. REG_DWORD,
  3181. (CONST BYTE *)&dw,
  3182. sizeof(DWORD));
  3183. }
  3184. RegCloseKey(*phRegKey);
  3185. *phRegKey = NULL;
  3186. } else if (((ULONG_PTR)pTVWnd->ComPropSheetUI.pDlgPage ==
  3187. (ULONG_PTR)CPSUI_PDLGPAGE_DOCPROP) &&
  3188. (RegCreateKey(HKEY_CURRENT_USER,
  3189. szCPSUIRegKey,
  3190. phRegKey) == ERROR_SUCCESS) &&
  3191. (*phRegKey)) {
  3192. DWORD Type = REG_DWORD;
  3193. DWORD Size = sizeof(DWORD);
  3194. if (RegQueryValueEx(*phRegKey,
  3195. szDocPropKeyName,
  3196. NULL,
  3197. &Type,
  3198. (LPBYTE)pdw,
  3199. &Size) != ERROR_SUCCESS) {
  3200. *pdw = REGDPF_DEFAULT;
  3201. }
  3202. *pdw &= REGDPF_MASK;
  3203. CPSUIDBG(DBG_GETSETREG, ("GetSetCurUserReg(): Get Cur DW=%08lx", *pdw));
  3204. if ((*pdw & REGDPF_TVPAGE) &&
  3205. (pTVWnd->TVPageIdx != PAGEIDX_NONE)) {
  3206. dw = pTVWnd->TVPageIdx;
  3207. } else if ((*pdw & REGDPF_STD_P1) &&
  3208. (pTVWnd->StdPageIdx1 != PAGEIDX_NONE)) {
  3209. dw = pTVWnd->StdPageIdx1;
  3210. } else if (pTVWnd->StdPageIdx2 != PAGEIDX_NONE) {
  3211. dw = pTVWnd->StdPageIdx2;
  3212. } else {
  3213. dw = (DWORD)-1;
  3214. }
  3215. if ((pTVWnd->IntTVOptIdx) &&
  3216. (pItem = PIDX_INTOPTITEM(pTVWnd, pTVWnd->IntTVOptIdx))) {
  3217. if (*pdw & REGDPF_EXPAND_OPTIONS) {
  3218. pItem->Flags &= ~OPTIF_COLLAPSE;
  3219. } else {
  3220. pItem->Flags |= OPTIF_COLLAPSE;
  3221. }
  3222. }
  3223. }
  3224. return(dw);
  3225. }
  3226. LONG
  3227. DoComPropSheet(
  3228. PCPSUIPAGE pRootPage,
  3229. PPROPSHEETUI_INFO_HEADER pPSUIInfoHdr
  3230. )
  3231. /*++
  3232. Routine Description:
  3233. Arguments:
  3234. Return Value:
  3235. Author:
  3236. 29-Aug-1995 Tue 12:55:41 created -by- Daniel Chou (danielc)
  3237. Revision History:
  3238. 28-Nov-1995 Tue 16:30:29 updated -by- Daniel Chou (danielc)
  3239. Remove help button, since all help will be right mouse/question mark
  3240. activated.
  3241. --*/
  3242. {
  3243. PTVWND pTVWnd;
  3244. PCPSUIPAGE pPage = NULL;
  3245. PROPSHEETHEADER psh;
  3246. PPSHINFO pPSHInfo;
  3247. LPTSTR pTitle;
  3248. PAGEPROCINFO PageProcInfo;
  3249. HICON hIcon = NULL;
  3250. HKEY hRegKey = NULL;
  3251. DWORD Data;
  3252. DWORD dw;
  3253. UINT IntFmtStrID;
  3254. LONG Result;
  3255. WORD GBFAnsi;
  3256. BOOL AnsiCall;
  3257. UINT Idx = 0;
  3258. GBFAnsi = (WORD)((pRootPage->Flags & CPF_ANSI_CALL) ? GBF_ANSI_CALL : 0);
  3259. Result = sizeof(PSHINFO) +
  3260. (pRootPage->RootInfo.cPage * sizeof(HPROPSHEETPAGE));
  3261. if ((pRootPage->RootInfo.cPage) &&
  3262. (pPSHInfo = (PPSHINFO)LocalAlloc(LPTR, Result))) {
  3263. PageProcInfo.pTabTable = pRootPage->RootInfo.pTabTable;
  3264. PageProcInfo.pHandle = NULL;
  3265. PageProcInfo.phPage = (HPROPSHEETPAGE *)(pPSHInfo + 1);
  3266. PageProcInfo.iPage = 0;
  3267. PageProcInfo.cPage = (WORD)pRootPage->RootInfo.cPage;
  3268. EnumCPSUIPagesSeq(pRootPage,
  3269. pRootPage,
  3270. SetPageProcInfo,
  3271. (LPARAM)&PageProcInfo);
  3272. SHOW_TABWND(L"DoComPropSheet", PageProcInfo.pTabTable);
  3273. } else {
  3274. return(ERR_CPSUI_ALLOCMEM_FAILED);
  3275. }
  3276. psh.dwSize = sizeof(PROPSHEETHEADER);
  3277. psh.dwFlags = 0;
  3278. if (pPSUIInfoHdr->Flags & PSUIHDRF_PROPTITLE) {
  3279. psh.dwFlags |= PSH_PROPTITLE;
  3280. }
  3281. if (pPSUIInfoHdr->Flags & PSUIHDRF_NOAPPLYNOW) {
  3282. psh.dwFlags |= PSH_NOAPPLYNOW;
  3283. pRootPage->Flags |= CPF_NO_APPLY_BUTTON;
  3284. }
  3285. CPSUIDBGBLK(
  3286. {
  3287. if (DBG_CPSUIFILENAME & DBG_ALWAYS_APPLYNOW) {
  3288. psh.dwFlags &= ~PSH_NOAPPLYNOW;
  3289. pRootPage->Flags &= ~CPF_NO_APPLY_BUTTON;
  3290. }
  3291. })
  3292. psh.hwndParent = pPSUIInfoHdr->hWndParent;
  3293. psh.hInstance = pPSUIInfoHdr->hInst;
  3294. psh.pStartPage = NULL;
  3295. psh.nPages = (UINT)pRootPage->RootInfo.cPage;
  3296. psh.phpage = PageProcInfo.phPage;
  3297. psh.pszCaption = (LPTSTR)pPSHInfo->CaptionName;
  3298. if (pPSUIInfoHdr->Flags & PSUIHDRF_USEHICON) {
  3299. psh.dwFlags |= PSH_USEHICON;
  3300. psh.hIcon = pPSUIInfoHdr->hIcon;
  3301. } else {
  3302. if (!(hIcon = GETICON16(pPSUIInfoHdr->hInst, pPSUIInfoHdr->IconID))) {
  3303. hIcon = GETICON16(hInstDLL, IDI_CPSUI_OPTION);
  3304. }
  3305. psh.dwFlags |= PSH_USEHICON;
  3306. psh.hIcon = hIcon;
  3307. }
  3308. //
  3309. // Set Start page now
  3310. //
  3311. if (pPage = pRootPage->RootInfo.pStartPage) {
  3312. if (pRootPage->Flags & CPF_PSZ_PSTARTPAGE) {
  3313. psh.dwFlags |= PSH_USEPSTARTPAGE;
  3314. psh.pStartPage = (LPCTSTR)pPage;
  3315. } else {
  3316. while ((pPage) && (pPage->Flags & CPF_PARENT)) {
  3317. pPage = pPage->pChild;
  3318. }
  3319. if ((pPage) &&
  3320. (!(pPage->Flags & CPF_PARENT)) &&
  3321. (pPage->hPage)) {
  3322. while (psh.nStartPage < psh.nPages) {
  3323. if (psh.phpage[psh.nStartPage] == pPage->hPage) {
  3324. //
  3325. // Found it
  3326. //
  3327. break;
  3328. }
  3329. psh.nStartPage++;
  3330. }
  3331. }
  3332. }
  3333. }
  3334. //
  3335. // Get the internal format string ID for the title bar
  3336. //
  3337. if ((pTitle = pPSUIInfoHdr->pTitle) &&
  3338. (pPSUIInfoHdr->Flags & PSUIHDRF_EXACT_PTITLE)) {
  3339. psh.dwFlags &= ~PSH_PROPTITLE;
  3340. IntFmtStrID = 0;
  3341. } else {
  3342. IntFmtStrID = (pPSUIInfoHdr->Flags & PSUIHDRF_DEFTITLE) ?
  3343. IDS_INT_CPSUI_DEFAULT : 0;
  3344. if ((pRootPage->Flags & (CPF_DOCPROP | CPF_ADVDOCPROP)) &&
  3345. (pRootPage->RootInfo.cPage >= pRootPage->RootInfo.cCPSUIPage)) {
  3346. if (pRootPage->Flags & CPF_ADVDOCPROP) {
  3347. //
  3348. // Can only be 'XXX Advance Document Properties';
  3349. //
  3350. IntFmtStrID = IDS_INT_CPSUI_ADVDOCUMENT;
  3351. psh.dwFlags |= PSH_PROPTITLE;
  3352. } else if (pRootPage->Flags & CPF_DOCPROP) {
  3353. //
  3354. // Can be 'XXX Document Properties' or
  3355. // 'XXX Default Document Properties'
  3356. //
  3357. IntFmtStrID = (pPSUIInfoHdr->Flags & PSUIHDRF_DEFTITLE) ?
  3358. IDS_INT_CPSUI_DEFDOCUMENT :
  3359. IDS_INT_CPSUI_DOCUMENT;
  3360. psh.dwFlags |= PSH_PROPTITLE;
  3361. if (!pRootPage->RootInfo.pStartPage) {
  3362. pPage = pRootPage;
  3363. while ((pPage) && (pPage->Flags & CPF_PARENT)) {
  3364. pPage = pPage->pChild;
  3365. }
  3366. if ((pPage) &&
  3367. (pPage->pParent->Flags & CPF_COMPROPSHEETUI) &&
  3368. (pTVWnd = pPage->pParent->CPSUIInfo.pTVWnd)) {
  3369. if ((dw = GetSetCurUserReg(&hRegKey,
  3370. pTVWnd,
  3371. &Data)) != (DWORD)-1) {
  3372. psh.nStartPage += dw;
  3373. }
  3374. }
  3375. }
  3376. }
  3377. }
  3378. }
  3379. //
  3380. // Compose Title, first make sure the title exist, if not then use
  3381. // 'Options' as title
  3382. //
  3383. if ((!pTitle) ||
  3384. (!GetStringBuffer(pPSUIInfoHdr->hInst,
  3385. (WORD)(GBF_PREFIX_OK |
  3386. GBF_INT_NO_PREFIX |
  3387. GBFAnsi),
  3388. L'\0',
  3389. pTitle,
  3390. pPSHInfo->CaptionName,
  3391. COUNT_ARRAY(pPSHInfo->CaptionName)))) {
  3392. GetStringBuffer(hInstDLL,
  3393. (WORD)(GBF_PREFIX_OK |
  3394. GBF_INT_NO_PREFIX |
  3395. GBFAnsi),
  3396. L'\0',
  3397. pTitle = (LPTSTR)IDS_CPSUI_OPTIONS,
  3398. pPSHInfo->CaptionName,
  3399. COUNT_ARRAY(pPSHInfo->CaptionName));
  3400. }
  3401. //
  3402. // If we need to composed with internal format string, then redo it using
  3403. // compose calls, otherwise the CaptionName already has user title
  3404. //
  3405. if (IntFmtStrID) {
  3406. ComposeStrData(pPSUIInfoHdr->hInst,
  3407. (WORD)(GBF_PREFIX_OK | GBF_INT_NO_PREFIX | GBFAnsi),
  3408. pPSHInfo->CaptionName,
  3409. COUNT_ARRAY(pPSHInfo->CaptionName),
  3410. IntFmtStrID,
  3411. pTitle,
  3412. 0,
  3413. 0);
  3414. }
  3415. if ((!(psh.dwFlags & PSH_USEPSTARTPAGE)) &&
  3416. (psh.nStartPage >= psh.nPages)) {
  3417. psh.nStartPage = 0;
  3418. }
  3419. CPSUIDBG(DBG_DOCOMPROPSHEET, ("pRootPage=%08lx, RootFlags=%08lx, pPSUIInfoHdr->Flags=%08lx\nCaption(%ld)='%ws', Start Page=%ld (%08lx)",
  3420. pRootPage, pRootPage->Flags, pPSUIInfoHdr->Flags,
  3421. (LONG)Idx, pPSHInfo->CaptionName, psh.nStartPage,
  3422. psh.pStartPage));
  3423. psh.dwFlags |= PSH_USECALLBACK;
  3424. psh.pfnCallback = PropSheetProc;
  3425. //
  3426. // Make sure only one person go through the PropertySheet
  3427. //
  3428. LOCK_CPSUI_HANDLETABLE();
  3429. CPSUIDBG(DBG_PAGE_PROC, ("<< ProcessID=%ld, ThreadID=%ld, TIsValue(%ld)=%08lx",
  3430. GetCurrentProcessId(), GetCurrentThreadId(),
  3431. TlsIndex, TlsGetValue(TlsIndex)));
  3432. Data = (DWORD)TLSVALUE_2_CWAIT(TlsGetValue(TlsIndex));
  3433. Idx = (UINT)HANDLE_2_IDX(pRootPage->hCPSUIPage);
  3434. TlsSetValue(TlsIndex, ULongToPtr(MK_TLSVALUE(Data, Idx)));
  3435. UNLOCK_CPSUI_HANDLETABLE();
  3436. DBG_SHOW_CPSUIPAGE(pRootPage, 0);
  3437. if ((Result = (LONG)PropertySheet((LPCPROPSHEETHEADER)&psh)) < 0) {
  3438. Result = ERR_CPSUI_GETLASTERROR;
  3439. } else if (Result == ID_PSRESTARTWINDOWS) {
  3440. Result = CPSUI_RESTARTWINDOWS;
  3441. } else if (Result == ID_PSREBOOTSYSTEM) {
  3442. Result = CPSUI_REBOOTSYSTEM;
  3443. } else {
  3444. Result = CPSUI_OK;
  3445. }
  3446. //
  3447. // Free all the stuff first
  3448. //
  3449. LocalFree((HLOCAL)pPSHInfo);
  3450. if (hIcon) {
  3451. DestroyIcon(hIcon);
  3452. }
  3453. //
  3454. // Save things back to registry if we got one
  3455. //
  3456. if (hRegKey) {
  3457. GetSetCurUserReg(&hRegKey, pTVWnd, &Data);
  3458. }
  3459. CPSUIINT(("PropertySheet() = %ld", Result));
  3460. return(Result);
  3461. }
  3462. LONG
  3463. DoCommonPropertySheetUI(
  3464. HWND hWndOwner,
  3465. PFNPROPSHEETUI pfnPropSheetUI,
  3466. LPARAM lParam,
  3467. LPDWORD pResult,
  3468. BOOL AnsiCall
  3469. )
  3470. /*++
  3471. Routine Description:
  3472. The CommonPropSheetUI is the main entry point for the common property sheet
  3473. user interface. The original caller that wish to using common UI to
  3474. pop-up property sheet will call this function and passed its own
  3475. PFNPROPSHEETUI function address and a long parameter.
  3476. If pfnPropSheetUI function return a LONG number greater than zero (0) then
  3477. common UI will pop-up the property sheet page dialog boxes, when Property
  3478. sheet pages is finished. (either hit Ok or Cancel) it will return the
  3479. result of CPSUI_xxxx back to the caller.
  3480. If pfnPropSheetUI function return a LONG number equal or less than zero (0)
  3481. then it will return the CPSUI_CANCEL back to caller without pop-up the
  3482. property sheet page dialog boxes.
  3483. Arguments:
  3484. hWndOwner - Window handle for the owner of this proerty sheet
  3485. pages dialog boxes.
  3486. pfnPropSheetUI - a PFNPROPSHEETUI function pointer which is used by
  3487. the caller to add its property sheet pages.
  3488. lParam - a long parameter will be passed to the pfnPropSheetUI
  3489. funciton. The common UI called the pfnPropSheetUI as
  3490. PROPSHEETUI_INFO PSUIInfo;
  3491. pfnPropSheetUI(&PSUIInfo, lParam);
  3492. The caller must use pfnComPropSheet() to add/delete
  3493. pages. When it is done adding pages, it retuned
  3494. greater than zero to indicate successful, and return
  3495. less or equal to zero to indicate failure.
  3496. pResult - a pointer to DWORD which received the final result
  3497. of pfnPropSheetUI() funciton, this result is a copy
  3498. from Result field of PROPSHEETUI_INFO data structure
  3499. which passed to the pfnPropSheetUI() as the first
  3500. parameter.
  3501. if pResult is NULL then common UI will not return
  3502. pfnPropSheetUI()'s result back.
  3503. Return Value:
  3504. LONG - < 0 - Error, ERR_CPSUI_xxxx
  3505. CPSUI_CANCEL - User hit Cancel.
  3506. CPSUI_OK - User hit Ok.
  3507. CPSUI_RESTARTWINDOWS - Ok and need to restart window
  3508. CPSUI_REBOOTSYSTEM - Ok and need to reboot system
  3509. Author:
  3510. 04-Feb-1996 Sun 07:52:49 created -by- Daniel Chou (danielc)
  3511. Revision History:
  3512. --*/
  3513. {
  3514. PTABTABLE pTabTable = NULL;
  3515. PCPSUIPAGE pRootPage;
  3516. PROPSHEETUI_INFO_HEADER PSUIInfoHdr;
  3517. PMYDATABLOCK pMyDB;
  3518. LONG Result;
  3519. if (!(pRootPage = AddCPSUIPage(NULL, NULL, 0))) {
  3520. CPSUIERR(("DoCommonPropertySheetUI(), Create RootPage failed"));
  3521. return(ERR_CPSUI_ALLOCMEM_FAILED);
  3522. }
  3523. PSUIInfoHdr.cbSize = sizeof(PROPSHEETUI_INFO_HEADER);
  3524. PSUIInfoHdr.Flags = 0;
  3525. PSUIInfoHdr.pTitle = NULL;
  3526. PSUIInfoHdr.hWndParent = hWndOwner;
  3527. PSUIInfoHdr.hInst = NULL;
  3528. PSUIInfoHdr.IconID = IDI_CPSUI_OPTION;
  3529. pRootPage->RootInfo.pResult = pResult;
  3530. CPSUIDBG(DBG_DO_CPSUI, ("DoComPropSheetUI(hWndOwner=%08lx, Active=%08lx, Focus=%08lx)",
  3531. hWndOwner, GetActiveWindow(), GetFocus()));
  3532. if (GetCapture()) {
  3533. CPSUIDBG(DBG_DO_CPSUI, ("DoComPropSheetUI(): MouseCapture=%08lx",
  3534. GetCapture()));
  3535. ReleaseCapture();
  3536. }
  3537. if (AnsiCall) {
  3538. CPSUIDBG(DBG_DO_CPSUI, ("DoComPropSheetUI(ANSI CALL)"));
  3539. pRootPage->Flags |= CPF_ANSI_CALL;
  3540. }
  3541. if (!CPSUICallBack(pRootPage->hCPSUIPage,
  3542. (AnsiCall) ? CPSFUNC_ADD_PFNPROPSHEETUIA :
  3543. CPSFUNC_ADD_PFNPROPSHEETUIW,
  3544. (LPARAM)pfnPropSheetUI,
  3545. (LPARAM)lParam)) {
  3546. CPSUIERR(("DoCommonPropertySheetUI: ADD_PFNPROPSHEETUI failed"));
  3547. Result = ERR_CPSUI_GETLASTERROR;
  3548. } else if (CallpfnPSUI(pRootPage->pChild,
  3549. PROPSHEETUI_REASON_GET_INFO_HEADER,
  3550. (LPARAM)&PSUIInfoHdr) <= 0) {
  3551. CPSUIERR(("DoCommonPropertySheetUI: GET_INFO_HEADER, Canceled"));
  3552. Result = CPSUI_CANCEL;
  3553. } else if (!(pRootPage->RootInfo.cPage)) {
  3554. CPSUIERR(("DoCommonPropertySheetUI: RootInfo.cPage=0, Canceled."));
  3555. Result = ERR_CPSUI_NO_PROPSHEETPAGE;
  3556. } else if (!(pTabTable = (PTABTABLE)LocalAlloc(LMEM_FIXED,
  3557. sizeof(TABTABLE)))) {
  3558. CPSUIERR(("DoCommonPropertySheetUI: Allocation of TABTABLE=%ld failed",
  3559. sizeof(TABTABLE)));
  3560. Result = ERR_CPSUI_ALLOCMEM_FAILED;
  3561. } else {
  3562. DoTabTable(TAB_MODE_DELETE_ALL, pTabTable, 0, 0);
  3563. pRootPage->RootInfo.pTabTable =
  3564. pTabTable->pTabTable = pTabTable;
  3565. pTabTable->hWndTab = NULL;
  3566. pTabTable->WndProc = NULL;
  3567. pTabTable->hPSDlg = NULL;
  3568. // pTabTable->hRootPage = pRootPage->hCPSUIPage;
  3569. pRootPage->Flags |= CPF_SHOW_PROPSHEET;
  3570. Result = DoComPropSheet(pRootPage, &PSUIInfoHdr);
  3571. pRootPage->Flags &= ~CPF_SHOW_PROPSHEET;
  3572. pRootPage->Flags |= CPF_DONE_PROPSHEET;
  3573. }
  3574. if (pTabTable) {
  3575. CPSUIDBG(DBG_PAGE_PROC, ("=+=+ FREE pTableTable=%08lx", pTabTable));
  3576. LocalFree((HLOCAL)pTabTable);
  3577. pTabTable = NULL;
  3578. }
  3579. //
  3580. // Free up the Datablock even if failed, so if misbehave by the caller
  3581. // that register the data block then we should remove it now
  3582. //
  3583. while (pMyDB = pRootPage->RootInfo.pMyDB) {
  3584. pRootPage->RootInfo.pMyDB = pMyDB->pNext;
  3585. CPSUIDBG(DBG_DO_CPSUI,
  3586. ("Free DataBlock: ID=%08lx, pCurDB=%08lx (%ld)",
  3587. pMyDB->ID, pMyDB, pMyDB->cb));
  3588. LocalFree((HLOCAL)pMyDB);
  3589. }
  3590. HANDLETABLE_UnGetCPSUIPage(pRootPage);
  3591. EnumCPSUIPages(pRootPage, pRootPage, DeleteCPSUIPageProc, (LPARAM)0);
  3592. if (pResult) {
  3593. CPSUIDBG(DBG_DO_CPSUI, ("DoCommonPropertySheetUI(): Result=%ld, *pResult=%ld",
  3594. Result, *pResult));
  3595. } else {
  3596. CPSUIDBG(DBG_DO_CPSUI, ("DoCommonPropertySheetUI(): Result=%ld, *pResult=NULL",
  3597. Result));
  3598. }
  3599. return(Result);
  3600. }
  3601. LONG
  3602. APIENTRY
  3603. CommonPropertySheetUIA(
  3604. HWND hWndOwner,
  3605. PFNPROPSHEETUI pfnPropSheetUI,
  3606. LPARAM lParam,
  3607. LPDWORD pResult
  3608. )
  3609. /*++
  3610. Routine Description:
  3611. SEE DoCommonPropertySheetUI description
  3612. Arguments:
  3613. SEE DoCommonPropertySheetUI description
  3614. Return Value:
  3615. SEE DoCommonPropertySheetUI description
  3616. Author:
  3617. 01-Sep-1995 Fri 12:29:10 created -by- Daniel Chou (danielc)
  3618. Revision History:
  3619. --*/
  3620. {
  3621. return(DoCommonPropertySheetUI(hWndOwner,
  3622. pfnPropSheetUI,
  3623. lParam,
  3624. pResult,
  3625. TRUE));
  3626. }
  3627. LONG
  3628. APIENTRY
  3629. CommonPropertySheetUIW(
  3630. HWND hWndOwner,
  3631. PFNPROPSHEETUI pfnPropSheetUI,
  3632. LPARAM lParam,
  3633. LPDWORD pResult
  3634. )
  3635. /*++
  3636. Routine Description:
  3637. SEE DoCommonPropertySheetUI description
  3638. Arguments:
  3639. SEE DoCommonPropertySheetUI description
  3640. Return Value:
  3641. SEE DoCommonPropertySheetUI description
  3642. Author:
  3643. 30-Jan-1996 Tue 15:30:41 created -by- Daniel Chou (danielc)
  3644. Revision History:
  3645. --*/
  3646. {
  3647. return(DoCommonPropertySheetUI(hWndOwner,
  3648. pfnPropSheetUI,
  3649. lParam,
  3650. pResult,
  3651. FALSE));
  3652. }