Leaked source code of windows server 2003
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.

703 lines
19 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Copyright (c) Microsoft Corporation 1993-1994
  4. //
  5. // File: dobj.c
  6. //
  7. // This file contains support routines for the reconciliation-action
  8. // control class code
  9. //
  10. //
  11. // History:
  12. // 09-13-93 ScottH Extracted from recact.c
  13. //
  14. //---------------------------------------------------------------------------
  15. ///////////////////////////////////////////////////// INCLUDES
  16. #include "pch.h"
  17. #include "extra.h"
  18. #include "resource.h"
  19. #include "recact.h"
  20. #include "dobj.h"
  21. ///////////////////////////////////////////////////// CONTROLLING DEFINES
  22. ///////////////////////////////////////////////////// DEFINES
  23. #define DT_CALCWRAP (DT_CALCRECT | DT_CENTER | DT_WORDBREAK | DT_NOPREFIX)
  24. #define DT_CALC (DT_CALCRECT | DT_CENTER | DT_SINGLELINE | DT_NOPREFIX)
  25. /*----------------------------------------------------------
  26. Purpose: Formats the given path to the correct location format
  27. Returns: --
  28. Cond: --
  29. */
  30. void PRIVATE FormatLocationPath(
  31. LPCSTR pszPath,
  32. LPSTR pszBuffer) // Must be MAX_PATH
  33. {
  34. UINT ids;
  35. // tHACK char szBrfDir[MAX_PATH];
  36. LPCSTR psz;
  37. LPSTR pszMsg;
  38. // The format for the directory location is:
  39. //
  40. // Inside briefcase: "In Briefcase"
  41. // Below briefcase: "In Briefcase\FolderName"
  42. // Outside briefcase: "In FullPath"
  43. //
  44. // We assume that paths outside the current briefcase
  45. // never consist of a briefcase name of another.
  46. //
  47. #if 0
  48. // tHACK
  49. if (PathGetLocality(pszPath, szBrfDir) != PL_FALSE)
  50. {
  51. // Inside the briefcase
  52. psz = &pszPath[lstrlen(szBrfDir)];
  53. ids = IDS_InBriefcase;
  54. }
  55. else
  56. #endif
  57. {
  58. // Outside the briefcase
  59. psz = pszPath;
  60. ids = IDS_InLocation;
  61. }
  62. if (ConstructMessage(&pszMsg, vhinstCur, MAKEINTRESOURCE(ids), psz))
  63. {
  64. lstrcpy(pszBuffer, pszMsg);
  65. GFree(pszMsg);
  66. }
  67. else
  68. *pszBuffer = 0;
  69. }
  70. /*----------------------------------------------------------
  71. Purpose: Return the string describing the status of this sideitem
  72. Returns: ptr to status string
  73. Cond: --
  74. */
  75. LPSTR PRIVATE SideItem_GetStatus(
  76. LPSIDEITEM this,
  77. LPSTR pszBuf,
  78. UINT cchBuf)
  79. {
  80. switch (this->uState)
  81. {
  82. case SI_CHANGED:
  83. return SzFromIDS(IDS_STATE_Changed, pszBuf, cchBuf);
  84. case SI_UNCHANGED:
  85. return SzFromIDS(IDS_STATE_Unchanged, pszBuf, cchBuf);
  86. case SI_NEW:
  87. return SzFromIDS(IDS_STATE_NewFile, pszBuf, cchBuf);
  88. case SI_UNAVAILABLE:
  89. return SzFromIDS(IDS_STATE_Unavailable, pszBuf, cchBuf);
  90. default:
  91. return NULL;
  92. }
  93. }
  94. /*----------------------------------------------------------
  95. Purpose: Displays the 3-liner: location, status, and timestamp
  96. Returns: --
  97. Cond: --
  98. */
  99. void PRIVATE SideItem_Display(
  100. LPSIDEITEM this,
  101. HDC hdc,
  102. LPRECT prc,
  103. int cxEllipses,
  104. int cyText)
  105. {
  106. char sz[MAX_PATH];
  107. char szBuf[MAXBUFLEN];
  108. LPSTR psz;
  109. RECT rc = *prc;
  110. // Directory location.
  111. FormatLocationPath(this->pszDir, sz);
  112. // strcpy(sz, "a long path tHACKed");
  113. MyDrawText(hdc, sz, &rc, MDT_LEFT | MDT_TRANSPARENT | MDT_ELLIPSES,
  114. cyText, cxEllipses, CLR_DEFAULT, CLR_DEFAULT);
  115. // Status string
  116. psz = SideItem_GetStatus(this, szBuf, sizeof(szBuf));
  117. if (psz)
  118. {
  119. // Only bother with these two lines if the file actually
  120. // exists.
  121. rc.top += cyText;
  122. MyDrawText(hdc, psz, &rc, MDT_LEFT | MDT_TRANSPARENT,
  123. cyText, cxEllipses, CLR_DEFAULT, CLR_DEFAULT);
  124. // Date stamp. Skip this if this is a folder or unavailable.
  125. //
  126. if (this->fs.fscond != FS_COND_UNAVAILABLE)
  127. {
  128. FileTimeToDateTimeString(&this->fs.ftMod, sz, sizeof(sz));
  129. rc.top += cyText;
  130. MyDrawText(hdc, sz, &rc, MDT_LEFT | MDT_TRANSPARENT,
  131. cyText, cxEllipses, CLR_DEFAULT, CLR_DEFAULT);
  132. }
  133. }
  134. }
  135. /*----------------------------------------------------------
  136. Purpose: Return the bounding rect for a labelled image.
  137. Returns: --
  138. Cond: --
  139. */
  140. void PUBLIC ComputeImageRects(
  141. LPCSTR psz,
  142. HDC hdc,
  143. LPPOINT pptInOut,
  144. LPRECT prcWhole, // May be NULL
  145. LPRECT prcLabel, // May be NULL
  146. int cxIcon,
  147. int cyIcon,
  148. int cxIconSpacing,
  149. int cyText)
  150. {
  151. RECT rc;
  152. int yLabel;
  153. int cxLabel;
  154. int cyLabel;
  155. int cchLabel;
  156. POINT pt;
  157. ASSERT(psz);
  158. // Set our minimum rect size for icon spacing
  159. if (cxIconSpacing < cxIcon)
  160. cxIconSpacing = cxIcon + g_cxIconMargin * 2;
  161. // Upon entry, *pptInOut is expected to be the upper left corner of the
  162. // icon-spacing rect. This function will set it to the upper left
  163. // corner of the icon itself.
  164. pt.x = pptInOut->x + (cxIconSpacing - cxIcon) / 2;
  165. pt.y = pptInOut->y + g_cyIconMargin;
  166. // Determine rectangle of label with wrap
  167. rc.left = rc.top = rc.bottom = 0;
  168. rc.right = cxIconSpacing - g_cxLabelMargin * 2;
  169. cchLabel = lstrlen(psz);
  170. if (0 < cchLabel)
  171. {
  172. DrawText(hdc, psz, cchLabel, &rc, DT_CALCWRAP);
  173. }
  174. else
  175. {
  176. rc.bottom = rc.top + cyText;
  177. }
  178. yLabel = pptInOut->y + g_cyIconMargin + cyIcon + g_cyLabelSpace;
  179. cxLabel = (rc.right - rc.left) + 2 * g_cxLabelMargin;
  180. cyLabel = rc.bottom - rc.top;
  181. if (prcWhole)
  182. {
  183. prcWhole->left = pptInOut->x;
  184. prcWhole->right = prcWhole->left + cxIconSpacing;
  185. prcWhole->top = pptInOut->y;
  186. prcWhole->bottom = max(prcWhole->top + g_cyIconSpacing,
  187. yLabel + cyLabel + g_cyLabelSpace);
  188. }
  189. if (prcLabel)
  190. {
  191. prcLabel->left = pptInOut->x + ((cxIconSpacing - cxLabel) / 2);
  192. prcLabel->right = prcLabel->left + cxLabel;
  193. prcLabel->top = yLabel;
  194. prcLabel->bottom = prcLabel->top + cyLabel;
  195. }
  196. *pptInOut = pt;
  197. }
  198. /*----------------------------------------------------------
  199. Purpose: Set the colors for the given HDC. The previous colors
  200. are stored in pcrText and pcrBk.
  201. Returns: uStyle to pass to ImageList_Draw (specific to images only)
  202. Cond: --
  203. */
  204. UINT PRIVATE Dobj_SetColors(
  205. LPDOBJ this,
  206. HDC hdc,
  207. UINT uState,
  208. COLORREF clrBkgnd)
  209. {
  210. COLORREF clrText;
  211. COLORREF clrBk;
  212. UINT uStyleILD = ILD_NORMAL;
  213. BOOL bSetColors = FALSE;
  214. BOOL bDiffer;
  215. BOOL bMenu;
  216. BOOL bDisabled;
  217. // Determine selection colors
  218. //
  219. bDiffer = IsFlagSet(this->uFlags, DOF_DIFFER);
  220. bMenu = IsFlagSet(this->uFlags, DOF_MENU);
  221. bDisabled = IsFlagSet(this->uFlags, DOF_DISABLED);
  222. switch (this->uKind)
  223. {
  224. case DOK_STRING:
  225. case DOK_IDS:
  226. case DOK_SIDEITEM:
  227. bSetColors = TRUE;
  228. break;
  229. }
  230. // Set the text and background colors
  231. //
  232. if (bSetColors)
  233. {
  234. if (bDiffer)
  235. {
  236. // Make the colors differ based on selection state
  237. //
  238. if (bMenu)
  239. {
  240. if (bDisabled)
  241. clrText = GetSysColor(COLOR_GRAYTEXT);
  242. else
  243. clrText = GetSysColor(ColorMenuText(uState));
  244. clrBk = GetSysColor(ColorMenuBk(uState));
  245. }
  246. else
  247. {
  248. if (bDisabled)
  249. clrText = GetSysColor(COLOR_GRAYTEXT);
  250. else
  251. clrText = GetSysColor(ColorText(uState));
  252. clrBk = GetSysColor(ColorBk(uState));
  253. }
  254. }
  255. else
  256. {
  257. // Transparent colors
  258. //
  259. if (bMenu)
  260. {
  261. if (bDisabled)
  262. clrText = GetSysColor(COLOR_GRAYTEXT);
  263. else
  264. clrText = GetSysColor(COLOR_MENUTEXT);
  265. clrBk = GetSysColor(COLOR_MENU);
  266. }
  267. else
  268. {
  269. if (bDisabled)
  270. clrText = GetSysColor(COLOR_GRAYTEXT);
  271. else
  272. clrText = GetSysColor(COLOR_WINDOWTEXT);
  273. clrBk = clrBkgnd;
  274. }
  275. }
  276. SetTextColor(hdc, clrText);
  277. SetBkColor(hdc, clrBk);
  278. }
  279. return uStyleILD;
  280. }
  281. /*----------------------------------------------------------
  282. Purpose: Draw the menu image and text
  283. Returns: --
  284. Cond: --
  285. */
  286. void PRIVATE Dobj_DrawMenuImage(
  287. LPDOBJ this,
  288. HDC hdc,
  289. UINT uState,
  290. int cyText,
  291. COLORREF clrBkgnd)
  292. {
  293. UINT uStyleILD;
  294. UINT uFlagsETO;
  295. LPCSTR psz;
  296. char szIDS[MAXBUFLEN];
  297. int cch;
  298. HIMAGELIST himl = this->himl;
  299. COLORREF clrText;
  300. COLORREF clrBk;
  301. int x;
  302. int y;
  303. int cxIcon;
  304. RECT rc;
  305. if (IsFlagSet(this->uFlags, DOF_USEIDS))
  306. psz = SzFromIDS((UINT)this->lpvObject, szIDS, sizeof(szIDS));
  307. else
  308. psz = (LPCSTR)this->lpvObject;
  309. ASSERT(psz);
  310. cch = lstrlen(psz);
  311. ImageList_GetImageRect(himl, this->iImage, &rc);
  312. cxIcon = rc.right-rc.left;
  313. // Draw the text first
  314. uFlagsETO = ETO_OPAQUE | ETO_CLIPPED;
  315. x = this->rcLabel.left + g_cxMargin + cxIcon + g_cxMargin;
  316. y = this->rcLabel.top + ((this->rcLabel.bottom - this->rcLabel.top - cyText) / 2);
  317. if (IsFlagSet(this->uFlags, DOF_DISABLED) &&
  318. IsFlagClear(uState, ODS_SELECTED))
  319. {
  320. int imodeOld;
  321. COLORREF crOld;
  322. // For disabled menu strings (not selected), we draw the string
  323. // twice. The first is offset down and to the right and drawn
  324. // in the 3D hilight color. The second time is the disabled text
  325. // color in the normal offset.
  326. //
  327. crOld = SetTextColor(hdc, GetSysColor(COLOR_3DHILIGHT));
  328. imodeOld = SetBkMode(hdc, TRANSPARENT);
  329. ExtTextOut(hdc, x+1, y+1, uFlagsETO, &this->rcLabel, psz, cch, NULL);
  330. // Reset back to original color. Also, turn off the opaqueness.
  331. //
  332. SetTextColor(hdc, crOld);
  333. uFlagsETO ^= ETO_OPAQUE;
  334. }
  335. if (IsFlagSet(this->uFlags, DOF_DISABLED))
  336. clrText = GetSysColor(COLOR_GRAYTEXT);
  337. else
  338. clrText = GetSysColor(ColorMenuText(uState));
  339. clrBk = GetSysColor(ColorMenuBk(uState));
  340. SetTextColor(hdc, clrText);
  341. SetBkColor(hdc, clrBk);
  342. ExtTextOut(hdc, x, y, uFlagsETO, &this->rcLabel, psz, cch, NULL);
  343. // Draw the image
  344. if (GetBkColor(hdc) == ImageList_GetBkColor(himl))
  345. uStyleILD = ILD_NORMAL; // Paint quicker
  346. else
  347. uStyleILD = ILD_TRANSPARENT;
  348. ImageList_Draw(himl, this->iImage, hdc, this->x, this->y, uStyleILD);
  349. }
  350. /*----------------------------------------------------------
  351. Purpose: Draw the icon image and label
  352. Returns: --
  353. Cond: --
  354. */
  355. void PRIVATE Dobj_DrawIconImage(
  356. LPDOBJ this,
  357. HDC hdc,
  358. UINT uState,
  359. int cxEllipses,
  360. int cyText,
  361. COLORREF clrBkgnd)
  362. {
  363. UINT uStyleILD;
  364. UINT uFlagsMDT;
  365. LPCSTR psz;
  366. char szIDS[MAXBUFLEN];
  367. if (IsFlagSet(this->uFlags, DOF_USEIDS))
  368. psz = SzFromIDS((UINT)this->lpvObject, szIDS, sizeof(szIDS));
  369. else
  370. psz = (LPCSTR)this->lpvObject;
  371. ASSERT(psz);
  372. // Draw the image
  373. //
  374. if (IsFlagClear(this->uFlags, DOF_IGNORESEL))
  375. {
  376. uStyleILD = GetImageDrawStyle(uState);
  377. uFlagsMDT = IsFlagSet(uState, ODS_SELECTED) ? MDT_SELECTED : MDT_DESELECTED;
  378. }
  379. else
  380. {
  381. uStyleILD = ILD_NORMAL;
  382. uFlagsMDT = MDT_DESELECTED;
  383. ClearFlag(uState, ODS_FOCUS);
  384. }
  385. ImageList_Draw(this->himl, this->iImage, hdc, this->x, this->y, uStyleILD);
  386. // Draw the file label. Wrap if it is long.
  387. if (this->rcLabel.bottom - this->rcLabel.top > cyText)
  388. uFlagsMDT |= MDT_DRAWTEXT;
  389. MyDrawText(hdc, psz, &this->rcLabel, MDT_CENTER | uFlagsMDT, cyText,
  390. cxEllipses, CLR_DEFAULT, clrBkgnd);
  391. // (uState may have been changed above)
  392. if (IsFlagSet(uState, ODS_FOCUS))
  393. DrawFocusRect(hdc, &this->rcLabel);
  394. }
  395. #ifdef UNUSED
  396. /*----------------------------------------------------------
  397. Purpose: Draw a picture
  398. Returns: --
  399. Cond: --
  400. */
  401. void PRIVATE Dobj_DrawPicture(
  402. LPDOBJ this,
  403. HDC hdc,
  404. UINT uState,
  405. UINT uDrawStyle)
  406. {
  407. HIMAGELIST himl;
  408. HDC hdcMem;
  409. HBITMAP hbmp;
  410. BITMAP bm;
  411. RECT rc;
  412. int iImage;
  413. int cx;
  414. int x;
  415. int y;
  416. switch (this->uKind)
  417. {
  418. case DOK_BITMAP:
  419. hbmp = (HBITMAP)(DWORD)this->lpvObject;
  420. GetObject(hbmp, sizeof(BITMAP), &bm);
  421. cx = this->rcSrc.right - this->rcSrc.left;
  422. break;
  423. case DOK_ICON:
  424. cx = 32;
  425. break;
  426. }
  427. // We only align horizontally
  428. //
  429. y = this->y;
  430. if (IsFlagSet(this->uFlags, DOF_CENTER))
  431. x = this->x - (cx / 2);
  432. else if (IsFlagSet(this->uFlags, DOF_RIGHT))
  433. x = this->x - cx;
  434. else
  435. x = this->x;
  436. // Draw the object
  437. //
  438. switch (this->uKind)
  439. {
  440. case DOK_ICON:
  441. // BUGBUG: we don't handle DOF_DIFFER for icons
  442. DrawIcon(hdc, x, y, (HICON)(DWORD)this->lpvObject);
  443. break;
  444. case DOK_BITMAP:
  445. hdcMem = CreateCompatibleDC(hdc);
  446. if (hdcMem)
  447. {
  448. SIZE size;
  449. SelectBitmap(hdcMem, hbmp);
  450. size.cx = this->rcSrc.right - this->rcSrc.left;
  451. size.cy = this->rcSrc.bottom - this->rcSrc.top;
  452. if (IsFlagSet(this->uFlags, DOF_MENU) &&
  453. IsFlagSet(this->uFlags, DOF_DISABLED) &&
  454. IsFlagClear(uState, ODS_SELECTED))
  455. {
  456. COLORREF crOld;
  457. // For disabled menu strings (not selected), we draw the bitmap
  458. // twice. The first is offset down and to the right and drawn
  459. // in the 3D hilight color. The second time is the disabled
  460. // color in the normal offset.
  461. //
  462. crOld = SetTextColor(hdc, GetSysColor(COLOR_3DHILIGHT));
  463. BitBlt(hdc, x+1, y+1, size.cx, size.cy, hdcMem, this->rcSrc.left,
  464. this->rcSrc.top, SRCCOPY);
  465. // Reset back to original color. Also, turn off the opaqueness.
  466. //
  467. SetTextColor(hdc, crOld);
  468. }
  469. BitBlt(hdc, x, y, size.cx, size.cy, hdcMem, this->rcSrc.left, this->rcSrc.top, SRCCOPY);
  470. DeleteDC(hdcMem);
  471. }
  472. break;
  473. }
  474. }
  475. #endif
  476. /*----------------------------------------------------------
  477. Purpose: Draw a string
  478. Returns: --
  479. Cond: --
  480. */
  481. void PRIVATE Dobj_DrawString(
  482. LPDOBJ this,
  483. HDC hdc,
  484. UINT uState,
  485. int cxEllipses,
  486. int cyText)
  487. {
  488. UINT ufAlignSav;
  489. ASSERT(this);
  490. // Prep the alignment
  491. //
  492. if (this->uFlags & (DOF_LEFT | DOF_CENTER | DOF_RIGHT))
  493. {
  494. UINT ufMode;
  495. ufMode = IsFlagSet(this->uFlags, DOF_CENTER) ? TA_CENTER :
  496. (IsFlagSet(this->uFlags, DOF_RIGHT) ? TA_RIGHT : TA_LEFT);
  497. ufAlignSav = SetTextAlign(hdc, ufMode);
  498. }
  499. // Draw the string
  500. //
  501. switch (this->uKind)
  502. {
  503. case DOK_IDS:
  504. case DOK_STRING:
  505. {
  506. char szBuf[MAXBUFLEN];
  507. LPSTR lpsz;
  508. UINT uflag = ETO_OPAQUE;
  509. if (this->uKind == DOK_IDS)
  510. lpsz = SzFromIDS((UINT)(DWORD)this->lpvObject, szBuf, sizeof(szBuf));
  511. else
  512. lpsz = (LPSTR)this->lpvObject;
  513. if (!IsRectEmpty(&this->rcClip))
  514. uflag |= ETO_CLIPPED;
  515. if (IsFlagSet(this->uFlags, DOF_MENU) &&
  516. IsFlagSet(this->uFlags, DOF_DISABLED) &&
  517. IsFlagClear(uState, ODS_SELECTED))
  518. {
  519. int imodeOld;
  520. COLORREF crOld;
  521. // For disabled menu strings (not selected), we draw the string
  522. // twice. The first is offset down and to the right and drawn
  523. // in the 3D hilight color. The second time is the disabled text
  524. // color in the normal offset.
  525. //
  526. crOld = SetTextColor(hdc, GetSysColor(COLOR_3DHILIGHT));
  527. imodeOld = SetBkMode(hdc, TRANSPARENT);
  528. ExtTextOut(hdc, this->x+1, this->y+1, uflag, &this->rcClip, lpsz,
  529. lstrlen(lpsz), NULL);
  530. // Reset back to original color. Also, turn off the opaqueness.
  531. //
  532. SetTextColor(hdc, crOld);
  533. uflag ^= ETO_OPAQUE;
  534. }
  535. ExtTextOut(hdc, this->x, this->y, uflag, &this->rcClip, lpsz,
  536. lstrlen(lpsz), NULL);
  537. }
  538. break;
  539. case DOK_SIDEITEM:
  540. SideItem_Display((LPSIDEITEM)this->lpvObject, hdc, &this->rcClip,
  541. cxEllipses, cyText);
  542. break;
  543. }
  544. // Clean up
  545. //
  546. if (this->uFlags & (DOF_LEFT | DOF_CENTER | DOF_RIGHT))
  547. {
  548. SetTextAlign(hdc, ufAlignSav);
  549. }
  550. }
  551. /*----------------------------------------------------------
  552. Purpose: Draw an object
  553. Returns: --
  554. Cond: --
  555. */
  556. void PUBLIC Dobj_Draw(
  557. HDC hdc,
  558. LPDOBJ rgdobj,
  559. int cItems,
  560. UINT uState, // ODS_*
  561. int cxEllipses,
  562. int cyText,
  563. COLORREF clrBkgnd)
  564. {
  565. UINT uDrawStyle;
  566. LPDOBJ pdobj;
  567. int i;
  568. ASSERT(rgdobj);
  569. for (i = 0, pdobj = rgdobj; i < cItems; i++, pdobj++)
  570. {
  571. if (IsFlagSet(pdobj->uFlags, DOF_NODRAW))
  572. continue ;
  573. uDrawStyle = Dobj_SetColors(pdobj, hdc, uState, clrBkgnd);
  574. // Draw the object
  575. //
  576. switch (pdobj->uKind)
  577. {
  578. case DOK_IMAGE:
  579. if (IsFlagSet(pdobj->uFlags, DOF_MENU))
  580. Dobj_DrawMenuImage(pdobj, hdc, uState, cyText, clrBkgnd);
  581. else
  582. Dobj_DrawIconImage(pdobj, hdc, uState, cxEllipses, cyText, clrBkgnd);
  583. break;
  584. #ifdef UNUSED
  585. case DOK_BITMAP:
  586. case DOK_ICON:
  587. Dobj_DrawPicture(pdobj, hdc, uState, uDrawStyle);
  588. break;
  589. #endif
  590. case DOK_IDS:
  591. case DOK_STRING:
  592. case DOK_SIDEITEM:
  593. Dobj_DrawString(pdobj, hdc, uState, cxEllipses, cyText);
  594. break;
  595. }
  596. }
  597. }