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.

1071 lines
26 KiB

  1. /*++
  2. Copyright (c) 1990-1995 Microsoft Corporation
  3. Module Name:
  4. tvctrl.c
  5. Abstract:
  6. This module contains all procedures to paint the treeview window
  7. Author:
  8. 17-Oct-1995 Tue 16:06:50 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 DbgTVCtrl
  17. #define DBG_WM_PAINT 0x00000001
  18. #define DBG_DRAWITEM_RECT 0x00000002
  19. #define DBG_DRAWITEM_COLOR 0x00000004
  20. #define DBG_SYS_COLOR 0x00000008
  21. #define DBG_ORIGIN 0x00000010
  22. #define DBG_COMMAND 0x00000020
  23. #define DBG_EDIT_PROC 0x00000040
  24. #define DBG_SCROLL 0x00000080
  25. #define DBG_CYICON 0x00000100
  26. #define DBG_WM_SETFONT 0x00000200
  27. #define DBG_KEYS 0x00000400
  28. #define DBG_CTRLCOLOR 0x00000800
  29. DEFINE_DBGVAR(0);
  30. extern HINSTANCE hInstDLL;
  31. typedef struct _MYBMPINFO {
  32. BITMAPINFOHEADER bh;
  33. RGBQUAD clr[2];
  34. } MYBMPINFO;
  35. #define CY_LINES 9
  36. static const BYTE HLineBits[CY_LINES * 4] = {
  37. 0x00, 0x00, 0x00, 0x00,
  38. 0x00, 0x00, 0x00, 0x00,
  39. 0x00, 0x00, 0x00, 0x00,
  40. 0x00, 0x00, 0x00, 0x00,
  41. 0x00, 0x00, 0x00, 0x00,
  42. 0x00, 0x00, 0x00, 0x00,
  43. 0x00, 0x00, 0x00, 0x00,
  44. 0x00, 0x00, 0x00, 0x00,
  45. 0x55, 0x55, 0x55, 0x55
  46. };
  47. static const BYTE TLineBits[CY_LINES * 4] = {
  48. 0x00, 0x80, 0x00, 0x00,
  49. 0x00, 0x00, 0x00, 0x00,
  50. 0x00, 0x80, 0x00, 0x00,
  51. 0x00, 0x00, 0x00, 0x00,
  52. 0x00, 0x80, 0x00, 0x00,
  53. 0x00, 0x00, 0x00, 0x00,
  54. 0x00, 0x80, 0x00, 0x00,
  55. 0x00, 0x00, 0x00, 0x00,
  56. 0x55, 0x55, 0x55, 0x55
  57. };
  58. static const BITMAPINFOHEADER bhLines = {
  59. sizeof(BITMAPINFOHEADER),
  60. CXIMAGE,
  61. CY_LINES,
  62. 1,
  63. 1,
  64. BI_RGB,
  65. ALIGN_DW(CXIMAGE, 24) * CY_LINES,
  66. 0,
  67. 0,
  68. 2,
  69. 2
  70. };
  71. VOID
  72. DeleteTVFonts(
  73. PTVWND pTVWnd
  74. )
  75. /*++
  76. Routine Description:
  77. Arguments:
  78. Return Value:
  79. Author:
  80. 11-Aug-1998 Tue 14:05:24 created -by- Daniel Chou (danielc)
  81. Revision History:
  82. --*/
  83. {
  84. HDC hDC;
  85. HFONT hFont;
  86. if ((hDC = pTVWnd->hDCTVWnd) &&
  87. (hFont = pTVWnd->hTVFont[0])) {
  88. SelectObject(hDC, (HANDLE)hFont);
  89. if (hFont = pTVWnd->hTVFont[1]) {
  90. DeleteObject(hFont);
  91. pTVWnd->hTVFont[1] = NULL;
  92. }
  93. if (hFont = pTVWnd->hTVFont[2]) {
  94. DeleteObject(hFont);
  95. pTVWnd->hTVFont[2] = NULL;
  96. }
  97. if (hFont = pTVWnd->hTVFont[3]) {
  98. DeleteObject(hFont);
  99. pTVWnd->hTVFont[3] = NULL;
  100. }
  101. }
  102. }
  103. BOOL
  104. CreateTVFonts(
  105. PTVWND pTVWnd,
  106. HFONT hFont
  107. )
  108. /*++
  109. Routine Description:
  110. Arguments:
  111. Return Value:
  112. Author:
  113. 11-Aug-1998 Tue 14:04:04 created -by- Daniel Chou (danielc)
  114. Revision History:
  115. --*/
  116. {
  117. HWND hWndTV;
  118. HDC hDC;
  119. if ((hWndTV = pTVWnd->hWndTV) &&
  120. (hDC = pTVWnd->hDCTVWnd) &&
  121. (hFont)) {
  122. RECT rc;
  123. SIZEL szlText;
  124. WCHAR Buf[16];
  125. LOGFONT lf;
  126. TEXTMETRIC tm;
  127. DeleteTVFonts(pTVWnd);
  128. //
  129. // hTVFont[0] = Regular current treeview font
  130. //
  131. pTVWnd->hTVFont[0] = hFont;
  132. GetObject(hFont, sizeof(lf), &lf);
  133. //
  134. // hTVFont[1] = BOLD Font
  135. //
  136. lf.lfWeight = FW_BOLD;
  137. if (!(pTVWnd->hTVFont[1] = CreateFontIndirect(&lf))) {
  138. CPSUIERR(("CreateFontIndirect(hTVFont[1] BOLD) failed"));
  139. pTVWnd->hTVFont[1] = hFont;
  140. }
  141. //
  142. // hTVFont[2] = Underline font
  143. //
  144. GetObject(hFont, sizeof(lf), &lf);
  145. lf.lfUnderline = 1;
  146. if (!(pTVWnd->hTVFont[2] = CreateFontIndirect(&lf))) {
  147. CPSUIERR(("CreateFontIndirect(hTVFont[2] UnderLine) failed"));
  148. pTVWnd->hTVFont[2] = hFont;
  149. }
  150. //
  151. // hTVFont[3] = Bold + Underline font
  152. //
  153. lf.lfWeight = FW_BOLD;
  154. if (!(pTVWnd->hTVFont[3] = CreateFontIndirect(&lf))) {
  155. CPSUIERR(("CreateFontIndirect(hTVFont[3]) failed"));
  156. pTVWnd->hTVFont[3] = hFont;
  157. }
  158. SelectObject(hDC, (HANDLE)pTVWnd->hTVFont[0]);
  159. Buf[0] = L' ';
  160. GetTextExtentPoint(hDC, Buf, 1, &szlText);
  161. pTVWnd->cxSpace = (WORD)szlText.cx;
  162. pTVWnd->cxSelAdd = (WORD)((szlText.cx + 1) / 2);
  163. szlText.cy = (LONG)wsprintf(Buf, L"-88888 ");
  164. GetTextExtentPoint(hDC, Buf, szlText.cy, &szlText);
  165. pTVWnd->cxMaxUDEdit = (WORD)szlText.cx;
  166. GetTextMetrics(hDC, &tm);
  167. pTVWnd->cxAveChar = (WORD)tm.tmAveCharWidth;
  168. GetClientRect(hWndTV, &rc);
  169. pTVWnd->cxExtAdd = (WORD)(tm.tmAveCharWidth + pTVWnd->cxSelAdd);
  170. CPSUIDBG(DBG_WM_SETFONT, ("CreateTVFonts: 0=%p, 1=%p, 2=%p, 3=%p, Ave=%ld, Space=%ld",
  171. pTVWnd->hTVFont[0], pTVWnd->hTVFont[1],
  172. pTVWnd->hTVFont[2], pTVWnd->hTVFont[3],
  173. pTVWnd->cxAveChar, pTVWnd->cxSpace));
  174. return(TRUE);
  175. } else {
  176. return(FALSE);
  177. }
  178. }
  179. UINT
  180. DrawTVItems(
  181. HDC hDC,
  182. HWND hWndTV,
  183. PTVWND pTVWnd,
  184. PRECT prcUpdate
  185. )
  186. /*++
  187. Routine Description:
  188. Arguments:
  189. Return Value:
  190. Author:
  191. 17-Oct-1995 Tue 14:54:47 created -by- Daniel Chou (danielc)
  192. Revision History:
  193. --*/
  194. {
  195. HFONT hTVFont;
  196. HFONT hBoldFont;
  197. HFONT hStdFont;
  198. HFONT hChgFont;
  199. HFONT hOldFont;
  200. HTREEITEM hCurItem;
  201. DWORD OldTextClr;
  202. DWORD OldBkClr;
  203. DWORD ClrFill;
  204. RECT rcUpdate;
  205. RECT rc;
  206. TV_ITEM tvi;
  207. POINTL ptlOff;
  208. MYBMPINFO bi;
  209. LONG yIconOff = -1;
  210. UINT cUpdate = 0;
  211. UINT cxIndent;
  212. UINT OldTAMode;
  213. UINT OldBkMode;
  214. INT yLinesOff;
  215. DWORD HLState;
  216. BOOL HasFocus;
  217. WCHAR Buf[MAX_RES_STR_CHARS * 2 + 10];
  218. rcUpdate = *prcUpdate;
  219. hTVFont = pTVWnd->hTVFont[0];
  220. hBoldFont = pTVWnd->hTVFont[1];
  221. hStdFont = pTVWnd->hTVFont[2];
  222. hChgFont = pTVWnd->hTVFont[3];
  223. hOldFont = SelectObject(hDC, hTVFont);
  224. cxIndent = TreeView_GetIndent(hWndTV);
  225. HasFocus = (BOOL)(GetFocus() == hWndTV);
  226. hCurItem = (pTVWnd->pCurTVItem) ? _OI_HITEM(pTVWnd->pCurTVItem) : NULL;
  227. OldTextClr = SetTextColor(hDC, RGB(0x00, 0x00, 0x00));
  228. OldBkClr = SetBkColor(hDC, RGB(0xFF, 0xFF, 0xFF));
  229. OldBkMode = (UINT)SetBkMode(hDC, TRANSPARENT);
  230. OldTAMode = (UINT)SetTextAlign(hDC, TA_UPDATECP);
  231. tvi.mask = TVIF_CHILDREN |
  232. TVIF_HANDLE |
  233. TVIF_STATE |
  234. TVIF_PARAM |
  235. TVIF_IMAGE |
  236. TVIF_SELECTEDIMAGE |
  237. TVIF_TEXT;
  238. tvi.hItem = TreeView_GetFirstVisible(hWndTV);
  239. HLState = (DWORD)((TreeView_GetDropHilight(hWndTV)) ? TVIS_DROPHILITED :
  240. TVIS_SELECTED);
  241. bi.bh = bhLines;
  242. ClrFill = GetSysColor(COLOR_WINDOW);
  243. bi.clr[0].rgbRed = GetRValue(ClrFill);
  244. bi.clr[0].rgbGreen = GetGValue(ClrFill);
  245. bi.clr[0].rgbBlue = GetBValue(ClrFill);
  246. ClrFill = GetSysColor(COLOR_3DSHADOW);
  247. bi.clr[1].rgbRed = GetRValue(ClrFill);
  248. bi.clr[1].rgbGreen = GetGValue(ClrFill);
  249. bi.clr[1].rgbBlue = GetBValue(ClrFill);
  250. while (tvi.hItem) {
  251. tvi.pszText = Buf;
  252. tvi.cchTextMax = sizeof(Buf);
  253. if ((TreeView_GetItemRect(hWndTV, tvi.hItem, &rc, TRUE)) &&
  254. (rc.left < rcUpdate.right) &&
  255. (rc.right > rcUpdate.left) &&
  256. (rc.top < rcUpdate.bottom) &&
  257. (rc.bottom > rcUpdate.top) &&
  258. (TreeView_GetItem(hWndTV, &tvi))) {
  259. TVLP tvlp;
  260. UINT cBuf;
  261. UINT cName;
  262. RECT rcFill;
  263. DWORD ClrBk;
  264. DWORD ClrName;
  265. SIZEL szlText;
  266. INT xIcon;
  267. INT yIcon;
  268. rcFill = rc;
  269. rcFill.left = rc.right;
  270. //
  271. // Draw the Text
  272. //
  273. tvlp = GET_TVLP(tvi.lParam);
  274. cBuf = (UINT)lstrlen(Buf);
  275. cName = (UINT)tvlp.cName;
  276. SelectObject(hDC, (tvi.state & TVIS_BOLD) ? hBoldFont : hTVFont);
  277. GetTextExtentPoint(hDC, Buf, cBuf, &szlText);
  278. if (yIconOff == -1) {
  279. yIconOff = rc.bottom - rc.top;
  280. //
  281. // Currently the common control group is drawing the text left aligned, starting at
  282. // rc.left + GetSystemMetrics(SM_CXEDGE). So we are following the methods
  283. // in common control to draw the text. Though "guessing" their implementation is
  284. // not the best way to do, it's the only solution we can take. Otherwise, we need
  285. // to implement all the drawing work for the treeview text, which could be even
  286. // worse.
  287. //
  288. ptlOff.x = GetSystemMetrics(SM_CXEDGE);
  289. ptlOff.y = (yIconOff - szlText.cy) / 2;
  290. yIconOff = (yIconOff - (LONG)pTVWnd->cyImage) / 2;
  291. yLinesOff = (INT)((pTVWnd->cyImage / 2) + pTVWnd->yLinesOff);
  292. CPSUIDBG(DBG_CYICON, ("cy=%ld, cyImage=%ld, yIconOff=%ld, yLinesOff=%ld, Indent=%ld",
  293. rc.bottom - rc.top, pTVWnd->cyImage, yIconOff,
  294. yLinesOff, cxIndent));
  295. }
  296. xIcon = (INT)(rc.left - cxIndent);
  297. yIcon = (INT)(rc.top + yIconOff);
  298. rc.left += ptlOff.x;
  299. rc.top += ptlOff.y;
  300. CPSUIDBG(DBG_DRAWITEM_RECT,
  301. ("tvlp=[%04lx] (%ld, %ld)-(%ld, %ld)=%ldx%ld (%ld/%ld) <%ws>",
  302. tvlp.Flags, rc.left, rc.top, rc.right, rc.bottom,
  303. rc.right - rc.left, rc.bottom - rc.top,
  304. cName, cBuf, Buf));
  305. if (tvi.state & HLState) {
  306. //
  307. // Current item is selected
  308. //
  309. if (HasFocus) {
  310. ClrBk = COLOR_HIGHLIGHT;
  311. ClrName = (tvlp.Flags & TVLPF_DISABLED) ?
  312. COLOR_3DFACE : COLOR_HIGHLIGHTTEXT;
  313. } else {
  314. //
  315. // The COLOR_3DFACE is a text background
  316. //
  317. ClrBk = COLOR_3DFACE;
  318. ClrName = (tvlp.Flags & TVLPF_DISABLED) ? COLOR_3DSHADOW :
  319. COLOR_BTNTEXT;
  320. }
  321. } else {
  322. //
  323. // The item is not currently selected
  324. //
  325. ClrBk = COLOR_WINDOW;
  326. ClrName = (tvlp.Flags & TVLPF_DISABLED) ? COLOR_3DSHADOW :
  327. COLOR_WINDOWTEXT;
  328. }
  329. ClrFill = ClrBk + 1;
  330. ClrBk = GetSysColor((UINT)ClrBk);
  331. ClrName = GetSysColor((UINT)ClrName);
  332. CPSUIDBG(DBG_SYS_COLOR,
  333. ("ClrBk=(%3d,%3d,%3d), ClrName=(%3d,%3d,%3d), State=%08lx/%08lx, Focus=%ld, %ws",
  334. GetRValue(ClrBk), GetGValue(ClrBk), GetBValue(ClrBk),
  335. GetRValue(ClrName), GetGValue(ClrName), GetBValue(ClrName),
  336. tvi.state, HLState, (HasFocus) ? 1 : 0, Buf));
  337. CPSUIDBG(DBG_DRAWITEM_COLOR,
  338. ("COLOR: Item=(%3d,%3d,%3d)",
  339. GetRValue(ClrName), GetGValue(ClrName), GetBValue(ClrName)));
  340. if (cBuf > cName) {
  341. GetTextExtentPoint(hDC, Buf, cName, &szlText);
  342. MoveToEx(hDC, rc.left += szlText.cx, rc.top, NULL);
  343. SelectObject(hDC, (tvlp.Flags & TVLPF_CHANGEONCE) ? hChgFont :
  344. hStdFont);
  345. GetTextExtentPoint(hDC, &Buf[cName], cBuf - cName, &szlText);
  346. if ((rcFill.right = rc.left + szlText.cx) > rcFill.left) {
  347. FillRect(hDC, &rcFill, (HBRUSH)LongToHandle(ClrFill));
  348. }
  349. SetTextColor(hDC, ClrName);
  350. SetBkColor(hDC, ClrBk);
  351. SetBkMode(hDC, OPAQUE);
  352. TextOut(hDC, rc.left, rc.top, &Buf[cName], cBuf - cName);
  353. }
  354. #if DO_IN_PLACE
  355. if (tvlp.Flags & TVLPF_EMPTYICON) {
  356. #if DBG
  357. Buf[cName] = L'\0';
  358. CPSUIDBG(DBG_CYICON, ("%40ws Lines='%hs'",
  359. Buf, ((tvi.cChildren) &&
  360. (tvi.state & TVIS_EXPANDED)) ? "T" : "-"));
  361. #endif
  362. SetDIBitsToDevice(hDC,
  363. xIcon,
  364. yIcon + yLinesOff,
  365. CXIMAGE,
  366. CY_LINES,
  367. 0,
  368. 0,
  369. 0,
  370. CY_LINES,
  371. ((tvi.cChildren) &&
  372. (tvi.state & TVIS_EXPANDED)) ? TLineBits :
  373. HLineBits,
  374. (BITMAPINFO *)&bi,
  375. DIB_RGB_COLORS);
  376. }
  377. #endif
  378. if (tvlp.Flags & TVLPF_ECBICON) {
  379. POPTITEM pItem;
  380. PEXTCHKBOX pECB;
  381. pItem = GetOptions(pTVWnd, tvi.lParam);
  382. pECB = pItem->pExtChkBox;
  383. ImageList_Draw(pTVWnd->himi,
  384. GetIcon16Idx(pTVWnd,
  385. _OI_HINST(pItem),
  386. GET_ICONID(pECB,
  387. ECBF_ICONID_AS_HICON),
  388. IDI_CPSUI_EMPTY),
  389. hDC,
  390. xIcon,
  391. yIcon,
  392. ILD_TRANSPARENT);
  393. }
  394. if (tvlp.Flags & TVLPF_STOP) {
  395. ImageList_Draw(pTVWnd->himi,
  396. GetIcon16Idx(pTVWnd, NULL, 0, IDI_CPSUI_STOP),
  397. hDC,
  398. xIcon,
  399. yIcon,
  400. ILD_TRANSPARENT);
  401. }
  402. if (tvlp.Flags & TVLPF_NO) {
  403. ImageList_Draw(pTVWnd->himi,
  404. GetIcon16Idx(pTVWnd, NULL, 0, IDI_CPSUI_NO),
  405. hDC,
  406. xIcon,
  407. yIcon,
  408. ILD_TRANSPARENT);
  409. }
  410. if (tvlp.Flags & TVLPF_WARNING) {
  411. ImageList_Draw(pTVWnd->himi,
  412. GetIcon16Idx(pTVWnd,
  413. NULL,
  414. 0,
  415. IDI_CPSUI_WARNING_OVERLAY),
  416. hDC,
  417. xIcon + X_WARNOVLY_ADD,
  418. yIcon + Y_WARNOVLY_ADD,
  419. ILD_TRANSPARENT);
  420. }
  421. ++cUpdate;
  422. }
  423. tvi.hItem = TreeView_GetNextVisible(hWndTV, tvi.hItem);
  424. }
  425. SelectObject(hDC, hOldFont);
  426. SetTextColor(hDC, OldTextClr);
  427. SetBkColor(hDC, OldBkClr);
  428. SetBkMode(hDC, OldBkMode);
  429. SetTextAlign(hDC, OldTAMode);
  430. return(cUpdate);
  431. }
  432. #if 0
  433. LRESULT
  434. CALLBACK
  435. FocusCtrlProc(
  436. HWND hWnd,
  437. UINT Msg,
  438. WPARAM wParam,
  439. LPARAM lParam
  440. )
  441. /*++
  442. Routine Description:
  443. Arguments:
  444. Return Value:
  445. Author:
  446. 12-Feb-1998 Thu 13:08:24 created -by- Daniel Chou (danielc)
  447. Revision History:
  448. --*/
  449. {
  450. PTVWND pTVWnd;
  451. HWND hDlg;
  452. HWND hWndTV;
  453. HWND hFocus;
  454. UINT chWndEdit;
  455. HWND hWndEdit[2];
  456. BOOL PrevCtrl;
  457. WNDPROC WndProc;
  458. if (WndProc = (WNDPROC)GetProp(hWnd, CPSUIPROP_WNDPROC)) {
  459. switch (Msg) {
  460. case WM_SETFOCUS:
  461. if (!wParam) {
  462. wParam = (WPARAM)GetFocus();
  463. }
  464. CPSUIDBG(DBG_EDIT_PROC,
  465. ("%ws WM_SETFOCUS, Old=%08lx (%ld)",
  466. (GetWindowLongPtr(hWnd, GWLP_ID) == IDD_PRE_EDIT) ?
  467. L"PREV" : L"NEXT",
  468. wParam, GetWindowLongPtr((HWND)wParam, GWLP_ID)));
  469. if ((wParam) &&
  470. (hDlg = GetParent(hWnd)) &&
  471. (pTVWnd = GET_PTVWND(hDlg)) &&
  472. (chWndEdit = (UINT)pTVWnd->chWndEdit) &&
  473. (hWndTV = pTVWnd->hWndTV)) {
  474. if (hWndEdit[0] = pTVWnd->hWndEdit[0]) {
  475. if ((!IsWindowVisible(hWndEdit[0])) ||
  476. (!IsWindowEnabled(hWndEdit[0]))) {
  477. hWndEdit[0] = NULL;
  478. }
  479. }
  480. if (hWndEdit[1] = pTVWnd->hWndEdit[1]) {
  481. if ((!IsWindowVisible(hWndEdit[1])) ||
  482. (!IsWindowEnabled(hWndEdit[1]))) {
  483. hWndEdit[1] = NULL;
  484. }
  485. }
  486. if (PrevCtrl = (BOOL)(GetWindowLongPtr(hWnd, GWLP_ID) ==
  487. IDD_PRE_EDIT)) {
  488. if ((HWND)wParam == hWndTV) {
  489. hFocus = NULL;
  490. } else if ((HWND)wParam == hWndEdit[1]) {
  491. hFocus = hWndEdit[0];
  492. } else {
  493. hFocus = hWndTV;
  494. }
  495. } else {
  496. if ((HWND)wParam == hWndTV) {
  497. hFocus = hWndEdit[0];
  498. } else if ((HWND)wParam == hWndEdit[0]) {
  499. hFocus = hWndEdit[1];
  500. } else if ((HWND)wParam == hWndEdit[1]) {
  501. hFocus = NULL;
  502. } else if (!(hFocus = hWndEdit[1])) {
  503. if (!(hFocus = hWndEdit[0])) {
  504. hFocus = hWndTV;
  505. }
  506. }
  507. }
  508. if (hFocus) {
  509. SetFocus(hFocus);
  510. } else {
  511. if (!(pTVWnd->Flags & TWF_TV_BY_PUSH)) {
  512. hDlg = GetParent(hDlg);
  513. }
  514. PostMessage(hDlg, WM_NEXTDLGCTL, PrevCtrl, 0);
  515. }
  516. CPSUIDBG(DBG_EDIT_PROC,
  517. (" %ws WM_SETFOCUS, Old=%08lx (%ld), hWndTV=%08lx, Set to %08lx (%ld)",
  518. (PrevCtrl) ? L"PREV" : L"NEXT",
  519. wParam, GetWindowLongPtr((HWND)wParam, GWLP_ID),
  520. hWndTV, hFocus, GetWindowLongPtr(hFocus, GWLP_ID)));
  521. return(TRUE);
  522. }
  523. break;
  524. case WM_DESTROY:
  525. SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LPARAM)WndProc);
  526. RemoveProp(hWnd, CPSUIPROP_WNDPROC);
  527. break;
  528. default:
  529. break;
  530. }
  531. return(CallWindowProc(WndProc, hWnd, Msg, wParam, lParam));
  532. }
  533. return(FALSE);
  534. }
  535. #endif
  536. LRESULT
  537. CALLBACK
  538. MyTVWndProc(
  539. HWND hWnd,
  540. UINT Msg,
  541. WPARAM wParam,
  542. LPARAM lParam
  543. )
  544. /*++
  545. Routine Description:
  546. Arguments:
  547. Return Value:
  548. Author:
  549. 17-Oct-1995 Tue 12:36:19 created -by- Daniel Chou (danielc)
  550. Revision History:
  551. --*/
  552. {
  553. HWND hDlg;
  554. HWND *phWndEdit;
  555. HWND hWndEdit;
  556. UINT chWndEdit;
  557. HDWP hDWP;
  558. PTVWND pTVWnd;
  559. WNDPROC TVWndProc;
  560. DWORD ClrBk;
  561. DWORD ClrText;
  562. if ((hDlg = GetParent(hWnd)) &&
  563. (pTVWnd = GET_PTVWND(hDlg)) &&
  564. (TVWndProc = pTVWnd->TVWndProc)) {
  565. HDC hDC;
  566. LRESULT lResult;
  567. RECT rcUpdate;
  568. switch (Msg) {
  569. #if DO_IN_PLACE
  570. case WM_VSCROLL:
  571. case WM_HSCROLL:
  572. CPSUIDBG(DBG_SCROLL, ("MyTVWndProc: WM_%cSCROLL, hScroll=%08lx (%08lx:%08lx:%08lx)=%ld, Pos=%ld, Code=%ld",
  573. (Msg == WM_VSCROLL) ? 'V' : 'H',
  574. lParam, pTVWnd->hWndEdit[0],
  575. pTVWnd->hWndEdit[1], pTVWnd->hWndEdit[2],
  576. pTVWnd->chWndEdit, HIWORD(wParam), LOWORD(wParam)));
  577. chWndEdit = pTVWnd->chWndEdit;
  578. phWndEdit = pTVWnd->hWndEdit;
  579. if (lParam) {
  580. while (chWndEdit--) {
  581. if ((HWND)lParam == *phWndEdit++) {
  582. PostMessage(hDlg, WM_COMMAND, wParam, lParam);
  583. break;
  584. }
  585. }
  586. return(FALSE);
  587. }
  588. break;
  589. #endif
  590. case WM_COMMAND:
  591. CPSUIDBG(DBG_COMMAND, ("MyTVWndProc: WM_COMMAND"));
  592. PostMessage(hDlg, WM_COMMAND, wParam, lParam);
  593. return(FALSE);
  594. break;
  595. case WM_CTLCOLORBTN:
  596. case WM_CTLCOLORSTATIC:
  597. switch (GetWindowLongPtr((HWND)lParam, GWLP_ID)) {
  598. case IDD_TV_CHKBOX:
  599. case IDD_TV_EXTCHKBOX:
  600. if (GetFocus() == (HWND)lParam) {
  601. CPSUIDBG(DBG_CTRLCOLOR, ("Get WM_CTLCOLOR, HAS FOCUS"));
  602. ClrText = (DWORD)COLOR_HIGHLIGHTTEXT;
  603. ClrBk = (DWORD)COLOR_HIGHLIGHT;
  604. } else {
  605. CPSUIDBG(DBG_CTRLCOLOR, ("Get WM_CTLCOLOR, NO FOCUS"));
  606. ClrText = COLOR_WINDOWTEXT;
  607. ClrBk = COLOR_WINDOW;
  608. }
  609. SetTextColor((HDC)wParam, GetSysColor(ClrText));
  610. SetBkMode((HDC)wParam, TRANSPARENT);
  611. return((LRESULT)GetSysColorBrush(ClrBk));
  612. break;
  613. }
  614. break;
  615. case WM_HELP:
  616. case WM_CONTEXTMENU:
  617. PostMessage(hDlg, Msg, wParam, lParam);
  618. break;
  619. case WM_SETFONT:
  620. CPSUIDBG(DBG_WM_SETFONT, ("MyTVWndProc: WM_SETFONT, IGNORE"));
  621. return(TRUE);
  622. break;
  623. case WM_KEYDOWN:
  624. switch (wParam) {
  625. case VK_RIGHT:
  626. if ((pTVWnd->chWndEdit) &&
  627. (pTVWnd->hWndEdit[0])) {
  628. SetFocus(pTVWnd->hWndEdit[0]);
  629. return(0);
  630. }
  631. }
  632. case WM_KEYUP:
  633. CPSUIDBG(DBG_KEYS, ("MyTVWndProc: WM_KEY%hs: VK=%ld",
  634. (Msg == WM_KEYUP) ? "UP" : "DOWN", wParam));
  635. break;
  636. case WM_PAINT:
  637. #if DO_IN_PLACE
  638. if ((pTVWnd->pCurTVItem) &&
  639. (chWndEdit = (UINT)pTVWnd->chWndEdit) &&
  640. (TreeView_GetItemRect(hWnd,
  641. _OI_HITEM(pTVWnd->pCurTVItem),
  642. &rcUpdate,
  643. TRUE)) &&
  644. ((rcUpdate.left != pTVWnd->ptCur.x) ||
  645. (rcUpdate.top != pTVWnd->ptCur.y)) &&
  646. (hDWP = BeginDeferWindowPos(chWndEdit))) {
  647. POINTL pt;
  648. phWndEdit = pTVWnd->hWndEdit;
  649. CPSUIDBG(DBG_ORIGIN, ("CurTVItem=Moved (%08lx:%08lx:%08lx)From (%4ld, %4ld) ---> (%4ld, %4ld)",
  650. pTVWnd->hWndEdit[0],
  651. pTVWnd->hWndEdit[1], pTVWnd->hWndEdit[2],
  652. pTVWnd->ptCur.x, pTVWnd->ptCur.y,
  653. rcUpdate.left, rcUpdate.top));
  654. pt.x = rcUpdate.left - pTVWnd->ptCur.x;
  655. pt.y = rcUpdate.top - pTVWnd->ptCur.y;
  656. pTVWnd->ptCur.x = rcUpdate.left;
  657. pTVWnd->ptCur.y = rcUpdate.top;
  658. while ((chWndEdit--) && (hDWP)) {
  659. if (hWndEdit = *phWndEdit++) {
  660. GetWindowRect(hWndEdit, &rcUpdate);
  661. rcUpdate.left += pt.x;
  662. rcUpdate.top += pt.y;
  663. rcUpdate.right += pt.x;
  664. rcUpdate.bottom += pt.y;
  665. MapWindowPoints(NULL, hWnd, (LPPOINT)&rcUpdate, 2);
  666. hDWP = DeferWindowPos(hDWP, hWndEdit, NULL,
  667. rcUpdate.left, rcUpdate.top, 0, 0,
  668. SWP_DRAWFRAME |
  669. SWP_FRAMECHANGED |
  670. SWP_NOSIZE |
  671. SWP_NOZORDER);
  672. }
  673. }
  674. if (hDWP) {
  675. EndDeferWindowPos(hDWP);
  676. }
  677. }
  678. #endif
  679. GetUpdateRect(hWnd, &rcUpdate, FALSE);
  680. lResult = CallWindowProc(TVWndProc, hWnd, Msg, wParam, lParam);
  681. CPSUIDBG(DBG_WM_PAINT,
  682. ("\n!! Update Rect = (%ld, %ld)-(%ld, %ld) = %ld x %ld\n\n",
  683. rcUpdate.left, rcUpdate.top,
  684. rcUpdate.right, rcUpdate.bottom,
  685. rcUpdate.right - rcUpdate.left,
  686. rcUpdate.bottom - rcUpdate.top));
  687. if (hDC = GetDC(hWnd)) {
  688. IntersectClipRect(hDC,
  689. rcUpdate.left,
  690. rcUpdate.top,
  691. rcUpdate.right,
  692. rcUpdate.bottom);
  693. DrawTVItems(hDC, hWnd, pTVWnd, &rcUpdate);
  694. ReleaseDC(hWnd, hDC);
  695. } else {
  696. CPSUIERR(("MyTVWndProc: GetDC(%08lx) FAILED", hWnd));
  697. }
  698. return(lResult);
  699. default:
  700. break;
  701. }
  702. return(CallWindowProc(TVWndProc, hWnd, Msg, wParam, lParam));
  703. } else {
  704. CPSUIERR(("MyTVWndProc: hDlg=%08lx, pTVWnd=%08lx, TVWndProc=%08lx",
  705. hDlg, pTVWnd, TVWndProc));
  706. return(TRUE);
  707. }
  708. }