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.

3620 lines
78 KiB

  1. /*++
  2. Copyright (c) 1990-1995 Microsoft Corporation
  3. Module Name:
  4. proppage.c
  5. Abstract:
  6. This module contains user page procs
  7. Author:
  8. 18-Aug-1995 Fri 18:57:12 created -by- Daniel Chou (danielc)
  9. [Environment:]
  10. NT Windows - Common Printer Driver UI DLL.
  11. [Notes:]
  12. Revision History:
  13. --*/
  14. #include "precomp.h"
  15. #pragma hdrstop
  16. #define DBG_CPSUIFILENAME DbgPropPage
  17. #define DBG_PROPPAGEPROC 0x00000001
  18. #define DBG_INITP1 0x00000002
  19. #define DBGITEM_INITP1 0x00000004
  20. #define DBGITEM_UP1 0x00000008
  21. #define DBG_HMII 0x00000010
  22. #define DBG_AII 0x00000020
  23. #define DBG_QSORT 0x00000040
  24. #define DBG_SETFOCUS 0x00000080
  25. #define DBG_STATES 0x00000100
  26. #define DBG_ADVPUSH 0x00000200
  27. DEFINE_DBGVAR(0);
  28. extern HINSTANCE hInstDLL;
  29. extern STDPAGEINFO StdPageInfo[];
  30. extern BYTE StdTVOT[];
  31. #define MAX_ITEM_CTRLS 12
  32. const BYTE cTVOTCtrls[] = { 8, 10, 9, 9, 9, 6, 6, 8, 6, 6, 0 };
  33. #define IIF_3STATES_1 OTINTF_STATES_1
  34. #define IIF_3STATES_2 OTINTF_STATES_2
  35. #define IIF_3STATES_3 OTINTF_STATES_3
  36. #define IIF_3STATES_HIDE OTINTF_STATES_HIDE_MASK
  37. #define IIF_STDPAGE_3STATES OTINTF_STDPAGE_3STATES
  38. #define IIF_ITEM_HIDE 0x10
  39. #define IIF_EXT_HIDE 0x20
  40. typedef struct _ITEMINFO {
  41. POPTITEM pItem;
  42. BYTE Flags;
  43. BYTE Type;
  44. WORD BegCtrlID;
  45. WORD CtrlBits;
  46. SHORT xExtMove;
  47. WORD yExt;
  48. WORD yMoveUp;
  49. WORD Extra;
  50. RECT rc;
  51. RECT rcCtrls;
  52. } ITEMINFO, *PITEMINFO;
  53. typedef struct _ITEMINFOHEADER {
  54. HWND hDlg;
  55. PTVWND pTVWnd;
  56. WORD cItem;
  57. WORD cMaxItem;
  58. ITEMINFO ItemInfo[1];
  59. } ITEMINFOHEADER, *PITEMINFOHEADER;
  60. #define OUTRANGE_LEFT 0x7FFFFFFFL
  61. #define INIT_ADDRECT(rc) ((rc).left = OUTRANGE_LEFT)
  62. #define HAS_ADDRECT(rc) ((rc).left != OUTRANGE_LEFT)
  63. typedef struct _HSINFO {
  64. HWND hCtrl;
  65. LONG x;
  66. LONG y;
  67. } HSINFO, *PHSINFO;
  68. INT
  69. __cdecl
  70. ItemInfoCompare(
  71. const void *pItemInfo1,
  72. const void *pItemInfo2
  73. )
  74. {
  75. return((INT)(((PITEMINFO)pItemInfo1)->rc.top) -
  76. (INT)(((PITEMINFO)pItemInfo2)->rc.top));
  77. }
  78. UINT
  79. AddRect(
  80. RECT *prc1,
  81. RECT *prc2
  82. )
  83. /*++
  84. Routine Description:
  85. This function add the *prc1 to *prc2, if any of the prc1 corners are
  86. outside of prc2
  87. Arguments:
  88. Return Value:
  89. UINT, count of *prc1 corners which is at outside of *prc2 corners, other
  90. word is the *prc2 corners which added to the *prc2 corner that is.
  91. Author:
  92. 16-Sep-1995 Sat 23:06:53 created -by- Daniel Chou (danielc)
  93. Revision History:
  94. --*/
  95. {
  96. UINT cAdded = 0;
  97. if (prc2->left == OUTRANGE_LEFT) {
  98. *prc2 = *prc1;
  99. return(0);
  100. } else {
  101. CPSUIASSERT(0, "AddRect: invalid rc.left=%d",
  102. (prc2->left >= 0) && (prc2->top >= 0) &&
  103. (prc2->right >= prc2->left) && (prc2->bottom >= prc2->top),
  104. LongToPtr(prc2->left));
  105. }
  106. if (prc2->left > prc1->left) {
  107. prc2->left = prc1->left;
  108. ++cAdded;
  109. }
  110. if (prc2->top > prc1->top) {
  111. prc2->top = prc1->top;
  112. ++cAdded;
  113. }
  114. if (prc2->right < prc1->right) {
  115. prc2->right = prc1->right;
  116. ++cAdded;
  117. }
  118. if (prc2->bottom < prc1->bottom) {
  119. prc2->bottom = prc1->bottom;
  120. ++cAdded;
  121. }
  122. return(cAdded);
  123. }
  124. UINT
  125. HideStates(
  126. HWND hDlg,
  127. PITEMINFO pII,
  128. RECT *prcVisibleNoStates
  129. )
  130. /*++
  131. Routine Description:
  132. Arguments:
  133. Return Value:
  134. Author:
  135. 22-Aug-1995 Tue 16:58:37 created -by- Daniel Chou (danielc)
  136. Revision History:
  137. --*/
  138. {
  139. PHSINFO pHSInfo;
  140. HSINFO HSInfo[6];
  141. HWND hCurCtrl;
  142. UINT HideBits;
  143. UINT Mask;
  144. UINT CtrlID = (UINT)(pII->BegCtrlID + 2);
  145. RECT rcStates;
  146. RECT rcMax[3];
  147. UINT yRemoved = 0;
  148. SIZEL szlHide;
  149. SIZEL szlSpace;
  150. INT cStates;
  151. INT cHide;
  152. INT i;
  153. INT j;
  154. BOOL DoXDir;
  155. szlSpace.cx =
  156. szlSpace.cy =
  157. szlHide.cx =
  158. szlHide.cy = 0;
  159. cStates = (UINT)((pII->Type == TVOT_2STATES) ? 2 : 3);
  160. HideBits = (UINT)(pII->Flags & IIF_3STATES_HIDE);
  161. CPSUIDBG(DBG_STATES, ("\ncStates=%ld, HideBits=%02lx", cStates, HideBits));
  162. INIT_ADDRECT(rcStates);
  163. for (i = 0, cHide = 0, Mask = HideBits, pHSInfo = HSInfo;
  164. i < cStates;
  165. i++, Mask >>= 1) {
  166. INIT_ADDRECT(rcMax[i]);
  167. for (j = 0; j < 2; j++, pHSInfo++) {
  168. RECT rc;
  169. if (hCurCtrl = CtrlIDrcWnd(hDlg, CtrlID++, &rc)) {
  170. CPSUIDBG(DBG_STATES,
  171. ("MoveStates: States=(%d:%d), ID=%d, Hide=%d",
  172. i, j, CtrlID - 1, (Mask & 0x01) ? 1 : 0));
  173. pHSInfo->hCtrl = hCurCtrl;
  174. if (Mask & 0x01) {
  175. CPSUIDBG(DBG_STATES, ("Hide the State %d", i));
  176. }
  177. pHSInfo->x = rc.left;
  178. pHSInfo->y = rc.top;
  179. AddRect(&rc, &rcMax[i]);
  180. CPSUIDBG(DBG_STATES, ("i=%ld, j=%ld, rc=(%ld, %ld)-(%ld, %ld)=%ldx%ld",
  181. i, j, rc.left, rc.top, rc.right, rc.bottom,
  182. rc.right - rc.left, rc.bottom - rc.top));
  183. }
  184. }
  185. if (HAS_ADDRECT(rcMax[i])) {
  186. CPSUIRECT(0, "rcMax", &rcMax[i], i, 0);
  187. if (i) {
  188. if (rcMax[i].top > rcMax[i - 1].bottom) {
  189. yRemoved++;
  190. }
  191. szlSpace.cx += (rcMax[i].left - rcMax[i - 1].right);
  192. szlSpace.cy += (rcMax[i].top - rcMax[i - 1].bottom);
  193. }
  194. AddRect(&rcMax[i], &rcStates);
  195. if (Mask & 0x01) {
  196. CPSUIDBG(DBG_STATES, ("Hide i=%ld, szlHide.cy=%ld",
  197. i, szlHide.cy));
  198. if (i) {
  199. szlHide.cy += (rcMax[i].top - rcMax[i - 1].bottom);
  200. }
  201. szlHide.cx += rcMax[i].right - rcMax[i].left;
  202. szlHide.cy += rcMax[i].bottom - rcMax[i].top;
  203. if (++cHide == cStates) {
  204. CPSUIASSERT(0, "Error: HideStates(HIDE EVERY THING)=%d",
  205. cHide < cStates, UIntToPtr(cHide));
  206. return(0);
  207. }
  208. }
  209. }
  210. }
  211. CPSUIDBG(DBG_STATES, ("rcStates=(%ld, %ld)-(%ld, %ld)=%ldx%ld",
  212. rcStates.left, rcStates.top, rcStates.right, rcStates.bottom,
  213. rcStates.right - rcStates.left, rcStates.bottom - rcStates.top));
  214. CPSUIDBG(DBG_STATES,
  215. ("szlHide=%ldx%ld, szlSpace=%ldx%ld, yReMoved=%ld",
  216. szlHide.cx, szlHide.cy, szlSpace.cx, szlSpace.cy, yRemoved));
  217. if (yRemoved) {
  218. szlSpace.cy /= yRemoved;
  219. //
  220. // If we arrange top/down and we do not intersect with the visible
  221. // bits then we can remove the y space
  222. //
  223. if ((rcStates.top >= prcVisibleNoStates->bottom) ||
  224. (rcStates.bottom <= prcVisibleNoStates->top)) {
  225. //
  226. // We can remove the Y line now
  227. //
  228. rcStates.bottom -= (yRemoved = szlHide.cy);
  229. szlHide.cy = 0;
  230. CPSUIDBG(DBG_STATES,
  231. ("HideStates: OK to remove Y, yRemoved=%ld", yRemoved));
  232. } else {
  233. yRemoved = 0;
  234. //
  235. // Do not remove Y spaces, just arrange it
  236. //
  237. CPSUIINT(("---- STATES: CANNOT remove Y space, Re-Arrange it ---"));
  238. }
  239. DoXDir = FALSE;
  240. szlHide.cx =
  241. szlHide.cy = 0;
  242. szlSpace.cx = 0;
  243. } else {
  244. DoXDir = TRUE;
  245. szlHide.cy =
  246. szlSpace.cy = 0;
  247. }
  248. switch (cStates - cHide) {
  249. case 1:
  250. //
  251. // Only one state left, just center it
  252. //
  253. if (DoXDir) {
  254. szlHide.cx = ((szlSpace.cx + szlHide.cx) / 2);
  255. }
  256. break;
  257. case 2:
  258. if (DoXDir) {
  259. szlHide.cx = ((szlHide.cx + 1) / 3);
  260. szlSpace.cx += szlHide.cx;
  261. }
  262. break;
  263. }
  264. rcStates.left += szlHide.cx;
  265. rcStates.top += szlHide.cy;
  266. CPSUIDBG(DBG_STATES,
  267. ("State1=(%ld, %ld): szlHide=%ld x %ld, szlSpace=%ld x %ld, DoXDir=%ld",
  268. rcStates.left, rcStates.top,
  269. szlHide.cx, szlHide.cy, szlSpace.cx, szlSpace.cy, DoXDir));
  270. for (i = 0, Mask = HideBits, pHSInfo = HSInfo;
  271. i < cStates;
  272. i++, Mask >>= 1) {
  273. if (Mask & 0x01) {
  274. pHSInfo += 2;
  275. } else {
  276. for (j = 0; j < 2; j++, pHSInfo++) {
  277. if (hCurCtrl = pHSInfo->hCtrl) {
  278. szlHide.cx = pHSInfo->x - rcMax[i].left;
  279. szlHide.cy = pHSInfo->y - rcMax[i].top;
  280. CPSUIDBG(DBG_STATES,
  281. ("HideStates: MOVE(%d:%d) from (%ld, %ld) to (%ld, %ld)",
  282. i, j, pHSInfo->x, pHSInfo->y,
  283. rcStates.left + szlHide.cx,
  284. rcStates.top + szlHide.cy));
  285. SetWindowPos(hCurCtrl, NULL,
  286. rcStates.left + szlHide.cx,
  287. rcStates.top + szlHide.cy,
  288. 0, 0,
  289. SWP_NOSIZE | SWP_NOZORDER);
  290. }
  291. }
  292. if (DoXDir) {
  293. rcStates.left += (szlSpace.cx + rcMax[i].right - rcMax[i].left);
  294. } else {
  295. rcStates.top += (szlSpace.cy + rcMax[i].bottom - rcMax[i].top);
  296. }
  297. }
  298. }
  299. return(yRemoved);
  300. }
  301. VOID
  302. AddItemInfo(
  303. PITEMINFOHEADER pIIHdr,
  304. POPTITEM pItem
  305. )
  306. /*++
  307. Routine Description:
  308. Arguments:
  309. Return Value:
  310. Author:
  311. 09-Sep-1995 Sat 17:27:01 created -by- Daniel Chou (danielc)
  312. Revision History:
  313. --*/
  314. {
  315. HWND hDlg;
  316. WORD Mask;
  317. WORD HideBits;
  318. WORD ExtBits;
  319. WORD NonStatesBits;
  320. UINT CurCtrlID;
  321. UINT cCtrls;
  322. UINT cStates;
  323. RECT rcVisible;
  324. RECT rcVisibleNoStates;
  325. RECT rcExt;
  326. RECT rcGrpBox;
  327. ITEMINFO II;
  328. if (pItem) {
  329. POPTTYPE pOptType;
  330. II.Flags = (pItem->Flags & OPTIF_ITEM_HIDE) ? IIF_ITEM_HIDE : 0;
  331. if ((pItem->Flags & OPTIF_EXT_HIDE) ||
  332. (!pItem->pExtChkBox)) {
  333. II.Flags |= IIF_EXT_HIDE;
  334. }
  335. if (pOptType = pItem->pOptType) {
  336. II.BegCtrlID = (WORD)pOptType->BegCtrlID;
  337. if (((II.Type = pOptType->Type) == TVOT_2STATES) ||
  338. (II.Type == TVOT_3STATES)) {
  339. II.Flags |= (_OT_FLAGS(pOptType) &
  340. (IIF_3STATES_HIDE | IIF_STDPAGE_3STATES));
  341. }
  342. } else {
  343. II.Type = TVOT_NONE;
  344. II.BegCtrlID = 0;
  345. }
  346. } else {
  347. //
  348. // Some Flags/Type/BegCtrlID and of the stuff already set in here
  349. //
  350. II = pIIHdr->ItemInfo[pIIHdr->cItem];
  351. }
  352. if (II.Flags & IIF_STDPAGE_3STATES) {
  353. II.Type = TVOT_3STATES;
  354. }
  355. CurCtrlID = II.BegCtrlID;
  356. cCtrls = (UINT)cTVOTCtrls[II.Type];
  357. II.pItem = pItem;
  358. II.CtrlBits = 0;
  359. II.xExtMove = 0;
  360. II.yExt = 0;
  361. II.yMoveUp = 0;
  362. hDlg = pIIHdr->hDlg;
  363. INIT_ADDRECT(II.rc);
  364. INIT_ADDRECT(rcExt);
  365. INIT_ADDRECT(rcVisible);
  366. INIT_ADDRECT(rcGrpBox);
  367. INIT_ADDRECT(rcVisibleNoStates);
  368. HideBits = 0;
  369. if ((II.Flags & IIF_3STATES_HIDE) &&
  370. (!(II.Flags & IIF_ITEM_HIDE))) {
  371. if (II.Flags & IIF_3STATES_1) {
  372. HideBits |= 0x0c;
  373. }
  374. if (II.Flags & IIF_3STATES_2) {
  375. HideBits |= 0x30;
  376. }
  377. if (II.Flags & IIF_3STATES_3) {
  378. HideBits |= 0xc0;
  379. }
  380. NonStatesBits = 0xff03;
  381. } else {
  382. NonStatesBits = 0;
  383. }
  384. if (II.Flags & IIF_EXT_HIDE) {
  385. ExtBits = (WORD)(3 << (cCtrls - 2));
  386. HideBits |= ExtBits;
  387. } else {
  388. ExtBits = 0;
  389. }
  390. CPSUIINT((" !! HideBits=%04lx, NonStateBits=%04lx, ExtBits=%04lx",
  391. HideBits, NonStatesBits, ExtBits));
  392. Mask = 0x0001;
  393. while (cCtrls--) {
  394. HWND hCtrl;
  395. RECT rc;
  396. //
  397. // We only count this ctrl's rectangle if it is vaild and visible
  398. //
  399. if (hCtrl = CtrlIDrcWnd(hDlg, CurCtrlID, &rc)) {
  400. CPSUIRECT(0, "AddItemInfo", &rc, cCtrls, CurCtrlID);
  401. if (Mask == 0x0001) {
  402. rcGrpBox = rc;
  403. } else {
  404. if (HideBits & Mask) {
  405. ShowWindow(hCtrl, SW_HIDE);
  406. EnableWindow(hCtrl, FALSE);
  407. } else {
  408. AddRect(&rc, &rcVisible);
  409. if (Mask & NonStatesBits) {
  410. AddRect(&rc, &rcVisibleNoStates);
  411. }
  412. }
  413. if (ExtBits & Mask) {
  414. AddRect(&rc, &rcExt);
  415. }
  416. AddRect(&rc, &II.rc);
  417. }
  418. II.CtrlBits |= Mask;
  419. }
  420. Mask <<= 1;
  421. CurCtrlID++;
  422. }
  423. II.rcCtrls = II.rc;
  424. CPSUIRECT(0, " rcGrpBox", &rcGrpBox, 0, 0);
  425. CPSUIRECT(0, " rcCtrls", &II.rcCtrls, 0, 0);
  426. CPSUIRECT(0, " rcExt", &rcExt, 0, 0);
  427. CPSUIRECT(0, "rcVisiable", &rcVisible, 0, 0);
  428. if (II.CtrlBits & 0x0001) {
  429. UINT cAdded;
  430. if ((cAdded = AddRect(&rcGrpBox, &II.rc)) != 4) {
  431. CPSUIINT(("AddRect(&rcGrp, &II.rc)=%d", cAdded));
  432. CPSUIOPTITEM(DBG_AII, pIIHdr->pTVWnd,
  433. "GroupBox too small", 1, pItem);
  434. }
  435. }
  436. if (HAS_ADDRECT(rcVisible)) {
  437. if ((II.Flags & IIF_3STATES_HIDE) &&
  438. (!(II.Flags & IIF_ITEM_HIDE))) {
  439. if (!HAS_ADDRECT(rcVisibleNoStates)) {
  440. rcVisibleNoStates.left =
  441. rcVisibleNoStates.top = 999999;
  442. rcVisibleNoStates.right =
  443. rcVisibleNoStates.bottom = -999999;
  444. }
  445. CPSUIRECT(0, "rcVisiableNoStates", &rcVisibleNoStates, 0, 0);
  446. II.yExt += (WORD)HideStates(hDlg, &II, &rcVisibleNoStates);
  447. }
  448. if (HAS_ADDRECT(rcExt)) {
  449. //
  450. // We need to move all other controls and shrink the group
  451. // box if necessary
  452. //
  453. if (II.CtrlBits & 0x0001) {
  454. if (rcExt.left > rcVisible.right) {
  455. //
  456. // The extended are at right of the ctrls, move to right
  457. //
  458. II.xExtMove = (SHORT)(rcExt.left - rcVisible.right);
  459. } else if (rcExt.right < rcVisible.left) {
  460. //
  461. // The extended are at left of the ctrls, move to left
  462. //
  463. II.xExtMove = (SHORT)(rcVisible.left - rcVisible.right);
  464. }
  465. //
  466. // distribute the move size on each side of the control
  467. //
  468. II.xExtMove /= 2;
  469. }
  470. if (rcExt.bottom > rcVisible.bottom) {
  471. //
  472. // The extended are at bottom of the ctrls, remove overlay
  473. //
  474. II.yExt += (WORD)(rcExt.bottom - rcVisible.bottom);
  475. }
  476. if (rcExt.top < rcVisible.top) {
  477. //
  478. // The extended are at top of the ctrls, remove that overlay
  479. //
  480. II.yExt += (WORD)(rcVisible.top - rcExt.top);
  481. }
  482. CPSUIINT(("!! Hide Extended(%d): xMove=%ld, yExt=%ld",
  483. II.BegCtrlID, (LONG)II.xExtMove, (LONG)II.yExt));
  484. }
  485. } else {
  486. II.Flags |= (IIF_ITEM_HIDE | IIF_EXT_HIDE);
  487. }
  488. if (pIIHdr->cItem >= pIIHdr->cMaxItem) {
  489. CPSUIERR(("AddItemInfo: Too many Items, Max=%ld", pIIHdr->cMaxItem));
  490. } else {
  491. pIIHdr->ItemInfo[pIIHdr->cItem++] = II;
  492. }
  493. }
  494. VOID
  495. HideMoveII(
  496. HWND hDlg,
  497. PITEMINFO pII
  498. )
  499. /*++
  500. Routine Description:
  501. Arguments:
  502. Return Value:
  503. Author:
  504. 11-Sep-1995 Mon 12:56:06 created -by- Daniel Chou (danielc)
  505. Revision History:
  506. --*/
  507. {
  508. ITEMINFO II = *pII;
  509. BOOL GrpBox = TRUE;
  510. if ((!(II.Flags & IIF_ITEM_HIDE)) &&
  511. (II.xExtMove == 0) &&
  512. (II.yExt == 0) &&
  513. (II.yMoveUp == 0)) {
  514. return;
  515. }
  516. CPSUIINT(("\n%hs Item: Flags=%04x, CtrlBits=%04lx, xExt=%d, yExt=%d, yMoveUp=%d",
  517. (II.Flags & IIF_ITEM_HIDE) ? "HIDE" : "MOVE",
  518. II.Flags, II.CtrlBits, II.xExtMove, II.yExt, II.yMoveUp));
  519. CPSUIRECT(DBG_HMII, "II.rcCtrls", &II.rcCtrls, II.BegCtrlID, 0);
  520. CPSUIRECT(DBG_HMII, " II.rc", &II.rc, II.BegCtrlID, 0);
  521. CPSUIOPTITEM(DBG_HMII, GET_PTVWND(hDlg), "HideMoveII", 1, II.pItem);
  522. while (II.CtrlBits) {
  523. HWND hCtrl;
  524. if ((II.CtrlBits & 0x0001) &&
  525. (hCtrl = GetDlgItem(hDlg, II.BegCtrlID))) {
  526. RECT rc;
  527. if (II.Flags & IIF_ITEM_HIDE) {
  528. ShowWindow(hCtrl, SW_HIDE);
  529. EnableWindow(hCtrl, FALSE);
  530. CPSUIINT((" HIDE Ctrls ID=%d", II.BegCtrlID));
  531. } else {
  532. hCtrlrcWnd(hDlg, hCtrl, &rc);
  533. if (GrpBox) {
  534. if ((II.yExt) || (II.yMoveUp)) {
  535. CPSUIINT(("Move GrpBox ID=%5d, Y: %ld -> %ld, cy: %ld -> %ld",
  536. II.BegCtrlID, rc.top,
  537. rc.top - II.yMoveUp, rc.bottom - rc.top,
  538. rc.bottom - rc.top - (LONG)II.yExt));
  539. SetWindowPos(hCtrl, NULL,
  540. rc.left, rc.top - II.yMoveUp,
  541. rc.right - rc.left,
  542. rc.bottom - rc.top - (LONG)II.yExt,
  543. SWP_NOZORDER);
  544. }
  545. } else if ((II.xExtMove) || (II.yMoveUp)) {
  546. //
  547. // We only need to move xExtMove if it is not group box
  548. // and also do the yMoveUp
  549. //
  550. CPSUIINT((" Move Ctrls ID=%5d, (%ld, %d) -> (%ld, %ld)",
  551. II.BegCtrlID, rc.left, rc.top,
  552. rc.left + (LONG)II.xExtMove,
  553. rc.top - (LONG)II.yMoveUp));
  554. SetWindowPos(hCtrl, NULL,
  555. rc.left + (LONG)II.xExtMove,
  556. rc.top - (LONG)II.yMoveUp,
  557. 0, 0,
  558. SWP_NOSIZE | SWP_NOZORDER);
  559. }
  560. }
  561. }
  562. GrpBox = FALSE;
  563. II.CtrlBits >>= 1;
  564. II.BegCtrlID++;
  565. }
  566. }
  567. VOID
  568. HideMoveType(
  569. HWND hDlg,
  570. UINT BegCtrlID,
  571. UINT Type
  572. )
  573. /*++
  574. Routine Description:
  575. Arguments:
  576. Return Value:
  577. Author:
  578. 19-Sep-1995 Tue 21:01:55 created -by- Daniel Chou (danielc)
  579. Revision History:
  580. --*/
  581. {
  582. ITEMINFO II;
  583. UINT cCtrls;
  584. cCtrls = (UINT)cTVOTCtrls[Type];
  585. II.Flags = IIF_ITEM_HIDE | IIF_EXT_HIDE;
  586. II.BegCtrlID = (WORD)BegCtrlID;
  587. II.CtrlBits = (WORD)(0xFFFF >> (16 - cCtrls));
  588. HideMoveII(hDlg, &II);
  589. }
  590. INT
  591. HideMovePropPage(
  592. PITEMINFOHEADER pIIHdr
  593. )
  594. /*++
  595. Routine Description:
  596. Arguments:
  597. Return Value:
  598. Author:
  599. 11-Sep-1995 Mon 01:25:53 created -by- Daniel Chou (danielc)
  600. Revision History:
  601. --*/
  602. {
  603. HWND hDlg;
  604. PITEMINFO pII;
  605. PITEMINFO pIIEnd;
  606. UINT yMoveUp;
  607. UINT yLastTop;
  608. UINT cItem;
  609. //
  610. // firstable, sort all the item based on the rc.top of each item
  611. //
  612. qsort(pII = pIIHdr->ItemInfo,
  613. cItem = (UINT)pIIHdr->cItem,
  614. sizeof(ITEMINFO),
  615. ItemInfoCompare);
  616. pIIEnd = pII + cItem;
  617. yMoveUp = 0;
  618. yLastTop = (UINT)pII->rc.top;
  619. hDlg = pIIHdr->hDlg;
  620. CPSUIDBGBLK({
  621. UINT i = cItem;
  622. PITEMINFO pIITmp = pII;
  623. CPSUIDBG(DBG_QSORT, ("qsort: cItem = %d", cItem));
  624. while (i--) {
  625. CPSUIRECT(DBG_QSORT, "QSort", &pIITmp->rc, pIITmp->BegCtrlID, 0);
  626. CPSUIOPTITEM(DBG_QSORT, pIIHdr->pTVWnd,
  627. "Sorted Item RECT", 1, pIITmp->pItem);
  628. pIITmp++;
  629. }
  630. })
  631. while (pII < pIIEnd) {
  632. PITEMINFO pIIBeg;
  633. PITEMINFO pIIBegSave;
  634. RECT rcBeg;
  635. UINT cHide;
  636. UINT cII;
  637. UINT cyCurHide;
  638. UINT yBegExt;
  639. UINT yGrpBoxShrink;
  640. UINT yGrpHideMoveUp;
  641. INT GrpBox;
  642. //
  643. // Do the group item first assume we do not need to hide the group
  644. // box, and skip the space between group box and first control, The
  645. // first group's top is the first control's top
  646. //
  647. pIIBegSave =
  648. pIIBeg = pII;
  649. rcBeg = pIIBeg->rc;
  650. cHide = 0;
  651. GrpBox = 1;
  652. //
  653. // yLastTop < 0 means the last group is totally hide and it need to
  654. // delete the space between last group end and this group begin
  655. //
  656. if (yLastTop == (UINT)0xFFFF) {
  657. yLastTop = 0;
  658. } else {
  659. yLastTop = (UINT)(rcBeg.top - yLastTop);
  660. }
  661. yGrpBoxShrink = 0;
  662. yMoveUp += yLastTop;
  663. yGrpHideMoveUp = (UINT)(yMoveUp + (rcBeg.bottom - rcBeg.top));
  664. yLastTop = rcBeg.top;
  665. do {
  666. CPSUIINT(("Item: yLastTop=%ld, yGrpBoxShrink=%d, yMoveUp=%d",
  667. yLastTop, yGrpBoxShrink, yMoveUp));
  668. if (pII->rc.bottom > rcBeg.bottom) {
  669. CPSUIOPTITEM(DBG_HMII, pIIHdr->pTVWnd, "Item Ctrls Overlay",
  670. 1, pII->pItem);
  671. CPSUIASSERT(0, "Item ctrls overlay",
  672. pII->rc.bottom <= rcBeg.bottom, LongToPtr(pII->rc.bottom));
  673. }
  674. if (pII->Flags & IIF_ITEM_HIDE) {
  675. cyCurHide = (UINT)(pII->rc.top - yLastTop);
  676. ++cHide;
  677. } else {
  678. cyCurHide = pII->yExt;
  679. pII->yMoveUp = (WORD)yMoveUp;
  680. }
  681. yGrpBoxShrink += cyCurHide;
  682. yMoveUp += cyCurHide;
  683. yLastTop = (GrpBox-- > 0) ? pII->rcCtrls.top : pII->rc.top;
  684. } while ((++pII < pIIEnd) && (pII->rc.top < rcBeg.bottom));
  685. CPSUIINT(("FINAL: yLastTop=%ld, yGrpBoxShrink=%d, yMoveUp=%d",
  686. yLastTop, yGrpBoxShrink, yMoveUp));
  687. //
  688. // Now check if we have same hide item
  689. //
  690. if (cHide == (cII = (UINT)(pII - pIIBeg))) {
  691. //
  692. // Hide them all and add in the extra yMoveUp for the the space
  693. // between group box and the first control which we reduced out
  694. // front.
  695. //
  696. yMoveUp = yGrpHideMoveUp;
  697. yLastTop = rcBeg.bottom;
  698. CPSUIINT(("Hide ALL items = %d, yMoveUp Change to %ld",
  699. cHide, yMoveUp));
  700. while (cHide--) {
  701. HideMoveII(hDlg, pIIBegSave++);
  702. }
  703. } else {
  704. CPSUIINT(("!! Grpup Items cII=%d !!", cII));
  705. //
  706. // We need to enable the group box and shrink it too
  707. //
  708. if (pIIBeg->Flags & IIF_ITEM_HIDE) {
  709. pIIBeg->yExt += (WORD)yGrpBoxShrink;
  710. pIIBeg->Flags &= ~IIF_ITEM_HIDE;
  711. pIIBeg->CtrlBits &= 0x01;
  712. } else {
  713. pIIBeg->yExt = (WORD)yGrpBoxShrink;
  714. }
  715. while (cII--) {
  716. HideMoveII(hDlg, pIIBegSave++);
  717. }
  718. yLastTop = 0xFFFF;
  719. }
  720. }
  721. return(yMoveUp);
  722. }
  723. LONG
  724. UpdatePropPageItem(
  725. HWND hDlg,
  726. PTVWND pTVWnd,
  727. POPTITEM pItem,
  728. BOOL DoInit
  729. )
  730. /*++
  731. Routine Description:
  732. Arguments:
  733. Return Value:
  734. Author:
  735. 31-Aug-1995 Thu 23:53:44 created -by- Daniel Chou (danielc)
  736. Revision History:
  737. --*/
  738. {
  739. HWND hCtrl;
  740. POPTTYPE pOptType;
  741. POPTPARAM pOptParam;
  742. LONG Sel;
  743. UINT Type;
  744. UINT BegCtrlID;
  745. UINT SetCurSelID;
  746. UINT cSetIcon;
  747. UINT ExtID;
  748. UINT UDArrowHelpID = 0;
  749. LONG Result = 1;
  750. WORD InitItemIdx;
  751. WORD InitFlags;
  752. BYTE CtrlData = 0;
  753. BOOL CanUpdate;
  754. InitItemIdx = (WORD)(pItem - pTVWnd->ComPropSheetUI.pOptItem);
  755. pOptType = pItem->pOptType;
  756. pOptParam = pOptType->pOptParam;
  757. BegCtrlID = (UINT)pOptType->BegCtrlID;
  758. Sel = pItem->Sel;
  759. Type = (UINT)pOptType->Type;
  760. //
  761. // If we have push button, and it said we always can call it then update
  762. // is true
  763. //
  764. if ((Type == TVOT_PUSHBUTTON) &&
  765. (pOptType->Flags & OTS_PUSH_ENABLE_ALWAYS)) {
  766. CanUpdate = TRUE;
  767. } else {
  768. CanUpdate = (BOOL)(pTVWnd->Flags & TWF_CAN_UPDATE);
  769. }
  770. if ((pItem->Flags & OPTIF_DISABLED) || (!CanUpdate)) {
  771. InitFlags = 0;
  772. } else {
  773. InitFlags = INITCF_ENABLE;
  774. }
  775. if (DoInit) {
  776. InitFlags |= (INITCF_INIT | INITCF_SETCTRLDATA);
  777. for (cSetIcon = 0; cSetIcon < (UINT)cTVOTCtrls[Type]; cSetIcon++) {
  778. if (hCtrl = GetDlgItem(hDlg, BegCtrlID++)) {
  779. //
  780. // This prevent to overwrite GWLP_USERDATA for the WNDPROC
  781. // saved for the hEdit
  782. //
  783. SETCTRLDATA(hCtrl, CTRLS_PROPPAGE_STATIC, (BYTE)cSetIcon);
  784. CPSUIINT(("SETCTRLDATA: %ld, hCtrl=%08lx, USER_DATA=%p",
  785. BegCtrlID - 1, hCtrl,
  786. GetWindowLongPtr(hCtrl, GWLP_USERDATA)));
  787. #if 0
  788. if ((Type != TVOT_UDARROW) &&
  789. (cSetIcon != 6)) {
  790. SETCTRLDATA(hCtrl, CTRLS_PROPPAGE_STATIC, (BYTE)cSetIcon);
  791. }
  792. #endif
  793. }
  794. }
  795. BegCtrlID = (UINT)pOptType->BegCtrlID;
  796. }
  797. //
  798. // We always set at least one icon
  799. //
  800. cSetIcon = 1;
  801. ExtID = (UINT)(BegCtrlID + cTVOTCtrls[Type] - 2);
  802. INIT_EXTENDED(pTVWnd,
  803. hDlg,
  804. pItem,
  805. ExtID,
  806. ExtID,
  807. ExtID + 1,
  808. InitItemIdx,
  809. InitFlags);
  810. if (pOptType->Flags & OPTTF_TYPE_DISABLED) {
  811. InitFlags &= ~INITCF_ENABLE;
  812. }
  813. switch(Type) {
  814. case TVOT_3STATES:
  815. case TVOT_2STATES:
  816. //
  817. // If this internal flag is set then this is a standard page which
  818. // always has a 3 states contrl ID but the caller's POPTTYPE only
  819. // presendt as TVOT_2STATES
  820. //
  821. if (_OT_FLAGS(pOptType) & OTINTF_STDPAGE_3STATES) {
  822. ExtID = (UINT)(BegCtrlID + cTVOTCtrls[TVOT_3STATES] - 2);
  823. }
  824. InitStates(pTVWnd,
  825. hDlg,
  826. pItem,
  827. pOptType,
  828. BegCtrlID + 2,
  829. InitItemIdx,
  830. (LONG)Sel,
  831. InitFlags);
  832. if (InitFlags & INITCF_INIT) {
  833. cSetIcon = pOptType->Count;
  834. CtrlData = 0;
  835. } else {
  836. CtrlData = (BYTE)Sel;
  837. pOptParam += Sel;
  838. BegCtrlID += (Sel << 1);
  839. }
  840. InitFlags |= INITCF_ICON_NOTIFY;
  841. break;
  842. case TVOT_UDARROW:
  843. if ((Result = InitUDArrow(pTVWnd,
  844. hDlg,
  845. pItem,
  846. pOptParam,
  847. BegCtrlID + 6,
  848. BegCtrlID + 2,
  849. BegCtrlID + 4,
  850. UDArrowHelpID = BegCtrlID + 5,
  851. InitItemIdx,
  852. Sel,
  853. InitFlags)) < 0) {
  854. return(Result);
  855. }
  856. break;
  857. case TVOT_TRACKBAR:
  858. case TVOT_SCROLLBAR:
  859. InitFlags |= INITCF_ADDSELPOSTFIX;
  860. hCtrl = GetDlgItem(hDlg, BegCtrlID + 2);
  861. if (Type == TVOT_TRACKBAR) {
  862. hCtrl = GetWindow(hCtrl, GW_HWNDNEXT);
  863. }
  864. InitTBSB(pTVWnd,
  865. hDlg,
  866. pItem,
  867. hCtrl,
  868. pOptType,
  869. BegCtrlID + 6,
  870. BegCtrlID + 4,
  871. BegCtrlID + 5,
  872. InitItemIdx,
  873. Sel,
  874. InitFlags);
  875. break;
  876. case TVOT_LISTBOX:
  877. case TVOT_COMBOBOX:
  878. SetCurSelID = LB_SETCURSEL;
  879. if (Type == TVOT_LISTBOX) {
  880. if (pOptType->Style & OTS_LBCB_PROPPAGE_LBUSECB) {
  881. SetCurSelID = CB_SETCURSEL;
  882. }
  883. } else if (!(pOptType->Style & OTS_LBCB_PROPPAGE_CBUSELB)) {
  884. SetCurSelID = CB_SETCURSEL;
  885. }
  886. //
  887. // Always need to set this new state icon
  888. //
  889. if ((DWORD)pItem->Sel >= (DWORD)pOptType->Count) {
  890. pOptParam = &pTVWnd->OptParamNone;
  891. } else {
  892. pOptParam += (DWORD)pItem->Sel;
  893. }
  894. if (hCtrl = GetDlgItem(hDlg, BegCtrlID + 2)) {
  895. InvalidateRect(hCtrl, NULL, FALSE);
  896. }
  897. InitLBCB(pTVWnd,
  898. hDlg,
  899. pItem,
  900. BegCtrlID + 2,
  901. SetCurSelID,
  902. pOptType,
  903. InitItemIdx,
  904. Sel,
  905. InitFlags,
  906. (UINT)_OT_ORGLBCBCY(pOptType));
  907. break;
  908. case TVOT_EDITBOX:
  909. InitEditBox(pTVWnd,
  910. hDlg,
  911. pItem,
  912. pOptParam,
  913. BegCtrlID + 2,
  914. BegCtrlID + 4,
  915. BegCtrlID + 5,
  916. InitItemIdx,
  917. (LPTSTR)(LONG_PTR)Sel,
  918. InitFlags);
  919. break;
  920. case TVOT_PUSHBUTTON:
  921. InitPushButton(pTVWnd,
  922. hDlg,
  923. pItem,
  924. (WORD)(BegCtrlID + 2),
  925. InitItemIdx,
  926. InitFlags);
  927. break;
  928. case TVOT_CHKBOX:
  929. InitFlags |= INITCF_ICON_NOTIFY;
  930. InitChkBox(pTVWnd,
  931. hDlg,
  932. pItem,
  933. BegCtrlID + 2,
  934. pItem->pName,
  935. InitItemIdx,
  936. (BOOL)Sel,
  937. InitFlags);
  938. break;
  939. default:
  940. return(ERR_CPSUI_INVALID_TVOT_TYPE);
  941. }
  942. if (InitFlags & (INITCF_INIT | INITCF_ADDSELPOSTFIX)) {
  943. SetDlgPageItemName(hDlg, pTVWnd, pItem, InitFlags, UDArrowHelpID);
  944. }
  945. if (cSetIcon) {
  946. UINT i;
  947. for (i = 0, BegCtrlID += 3;
  948. i < cSetIcon;
  949. i++, pOptParam++, CtrlData++, BegCtrlID += 2) {
  950. if (hCtrl = GetDlgItem(hDlg, BegCtrlID)) {
  951. WORD IconMode = 0;
  952. if ((pItem->Flags & OPTIF_OVERLAY_WARNING_ICON) ||
  953. (pOptParam->Flags & OPTPF_OVERLAY_WARNING_ICON)) {
  954. IconMode |= MIM_WARNING_OVERLAY;
  955. }
  956. if ((pItem->Flags & (OPTIF_OVERLAY_STOP_ICON | OPTIF_HIDE)) ||
  957. (pOptParam->Flags & OPTPF_OVERLAY_STOP_ICON)) {
  958. IconMode |= MIM_STOP_OVERLAY;
  959. }
  960. if ((pItem->Flags & (OPTIF_OVERLAY_NO_ICON)) ||
  961. (pOptParam->Flags & OPTPF_OVERLAY_NO_ICON)) {
  962. IconMode |= MIM_NO_OVERLAY;
  963. }
  964. SetIcon(_OI_HINST(pItem),
  965. hCtrl,
  966. GET_ICONID(pOptParam, OPTPF_ICONID_AS_HICON),
  967. MK_INTICONID(IDI_CPSUI_GENERIC_ITEM, IconMode),
  968. 32);
  969. if (InitFlags & INITCF_INIT) {
  970. HCTRL_SETCTRLDATA(hCtrl, CTRLS_PROPPAGE_ICON, CtrlData);
  971. }
  972. if (InitFlags & INITCF_ICON_NOTIFY) {
  973. DWORD dw = (DWORD)GetWindowLongPtr(hCtrl, GWL_STYLE);
  974. if (pOptParam->Flags & (OPTPF_DISABLED | OPTPF_HIDE)) {
  975. dw &= ~SS_NOTIFY;
  976. } else {
  977. dw |= SS_NOTIFY;
  978. }
  979. SetWindowLongPtr(hCtrl, GWL_STYLE, (LONG)dw);
  980. }
  981. }
  982. }
  983. }
  984. return(Result);
  985. }
  986. LONG
  987. InitPropPage(
  988. HWND hDlg,
  989. PMYDLGPAGE pCurMyDP
  990. )
  991. /*++
  992. Routine Description:
  993. Arguments:
  994. Return Value:
  995. Author:
  996. 14-Jun-1995 Wed 15:30:28 created -by- Daniel Chou (danielc)
  997. Revision History:
  998. --*/
  999. {
  1000. PITEMINFOHEADER pIIHdr = NULL;
  1001. PSTDPAGEINFO pSPI;
  1002. PTVWND pTVWnd;
  1003. POPTITEM pItem;
  1004. POPTITEM pLastItem;
  1005. LONG Result;
  1006. WORD StdPageHide[DMPUB_LAST];
  1007. BYTE CurPageIdx;
  1008. UINT i;
  1009. UINT BegCtrlID;
  1010. UINT Type;
  1011. UINT cStdPageHide = 0;
  1012. UINT cStatesHide = 0;
  1013. UINT cItem;
  1014. UINT cHide;
  1015. pTVWnd = (PTVWND)pCurMyDP->pTVWnd;
  1016. CurPageIdx = pCurMyDP->PageIdx;
  1017. pItem = pTVWnd->ComPropSheetUI.pOptItem;
  1018. pLastItem = pTVWnd->pLastItem;
  1019. cItem = (UINT)pCurMyDP->cItem;
  1020. cHide = (UINT)pCurMyDP->cHide;
  1021. if ((CurPageIdx == pTVWnd->StdPageIdx1) ||
  1022. (CurPageIdx == pTVWnd->StdPageIdx2)) {
  1023. //
  1024. // Check if any our standard pages' controls are not present in the
  1025. // pOptItem
  1026. //
  1027. for (i = 0, pSPI = StdPageInfo; i < DMPUB_LAST; i++, pSPI++) {
  1028. POPTITEM pDMPubItem;
  1029. POPTTYPE pOptType;
  1030. WORD Idx;
  1031. if ((pSPI->StdPageID == CurPageIdx) &&
  1032. (pSPI->BegCtrlID)) {
  1033. if ((Idx = pTVWnd->DMPubIdx[i]) == 0xFFFF) {
  1034. ++cStdPageHide;
  1035. } else {
  1036. pDMPubItem = pItem + Idx;
  1037. pOptType = pDMPubItem->pOptType;
  1038. switch (pOptType->Type) {
  1039. case TVOT_2STATES:
  1040. case TVOT_3STATES:
  1041. if (_OT_FLAGS(pOptType) & OTINTF_STATES_HIDE_MASK) {
  1042. ++cStatesHide;
  1043. }
  1044. break;
  1045. default:
  1046. break;
  1047. }
  1048. }
  1049. }
  1050. }
  1051. }
  1052. CPSUIDBG(DBG_INITP1,
  1053. ("InitPropPage: PageIdx=%d, cItem=%d, cHide=%d, cStdPageHide=% (%d)",
  1054. CurPageIdx, cItem, cHide, cStdPageHide, cStatesHide));
  1055. if ((cHide += cStdPageHide) || (cStatesHide)) {
  1056. //
  1057. // Some item in this page may have to hide
  1058. //
  1059. i = (UINT)(((cItem + cStdPageHide + cStatesHide) * sizeof(ITEMINFO)) +
  1060. sizeof(ITEMINFOHEADER));
  1061. CPSUIINT(("Total ItemInfo allocated=%d, cb=%d", cItem+cStdPageHide, i));
  1062. if (pIIHdr = LocalAlloc(LPTR, i)) {
  1063. pIIHdr->hDlg = hDlg;
  1064. pIIHdr->pTVWnd = pTVWnd;
  1065. pIIHdr->cItem = 0;
  1066. pIIHdr->cMaxItem = (WORD)(cItem + cStdPageHide);
  1067. //
  1068. // Stop redraw everything
  1069. //
  1070. SendMessage(hDlg, WM_SETREDRAW, (WPARAM)FALSE, 0L);
  1071. } else {
  1072. CPSUIERR(("LocalAlloc(pIIHdr(%u)) failed, cannot move items", i));
  1073. }
  1074. }
  1075. while (pItem <= pLastItem) {
  1076. BYTE CurLevel = pItem->Level;
  1077. if (pItem->DlgPageIdx != CurPageIdx) {
  1078. SKIP_CHILDREN(pItem, pLastItem, CurLevel);
  1079. continue;
  1080. }
  1081. do {
  1082. POPTTYPE pOptType;
  1083. if (pOptType = pItem->pOptType) {
  1084. UINT BegCtrlID = (UINT)pOptType->BegCtrlID;
  1085. DWORD cySize;
  1086. --cItem;
  1087. BegCtrlID = (UINT)pOptType->BegCtrlID;
  1088. Type = (UINT)pOptType->Type;
  1089. if (pItem->Flags & OPTIF_ITEM_HIDE) {
  1090. --cHide;
  1091. if (!pIIHdr) {
  1092. HideMoveType(hDlg, BegCtrlID, Type);
  1093. }
  1094. } else {
  1095. CPSUIOPTITEM(DBGITEM_INITP1, pTVWnd, "InitP1", 2, pItem);
  1096. //
  1097. // Checking anything need to done for the internal item
  1098. //
  1099. switch (Type) {
  1100. case TVOT_LISTBOX:
  1101. cySize = ReCreateLBCB(hDlg,
  1102. BegCtrlID + 2,
  1103. !(BOOL)(pOptType->Style &
  1104. OTS_LBCB_PROPPAGE_LBUSECB));
  1105. _OT_ORGLBCBCY(pOptType) = HIWORD(cySize);
  1106. break;
  1107. case TVOT_COMBOBOX:
  1108. cySize = ReCreateLBCB(hDlg,
  1109. BegCtrlID + 2,
  1110. (BOOL)(pOptType->Style &
  1111. OTS_LBCB_PROPPAGE_CBUSELB));
  1112. _OT_ORGLBCBCY(pOptType) = HIWORD(cySize);
  1113. break;
  1114. case TVOT_TRACKBAR:
  1115. if (!CreateTrackBar(hDlg, BegCtrlID + 2)) {
  1116. return(ERR_CPSUI_CREATE_TRACKBAR_FAILED);
  1117. }
  1118. break;
  1119. case TVOT_UDARROW:
  1120. if (!CreateUDArrow(hDlg,
  1121. BegCtrlID + 2,
  1122. BegCtrlID + 6,
  1123. (LONG)pOptType->pOptParam[1].IconID,
  1124. (LONG)pOptType->pOptParam[1].lParam,
  1125. (LONG)pItem->Sel)) {
  1126. return(ERR_CPSUI_CREATE_UDARROW_FAILED);
  1127. }
  1128. break;
  1129. }
  1130. if ((Result = UpdatePropPageItem(hDlg,
  1131. pTVWnd,
  1132. pItem,
  1133. TRUE)) < 0) {
  1134. return(Result);
  1135. }
  1136. }
  1137. if (pIIHdr) {
  1138. //
  1139. // Add the item info header
  1140. //
  1141. AddItemInfo(pIIHdr, pItem);
  1142. }
  1143. }
  1144. } WHILE_SKIP_CHILDREN(pItem, pLastItem, CurLevel);
  1145. }
  1146. CPSUIASSERT(0, "Error: mismatch visable items=%d", cItem == 0, UIntToPtr(cItem));
  1147. if (cStdPageHide) {
  1148. PITEMINFO pII;
  1149. if (pIIHdr) {
  1150. pII = &(pIIHdr->ItemInfo[pIIHdr->cItem]);
  1151. CPSUIINT(("cItem in ItemInfoHdr=%d", (UINT)pIIHdr->cItem));
  1152. }
  1153. for (i = 0, pSPI = StdPageInfo; i < DMPUB_LAST; i++, pSPI++) {
  1154. if ((BegCtrlID = (UINT)pSPI->BegCtrlID) &&
  1155. (pSPI->StdPageID == CurPageIdx) &&
  1156. (pTVWnd->DMPubIdx[i] == 0xFFFF)) {
  1157. Type = (UINT)StdTVOT[pSPI->iStdTVOT + pSPI->cStdTVOT - 1];
  1158. if (pIIHdr) {
  1159. CPSUIINT(("Add Extra DMPUB ID=%d, BegCtrID=%d ITEMINFO",
  1160. i, BegCtrlID));
  1161. pII->Flags = IIF_ITEM_HIDE | IIF_EXT_HIDE ;
  1162. pII->Type = (BYTE)Type;
  1163. pII->BegCtrlID = (WORD)BegCtrlID;
  1164. AddItemInfo(pIIHdr, NULL);
  1165. pII++;
  1166. } else {
  1167. HideMoveType(hDlg, BegCtrlID, Type);
  1168. }
  1169. --cHide;
  1170. }
  1171. }
  1172. }
  1173. if ((cStdPageHide) || (cStatesHide)) {
  1174. //
  1175. // Now hide/move all page's item
  1176. //
  1177. if (pIIHdr) {
  1178. HideMovePropPage(pIIHdr);
  1179. }
  1180. SendMessage(hDlg, WM_SETREDRAW, (WPARAM)TRUE, 0L);
  1181. InvalidateRect(hDlg, NULL, FALSE);
  1182. }
  1183. if (pIIHdr) {
  1184. LocalFree((HLOCAL)pIIHdr);
  1185. }
  1186. CPSUIASSERT(0, "Error: mismatch hide items=%d", cHide == 0, UIntToPtr(cHide));
  1187. return(pCurMyDP->cItem);
  1188. }
  1189. LONG
  1190. UpdatePropPage(
  1191. HWND hDlg,
  1192. PMYDLGPAGE pCurMyDP
  1193. )
  1194. /*++
  1195. Routine Description:
  1196. Arguments:
  1197. Return Value:
  1198. Author:
  1199. 08-Aug-1995 Tue 15:37:16 created -by- Daniel Chou (danielc)
  1200. Revision History:
  1201. --*/
  1202. {
  1203. INT cUpdated = 0;
  1204. if (pCurMyDP->Flags & (MYDPF_CHANGED | MYDPF_REINIT)) {
  1205. PTVWND pTVWnd;
  1206. POPTITEM pItem;
  1207. UINT cItem;
  1208. BYTE CurPageIdx;
  1209. BOOL ReInit;
  1210. pTVWnd = (PTVWND)pCurMyDP->pTVWnd;
  1211. CurPageIdx = (BYTE)pCurMyDP->PageIdx;
  1212. pItem = pTVWnd->ComPropSheetUI.pOptItem;
  1213. cItem = (UINT)pTVWnd->ComPropSheetUI.cOptItem;
  1214. ReInit = (BOOL)(pCurMyDP->Flags & MYDPF_REINIT);
  1215. CPSUIDBG(DBGITEM_UP1, ("UpdatePropPage Flags (OPTIDX_INT_CHANGED)"));
  1216. while (cItem--) {
  1217. if ((pItem->pOptType) &&
  1218. (pItem->DlgPageIdx == CurPageIdx) &&
  1219. (pItem->Flags & OPTIF_INT_CHANGED)) {
  1220. CPSUIOPTITEM(DBGITEM_UP1, pTVWnd, "UpdatePage1", 1, pItem);
  1221. UpdatePropPageItem(hDlg, pTVWnd, pItem, ReInit);
  1222. pItem->Flags &= ~OPTIF_INT_CHANGED;
  1223. ++cUpdated;
  1224. }
  1225. pItem++;
  1226. }
  1227. pCurMyDP->Flags &= ~(MYDPF_CHANGED | MYDPF_REINIT);
  1228. }
  1229. return((LONG)cUpdated);
  1230. }
  1231. LONG
  1232. CountPropPageItems(
  1233. PTVWND pTVWnd,
  1234. BYTE CurPageIdx
  1235. )
  1236. /*++
  1237. Routine Description:
  1238. Arguments:
  1239. Return Value:
  1240. Author:
  1241. 22-Aug-1995 Tue 14:34:01 created -by- Daniel Chou (danielc)
  1242. Revision History:
  1243. --*/
  1244. {
  1245. PMYDLGPAGE pCurMyDP;
  1246. POPTITEM pItem;
  1247. POPTITEM pLastItem;
  1248. BOOL IsTVPage;
  1249. UINT cHideItems = 0;
  1250. UINT cPageItems = 0;
  1251. if (CurPageIdx >= pTVWnd->cMyDlgPage) {
  1252. return(0);
  1253. }
  1254. pItem = pTVWnd->ComPropSheetUI.pOptItem;
  1255. pLastItem = pTVWnd->pLastItem;
  1256. if (pTVWnd->Flags & TWF_HAS_ADVANCED_PUSH) {
  1257. IsTVPage = FALSE;
  1258. } else {
  1259. IsTVPage = (BOOL)(pTVWnd->TVPageIdx == CurPageIdx);
  1260. }
  1261. while (pItem <= pLastItem) {
  1262. if (IsTVPage) {
  1263. ++cPageItems;
  1264. if (pItem->Flags & OPTIF_ITEM_HIDE) {
  1265. ++cHideItems;
  1266. }
  1267. } else if (pItem->DlgPageIdx == CurPageIdx) {
  1268. cPageItems++;
  1269. if (pItem->Flags & OPTIF_ITEM_HIDE) {
  1270. ++cHideItems;
  1271. }
  1272. }
  1273. pItem++;
  1274. }
  1275. pCurMyDP = pTVWnd->pMyDlgPage + CurPageIdx;
  1276. pCurMyDP->cItem = (WORD)cPageItems;
  1277. pCurMyDP->cHide = (WORD)cHideItems;
  1278. CPSUIINT(("PageIdx=%ld, cItem=%ld, cHide=%ld",
  1279. CurPageIdx, cPageItems, cHideItems));
  1280. return((LONG)(cPageItems - cHideItems));
  1281. }
  1282. BOOL
  1283. CALLBACK
  1284. ChildWndCleanUp(
  1285. HWND hWnd,
  1286. LPARAM lParam
  1287. )
  1288. {
  1289. UNREFERENCED_PARAMETER(lParam);
  1290. if ((SendMessage(hWnd, WM_GETDLGCODE, 0, 0) & DLGC_STATIC) &&
  1291. ((GetWindowLongPtr(hWnd, GWL_STYLE) & SS_TYPEMASK) == SS_ICON)) {
  1292. HICON hIcon;
  1293. if (hIcon = (HICON)SendMessage(hWnd, STM_SETICON, 0, 0L)) {
  1294. DestroyIcon(hIcon);
  1295. }
  1296. CPSUIINT(("ChildWndCleanUp: Static ID=%u, Icon=%08lx",
  1297. GetDlgCtrlID(hWnd), hIcon));
  1298. }
  1299. return(TRUE);
  1300. }
  1301. BOOL
  1302. CALLBACK
  1303. FixIconChildTo32x32(
  1304. HWND hWnd,
  1305. LPARAM lParam
  1306. )
  1307. {
  1308. HWND hDlg = (HWND)lParam;
  1309. if ((SendMessage(hWnd, WM_GETDLGCODE, 0, 0) & DLGC_STATIC) &&
  1310. ((GetWindowLongPtr(hWnd, GWL_STYLE) & SS_TYPEMASK) == SS_ICON)) {
  1311. RECT rc;
  1312. hCtrlrcWnd(hDlg, hWnd, &rc);
  1313. if (((rc.right - rc.left) != 32) ||
  1314. ((rc.bottom - rc.top) != 32)) {
  1315. CPSUIINT(("FixIcon32x32: Icon ID=%u, size=%ld x %ld, fix to 32x32",
  1316. GetDlgCtrlID(hWnd),
  1317. rc.right - rc.left, rc.bottom - rc.top));
  1318. SetWindowPos(hWnd, NULL, 0, 0, 32, 32, SWP_NOMOVE | SWP_NOZORDER);
  1319. }
  1320. }
  1321. return(TRUE);
  1322. }
  1323. VOID
  1324. MoveAdvancedPush(
  1325. HWND hDlg,
  1326. UINT EnlargeCtrlID,
  1327. UINT CenterCtrlID
  1328. )
  1329. /*++
  1330. Routine Description:
  1331. Arguments:
  1332. Return Value:
  1333. Author:
  1334. 25-Aug-1998 Tue 10:30:55 created -by- Daniel Chou (danielc)
  1335. Revision History:
  1336. --*/
  1337. {
  1338. HWND hTabCtrl;
  1339. HWND hCtrl;
  1340. RECT rcAdvPush;
  1341. RECT rcDlg;
  1342. POINTL ptl;
  1343. if ((hTabCtrl = PropSheet_GetTabControl(GetParent(hDlg))) &&
  1344. (hCtrl = GetDlgItem(hDlg, ADVANCED_PUSH))) {
  1345. GetWindowRect(hDlg, &rcDlg);
  1346. CPSUIDBG(DBG_ADVPUSH, ("Prop Page Rect (before adjust)=(%ld, %ld) - (%ld, %ld)",
  1347. rcDlg.left, rcDlg.top, rcDlg.right, rcDlg.bottom));
  1348. TabCtrl_AdjustRect(hTabCtrl, FALSE, &rcDlg);
  1349. CPSUIDBG(DBG_ADVPUSH, ("Prop Page Rect (after adjust)=(%ld, %ld) - (%ld, %ld)",
  1350. rcDlg.left, rcDlg.top, rcDlg.right, rcDlg.bottom));
  1351. GetWindowRect(hCtrl, &rcAdvPush);
  1352. CPSUIDBG(DBG_ADVPUSH, ("Advanced Btn Rect=(%ld, %ld) - (%ld, %ld)",
  1353. rcAdvPush.left, rcAdvPush.top, rcAdvPush.right, rcAdvPush.bottom));
  1354. ptl.y = rcDlg.bottom - (rcAdvPush.bottom - rcAdvPush.top);
  1355. CPSUIDBG(DBG_ADVPUSH, ("AdvPush cy=%ld, Move Y from %ld to %ld",
  1356. rcAdvPush.bottom - rcAdvPush.top, rcAdvPush.top, ptl.y));
  1357. MapWindowPoints(NULL, hDlg, (LPPOINT)&rcAdvPush, 2);
  1358. ScreenToClient(hDlg, (LPPOINT)&ptl);
  1359. ptl.x = rcAdvPush.left;
  1360. CPSUIDBG(DBG_ADVPUSH, ("New Push left/top in CLIENT top=%ld, Add=%ld",
  1361. ptl.y, ptl.y - rcAdvPush.top));
  1362. if (rcAdvPush.top != ptl.y) {
  1363. CPSUIDBG(DBG_ADVPUSH, ("Advance Push top change from %ld to %ld",
  1364. rcAdvPush.top, ptl.y));
  1365. SetWindowPos(hCtrl,
  1366. NULL,
  1367. ptl.x, ptl.y,
  1368. 0, 0,
  1369. SWP_NOSIZE | SWP_NOZORDER);
  1370. ptl.y -= rcAdvPush.top;
  1371. if (hCtrl = CtrlIDrcWnd(hDlg, EnlargeCtrlID, &rcDlg)) {
  1372. SetWindowPos(hCtrl,
  1373. NULL,
  1374. 0, 0,
  1375. rcDlg.right - rcDlg.left,
  1376. rcDlg.bottom - rcDlg.top + ptl.y,
  1377. SWP_NOMOVE | SWP_NOZORDER);
  1378. }
  1379. if (hCtrl = CtrlIDrcWnd(hDlg, CenterCtrlID, &rcDlg)) {
  1380. SetWindowPos(hCtrl,
  1381. NULL,
  1382. rcDlg.left,
  1383. rcDlg.top + (ptl.y / 2),
  1384. 0, 0,
  1385. SWP_NOSIZE | SWP_NOZORDER);
  1386. }
  1387. }
  1388. }
  1389. }
  1390. INT_PTR
  1391. CALLBACK
  1392. PropPageProc(
  1393. HWND hDlg,
  1394. UINT Msg,
  1395. WPARAM wParam,
  1396. LPARAM lParam
  1397. )
  1398. /*++
  1399. Routine Description:
  1400. Arguments:
  1401. Return Value:
  1402. Author:
  1403. 28-Aug-1995 Mon 16:13:10 created -by- Daniel Chou (danielc)
  1404. Revision History:
  1405. --*/
  1406. {
  1407. #define pNMHdr ((NMHDR *)lParam)
  1408. HWND hWndFocus;
  1409. HWND hCtrl;
  1410. PMYDLGPAGE pCurMyDP;
  1411. PTVWND pTVWnd;
  1412. POPTITEM pItem;
  1413. LONG MResult;
  1414. PLAYOUTBMP pData;
  1415. PCPSUIPAGE pPage;
  1416. if (Msg == WM_INITDIALOG) {
  1417. CPSUIINT(("PropPage WM_INITDIALOG: hDlg=%08lx, pPSP=%08lx", hDlg, lParam));
  1418. pCurMyDP = (PMYDLGPAGE)(((LPPROPSHEETPAGE)lParam)->lParam);
  1419. pTVWnd = (PTVWND)pCurMyDP->pTVWnd;
  1420. pCurMyDP->pPSPInfo = PPSPINFO_FROM_WM_INITDIALOG_LPARAM(lParam);
  1421. if (!ADD_PMYDLGPAGE(hDlg, pCurMyDP)) {
  1422. return(FALSE);
  1423. }
  1424. CreateImageList(hDlg, pTVWnd);
  1425. if ((MResult = InitPropPage(hDlg, pCurMyDP)) < 0) {
  1426. CPSUIERR(("InitProPage()=%ld, FAILED", MResult));
  1427. }
  1428. SetUniqChildID(hDlg);
  1429. CommonPropSheetUIHelpSetup(NULL, pTVWnd);
  1430. UpdateCallBackChanges(hDlg, pTVWnd, TRUE);
  1431. EnumChildWindows(hDlg, FixIconChildTo32x32, (LPARAM)hDlg);
  1432. SetFocus((HWND)wParam);
  1433. MResult = TRUE;
  1434. ((LPPROPSHEETPAGE)lParam)->lParam = pCurMyDP->CPSUIUserData;
  1435. if ((pTVWnd->Flags & TWF_HAS_ADVANCED_PUSH) &&
  1436. (hCtrl = GetDlgItem(hDlg, ADVANCED_PUSH))) {
  1437. if (CountPropPageItems(pTVWnd, (BYTE)(pTVWnd->cMyDlgPage - 1))) {
  1438. WORD InitItemIdx = INTIDX_ADVANCED;
  1439. SETCTRLDATA(hCtrl, CTRLS_PUSHBUTTON, 0);
  1440. } else {
  1441. ShowWindow(hCtrl, SW_HIDE);
  1442. }
  1443. }
  1444. }
  1445. if (pCurMyDP = GET_PMYDLGPAGE(hDlg)) {
  1446. pTVWnd = (PTVWND)pCurMyDP->pTVWnd;
  1447. if (pTVWnd) {
  1448. if (pCurMyDP->DlgPage.DlgProc) {
  1449. //
  1450. // Passed the caller's original CPSUIUserData which is the UserData
  1451. // in the COMPROPSHEETUI data structure
  1452. //
  1453. MResult = (LONG)pCurMyDP->DlgPage.DlgProc(hDlg, Msg, wParam, lParam);
  1454. if (MResult) {
  1455. return(TRUE);
  1456. }
  1457. }
  1458. if (Msg == WM_INITDIALOG) {
  1459. if ((pCurMyDP->PageIdx != pTVWnd->StdPageIdx1) ||
  1460. (!(hCtrl = GetDlgItem(hDlg, IDD_LAYOUT_PICTURE)))) {
  1461. hCtrl = NULL;
  1462. }
  1463. MoveAdvancedPush(hDlg,
  1464. IDD_LAYOUT_PICTURE_GROUP,
  1465. IDD_LAYOUT_PICTURE);
  1466. if ((hCtrl) &&
  1467. (pData = InitLayoutBmp(hDlg, hCtrl, pTVWnd))) {
  1468. SetProp(hCtrl, CPSUIPROP_LAYOUTPUSH, (HANDLE)pData);
  1469. }
  1470. return((BOOL)MResult);
  1471. }
  1472. } else {
  1473. return(FALSE);
  1474. }
  1475. } else {
  1476. return(FALSE);
  1477. }
  1478. //
  1479. // Check if which one got the keyboard focus, if it is not the same as
  1480. // the one recored then send out the Focus message
  1481. //
  1482. if ((pCurMyDP->Flags & MYDPF_PAGE_ACTIVE) &&
  1483. (hWndFocus = GetFocus()) &&
  1484. (hWndFocus != pCurMyDP->hWndFocus) &&
  1485. (pItem = pItemFromhWnd(hDlg, pTVWnd, hWndFocus, -1)) &&
  1486. (pItem != pCurMyDP->pCurItem)) {
  1487. pCurMyDP->hWndFocus = hWndFocus;
  1488. pCurMyDP->pCurItem = pItem;
  1489. CPSUIOPTITEM(DBG_SETFOCUS, pTVWnd,
  1490. "PropPage: Keyboard Focus Changed", 0, pItem);
  1491. if ((pItem->Flags & OPTIF_CALLBACK) &&
  1492. (pTVWnd->ComPropSheetUI.pfnCallBack) &&
  1493. (pItem >= pTVWnd->ComPropSheetUI.pOptItem) &&
  1494. (pItem <= pTVWnd->pLastItem)) {
  1495. DoCallBack(hDlg,
  1496. pTVWnd,
  1497. pItem,
  1498. pItem->pSel,
  1499. NULL,
  1500. NULL,
  1501. 0,
  1502. CPSUICB_REASON_OPTITEM_SETFOCUS);
  1503. }
  1504. }
  1505. switch (Msg) {
  1506. case WM_DRAWITEM:
  1507. return(DrawLBCBItem(pTVWnd, (LPDRAWITEMSTRUCT)lParam));
  1508. case WM_COMMAND:
  1509. if ((LOWORD(wParam) == ADVANCED_PUSH) &&
  1510. (pTVWnd->Flags & TWF_HAS_ADVANCED_PUSH) &&
  1511. (HIWORD(wParam) == BN_CLICKED) &&
  1512. (pTVWnd->hCPSUIPage) &&
  1513. (pPage = HANDLETABLE_GetCPSUIPage(pTVWnd->hCPSUIPage))) {
  1514. pPage->Flags |= CPF_CALL_TV_DIRECT;
  1515. pTVWnd->Flags |= TWF_TV_BY_PUSH;
  1516. AddComPropSheetPage(pPage, pTVWnd->cInitMyDlgPage);
  1517. pTVWnd->Flags &= ~TWF_TV_BY_PUSH;
  1518. pPage->Flags &= ~CPF_CALL_TV_DIRECT;
  1519. HANDLETABLE_UnGetCPSUIPage(pPage);
  1520. SET_APPLY_BUTTON(pTVWnd, hDlg);
  1521. UpdatePropPage(hDlg, pCurMyDP);
  1522. InvalidateBMP(hDlg, pTVWnd);
  1523. break;
  1524. } else {
  1525. NULL;
  1526. }
  1527. //
  1528. // Fall through
  1529. //
  1530. case WM_HSCROLL:
  1531. if (pItem = DlgHScrollCommand(hDlg, pTVWnd, (HWND)lParam, wParam)) {
  1532. UpdatePropPageItem(hDlg, pTVWnd, pItem, FALSE);
  1533. InvalidateBMP(hDlg, pTVWnd);
  1534. }
  1535. break;
  1536. case WM_HELP:
  1537. wParam = (WPARAM)((LPHELPINFO)lParam)->hItemHandle;
  1538. lParam = (LPARAM)MAKELONG(((LPHELPINFO)lParam)->MousePos.x,
  1539. ((LPHELPINFO)lParam)->MousePos.y);
  1540. case WM_CONTEXTMENU:
  1541. if (lParam == 0xFFFFFFFF) {
  1542. RECT rc;
  1543. wParam = (WPARAM)GetFocus();
  1544. GetWindowRect((HWND)wParam, &rc);
  1545. CPSUIINT(("MousePos=0xFFFFFFFF, GetFocus=%08lx, rc=(%ld, %ld)-(%ld, %ld)",
  1546. (HWND)wParam, rc.left, rc.top, rc.right, rc.bottom));
  1547. rc.left += ((rc.right - rc.left) / 2);
  1548. rc.top += ((rc.bottom - rc.top) / 2);
  1549. lParam = (LPARAM)MAKELONG(rc.left, rc.top);
  1550. }
  1551. pTVWnd = GET_PTVWND(hDlg);
  1552. if (pTVWnd) {
  1553. pItem = pItemFromhWnd(hDlg, pTVWnd, (HWND)wParam, (LONG)lParam);
  1554. if (Msg == WM_CONTEXTMENU) {
  1555. DoContextMenu(pTVWnd, hDlg, pItem, lParam);
  1556. } else if (pItem) {
  1557. CommonPropSheetUIHelp(hDlg,
  1558. pTVWnd,
  1559. hDlg, // (HWND)GetFocus(),
  1560. (DWORD)lParam,
  1561. pItem,
  1562. HELP_WM_HELP);
  1563. }
  1564. }
  1565. break;
  1566. case WM_NOTIFY:
  1567. MResult = 0;
  1568. switch (pNMHdr->code) {
  1569. case NM_SETFOCUS:
  1570. case NM_CLICK:
  1571. case NM_DBLCLK:
  1572. case NM_RDBLCLK:
  1573. case NM_RCLICK:
  1574. break;
  1575. case PSN_APPLY:
  1576. if ((pTVWnd->Flags & TWF_CAN_UPDATE) &&
  1577. (pTVWnd->ActiveDlgPage == pCurMyDP->PageIdx)) {
  1578. CPSUIDBG(DBG_PROPPAGEPROC,
  1579. ("\nPropPage: Do PSN_APPLY(%ld), Page: Cur=%u, Active=%u, Flags=%04lx, CALLBACK",
  1580. (pTVWnd->Flags & TWF_APPLY_NO_NEWDEF) ? 1 : 0,
  1581. (UINT)pCurMyDP->PageIdx, (UINT)pTVWnd->ActiveDlgPage,
  1582. pTVWnd->Flags));
  1583. if (DoCallBack(hDlg,
  1584. pTVWnd,
  1585. (pTVWnd->Flags & TWF_APPLY_NO_NEWDEF) ?
  1586. NULL : pTVWnd->ComPropSheetUI.pOptItem,
  1587. (LPVOID)pCurMyDP->PageIdx,
  1588. NULL,
  1589. NULL,
  1590. 0,
  1591. CPSUICB_REASON_APPLYNOW) ==
  1592. CPSUICB_ACTION_NO_APPLY_EXIT) {
  1593. MResult = PSNRET_INVALID_NOCHANGEPAGE;
  1594. }
  1595. } else {
  1596. CPSUIDBG(DBG_PROPPAGEPROC,
  1597. ("\nPropPage: Ignore PSN_APPLY, Page: Cur=%u, Active=%u, Flags=%04lx, DO NOTHING",
  1598. (UINT)pCurMyDP->PageIdx, (UINT)pTVWnd->ActiveDlgPage,
  1599. pTVWnd->Flags));
  1600. }
  1601. break;
  1602. case PSN_RESET:
  1603. CPSUIDBG(DBG_PROPPAGEPROC, ("\nPropPage: Got PSN_RESET (Cancel)"));
  1604. break;
  1605. case PSN_HELP:
  1606. CPSUIDBG(DBG_PROPPAGEPROC, ("\nPropPage: Got PSN_HELP (Help)"));
  1607. CommonPropSheetUIHelp(hDlg,
  1608. pTVWnd,
  1609. GetFocus(),
  1610. 0,
  1611. NULL,
  1612. HELP_CONTENTS);
  1613. break;
  1614. case PSN_SETACTIVE:
  1615. CPSUIDBG(DBG_PROPPAGEPROC,
  1616. ("\nPropPage: Got PSN_SETACTIVE, pTVWnd=%08lx (%ld), Page=%u -> %u\n",
  1617. pTVWnd, pTVWnd->cMyDlgPage,
  1618. (UINT)pTVWnd->ActiveDlgPage, (UINT)pCurMyDP->PageIdx));
  1619. pCurMyDP->Flags |= MYDPF_PAGE_ACTIVE;
  1620. pTVWnd->ActiveDlgPage = pCurMyDP->PageIdx;
  1621. DoCallBack(hDlg,
  1622. pTVWnd,
  1623. pTVWnd->ComPropSheetUI.pOptItem,
  1624. (LPVOID)pCurMyDP->PageIdx,
  1625. NULL,
  1626. NULL,
  1627. 0,
  1628. CPSUICB_REASON_SETACTIVE);
  1629. UpdatePropPage(hDlg, pCurMyDP);
  1630. InvalidateBMP(hDlg, pTVWnd);
  1631. break;
  1632. case PSN_KILLACTIVE:
  1633. CPSUIDBG(DBG_PROPPAGEPROC, ("\nPropPage: Got PSN_KILLACTIVE, pTVWnd=%08lx (%ld)",
  1634. pTVWnd, pTVWnd->cMyDlgPage));
  1635. pCurMyDP->Flags &= ~MYDPF_PAGE_ACTIVE;
  1636. DoCallBack(hDlg,
  1637. pTVWnd,
  1638. pTVWnd->ComPropSheetUI.pOptItem,
  1639. (LPVOID)pCurMyDP->PageIdx,
  1640. NULL,
  1641. NULL,
  1642. 0,
  1643. CPSUICB_REASON_KILLACTIVE);
  1644. break;
  1645. default:
  1646. CPSUIDBG(DBG_PROPPAGEPROC,
  1647. ("*PropPageProc: Unknow WM_NOTIFY=%u", pNMHdr->code));
  1648. break;
  1649. }
  1650. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, MResult);
  1651. return(TRUE);
  1652. break;
  1653. case WM_DESTROY:
  1654. CPSUIINT(("PropPage: Get WM_DESTROY Message"));
  1655. if ((hCtrl = GetDlgItem(hDlg, IDD_LAYOUT_PICTURE)) &&
  1656. (pData = (PLAYOUTBMP)GetProp(hCtrl, CPSUIPROP_LAYOUTPUSH))) {
  1657. FreeLayoutBmp(pData);
  1658. RemoveProp(hCtrl, CPSUIPROP_LAYOUTPUSH);
  1659. }
  1660. CommonPropSheetUIHelpSetup(hDlg, pTVWnd);
  1661. EnumChildWindows(hDlg, ChildWndCleanUp, 0);
  1662. DEL_PMYDLGPAGE(hDlg);
  1663. break;
  1664. }
  1665. return(FALSE);
  1666. #undef pNMHdr
  1667. }
  1668. PLAYOUTBMP
  1669. InitLayoutBmp(
  1670. HWND hDlg,
  1671. HANDLE hWnd,
  1672. PTVWND pTVWnd
  1673. )
  1674. /*++
  1675. Routine Description:
  1676. Loads bitmap resource and initializes array used in displaying layout preview
  1677. Arguments:
  1678. hDlg - Dialog handle
  1679. hWnd - Handle to the preview window control
  1680. pTVWnd - Treeview info
  1681. Return Value:
  1682. Pointer to LAYOUTBMP containing private settings
  1683. Author:
  1684. Revision History:
  1685. --*/
  1686. {
  1687. PLAYOUTBMP pData;
  1688. if (!(pData = LocalAlloc(LMEM_FIXED, sizeof(LAYOUTBMP)))) {
  1689. return NULL;
  1690. }
  1691. if (!(LoadLayoutBmp(hDlg, &pData->Portrait, IDI_CPSUI_LAYOUT_BMP_PORTRAIT)) ||
  1692. !(LoadLayoutBmp(hDlg, &pData->BookletL, IDI_CPSUI_LAYOUT_BMP_BOOKLETL)) ||
  1693. !(LoadLayoutBmp(hDlg, &pData->BookletP, IDI_CPSUI_LAYOUT_BMP_BOOKLETP)) ||
  1694. !(LoadLayoutBmp(hDlg, &pData->ArrowL, IDI_CPSUI_LAYOUT_BMP_ARROWL)) ||
  1695. !(LoadLayoutBmp(hDlg, &pData->ArrowS, IDI_CPSUI_LAYOUT_BMP_ARROWS)) ) {
  1696. // something went wrong. cleanup...
  1697. FreeLayoutBmp(pData);
  1698. return NULL;
  1699. }
  1700. pData->hWnd = hWnd;
  1701. InitData(pData, pTVWnd);
  1702. return pData;
  1703. }
  1704. BOOL
  1705. LoadLayoutBmp(
  1706. HWND hDlg,
  1707. MYBMP * pMyBmpData,
  1708. DWORD dwBitmapID
  1709. )
  1710. /*++
  1711. Routine Description:
  1712. Load bitmap resource and get color table information,
  1713. BITMAPINFOHEADER and offset to bits for bltting later.
  1714. Arguments:
  1715. Return Value:
  1716. Author:
  1717. Revision History:
  1718. --*/
  1719. {
  1720. HANDLE hResource, hBitmap;
  1721. LPBYTE lpBitmap;
  1722. LPBITMAPINFOHEADER lpbmi;
  1723. DWORD dwClrUsed;
  1724. if (!(hResource = FindResource(hInstDLL,
  1725. MAKEINTRESOURCE(dwBitmapID),
  1726. RT_BITMAP))){
  1727. return FALSE;
  1728. }
  1729. if (!(hBitmap = LoadResource(hInstDLL, hResource))) {
  1730. return FALSE;
  1731. }
  1732. if (!(lpBitmap = LockResource(hBitmap))) {
  1733. FreeResource(hBitmap);
  1734. return FALSE;
  1735. }
  1736. lpbmi = (LPBITMAPINFOHEADER)lpBitmap;
  1737. if (lpbmi->biSize == sizeof(BITMAPINFOHEADER)){
  1738. dwClrUsed = lpbmi->biClrUsed;
  1739. if (dwClrUsed == 0) {
  1740. switch(lpbmi->biBitCount){
  1741. case 1:
  1742. dwClrUsed = 2;
  1743. break;
  1744. case 4:
  1745. dwClrUsed = 16;
  1746. break;
  1747. case 8:
  1748. dwClrUsed = 256;
  1749. break;
  1750. default:
  1751. dwClrUsed = 0;
  1752. break;
  1753. }
  1754. }
  1755. lpBitmap += lpbmi->biSize + (dwClrUsed * sizeof(RGBQUAD));
  1756. } else {
  1757. FreeResource(hBitmap);
  1758. return FALSE;
  1759. }
  1760. pMyBmpData->hBitmap = hBitmap;
  1761. pMyBmpData->lpbmi = lpbmi;
  1762. pMyBmpData->lpBits = lpBitmap;
  1763. return TRUE;
  1764. }
  1765. VOID
  1766. DrawLayoutArrowAndText(
  1767. HDC hDC,
  1768. PRECT prcIn,
  1769. PRECT prcOut,
  1770. PLAYOUTBMP pData
  1771. )
  1772. /*++
  1773. Routine Description:
  1774. This function draws the arrow and the Side1/Side2 text for the
  1775. preview pages in duplex mode.
  1776. Arguments:
  1777. hDC - Screen DC
  1778. prcIn - Describes the total drawable dimensions for the preview control
  1779. prcOut - Pointer to RECT that describes the dimensions of the last page drawn
  1780. pData - Private data, stores the bitmap information
  1781. Return Value:
  1782. None
  1783. --*/
  1784. {
  1785. LPBITMAPINFOHEADER lpbmi;
  1786. LPBYTE lpBits;
  1787. INT left, top, strx1,strx2, stry1, stry2;
  1788. WCHAR awchBuf[MAX_RES_STR_CHARS];
  1789. HBITMAP hbm = NULL;
  1790. HDC hdcMem = NULL;
  1791. BOOL bArrowS;
  1792. if (pData->DuplexIdx == DUPLEX_SIMPLEX)
  1793. return;
  1794. if ((pData->DuplexIdx == DUPLEX_LONGSIDE && pData->OrientIdx == ORIENT_PORTRAIT) ||
  1795. (pData->DuplexIdx == DUPLEX_SHORTSIDE && pData->OrientIdx != ORIENT_PORTRAIT)) {
  1796. if ((pData->NupIdx == NUP_TWOUP || pData->NupIdx == NUP_SIXUP))
  1797. bArrowS = TRUE;
  1798. else
  1799. bArrowS = FALSE;
  1800. }
  1801. else {
  1802. if ((pData->NupIdx == NUP_TWOUP || pData->NupIdx == NUP_SIXUP))
  1803. bArrowS = FALSE;
  1804. else
  1805. bArrowS = TRUE;
  1806. }
  1807. if (bArrowS) {
  1808. lpbmi = pData->ArrowS.lpbmi;
  1809. lpBits = pData->ArrowS.lpBits;
  1810. left = prcOut->right + SHADOW_SIZE*2;
  1811. top = prcOut->top - (lpbmi->biHeight + SHADOW_SIZE)/2;
  1812. strx1 = strx2 = prcIn->left + (prcIn->right - prcIn->left)/16 ;
  1813. stry1 = prcIn->top;
  1814. stry2 = stry1 + ((prcIn->bottom - prcIn->top) + SHADOW_SIZE)/2;
  1815. }
  1816. else {
  1817. lpbmi = pData->ArrowL.lpbmi;
  1818. lpBits = pData->ArrowL.lpBits;
  1819. left = prcIn->left + (prcOut->right - prcOut->left) + SHADOW_SIZE;
  1820. top = prcOut->top + (prcOut->bottom - prcOut->top) + SHADOW_SIZE*2;
  1821. strx1 = prcIn->left + (prcIn->right - prcIn->left)/6 - SHADOW_SIZE;
  1822. stry1 = stry2 = prcIn->top + (prcIn->bottom - prcIn->top)/6 ;
  1823. strx2 = strx1 + (prcIn->right - prcIn->left)/2;
  1824. }
  1825. if (!(hbm = CreateCompatibleBitmap(hDC, lpbmi->biWidth, lpbmi->biHeight)) ||
  1826. !(hdcMem = CreateCompatibleDC(hDC)) ||
  1827. !SelectObject(hdcMem, hbm))
  1828. {
  1829. goto DrawArrowAndTextExit;
  1830. }
  1831. StretchDIBits(hdcMem,
  1832. 0,
  1833. 0,
  1834. lpbmi->biWidth,
  1835. lpbmi->biHeight,
  1836. 0,
  1837. 0,
  1838. lpbmi->biWidth,
  1839. lpbmi->biHeight,
  1840. lpBits,
  1841. (LPBITMAPINFO)lpbmi,
  1842. DIB_RGB_COLORS,
  1843. SRCCOPY
  1844. );
  1845. TransparentBlt(hDC,
  1846. left,
  1847. top,
  1848. lpbmi->biWidth,
  1849. lpbmi->biHeight,
  1850. hdcMem,
  1851. 0,
  1852. 0,
  1853. lpbmi->biWidth,
  1854. lpbmi->biHeight,
  1855. RGB(255, 0, 255)
  1856. );
  1857. //
  1858. // Draw the Text
  1859. //
  1860. LoadString(hInstDLL, IDS_CPSUI_SIDE1, awchBuf, MAX_RES_STR_CHARS);
  1861. TextOut(hDC, strx1, stry1, awchBuf, wcslen(awchBuf));
  1862. LoadString(hInstDLL, IDS_CPSUI_SIDE2, awchBuf, MAX_RES_STR_CHARS);
  1863. TextOut(hDC, strx2, stry2, awchBuf, wcslen(awchBuf));
  1864. DrawArrowAndTextExit:
  1865. if (hbm)
  1866. DeleteObject(hbm);
  1867. if (hdcMem)
  1868. DeleteDC(hdcMem);
  1869. }
  1870. VOID
  1871. UpdateLayoutBmp(
  1872. HDC hDC,
  1873. PLAYOUTBMP pData
  1874. )
  1875. /*++
  1876. Routine Description:
  1877. Calls whenever we get a WM_DRAWITEM to draw owner drawn controls.
  1878. Arguments:
  1879. hDC - Handle to screen DC
  1880. pData - Private data containing current selections etc.
  1881. Return Value:
  1882. None
  1883. Author:
  1884. Revision History:
  1885. Note:
  1886. PAGE_BOUNDARY_SCALE is 7 since it assumes that the destination control is
  1887. a square where in portrait mode, the width of the dest window is 5/7 of the square and in
  1888. landscape mode, the height of the dest window is 5/7 of the square. This is used to simplify
  1889. the code for both scenarios. We just need to scale based on the orientation
  1890. selected.
  1891. --*/
  1892. {
  1893. #define PAGE_BOUNDARY_SCALE 7
  1894. INT i, j, k, Row, Columm;
  1895. BOOL bDoBooklet = FALSE;
  1896. DWORD dwWidth, dwHeight, dwBookletLeft, dwBookletTop, dwOffset;
  1897. RECT rcControlIn, rcControlOut;
  1898. LPBITMAPINFOHEADER lpbmi;
  1899. LPBYTE lpBits;
  1900. HDC hCompDC;
  1901. HBITMAP hCompBitmap;
  1902. PAGEBORDER * pPageBorder;
  1903. BYTE DuplexIdx;
  1904. //
  1905. // PageBorder represents the factor for calculating the
  1906. // left, top, right, bottom rectangle of the current selected duplex option
  1907. //
  1908. static PAGEBORDER PageBorderP[] = {
  1909. { 4, 4, 2, 2 },
  1910. { 0, 4, 2, 2 },
  1911. { 2, 4, 2, 2 },
  1912. { 4, 0, 2, 2 },
  1913. { 4, 2, 2, 2 }
  1914. };
  1915. static PAGEBORDER PageBorderL[] = {
  1916. { 4, 4, 2, 2 },
  1917. { 4, 0, 2, 2 },
  1918. { 4, 2, 2, 2 },
  1919. { 0, 4, 2, 2 },
  1920. { 2, 4, 2, 2 }
  1921. };
  1922. //
  1923. // Duplex represents the the start and end of rectangles to be drawn for
  1924. // the current selected duplex options.
  1925. // For example, to draw page border for Long Side duplexinng,
  1926. // Start with PageBorder[1] and End with PageBorder[3]
  1927. //
  1928. static DUPLEX Duplex[MAX_DUPLEX_OPTION] = {
  1929. { 1, 3 }, // Long Side
  1930. { 3, 5 }, // Short Side
  1931. { 0, 1 } // Simplex
  1932. };
  1933. //
  1934. // Nup[] represents the row and columm for each Nup option
  1935. //
  1936. static NUP Nup[] = {
  1937. { 1, 1 }, // 1-up
  1938. { 2, 1 }, // 2-up
  1939. { 2, 2 }, // 4-up
  1940. { 3, 2 }, // 6-up
  1941. { 3, 3 }, // 9-up
  1942. { 4, 4 }, // 16-up
  1943. { 1, 1 } // Booklet
  1944. };
  1945. GetClientRect(pData->hWnd, &rcControlIn);
  1946. dwOffset = (rcControlIn.right - rcControlIn.left)/ PAGE_BOUNDARY_SCALE;
  1947. if (pData->OrientIdx == ORIENT_PORTRAIT){
  1948. if ((pData->NupIdx == NUP_TWOUP || pData->NupIdx == NUP_SIXUP))
  1949. {
  1950. rcControlIn.top += dwOffset;
  1951. rcControlIn.bottom -= dwOffset;
  1952. pPageBorder =PageBorderL;
  1953. }
  1954. else
  1955. {
  1956. rcControlIn.left += dwOffset;
  1957. rcControlIn.right -= dwOffset;
  1958. pPageBorder =PageBorderP;
  1959. }
  1960. }else {
  1961. if ((pData->NupIdx == NUP_TWOUP || pData->NupIdx == NUP_SIXUP))
  1962. {
  1963. rcControlIn.left += dwOffset;
  1964. rcControlIn.right -= dwOffset;
  1965. pPageBorder =PageBorderP;
  1966. }
  1967. else
  1968. {
  1969. rcControlIn.top += dwOffset;
  1970. rcControlIn.bottom -= dwOffset;
  1971. pPageBorder =PageBorderL;
  1972. }
  1973. }
  1974. CopyMemory(&rcControlOut, &rcControlIn, sizeof(RECT));
  1975. SetStretchBltMode(hDC, BLACKONWHITE);
  1976. if (bDoBooklet = (pData->NupIdx == NUP_BOOKLET))
  1977. DuplexIdx = DUPLEX_SIMPLEX;
  1978. else
  1979. DuplexIdx = pData->DuplexIdx;
  1980. for (k= Duplex[DuplexIdx].Start; k < Duplex[DuplexIdx].End; k++) {
  1981. DrawBorder(hDC,
  1982. !bDoBooklet,
  1983. !bDoBooklet,
  1984. &rcControlIn,
  1985. &rcControlOut,
  1986. &pPageBorder[k]
  1987. );
  1988. if (!bDoBooklet) {
  1989. rcControlOut.left += FRAME_BORDER;
  1990. rcControlOut.right -= FRAME_BORDER;
  1991. rcControlOut.top += FRAME_BORDER;
  1992. rcControlOut.bottom -= FRAME_BORDER;
  1993. dwWidth = rcControlOut.right - rcControlOut.left;
  1994. dwHeight = rcControlOut.bottom - rcControlOut.top;
  1995. lpBits = pData->Portrait.lpBits;
  1996. lpbmi = pData->Portrait.lpbmi;
  1997. if (pData->OrientIdx == ORIENT_PORTRAIT)
  1998. {
  1999. Row = Nup[pData->NupIdx].row;
  2000. Columm = Nup[pData->NupIdx].columm;
  2001. }
  2002. else {
  2003. Row = Nup[pData->NupIdx].columm;
  2004. Columm = Nup[pData->NupIdx].row;
  2005. }
  2006. if ((pData->NupIdx == NUP_TWOUP || pData->NupIdx == NUP_SIXUP)) {
  2007. i = Row;
  2008. Row = Columm;
  2009. Columm = i;
  2010. }
  2011. dwWidth /= Columm;
  2012. dwHeight /= Row;
  2013. }
  2014. else {
  2015. dwBookletLeft = rcControlOut.left;
  2016. dwBookletTop = rcControlOut.top;
  2017. if (pData->OrientIdx == ORIENT_PORTRAIT) {
  2018. lpBits = pData->BookletP.lpBits;
  2019. lpbmi = pData->BookletP.lpbmi;
  2020. dwWidth = pData->BookletP.lpbmi->biWidth;
  2021. dwHeight = pData->BookletP.lpbmi->biHeight;
  2022. rcControlOut.right = rcControlOut.left + dwWidth;
  2023. rcControlOut.bottom = rcControlOut.top + dwHeight;
  2024. rcControlOut.top = rcControlOut.top + dwHeight/5;
  2025. }
  2026. else {
  2027. lpBits = pData->BookletL.lpBits;
  2028. lpbmi = pData->BookletL.lpbmi;
  2029. dwWidth = pData->BookletL.lpbmi->biWidth;
  2030. dwHeight = pData->BookletL.lpbmi->biHeight;
  2031. rcControlOut.right = rcControlOut.left + dwWidth;
  2032. rcControlOut.bottom = rcControlOut.top + dwHeight;
  2033. rcControlOut.left = rcControlOut.left + dwWidth/5;
  2034. }
  2035. }
  2036. hCompDC = CreateCompatibleDC(hDC);
  2037. hCompBitmap = CreateCompatibleBitmap(hDC, dwWidth, dwHeight);
  2038. if (!hCompDC || !hCompBitmap)
  2039. return;
  2040. SelectObject(hCompDC, hCompBitmap);
  2041. StretchDIBits(hCompDC,
  2042. 0,
  2043. 0,
  2044. dwWidth,
  2045. dwHeight,
  2046. 0,
  2047. 0,
  2048. lpbmi->biWidth,
  2049. lpbmi->biHeight,
  2050. lpBits,
  2051. (LPBITMAPINFO)lpbmi,
  2052. DIB_RGB_COLORS,
  2053. SRCCOPY
  2054. );
  2055. if (bDoBooklet) {
  2056. DrawBorder(hDC,
  2057. TRUE,
  2058. FALSE,
  2059. NULL,
  2060. &rcControlOut,
  2061. NULL
  2062. );
  2063. TransparentBlt(hDC,
  2064. dwBookletLeft,
  2065. dwBookletTop ,
  2066. dwWidth,
  2067. dwHeight,
  2068. hCompDC,
  2069. 0,
  2070. 0,
  2071. dwWidth,
  2072. dwHeight,
  2073. RGB(255, 0, 255)
  2074. );
  2075. }
  2076. else {
  2077. for ( i = 0; i < Row; i++) {
  2078. for (j = 0; j < Columm; j++) {
  2079. BitBlt( hDC,
  2080. rcControlOut.left + dwWidth*j ,
  2081. rcControlOut.top + dwHeight*i,
  2082. dwWidth,
  2083. dwHeight,
  2084. hCompDC,
  2085. 0,
  2086. 0,
  2087. SRCCOPY
  2088. );
  2089. }
  2090. }
  2091. }
  2092. DeleteObject(hCompBitmap);
  2093. DeleteDC(hCompDC);
  2094. }
  2095. if (!bDoBooklet)
  2096. DrawLayoutArrowAndText(hDC,&rcControlIn, &rcControlOut, pData);
  2097. }
  2098. VOID
  2099. FreeLayoutBmp(
  2100. PLAYOUTBMP pData
  2101. )
  2102. /*++
  2103. Routine Description:
  2104. Unlock and Free Resources and free memory allocated for pData
  2105. Arguments:
  2106. Return Value:
  2107. Author:
  2108. Revision History:
  2109. --*/
  2110. {
  2111. if (pData){
  2112. UnlockResource(pData->Portrait.hBitmap);
  2113. UnlockResource(pData->BookletL.hBitmap);
  2114. UnlockResource(pData->BookletP.hBitmap);
  2115. UnlockResource(pData->ArrowL.hBitmap);
  2116. UnlockResource(pData->ArrowS.hBitmap);
  2117. FreeResource(pData->Portrait.hBitmap);
  2118. FreeResource(pData->BookletL.hBitmap);
  2119. FreeResource(pData->BookletP.hBitmap);
  2120. FreeResource(pData->ArrowL.hBitmap);
  2121. FreeResource(pData->ArrowS.hBitmap);
  2122. LocalFree(pData);
  2123. }
  2124. }
  2125. VOID
  2126. DrawBorder(
  2127. HDC hDC,
  2128. BOOL bDrawShadow,
  2129. BOOL bDrawBorder,
  2130. PRECT pRectIn,
  2131. PRECT pRectOut,
  2132. PAGEBORDER * pPageBorder
  2133. )
  2134. /*++
  2135. Routine Description:
  2136. Draw the page border for the preview bitmap
  2137. Arguments:
  2138. Return Value:
  2139. Author:
  2140. Revision History:
  2141. --*/
  2142. {
  2143. HPEN hOldPen, hPen;
  2144. HBRUSH hBrush;
  2145. DWORD dwWidth, dwHeight;
  2146. RECT rcShadow;
  2147. hPen = GetStockObject(BLACK_PEN);
  2148. hBrush = GetStockObject(GRAY_BRUSH);
  2149. hOldPen = (HPEN) SelectObject(hDC, hPen);
  2150. if (pPageBorder) {
  2151. dwWidth = pRectIn->right - pRectIn->left ;
  2152. dwHeight = pRectIn->bottom - pRectIn->top ;
  2153. pRectOut->left = pRectIn->left + ADDOFFSET(dwWidth ,pPageBorder->left);
  2154. pRectOut->top = pRectIn->top + ADDOFFSET(dwHeight,pPageBorder->top);
  2155. pRectOut->right = pRectOut->left + ADDOFFSET(dwWidth ,pPageBorder->right) ;
  2156. pRectOut->bottom = pRectOut->top + ADDOFFSET(dwHeight,pPageBorder->bottom);
  2157. }
  2158. if (bDrawBorder) {
  2159. InflateRect(pRectOut, -5, -5);
  2160. SelectObject ( hDC, hPen);
  2161. Rectangle( hDC, pRectOut->left, pRectOut->top, pRectOut->right , pRectOut->bottom );
  2162. }
  2163. if (bDrawShadow) {
  2164. rcShadow.left = pRectOut->right;
  2165. rcShadow.top = pRectOut->top + SHADOW_SIZE;
  2166. rcShadow.right = pRectOut->right + SHADOW_SIZE;
  2167. rcShadow.bottom = pRectOut->bottom + SHADOW_SIZE;
  2168. FillRect(hDC, &rcShadow, hBrush);
  2169. rcShadow.left = pRectOut->left + SHADOW_SIZE;
  2170. rcShadow.top = pRectOut->bottom;
  2171. rcShadow.right = pRectOut->right + SHADOW_SIZE;
  2172. rcShadow.bottom = pRectOut->bottom + SHADOW_SIZE;
  2173. FillRect(hDC, &rcShadow, hBrush);
  2174. }
  2175. SelectObject ( hDC, hOldPen);
  2176. if (hPen) {
  2177. DeleteObject ( hPen );
  2178. }
  2179. if (hBrush) {
  2180. DeleteObject ( hBrush );
  2181. }
  2182. }
  2183. VOID
  2184. InvalidateBMP(
  2185. HWND hDlg,
  2186. PTVWND pTVWnd
  2187. )
  2188. /*++
  2189. Routine Description:
  2190. Call InvalidateRect to get WM_DRAWITEM to update preview.
  2191. Arguments:
  2192. Return Value:
  2193. Author:
  2194. Revision History:
  2195. --*/
  2196. {
  2197. HWND hWnd;
  2198. PLAYOUTBMP pData;
  2199. if ((hWnd = GetDlgItem(hDlg, IDD_LAYOUT_PICTURE)) &&
  2200. (pData = (PLAYOUTBMP)GetProp(hWnd, CPSUIPROP_LAYOUTPUSH))) {
  2201. UpdateData(pData, pTVWnd);
  2202. InvalidateRect(hWnd, NULL, TRUE);
  2203. }
  2204. }
  2205. VOID
  2206. InitData(
  2207. PLAYOUTBMP pData,
  2208. PTVWND pTVWnd
  2209. )
  2210. /*++
  2211. Routine Description:
  2212. Arguments:
  2213. Return Value:
  2214. Author:
  2215. Revision History:
  2216. --*/
  2217. {
  2218. UINT Idx, Count, i;
  2219. POPTTYPE pOptType;
  2220. POPTPARAM pOptParam;
  2221. POPTITEM pItem = pTVWnd->ComPropSheetUI.pOptItem;
  2222. pData->OrientIdx = ORIENT_PORTRAIT;
  2223. pData->NupIdx = NUP_ONEUP;
  2224. pData->DuplexIdx = DUPLEX_SIMPLEX;
  2225. if (pItem = GET_PITEMDMPUB(pTVWnd, DMPUB_ORIENTATION, Idx)) {
  2226. pOptType = pItem->pOptType;
  2227. pOptParam = pOptType->pOptParam;
  2228. Count = pOptType->Count;
  2229. for ( i = 0; i < Count; i++) {
  2230. switch (pOptParam->IconID) {
  2231. case IDI_CPSUI_PORTRAIT:
  2232. pData->Orientation.PortraitIdx = (BYTE)i;
  2233. break;
  2234. case IDI_CPSUI_LANDSCAPE:
  2235. pData->Orientation.LandscapeIdx = (BYTE)i;
  2236. break;
  2237. case IDI_CPSUI_ROT_LAND:
  2238. pData->Orientation.RotateIdx = (BYTE)i;
  2239. break;
  2240. }
  2241. pOptParam++;
  2242. }
  2243. }
  2244. if (pItem = GET_PITEMDMPUB(pTVWnd, DMPUB_DUPLEX, Idx)) {
  2245. pOptType = pItem->pOptType;
  2246. pOptParam = pOptType->pOptParam;
  2247. Count = pOptType->Count;
  2248. for ( i = 0; i < Count; i++) {
  2249. switch (pOptParam->IconID) {
  2250. case IDI_CPSUI_DUPLEX_NONE:
  2251. case IDI_CPSUI_DUPLEX_NONE_L:
  2252. pData->Duplex.SimplexIdx = (BYTE)i;
  2253. break;
  2254. case IDI_CPSUI_DUPLEX_HORZ:
  2255. case IDI_CPSUI_DUPLEX_HORZ_L:
  2256. pData->Duplex.ShortSideIdx = (BYTE)i;
  2257. break;
  2258. case IDI_CPSUI_DUPLEX_VERT:
  2259. case IDI_CPSUI_DUPLEX_VERT_L:
  2260. pData->Duplex.LongSideIdx = (BYTE)i;
  2261. break;
  2262. }
  2263. pOptParam++;
  2264. }
  2265. }
  2266. }
  2267. VOID
  2268. UpdateData(
  2269. PLAYOUTBMP pData,
  2270. PTVWND pTVWnd
  2271. )
  2272. /*++
  2273. Routine Description:
  2274. Arguments:
  2275. Return Value:
  2276. Author:
  2277. Revision History:
  2278. --*/
  2279. {
  2280. POPTITEM pItem = pTVWnd->ComPropSheetUI.pOptItem;
  2281. UINT Idx;
  2282. if (pItem = GET_PITEMDMPUB(pTVWnd, DMPUB_DUPLEX, Idx)) {
  2283. if ((BYTE)pItem->Sel == pData->Duplex.SimplexIdx) {
  2284. pData->DuplexIdx = DUPLEX_SIMPLEX;
  2285. } else if ((BYTE)pItem->Sel == pData->Duplex.LongSideIdx) {
  2286. pData->DuplexIdx = DUPLEX_LONGSIDE;
  2287. } else if ((BYTE)pItem->Sel == pData->Duplex.ShortSideIdx) {
  2288. pData->DuplexIdx = DUPLEX_SHORTSIDE;
  2289. }
  2290. }
  2291. if (pItem = GET_PITEMDMPUB(pTVWnd, DMPUB_ORIENTATION, Idx)) {
  2292. if ((BYTE)pItem->Sel == pData->Orientation.PortraitIdx) {
  2293. pData->OrientIdx = ORIENT_PORTRAIT;
  2294. } else if ((BYTE)pItem->Sel == pData->Orientation.LandscapeIdx) {
  2295. pData->OrientIdx = ORIENT_LANDSCAPE;
  2296. } else if ((BYTE)pItem->Sel == pData->Orientation.RotateIdx) {
  2297. pData->OrientIdx = ORIENT_ROTATED;
  2298. }
  2299. }
  2300. if (pItem = GET_PITEMDMPUB(pTVWnd, DMPUB_NUP, Idx)) {
  2301. pData->NupIdx = (BYTE)pItem->Sel;
  2302. }
  2303. }