XTPReportPaintManager.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:85k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // XTPReportPaintManager.cpp : implementation of the CXTPReportPaintManager class.
  2. //
  3. // This file is a part of the XTREME REPORTCONTROL MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. #include "Resource.h"
  22. #include "Common/XTPResourceManager.h"
  23. #include "Common/XTPDrawHelpers.h"
  24. #include "Common/XTPImageManager.h"
  25. #include "Common/XTPVC80Helpers.h"
  26. #include "Common/XTPVC50Helpers.h"
  27. #include "Common/XTPOffice2007Image.h"
  28. #include "Common/XTPMarkupRender.h"
  29. #include "XTPReportPaintManager.h"
  30. #include "XTPReportRow.h"
  31. #include "XTPReportGroupRow.h"
  32. #include "XTPReportColumn.h"
  33. #include "XTPReportHeader.h"
  34. #include "XTPReportControl.h"
  35. #include "XTPReportInplaceControls.h"
  36. #include "XTPReportRecordItemControls.h"
  37. #include "XTPReportColumns.h"
  38. #include "XTPReportRecord.h"
  39. #include "XTPReportHyperlink.h"
  40. #ifdef _DEBUG
  41. #undef THIS_FILE
  42. static char THIS_FILE[] = __FILE__;
  43. #define new DEBUG_NEW
  44. #endif
  45. #define XTP_HLINK_SPACE_X   ((TCHAR)1)
  46. AFX_INLINE int GetTextExtentX(CDC* pDC, const CString& strString)
  47. {
  48. CString str(strString);
  49. REPLACE_S(str, XTP_HLINK_SPACE_X, _T(' '));
  50. int nExt1 = pDC->GetTextExtent(str).cx;
  51. if (pDC->IsPrinting())
  52. {
  53. int nExt2 = pDC->GetOutputTextExtent(str).cx;
  54. return max(nExt1, nExt2);
  55. }
  56. return nExt1;
  57. }
  58. AFX_INLINE int GetTextExtentX(CDC* pDC, LPTSTR pszString, int nCount)
  59. {
  60. CString str(pszString, nCount);
  61. REPLACE_S(str, XTP_HLINK_SPACE_X, _T(' '));
  62. int nExt1 = pDC->GetTextExtent(str).cx;
  63. if (pDC->IsPrinting())
  64. {
  65. int nExt2 = pDC->GetOutputTextExtent(str).cx;
  66. return max(nExt1, nExt2);
  67. }
  68. return nExt1;
  69. }
  70. /////////////////////////////////////////////////////////////////////////////
  71. // class CXTPFormulaMulDivC
  72. CXTPFormulaMulDivC::CXTPFormulaMulDivC()
  73. {
  74. m_nMultiplier = 1;
  75. m_nDivisor = 1;
  76. m_nConstant = 0;
  77. }
  78. CXTPFormulaMulDivC::~CXTPFormulaMulDivC()
  79. {
  80. }
  81. int CXTPFormulaMulDivC::Calculate(int nY) const
  82. {
  83. ASSERT((int)m_nDivisor);
  84. int nDiv = (int)m_nDivisor ? (int)m_nDivisor : (int)1;
  85. int nResult = nY * m_nMultiplier / nDiv + m_nConstant;
  86. return nResult;
  87. }
  88. void CXTPFormulaMulDivC::SetStandardValue(int nMul, int nDiv, int nC)
  89. {
  90. m_nMultiplier = nMul;
  91. m_nDivisor = nDiv;
  92. m_nConstant = nC;
  93. }
  94. void CXTPFormulaMulDivC::GetStandardValue(int& rnMul, int& rnDiv, int& rnC)
  95. {
  96. rnMul = m_nMultiplier;
  97. rnDiv = m_nDivisor;
  98. rnC = m_nConstant;
  99. }
  100. //////////////////////////////////////////////////////////////////////
  101. // CXTPReportPaintManager
  102. CXTPReportPaintManager::CXTPReportPaintManager()
  103. {
  104. m_pHeaderHeightFormula = new CXTPFormulaMulDivC;
  105. m_pHeaderHeightFormula->SetStandardValue(11, 10, 8);
  106. m_clrPreviewText.SetStandardValue(RGB(0, 0, 255));
  107. //m_clrColumnOffice2007CustomTheme.SetStandardValue(RGB(196, 221, 255));
  108. m_clrColumnOffice2007CustomTheme = COLORREF_NULL;
  109. m_nMaxPreviewLines = 3;
  110. m_szGlyph = CSize(12, 12);
  111. m_bThemedInplaceButtons = TRUE;
  112. // defaults
  113. m_nGroupGridLineHeight = 2;
  114. m_nResizingWidth = 1;
  115. m_bIsPreviewMode = FALSE;
  116. m_bShadeGroupHeadings = FALSE;
  117. m_bGroupRowTextBold = FALSE;
  118. m_bShadeSortColumn = TRUE;
  119. m_columnStyle = xtpReportColumnShaded;
  120. m_treeStructureStyle = xtpReportTreeStructureSolid;
  121. m_HeaderRowsDividerStyle = xtpReportFixedRowsDividerThin;
  122. m_FooterRowsDividerStyle = xtpReportFixedRowsDividerThin;
  123. m_verticalGridStyle = xtpReportGridNoLines;
  124. m_horizontalGridStyle = xtpReportGridSolid;
  125. m_bRevertAlignment = FALSE;
  126. m_bUseEditTextAlignment = TRUE;
  127. m_bUseColumnTextAlignment = FALSE;
  128. m_bHotTracking = TRUE;
  129. m_bInvertColumnOnClick = TRUE;
  130. XTPResourceManager()->LoadString(&m_strNoItems, XTP_IDS_REPORT_NOITEMS);
  131. XTPResourceManager()->LoadString(&m_strNoGroupBy, XTP_IDS_REPORT_NOGROUPBY);
  132. XTPResourceManager()->LoadString(&m_strNoFieldsAvailable, XTP_IDS_REPORT_NOFIELDSAVAILABLE);
  133. if (XTPResourceManager()->LoadString(&m_strSortBy, XTP_IDS_REPORT_SORTBY))
  134. {
  135. m_strSortBy += _T(" ");
  136. }
  137. m_bHideSelection = FALSE;
  138. m_rcPreviewIndent.SetRect(10, 0, 10, 2);
  139. m_nTreeIndent = 20;
  140. m_bDrawSortTriangleAlways = TRUE;
  141. // get system parameters
  142. LOGFONT lfIcon;
  143. VERIFY(::SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lfIcon), &lfIcon, 0));
  144. VERIFY(m_fontPreview.CreateFontIndirect(&lfIcon));
  145. SetCaptionFont(lfIcon);
  146. SetTextFont(lfIcon);
  147. VERIFY(m_ilGlyphs.Create(12, 12, ILC_COLOR24 | ILC_MASK, 0, 1));
  148. CBitmap bmp;
  149. VERIFY(XTPResourceManager()->LoadBitmap(&bmp, XTP_IDB_REPORT_GLYPHS));
  150. m_ilGlyphs.Add(&bmp, RGB(255, 0, 255));
  151. m_bFixedRowHeight = TRUE;
  152. m_bDrawGridForEmptySpace = FALSE;
  153. m_bFixedInplaceButtonHeight = FALSE;
  154. m_nFreezeColsDividerStyle = xtpReportFreezeColsDividerThin | xtpReportFreezeColsDividerShade | xtpReportFreezeColsDividerHeader;
  155. m_HeaderRowsDividerStyle = xtpReportFixedRowsDividerThin;
  156. m_FooterRowsDividerStyle = xtpReportFixedRowsDividerThin;
  157. m_nTreeStructureStyle = 0;
  158. RefreshMetrics();
  159. }
  160. CXTPReportPaintManager::~CXTPReportPaintManager()
  161. {
  162. CMDTARGET_RELEASE(m_pHeaderHeightFormula);
  163. }
  164. COLORREF CXTPReportPaintManager::GetControlBackColor(CXTPReportControl* /*pControl*/)
  165. {
  166. return m_clrControlBack;
  167. }
  168. void CXTPReportPaintManager::RefreshMetrics()
  169. {
  170. RefreshXtremeColors();
  171. m_clrBtnFace.SetStandardValue(GetXtremeColor(COLOR_BTNFACE));
  172. m_clrBtnText.SetStandardValue(GetXtremeColor(COLOR_BTNTEXT));
  173. m_clrControlDark.SetStandardValue(GetXtremeColor(COLOR_3DSHADOW));
  174. m_clrHighlight.SetStandardValue(GetXtremeColor(COLOR_HIGHLIGHT));
  175. m_clrHighlightText.SetStandardValue(GetXtremeColor(COLOR_HIGHLIGHTTEXT));
  176. m_clrWindowText.SetStandardValue(GetXtremeColor(COLOR_WINDOWTEXT));
  177. m_clrControlLightLight.SetStandardValue(GetXtremeColor(COLOR_3DHIGHLIGHT));
  178. m_clrControlBack.SetStandardValue(GetXtremeColor(COLOR_WINDOW));
  179. m_clrIndentControl.SetStandardValue(m_clrBtnFace);
  180. m_clrCaptionText.SetStandardValue(m_clrBtnText);
  181. m_clrGridLine.SetStandardValue(m_clrControlDark);
  182. m_clrHeaderControl.SetStandardValue(m_clrBtnFace);
  183. m_clrGroupShadeBorder.SetStandardValue(m_clrControlDark);
  184. m_clrGroupShadeBack.SetStandardValue(m_clrBtnFace);
  185. m_clrGroupShadeText.SetStandardValue(m_clrBtnText);
  186. m_clrGroupRowText.SetStandardValue(m_clrControlDark);
  187. m_clrGroupBoxBack.SetStandardValue(m_clrControlDark);
  188. m_clrSelectedRow.SetStandardValue(m_clrBtnFace);
  189. m_clrSelectedRowText.SetStandardValue(m_clrBtnText);
  190. m_clrHyper.SetStandardValue(RGB(0, 0, 0xFF));
  191. m_clrItemShade.SetStandardValue(RGB(245, 245, 245));
  192. m_clrHotDivider.SetStandardValue(RGB(0xFF, 0, 0));
  193. m_crlNoGroupByText.SetStandardValue(m_clrControlDark);
  194. m_clrGradientColumnSeparator.SetStandardValue(m_clrControlDark);
  195. m_themeWrapper.OpenThemeData(0, L"HEADER");
  196. m_themeButton.OpenThemeData(0, L"BUTTON");
  197. m_themeCombo.OpenThemeData(0, L"COMBOBOX");
  198. m_themeSpin.OpenThemeData(0, L"SPIN");
  199. if (!XTPColorManager()->IsLunaColorsDisabled())
  200. {
  201. XTPCurrentSystemTheme systemTheme = XTPColorManager()->GetCurrentSystemTheme();
  202. switch (systemTheme)
  203. {
  204. case xtpSystemThemeBlue:
  205. case xtpSystemThemeRoyale:
  206. case xtpSystemThemeAero:
  207. m_clrGroupShadeBorder.SetStandardValue(RGB(123, 164, 224));
  208. m_clrIndentControl.SetStandardValue(RGB(253, 238, 201));
  209. m_clrGroupShadeBack.SetStandardValue(RGB(190, 218, 251));
  210. m_clrGroupRowText.SetStandardValue(RGB(55, 104, 185));
  211. m_clrGridLine.SetStandardValue(RGB(234, 233, 225));
  212. break;
  213. case xtpSystemThemeOlive:
  214. m_clrGroupShadeBorder.SetStandardValue(RGB(181, 196, 143));
  215. m_clrIndentControl.SetStandardValue(RGB(253, 238, 201));
  216. m_clrGroupShadeBack.SetStandardValue(RGB(175, 186, 145));
  217. m_clrGroupRowText.SetStandardValue(RGB(115, 137, 84));
  218. m_clrGridLine.SetStandardValue(RGB(234, 233, 225));
  219. break;
  220. case xtpSystemThemeSilver:
  221. m_clrGroupShadeBorder.SetStandardValue(RGB(165, 164, 189));
  222. m_clrIndentControl.SetStandardValue(RGB(253, 238, 201));
  223. m_clrGroupShadeBack.SetStandardValue(RGB(229, 229, 235));
  224. m_clrGroupRowText.SetStandardValue(RGB(112, 111, 145));
  225. m_clrGridLine.SetStandardValue(RGB(229, 229, 235));
  226. break;
  227. }
  228. }
  229. if (m_columnStyle == xtpReportColumnOffice2007)
  230. {
  231. if (m_clrColumnOffice2007CustomTheme != COLORREF_NULL)
  232. {
  233. COLORREF clrHsl = XTPDrawHelpers()->RGBtoHSL(m_clrColumnOffice2007CustomTheme);
  234. BYTE Hue = GetRValue(clrHsl);
  235. BYTE Sat = GetGValue(clrHsl);
  236. m_grcGradientColumnPushed.SetStandardValue(XTPDrawHelpers()->HSLtoRGB(RGB(Hue, Sat, 212)), XTPDrawHelpers()->HSLtoRGB(RGB(Hue, Sat, 239)));
  237. m_grcGradientColumn.SetStandardValue(XTPDrawHelpers()->HSLtoRGB(RGB(Hue, Sat, 239)), XTPDrawHelpers()->HSLtoRGB(RGB(Hue, Sat, 212)));
  238. m_clrGradientColumnShadow.SetStandardValue(XTPDrawHelpers()->HSLtoRGB(RGB(Hue, (BYTE)(Sat * 0.525f), 145)));
  239. m_clrGradientColumnSeparator.SetStandardValue(XTPDrawHelpers()->HSLtoRGB(RGB(Hue, Sat, 192)));
  240. m_clrGroupBoxBack.SetStandardValue(XTPDrawHelpers()->HSLtoRGB(RGB(Hue, Sat, 227)));
  241. m_crlNoGroupByText.SetStandardValue(XTPDrawHelpers()->HSLtoRGB(RGB(Hue, (BYTE)(Sat * 0.75f), 79)));
  242. m_clrGroupShadeBack.SetStandardValue(XTPDrawHelpers()->HSLtoRGB(RGB(Hue, (BYTE)(Sat * 0.88f), 208)));
  243. }
  244. else
  245. {
  246. if (XTPOffice2007Images()->IsValid())
  247. {
  248. m_grcGradientColumn.SetStandardValue(XTPOffice2007Images()->GetImageColor(_T("ReportControl"), _T("NormalColumnLight")),
  249. XTPOffice2007Images()->GetImageColor(_T("ReportControl"), _T("NormalColumnDark")));
  250. m_grcGradientColumnPushed.SetStandardValue(XTPOffice2007Images()->GetImageColor(_T("ReportControl"), _T("PressedColumnLight")),
  251. XTPOffice2007Images()->GetImageColor(_T("ReportControl"), _T("PressedColumnDark")));
  252. m_clrGradientColumnShadow.SetStandardValue(XTPOffice2007Images()->GetImageColor(_T("ReportControl"), _T("ColumnShadow")));
  253. m_clrGradientColumnSeparator.SetStandardValue(XTPOffice2007Images()->GetImageColor(_T("ReportControl"), _T("ColumnSeparator")));
  254. m_clrGroupBoxBack.SetStandardValue(XTPOffice2007Images()->GetImageColor(_T("ReportControl"), _T("GroupBoxBackground")));
  255. m_crlNoGroupByText.SetStandardValue(XTPOffice2007Images()->GetImageColor(_T("ReportControl"), _T("GroupBoxTextColor")));
  256. m_clrGroupShadeBack.SetStandardValue(XTPOffice2007Images()->GetImageColor(_T("ReportControl"), _T("GroupShadeBackground")));
  257. m_clrGroupShadeBorder.SetStandardValue(XTPOffice2007Images()->GetImageColor(_T("ReportControl"), _T("GroupShadeBorder")));
  258. m_clrIndentControl.SetStandardValue(XTPOffice2007Images()->GetImageColor(_T("ReportControl"), _T("GroupShadeIndent")));
  259. m_clrHighlight.SetStandardValue(XTPOffice2007Images()->GetImageColor(_T("ReportControl"), _T("SelectionBackground")));
  260. m_clrHighlightText.SetStandardValue(0);
  261. }
  262. else
  263. {
  264. m_grcGradientColumnPushed.SetStandardValue(RGB(196, 221, 255), RGB(252, 253, 255));
  265. m_grcGradientColumn.SetStandardValue(RGB(252, 253,255), RGB(196, 221, 255));
  266. m_clrGradientColumnShadow.SetStandardValue(RGB(101, 147, 207));
  267. m_clrGradientColumnSeparator.SetStandardValue(RGB(154, 198, 255));
  268. m_clrGroupBoxBack.SetStandardValue(RGB(227, 239, 255));
  269. m_crlNoGroupByText.SetStandardValue(RGB(50, 75, 44));
  270. m_clrGroupShadeBack.SetStandardValue(RGB(190, 218, 251));
  271. m_clrGroupShadeBorder.SetStandardValue(RGB(111, 157, 217));
  272. m_clrIndentControl.SetStandardValue(RGB(253, 238, 201));
  273. }
  274. }
  275. m_grcGradientColumnHot.SetStandardValue(m_grcGradientColumn);
  276. m_clrGroupRowText.SetStandardValue(m_crlNoGroupByText);
  277. m_clrGroupShadeBorder.SetStandardValue(m_clrGradientColumnSeparator);
  278. }
  279. else if (m_columnStyle == xtpReportColumnOffice2003)
  280. {
  281. m_grcGradientColumn.SetStandardValue(XTPColorManager()->LightColor(GetXtremeColor(COLOR_3DFACE), GetXtremeColor(COLOR_WINDOW), 0xcd), GetXtremeColor(COLOR_3DFACE));
  282. m_grcGradientColumnHot.SetStandardValue(GetXtremeColor(XPCOLOR_HIGHLIGHT));
  283. m_grcGradientColumnPushed.SetStandardValue(GetXtremeColor(XPCOLOR_HIGHLIGHT_PUSHED));
  284. m_clrGradientColumnShadow.SetStandardValue(GetXtremeColor(XPCOLOR_TOOLBAR_FACE));
  285. m_clrGradientColumnSeparator.SetStandardValue(GetXtremeColor(XPCOLOR_SEPARATOR));
  286. switch (XTPColorManager()->GetCurrentSystemTheme())
  287. {
  288. case xtpSystemThemeBlue:
  289. case xtpSystemThemeRoyale:
  290. case xtpSystemThemeAero:
  291. m_grcGradientColumn.SetStandardValue(RGB(221, 236, 254), RGB(129, 169, 226));
  292. m_clrGradientColumnShadow.SetStandardValue(RGB(59, 97, 156));
  293. m_clrGradientColumnSeparator.SetStandardValue(RGB(106, 140, 203));
  294. m_grcGradientColumnPushed.SetStandardValue(RGB(254, 142, 75), RGB(255, 207, 139));
  295. m_grcGradientColumnHot.SetStandardValue(RGB(255, 242, 200), RGB(255, 212, 151));
  296. break;
  297. case xtpSystemThemeOlive:
  298. m_grcGradientColumn.SetStandardValue(RGB(244, 247, 222), RGB(183, 198, 145));
  299. m_clrGradientColumnShadow.SetStandardValue(RGB(96, 128, 88));
  300. m_clrGradientColumnSeparator.SetStandardValue(RGB(96, 128, 88));
  301. m_grcGradientColumnPushed.SetStandardValue(RGB(254, 142, 75), RGB(255, 207, 139));
  302. m_grcGradientColumnHot.SetStandardValue(RGB(255, 242, 200), RGB(255, 212, 151));
  303. break;
  304. case xtpSystemThemeSilver:
  305. m_grcGradientColumn.SetStandardValue(RGB(243, 244, 250), RGB(153, 151, 181));
  306. m_clrGradientColumnShadow.SetStandardValue(RGB(124, 124, 148));
  307. m_clrGradientColumnSeparator.SetStandardValue(RGB(110, 109, 143));
  308. m_grcGradientColumnPushed.SetStandardValue(RGB(254, 142, 75), RGB(255, 207, 139));
  309. m_grcGradientColumnHot.SetStandardValue(RGB(255, 242, 200), RGB(255, 212, 151));
  310. break;
  311. }
  312. }
  313. m_brushVeriticalGrid.DeleteObject();
  314. m_brushHorizontalGrid.DeleteObject();
  315. m_brushTreeStructure.DeleteObject();
  316. m_clrFreezeColsDivider.SetStandardValue(RGB(0, 0, 222));
  317. m_clrHeaderRowsDivider.SetStandardValue(COLOR_BTNFACE);
  318. m_clrFooterRowsDivider.SetStandardValue(COLOR_BTNFACE);
  319. LOGFONT lf;
  320. m_fontCaption.GetLogFont(&lf);
  321. SetCaptionFont(lf);
  322. }
  323. void CXTPReportPaintManager::FillRow(CDC* /*pDC*/, CXTPReportRow* /*pRow*/, CRect /*rcRow*/)
  324. {
  325. }
  326. void CXTPReportPaintManager::DrawGridPat(CDC* pDC, CBrush* pBrush, CRect rc, CONST VOID*pPattern, COLORREF clr)
  327. {
  328. if (pBrush->GetSafeHandle() == 0)
  329. {
  330. CBitmap bmp;
  331. bmp.CreateBitmap(8, 8, 1, 1, pPattern);
  332. pBrush->CreatePatternBrush(&bmp);
  333. }
  334. CBrush* pOldBrush = (CBrush*)pDC->SelectObject(pBrush);
  335. pDC->SetTextColor(m_clrControlBack);
  336. pDC->SetBkColor(clr);
  337. PatBlt(pDC->GetSafeHdc(), rc.left, rc.top, rc.Width(), rc.Height(), PATCOPY);
  338. pDC->SelectObject(pOldBrush);
  339. }
  340. void CXTPReportPaintManager::SetGridStyle(BOOL bVertical, XTPReportGridStyle gridStyle)
  341. {
  342. if (bVertical)
  343. {
  344. m_verticalGridStyle = gridStyle;
  345. m_brushVeriticalGrid.DeleteObject();
  346. }
  347. else
  348. {
  349. m_horizontalGridStyle = gridStyle;
  350. m_brushHorizontalGrid.DeleteObject();
  351. }
  352. }
  353. void CXTPReportPaintManager::DrawGrid(CDC* pDC, BOOL bVertical, CRect rc)
  354. {
  355. if (!bVertical)
  356. {
  357. switch (m_horizontalGridStyle)
  358. {
  359. case xtpReportGridSolid:
  360. DrawHorizontalLine(pDC, rc.left, rc.bottom, rc.Width(), m_clrGridLine);
  361. break;
  362. case xtpReportGridSmallDots:
  363. {
  364. const unsigned short _cb[] = {0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55};
  365. DrawGridPat(pDC, &m_brushHorizontalGrid, CRect(rc.left, rc.bottom, rc.right, rc.bottom + 1), _cb, m_clrGridLine);
  366. break;
  367. }
  368. case xtpReportGridLargeDots:
  369. {
  370. const unsigned short _cb[] = {0xcc, 0x33, 0xcc, 0x33, 0xcc, 0x33, 0xcc, 0x33};
  371. DrawGridPat(pDC, &m_brushHorizontalGrid, CRect(rc.left, rc.bottom, rc.right, rc.bottom + 1), _cb, m_clrGridLine);
  372. break;
  373. }
  374. case xtpReportGridDashes:
  375. {
  376. const unsigned short _cb[] = {0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0};
  377. DrawGridPat(pDC, &m_brushHorizontalGrid, CRect(rc.left, rc.bottom, rc.right, rc.bottom + 1), _cb, m_clrGridLine);
  378. break;
  379. }
  380. }
  381. }
  382. else
  383. {
  384. int nPos = rc.right - 1;
  385. switch (m_verticalGridStyle)
  386. {
  387. case xtpReportGridSolid:
  388. DrawVerticalLine(pDC, nPos, rc.top, rc.Height(), m_clrGridLine);
  389. break;
  390. case xtpReportGridSmallDots:
  391. {
  392. const unsigned short _cb[] = {0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55};
  393. DrawGridPat(pDC, &m_brushVeriticalGrid, CRect(nPos, rc.top, nPos + 1, rc.bottom), _cb, m_clrGridLine);
  394. break;
  395. }
  396. case xtpReportGridLargeDots:
  397. {
  398. const unsigned short _cb[] = {0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0x33, 0x33};
  399. DrawGridPat(pDC, &m_brushVeriticalGrid, CRect(nPos, rc.top, nPos + 1, rc.bottom), _cb, m_clrGridLine);
  400. break;
  401. }
  402. case xtpReportGridDashes:
  403. {
  404. const unsigned short _cb[] = {0xf0, 0xf0, 0xf0, 0xf0, 0xf, 0xf, 0xf, 0xf};
  405. DrawGridPat(pDC, &m_brushVeriticalGrid, CRect(nPos, rc.top, nPos + 1, rc.bottom), _cb, m_clrGridLine);
  406. break;
  407. }
  408. }
  409. }
  410. }
  411. void CXTPReportPaintManager::DrawFreezeColsDivider(CDC* pDC, const CRect& rc, CXTPReportControl* pControl, CXTPReportRow* pRow)
  412. {
  413. if (pControl->GetReportHeader()->IsAutoColumnSizing() ||
  414. (m_nFreezeColsDividerStyle == 0))
  415. return;
  416. CRect rcDvX = rc;
  417. if ((m_nFreezeColsDividerStyle & xtpReportFreezeColsDividerShade) &&
  418. pControl->GetScrollPos(SB_HORZ) && !pControl->IsFullColumnScrolling())
  419. {
  420. rcDvX.left = rcDvX.right-1;
  421. rcDvX.right = rcDvX.left + 4;
  422. XTPDrawHelpers()->GradientFill(pDC, rcDvX, m_clrFreezeColsDivider,
  423.    RGB(255, 255, 255), TRUE);
  424. }
  425. else if (m_nFreezeColsDividerStyle & (xtpReportFreezeColsDividerThin | xtpReportFreezeColsDividerBold))
  426. {
  427. int nWidth = (m_nFreezeColsDividerStyle & xtpReportFreezeColsDividerBold) ? 2 : 1;
  428. rcDvX.left = rcDvX.right-nWidth;
  429. pDC->FillSolidRect(&rcDvX, m_clrFreezeColsDivider);
  430. }
  431. int nMask = (xtpReportFreezeColsDividerThin | xtpReportFreezeColsDividerBold | xtpReportFreezeColsDividerShade);
  432. if (pRow && pRow->IsSelected() && (m_nFreezeColsDividerStyle & nMask))
  433. {
  434. pDC->InvertRect(&rcDvX);
  435. }
  436. }
  437. void CXTPReportPaintManager::FillGroupRowMetrics(CXTPReportGroupRow* pRow,
  438. XTP_REPORTRECORDITEM_METRICS* pMetrics, BOOL bPrinting)
  439. {
  440. ASSERT(pRow && pMetrics);
  441. if (!pRow || !pRow->GetControl() || !pMetrics)
  442. {
  443. return;
  444. }
  445. BOOL bControlFocused = pRow->GetControl()->HasFocus();
  446. pMetrics->clrForeground = m_clrGroupRowText;
  447. pMetrics->clrBackground = XTP_REPORT_COLOR_DEFAULT;
  448. if (pRow->IsSelected() && bControlFocused && !bPrinting)
  449. {
  450. pMetrics->clrForeground = m_clrHighlightText;
  451. pMetrics->clrBackground = m_clrHighlight;
  452. }
  453. else if (m_bShadeGroupHeadings)
  454. {
  455. pMetrics->clrForeground = m_clrGroupShadeText;
  456. pMetrics->clrBackground = m_clrGroupShadeBack;
  457. }
  458. //--------------------------------
  459. pMetrics->pFont = m_bGroupRowTextBold ? &m_fontBoldText : &m_fontText;
  460. }
  461. void CXTPReportPaintManager::DrawGroupRow(CDC* pDC, CXTPReportGroupRow* pRow, CRect rcRow,
  462. XTP_REPORTRECORDITEM_METRICS* pMetrics)
  463. {
  464. BOOL bControlFocused = pRow->GetControl()->HasFocus();
  465. if (pMetrics->clrBackground != XTP_REPORT_COLOR_DEFAULT)
  466. {
  467. pDC->FillSolidRect(rcRow, pMetrics->clrBackground);
  468. }
  469. pDC->SetTextColor(pMetrics->clrForeground);
  470. //--------------------------------
  471. ASSERT(pMetrics->pFont);
  472. CXTPFontDC font(pDC, pMetrics->pFont);
  473. int nRowLevel = pRow->GetTreeDepth();
  474. int nIndent = pRow->GetControl()->GetIndent(nRowLevel + 1);
  475. pDC->FillSolidRect(rcRow.left, rcRow.bottom - m_nGroupGridLineHeight, rcRow.Width(), m_nGroupGridLineHeight, m_clrGroupShadeBorder);
  476. if (pRow->IsFocused() && bControlFocused && !pDC->IsPrinting() && pRow->GetControl()->IsRowFocusVisible())
  477. {
  478. DrawFocusedRow(pDC, CRect(rcRow.left + nIndent, rcRow.top, rcRow.right, rcRow.bottom - 1));
  479. }
  480. if (nIndent > 0)
  481. {
  482. FillIndent(pDC, CRect(rcRow.left, rcRow.top, rcRow.left + nIndent, rcRow.bottom));
  483. }
  484. rcRow.left += nIndent;
  485. //-----------------------------------------------------------------------
  486. int nBitmapOffset = 0;
  487. int nTextOffset = 0;
  488. CSize szIcon(0, 0);
  489. int nGroupRowIconAlignment = pMetrics->nGroupRowIconAlignment;
  490. // check and set defaults if need
  491. if ((nGroupRowIconAlignment & xtpGroupRowIconHmask) == 0)
  492. {
  493. nGroupRowIconAlignment |= xtpGroupRowIconLeft;
  494. }
  495. if ((nGroupRowIconAlignment & xtpGroupRowIconVmask) == 0)
  496. {
  497. nGroupRowIconAlignment |= xtpGroupRowIconVCenter;
  498. }
  499. if (pMetrics->nGroupRowIcon != XTP_REPORT_NOICON)
  500. {
  501. CXTPImageManagerIcon* pIcon = pRow->GetControl()->GetImageManager()->
  502. GetImage(pMetrics->nGroupRowIcon, 0);
  503. if (pIcon)
  504. {
  505. szIcon = CSize(pIcon->GetWidth(), pIcon->GetHeight());
  506. }
  507. if (nGroupRowIconAlignment & xtpGroupRowIconLeft)
  508. {
  509. nBitmapOffset = szIcon.cx + 5;
  510. }
  511. if (nGroupRowIconAlignment & xtpGroupRowIconBeforeText)
  512. {
  513. nTextOffset = szIcon.cx + 5 + 5;
  514. }
  515. }
  516. //-----------------------------------------------------------------------
  517. CRect rcBitmap(rcRow);
  518. rcBitmap.top = rcBitmap.bottom - m_nRowHeight - 12;
  519. rcBitmap.top = rcBitmap.CenterPoint().y - m_szGlyph.cy / 2;
  520. rcBitmap.left += nBitmapOffset;
  521. int nBitmapWidth = DrawCollapsedBitmap(pDC, pRow, rcBitmap).cx;
  522. if (!pDC->IsPrinting())
  523. pRow->SetCollapseRect(rcBitmap);
  524. //-----------------------------------------------------------------------
  525. CRect rcText(rcBitmap.left + nBitmapWidth + 5, rcRow.top, rcRow.right, rcRow.bottom);
  526. rcText.top = rcText.bottom - m_nRowHeight - 6;
  527. rcText.left += nTextOffset;
  528. int nRightMask = (xtpGroupRowIconAfterText | xtpGroupRowIconRight);
  529. if (pMetrics->nGroupRowIcon != XTP_REPORT_NOICON &&
  530. (nGroupRowIconAlignment & nRightMask))
  531. {
  532. rcText.right -= szIcon.cx;
  533. }
  534. UINT nFlags = DT_SINGLELINE | DT_END_ELLIPSIS | DT_VCENTER | DT_NOPREFIX;
  535. pDC->DrawText(pMetrics->strText, rcText, nFlags);
  536. int nTextWidth = pDC->GetTextExtent(pMetrics->strText).cx;
  537. //-----------------------------------------------------------------------
  538. if (pMetrics->nGroupRowIcon != XTP_REPORT_NOICON)
  539. {
  540. CRect rcIcon(rcRow);
  541. if (nGroupRowIconAlignment & xtpGroupRowIconBeforeText)
  542. {
  543. rcIcon.left = rcBitmap.left + nBitmapWidth + 5;
  544. }
  545. else if (nGroupRowIconAlignment & xtpGroupRowIconAfterText)
  546. {
  547. rcIcon.left = rcText.left + nTextWidth + 5;
  548. rcIcon.left = min(rcIcon.left, rcRow.right - szIcon.cx - 1);
  549. }
  550. else if (nGroupRowIconAlignment & xtpGroupRowIconRight)
  551. {
  552. rcIcon.left = rcRow.right - szIcon.cx - 1;
  553. }
  554. else
  555. {
  556. // xtpGroupRowIconLeft
  557. }
  558. // ***
  559. if (nGroupRowIconAlignment & xtpGroupRowIconVTop)
  560. {
  561. rcIcon.bottom = rcIcon.top + szIcon.cy + 1;
  562. }
  563. else if (nGroupRowIconAlignment & xtpGroupRowIconVCenterToText)
  564. {
  565. rcIcon.top = rcText.CenterPoint().y - szIcon.cy / 2;
  566. rcIcon.bottom = rcIcon.top + szIcon.cy + 1;
  567. }
  568. else if (nGroupRowIconAlignment & xtpGroupRowIconVBottom)
  569. {
  570. rcIcon.top = rcIcon.bottom - szIcon.cy - 1;
  571. }
  572. else
  573. {
  574. // xtpGroupRowIconVCenter
  575. }
  576. //-------------------------------------------------------------------
  577. COLORREF clrBk = pMetrics->clrBackground != XTP_REPORT_COLOR_DEFAULT ?
  578. pMetrics->clrBackground : RGB(255, 255, 255);
  579. COLORREF clrBkPrev = pDC->SetBkColor(clrBk);
  580. DrawBitmap(pDC, pRow->GetControl(), rcIcon, pMetrics->nGroupRowIcon);
  581. pDC->SetBkColor(clrBkPrev);
  582. }
  583. }
  584. CSize CXTPReportPaintManager::DrawCollapsedBitmap(CDC* pDC, const CXTPReportRow* pRow, CRect& rcBitmap)
  585. {
  586. rcBitmap.left += 2;
  587. CSize sizeGlyph = DrawGlyph(pDC, rcBitmap, pRow->IsExpanded() ? 0 : 1);
  588. if (sizeGlyph.cx != 0 && pDC)
  589. {
  590. rcBitmap.right = rcBitmap.left + sizeGlyph.cx;
  591. }
  592. return CSize(2 + sizeGlyph.cx, 2 + sizeGlyph.cy);
  593. }
  594. void CXTPReportPaintManager::FillIndent(CDC* pDC, CRect rcRow)
  595. {
  596. pDC->FillSolidRect(&rcRow, m_clrIndentControl);
  597. }
  598. void CXTPReportPaintManager::FillItemShade(CDC* pDC, CRect rcItem)
  599. {
  600. // fill item background shade (for example when sorted by this column)
  601. if (!m_bShadeSortColumn)
  602. return;
  603. if (pDC)
  604. {
  605. pDC->FillSolidRect(rcItem, m_clrItemShade);
  606. }
  607. }
  608. void CXTPReportPaintManager::FillHeaderControl(CDC* pDC, CRect rcHeader)
  609. {
  610. pDC->FillSolidRect(rcHeader, m_clrHeaderControl);
  611. }
  612. void CXTPReportPaintManager::DrawNoGroupByText(CDC* pDC, CRect rcItem)
  613. {
  614. int nWidth = max(55, pDC->GetTextExtent(m_strNoGroupBy).cx + 8);
  615. rcItem.right = rcItem.left + nWidth;
  616. pDC->SetTextColor(m_crlNoGroupByText);
  617. if (m_columnStyle != xtpReportColumnOffice2007)
  618. FillHeaderControl(pDC, rcItem);
  619. pDC->DrawText(m_strNoGroupBy, rcItem, DT_END_ELLIPSIS | DT_CENTER | DT_NOPREFIX);
  620. }
  621. void CXTPReportPaintManager::FillFooter(CDC* pDC, CRect rcFooter)
  622. {
  623. if (m_columnStyle == xtpReportColumnOffice2007)
  624. {
  625. XTPDrawHelpers()->GradientFill(pDC, rcFooter,
  626. m_grcGradientColumn.clrDark, m_grcGradientColumn.clrLight, FALSE);
  627. DrawHorizontalLine(pDC, rcFooter.left, rcFooter.top, rcFooter.Width(), m_clrGroupBoxBack);
  628. DrawHorizontalLine(pDC, rcFooter.left, rcFooter.top + 1, rcFooter.Width(), m_clrGradientColumnShadow);
  629. DrawHorizontalLine(pDC, rcFooter.left, rcFooter.top + 2, rcFooter.Width(), MixColor(m_grcGradientColumn.clrDark, m_clrGradientColumnShadow, 0.25));
  630. DrawHorizontalLine(pDC, rcFooter.left, rcFooter.top + 3, rcFooter.Width(), MixColor(m_grcGradientColumn.clrDark, m_clrGradientColumnShadow, 0.1));
  631. DrawHorizontalLine(pDC, rcFooter.left, rcFooter.bottom - 1, rcFooter.Width(), m_clrGradientColumnShadow);
  632. }
  633. else if (m_columnStyle == xtpReportColumnOffice2003)
  634. {
  635. XTPDrawHelpers()->GradientFill(pDC, rcFooter,
  636. m_grcGradientColumn.clrDark, m_grcGradientColumn.clrLight, FALSE);
  637. DrawHorizontalLine(pDC, rcFooter.left, rcFooter.top, rcFooter.Width(), m_clrControlBack);
  638. DrawHorizontalLine(pDC, rcFooter.left, rcFooter.top + 1, rcFooter.Width(), m_clrGradientColumnShadow);
  639. DrawHorizontalLine(pDC, rcFooter.left, rcFooter.top + 2, rcFooter.Width(), MixColor(m_grcGradientColumn.clrDark, m_clrGradientColumnShadow, 0.25));
  640. DrawHorizontalLine(pDC, rcFooter.left, rcFooter.top + 3, rcFooter.Width(), MixColor(m_grcGradientColumn.clrDark, m_clrGradientColumnShadow, 0.1));
  641. DrawHorizontalLine(pDC, rcFooter.left, rcFooter.bottom - 1, rcFooter.Width(), m_clrGradientColumnShadow);
  642. }
  643. else
  644. {
  645. pDC->FillSolidRect(rcFooter, m_clrHeaderControl);
  646. DrawHorizontalLine(pDC, rcFooter.left, rcFooter.top, rcFooter.Width(), m_clrControlBack);
  647. DrawHorizontalLine(pDC, rcFooter.left, rcFooter.top + 1, rcFooter.Width(), m_clrControlDark);
  648. DrawHorizontalLine(pDC, rcFooter.left, rcFooter.top + 2, rcFooter.Width(), MixColor(m_clrHeaderControl, m_clrControlDark, 0.6));
  649. DrawHorizontalLine(pDC, rcFooter.left, rcFooter.top + 3, rcFooter.Width(), MixColor(m_clrHeaderControl, m_clrControlDark, 0.25));
  650. DrawHorizontalLine(pDC, rcFooter.left, rcFooter.bottom - 1, rcFooter.Width(), m_clrControlDark);
  651. }
  652. }
  653. void CXTPReportPaintManager::DrawHorizontalLine(CDC* pDC, int x, int y, int cx, COLORREF clr)
  654. {
  655. pDC->FillSolidRect(x, y, cx, 1, clr);
  656. }
  657. void CXTPReportPaintManager::DrawVerticalLine(CDC* pDC, int x, int y, int cy, COLORREF clr)
  658. {
  659. pDC->FillSolidRect(x, y, 1, cy, clr);
  660. }
  661. void CXTPReportPaintManager::DrawTriangle(CDC* pDC, CRect rcTriangle, BOOL bToDown)
  662. {
  663. CRect rcTRect;
  664. if (rcTriangle.Width() > 15)
  665. {
  666. CPoint pt(rcTriangle.left + 10, rcTriangle.CenterPoint().y);
  667. if (m_columnStyle == xtpReportColumnOffice2007 || m_columnStyle == xtpReportColumnExplorer)
  668. {
  669. if (bToDown)
  670. {
  671. CXTPDrawHelpers::Triangle(pDC, CPoint(pt.x - 4, pt.y - 2),
  672. CPoint(pt.x, pt.y + 2), CPoint(pt.x + 4, pt.y  - 2), m_clrGradientColumnSeparator);
  673. }
  674. else
  675. {
  676. CXTPDrawHelpers::Triangle(pDC, CPoint(pt.x - 4, pt.y + 2),
  677. CPoint(pt.x, pt.y - 2), CPoint(pt.x + 4, pt.y  + 2), m_clrGradientColumnSeparator);
  678. }
  679. return;
  680. }
  681. // Set up pens to use for drawing the triangle
  682. CPen penLight(PS_SOLID, 1, m_clrControlLightLight);
  683. CPen penShadow(PS_SOLID, 1, m_clrControlDark);
  684. if (bToDown)
  685. {
  686. Line(pDC, pt.x, pt.y - 3 + 6, 3, -6, &penLight);
  687. Line(pDC, pt.x, pt.y - 2 + 6, 3, -6, &penLight);
  688. Line(pDC, pt.x - 4, pt.y - 2, 3, +6, &penShadow);
  689. Line(pDC, pt.x - 1, pt.y - 2 + 6, -4, -7, &penShadow);
  690. Line(pDC, pt.x - 4, pt.y - 2, 8, 0, &penShadow);
  691. }
  692. else
  693. {
  694. Line(pDC, pt.x, pt.y - 3, 3, 6, &penLight);
  695. Line(pDC, pt.x, pt.y - 2, 3, 6, &penLight);
  696. Line(pDC, pt.x - 3, pt.y + 3, 6, 0, &penLight);
  697. Line(pDC, pt.x - 1, pt.y - 3, -3, 6, &penShadow);
  698. Line(pDC, pt.x - 2, pt.y - 2, -3, 6, &penShadow);
  699. }
  700. }
  701. }
  702. void CXTPReportPaintManager::DrawItemBitmap(XTP_REPORTRECORDITEM_DRAWARGS* pDrawArgs, CRect& rcItem, int nImage)
  703. {
  704. ASSERT(pDrawArgs->pControl);
  705. if (!pDrawArgs->pControl)
  706. return;
  707. POINT ptIcon;
  708. CXTPImageManagerIcon* pIcon = pDrawArgs->pControl->GetImageManager()->GetImage(nImage, 0);
  709. if (!pIcon)
  710. return;
  711. CSize szImage(pIcon->GetWidth(), pIcon->GetHeight());
  712. CSize szColumn(rcItem.Size());
  713. int nIconAlign = pDrawArgs->nTextAlign & xtpColumnIconMask;
  714. if (szImage.cx < szColumn.cx && szImage.cy < szColumn.cy && pDrawArgs->pDC)
  715. {
  716. // calculate image position
  717. if (nIconAlign & xtpColumnIconRight)
  718. {
  719. ptIcon.x = rcItem.right - szImage.cx - 1;
  720. rcItem.right -= (1 + szImage.cx); // shift text box to the left
  721. }
  722. else if (nIconAlign & xtpColumnIconCenter)
  723. {
  724. ptIcon.x = rcItem.left + szColumn.cx / 2 - szImage.cx / 2 - 1;
  725. }
  726. else //xtpColumnIconLeft : by default
  727. {
  728. ptIcon.x = rcItem.left + 1;
  729. rcItem.left += 1 + szImage.cx; // shift text box to the right
  730. }
  731. // vertically align
  732. if (nIconAlign & xtpColumnIconTop)
  733. {
  734. ptIcon.y = rcItem.top;
  735. }
  736. else if (nIconAlign & xtpColumnIconBottom)
  737. {
  738. ptIcon.y = rcItem.bottom - szImage.cy - 1;
  739. }
  740. else // xtpColumnIconVCenter - by default
  741. {
  742. ptIcon.y = rcItem.top + (szColumn.cy - szImage.cy) /2;
  743. }
  744. // draw image
  745. if (pDrawArgs->pDC->IsPrinting())
  746. {
  747. CBitmap bmp;
  748. bmp.CreateCompatibleBitmap(pDrawArgs->pDC, szImage.cx, szImage.cy);
  749. CXTPCompatibleDC dcMem(NULL, &bmp);
  750. dcMem.FillSolidRect(0, 0, szImage.cx, szImage.cy, pDrawArgs->pDC->GetBkColor());
  751. pIcon->Draw(&dcMem, CPoint(0, 0), pIcon->GetIcon());
  752. pDrawArgs->pDC->BitBlt(ptIcon.x, ptIcon.y, szImage.cx, szImage.cy, &dcMem, 0, 0, SRCCOPY);
  753. }
  754. else
  755. {
  756. pIcon->Draw(pDrawArgs->pDC, ptIcon, pIcon->GetIcon());
  757. }
  758. }
  759. }
  760. int CXTPReportPaintManager::DrawColumnIcon(CDC* pDC, CXTPReportColumn* pColumn,
  761.    CRect rcColumn, CRect rcIcon, int iIcon)
  762. {
  763. if (!pColumn || !pColumn->GetControl())
  764. {
  765. ASSERT(FALSE);
  766. return 0;
  767. }
  768. POINT ptIcon;
  769. CXTPImageManagerIcon* pIcon = pColumn->GetControl()->GetImageManager()->GetImage(iIcon, 0);
  770. if (!pIcon)
  771. return 0;
  772. CSize szImage(pIcon->GetWidth(), pIcon->GetHeight());
  773. CSize szColumn(rcIcon.Size());
  774. if (szImage.cx < szColumn.cx && szImage.cy < szColumn.cy && pDC)
  775. {
  776. ptIcon.x = rcIcon.left + 1;
  777. ptIcon.y = rcIcon.top + (szColumn.cy - szImage.cy) /2;
  778. if (pDC->IsPrinting())
  779. {
  780. CPoint ptIconOffset(ptIcon.x - rcColumn.left, ptIcon.y - rcColumn.top);
  781. CRect rcColumn2(0, 0, rcColumn.Width(), rcColumn.Height());
  782. CBitmap bmp;
  783. bmp.CreateCompatibleBitmap(pDC, rcColumn2.Width(), rcColumn2.Height());
  784. CXTPCompatibleDC dcMem(NULL, &bmp);
  785. // Fill background
  786. dcMem.FillSolidRect(&rcColumn2, pDC->GetBkColor());
  787. BOOL bColumnPressed = FALSE;
  788. DrawColumnBackground(&dcMem, pColumn, rcColumn2, bColumnPressed);
  789. pIcon->Draw(&dcMem, ptIconOffset, pIcon->GetIcon());
  790. pDC->BitBlt(ptIcon.x, ptIcon.y, szImage.cx, szImage.cy, &dcMem,
  791. ptIconOffset.x, ptIconOffset.y, SRCCOPY);
  792. }
  793. else
  794. {
  795. pIcon->Draw(pDC, ptIcon, pIcon->GetIcon());
  796. }
  797. }
  798. return 1 + szImage.cx;
  799. }
  800. int CXTPReportPaintManager::DrawBitmap(CDC* pDC, CXTPReportControl* pControl, CRect rcColumn, int iIcon)
  801. {
  802. ASSERT(pControl);
  803. if (!pControl)
  804. return 0;
  805. POINT ptIcon;
  806. CXTPImageManagerIcon* pIcon = pControl->GetImageManager()->GetImage(iIcon, 0);
  807. if (!pIcon)
  808. return 0;
  809. CSize szImage(pIcon->GetWidth(), pIcon->GetHeight());
  810. CSize szColumn(rcColumn.Size());
  811. if (szImage.cx < szColumn.cx && szImage.cy < szColumn.cy && pDC)
  812. {
  813. ptIcon.x = rcColumn.left + 1;
  814. ptIcon.y = rcColumn.top + (szColumn.cy - szImage.cy) /2;
  815. if (pDC->IsPrinting())
  816. {
  817. CBitmap bmp;
  818. bmp.CreateCompatibleBitmap(pDC, szImage.cx, szImage.cy);
  819. CXTPCompatibleDC dcMem(NULL, &bmp);
  820. dcMem.FillSolidRect(0, 0, szImage.cx, szImage.cy, pDC->GetBkColor());
  821. pIcon->Draw(&dcMem, CPoint(0, 0), pIcon->GetIcon());
  822. pDC->BitBlt(ptIcon.x, ptIcon.y, szImage.cx, szImage.cy, &dcMem, 0, 0, SRCCOPY);
  823. }
  824. else
  825. {
  826. pIcon->Draw(pDC, ptIcon, pIcon->GetIcon());
  827. }
  828. }
  829. return 1 + szImage.cx;
  830. }
  831. CSize CXTPReportPaintManager::DrawGlyph(CDC* pDC, CRect rcColumn, int iIcon)
  832. {
  833. CImageList* pImageList = &m_ilGlyphs;
  834. IMAGEINFO imgInf;
  835. if (!pImageList->GetImageInfo(iIcon, &imgInf))
  836. return CSize(0, 0);
  837. CSize szImage(imgInf.rcImage.right - imgInf.rcImage.left, imgInf.rcImage.bottom - imgInf.rcImage.top);
  838. CSize szColumn(rcColumn.Size());
  839. if (szImage.cy < szColumn.cy && pDC)
  840. {
  841. POINT ptIcon;
  842. ptIcon.x = rcColumn.left + 1;
  843. ptIcon.y = rcColumn.top + (szColumn.cy - szImage.cy) /2;
  844. if (pDC->IsPrinting())
  845. {
  846. CBitmap bmp;
  847. bmp.CreateCompatibleBitmap(pDC, szImage.cx, szImage.cy);
  848. CXTPCompatibleDC dcMem(NULL, &bmp);
  849. dcMem.FillSolidRect(0, 0, szImage.cx, szImage.cy, pDC->GetBkColor());
  850. pImageList->Draw(&dcMem, iIcon, CPoint(0, 0), ILD_TRANSPARENT);
  851. pDC->BitBlt(ptIcon.x, ptIcon.y, szImage.cx, szImage.cy, &dcMem, 0, 0, SRCCOPY);
  852. }
  853. else if (CXTPDrawHelpers::IsContextRTL(pDC))  // Revert Icon
  854. {
  855. HICON hIcon = pImageList->ExtractIcon(iIcon);
  856. DrawIconEx(pDC->GetSafeHdc(), ptIcon.x + szImage.cx, ptIcon.y, hIcon, -szImage.cx, szImage.cy, 0, 0, DI_NORMAL);
  857. DestroyIcon(hIcon);
  858. }
  859. else
  860. {
  861. pImageList->Draw(pDC, iIcon, ptIcon, ILD_TRANSPARENT);
  862. }
  863. }
  864. return CSize(1 + szImage.cx, 1 + szImage.cy);
  865. }
  866. int CXTPReportPaintManager::GetRowHeight(CDC* pDC, CXTPReportRow* pRow, int nTotalWidth)
  867. {
  868. if (m_bFixedRowHeight || pRow->IsGroupRow() || !pRow->IsItemsVisible())
  869. return GetRowHeight(pDC, pRow);
  870. CXTPReportColumns* pColumns = pRow->GetControl()->GetColumns();
  871. int nColumnCount = pColumns->GetCount();
  872. XTP_REPORTRECORDITEM_DRAWARGS drawArgs;
  873. drawArgs.pControl = pRow->GetControl();
  874. drawArgs.pDC = pDC;
  875. drawArgs.pRow = pRow;
  876. XTP_REPORTRECORDITEM_METRICS* pItemMetrics = new XTP_REPORTRECORDITEM_METRICS;
  877. int nHeight = 0;
  878. for (int nColumn = 0; nColumn < nColumnCount; nColumn++)
  879. {
  880. CXTPReportColumn* pColumn = pColumns->GetAt(nColumn);
  881. if (pColumn && pColumn->IsVisible())
  882. {
  883. CXTPReportRecordItem* pItem = pRow->GetRecord()->GetItem(pColumn);
  884. if (!pItem)
  885. continue;
  886. drawArgs.pItem = pItem;
  887. drawArgs.nTextAlign = pColumn->GetAlignment();
  888. pItemMetrics->Reset();
  889. pRow->GetItemMetrics(&drawArgs, pItemMetrics);
  890. CXTPFontDC fnt(pDC, pItemMetrics->pFont);
  891. int nWidth = pDC->IsPrinting() ? pColumn->GetPrintWidth(nTotalWidth) : pColumn->GetWidth();
  892. CRect rcItem(0, 0, nWidth - 4, 0);
  893. pRow->ShiftTreeIndent(rcItem, pColumn);
  894. pItem->GetCaptionRect(&drawArgs, rcItem);
  895. if (pItem->GetMarkupUIElement())
  896. {
  897. int nCalculatedHeight = XTPMarkupMeasureElement(pItem->GetMarkupUIElement(), rcItem.Width(), INT_MAX).cy;
  898. nHeight = max(nHeight, nCalculatedHeight);
  899. }
  900. else
  901. {
  902. BOOL bWordBreak = !!(pItemMetrics->nColumnAlignment & DT_WORDBREAK);
  903. CString strText = pItem->GetCaption(pColumn);
  904. ReplaceInHyperLinks(pItem, strText, XTP_HLINK_SPACE_X);
  905. int nCalculatedHeight = CalculateRowHeight(pDC, strText, rcItem.Width(), bWordBreak);
  906. nHeight = max(nHeight, nCalculatedHeight);
  907. }
  908. if (pItem->GetIconIndex() != XTP_REPORT_NOICON)
  909. {
  910. CXTPImageManagerIcon* pIcon = pRow->GetControl()->
  911. GetImageManager()->GetImage(pItem->GetIconIndex(), 0);
  912. if (pIcon)
  913. {
  914. nHeight = max(nHeight, pIcon->GetHeight());
  915. }
  916. }
  917. }
  918. }
  919. CMDTARGET_RELEASE(pItemMetrics);
  920. return max(nHeight + 5, m_nRowHeight) + (IsGridVisible(FALSE) ? 1 : 0);
  921. }
  922. int CXTPReportPaintManager::GetRowHeight(CDC* /*pDC*/, CXTPReportRow* pRow)
  923. {
  924. if (!pRow->IsGroupRow())
  925. {
  926. return m_nRowHeight + (IsGridVisible(FALSE) ? 1 : 0);
  927. }
  928. if (m_bShadeGroupHeadings)
  929. return m_nRowHeight + 6;
  930. return m_nRowHeight + 16;
  931. }
  932. BOOL CXTPReportPaintManager::IsColumHotTrackingEnabled() const
  933. {
  934. return m_bHotTracking && ((m_columnStyle == xtpReportColumnOffice2003) || ((m_columnStyle == xtpReportColumnExplorer) && m_themeWrapper.IsAppThemed()));
  935. }
  936. void CXTPReportPaintManager::DrawColumnBackground(CDC* pDC, CXTPReportColumn* pColumn, CRect rcColumn, BOOL& bColumnPressed, CXTPReportHeader* pHeader)
  937. {
  938. CXTPReportColumn* pPrevColumn = pHeader ? pHeader->GetNextVisibleColumn(pColumn->GetIndex(), -1) : NULL;
  939. if (m_columnStyle == xtpReportColumnShaded)
  940. {
  941. int nShadowWidth = 4;
  942. if (pColumn->GetDrawHeaderDivider())
  943. DrawVerticalLine(pDC, rcColumn.right - 1, rcColumn.top + 2, rcColumn.Height() - 2 - nShadowWidth, m_clrControlDark);
  944. DrawHorizontalLine(pDC, rcColumn.left, rcColumn.bottom - 3, rcColumn.Width(), MixColor(m_clrHeaderControl, m_clrControlDark, 0.25));
  945. DrawHorizontalLine(pDC, rcColumn.left, rcColumn.bottom - 2, rcColumn.Width(), MixColor(m_clrHeaderControl, m_clrControlDark, 0.4));
  946. DrawHorizontalLine(pDC, rcColumn.left, rcColumn.bottom - 1, rcColumn.Width(), MixColor(m_clrHeaderControl, m_clrControlDark, 0.6));
  947. if (!pPrevColumn || pPrevColumn->GetDrawHeaderDivider())
  948. DrawVerticalLine(pDC, rcColumn.left, rcColumn.top + 2, rcColumn.Height() - 2 - nShadowWidth, m_clrControlLightLight);
  949. }
  950. else if (m_columnStyle == xtpReportColumnOffice2003 || m_columnStyle == xtpReportColumnOffice2007)
  951. {
  952. XTPDrawHelpers()->GradientFill(pDC, rcColumn,
  953. bColumnPressed ? m_grcGradientColumnPushed: pColumn->IsHotTracking() ? m_grcGradientColumnHot : m_grcGradientColumn, FALSE);
  954. DrawHorizontalLine(pDC, rcColumn.left, rcColumn.bottom - 1, rcColumn.Width(), m_clrGradientColumnShadow);
  955. if (pColumn->GetDrawHeaderDivider())
  956. DrawVerticalLine(pDC, rcColumn.right - 1, rcColumn.top + 2, rcColumn.Height() - 2 - 4, m_clrGradientColumnSeparator);
  957. if (m_columnStyle == xtpReportColumnOffice2003 && (!pPrevColumn || pPrevColumn->GetDrawHeaderDivider()))
  958. DrawVerticalLine(pDC, rcColumn.left, rcColumn.top + 3, rcColumn.Height() - 2 - 4, m_clrControlLightLight);
  959. if (pColumn->GetControl()->IsGroupByVisible())
  960. DrawHorizontalLine(pDC, rcColumn.left, rcColumn.top, rcColumn.Width(), m_clrGradientColumnShadow);
  961. bColumnPressed = FALSE;
  962. }
  963. else if (m_columnStyle == xtpReportColumnExplorer)
  964. {
  965. if (m_themeWrapper.IsAppThemed())
  966. {
  967. int iState = bColumnPressed ? HIS_PRESSED: pColumn->IsHotTracking() ? HIS_HOT : HIS_NORMAL;
  968. m_themeWrapper.DrawThemeBackground(pDC->GetSafeHdc(), HP_HEADERITEM, iState, &rcColumn, NULL);
  969. }
  970. else
  971. {
  972. if (bColumnPressed)
  973. {
  974. pDC->Draw3dRect(rcColumn, m_clrControlDark, m_clrControlDark);
  975. }
  976. else
  977. {
  978. pDC->Draw3dRect(rcColumn, m_clrControlLightLight, m_clrBtnText);
  979. rcColumn.DeflateRect(1, 1);
  980. pDC->Draw3dRect(rcColumn, m_clrHeaderControl, m_clrControlDark);
  981. if(!pColumn->GetDrawHeaderDivider())
  982. {
  983. DrawVerticalLine(pDC, rcColumn.right - 1, rcColumn.top, rcColumn.Height() - 1, m_clrHeaderControl);
  984. DrawVerticalLine(pDC, rcColumn.right, rcColumn.top, rcColumn.Height() - 1, m_clrHeaderControl);
  985. pDC->SetPixel(rcColumn.right, rcColumn.top - 1, m_clrControlLightLight);
  986. pDC->SetPixel(rcColumn.right, rcColumn.bottom - 1, m_clrControlDark);
  987. }
  988. if(pPrevColumn && !pPrevColumn->GetDrawHeaderDivider())
  989. {
  990. DrawVerticalLine(pDC, rcColumn.left - 1, rcColumn.top, rcColumn.Height() - 1, m_clrHeaderControl);
  991. pDC->SetPixel(rcColumn.left - 1, rcColumn.bottom - 1, m_clrControlDark);
  992. }
  993. }
  994. }
  995. bColumnPressed = FALSE;
  996. }
  997. else
  998. { // xtpReportColumnFlat
  999. pDC->Draw3dRect(rcColumn, m_clrControlLightLight, m_clrControlDark);
  1000. if(!pColumn->GetDrawHeaderDivider())
  1001. {
  1002. DrawVerticalLine(pDC, rcColumn.right - 1, rcColumn.top + 1, rcColumn.Height() - 2, m_clrHeaderControl);
  1003. pDC->SetPixel(rcColumn.right - 1, rcColumn.top, m_clrControlLightLight);
  1004. }
  1005. if(pPrevColumn && !pPrevColumn->GetDrawHeaderDivider())
  1006. DrawVerticalLine(pDC, rcColumn.left, rcColumn.top + 1, rcColumn.Height() - 2, m_clrHeaderControl);
  1007. }
  1008. }
  1009. void CXTPReportPaintManager::DrawColumnFooter(CDC* pDC, CXTPReportColumn* pColumn, CXTPReportHeader* /*pHeader*/, CRect rcColumn)
  1010. {
  1011. if (pColumn->GetDrawFooterDivider())
  1012. {
  1013. DrawVerticalLine(pDC, rcColumn.right, rcColumn.top + 6, rcColumn.Height() - 9, m_clrControlLightLight);
  1014. DrawVerticalLine(pDC, rcColumn.right - 1, rcColumn.top + 5, rcColumn.Height() - 9,
  1015. m_columnStyle == xtpReportColumnOffice2003 || m_columnStyle == xtpReportColumnOffice2007 ? m_clrGradientColumnSeparator : m_clrControlDark);
  1016. }
  1017. pDC->SetBkMode(TRANSPARENT);
  1018. CXTPFontDC font(pDC, pColumn->GetFooterFont(), m_clrCaptionText);
  1019. CString strCaption = pColumn->GetFooterText();
  1020. CSize sizeText = pDC->GetTextExtent(strCaption);
  1021. CRect rcText(rcColumn);
  1022. rcText.DeflateRect(3, 2, 3, 2);
  1023. if (pColumn->GetFooterAlignment() != DT_LEFT)
  1024. {
  1025. int nLength = 6 + sizeText.cx;
  1026. if (rcText.Width() > nLength)
  1027. {
  1028. if (pColumn->GetFooterAlignment() & DT_RIGHT)
  1029. rcText.left = rcText.right - nLength;
  1030. if (pColumn->GetFooterAlignment() & DT_CENTER)
  1031. rcText.left = (rcText.left + rcText.right - nLength) / 2;
  1032. }
  1033. }
  1034. UINT uFlags = DT_END_ELLIPSIS | DT_NOPREFIX;
  1035. if (!m_bFixedRowHeight && (pColumn->GetFooterAlignment() & DT_WORDBREAK))
  1036. {
  1037. uFlags |= DT_WORDBREAK;
  1038. // try to center vertically because DT_VCENTER works only for DT_SINGLELINE;
  1039. CRect rcTextReal = rcText;
  1040. pDC->DrawText(strCaption, rcTextReal, uFlags | DT_CALCRECT);
  1041. int nHeightDiff = rcText.Height() - rcTextReal.Height();
  1042. if (nHeightDiff > 1)
  1043. {
  1044. rcText.top += nHeightDiff/2;
  1045. }
  1046. }
  1047. else
  1048. {
  1049. uFlags |= DT_SINGLELINE | DT_VCENTER;
  1050. }
  1051. if (strCaption.GetLength() > 0 && rcText.right > rcText.left)
  1052. {
  1053. pDC->DrawText(strCaption, rcText, uFlags);
  1054. }
  1055. }
  1056. void CXTPReportPaintManager::DrawColumn(CDC* pDC, CXTPReportColumn* pColumn, CXTPReportHeader* pHeader, CRect rcColumn, BOOL bDrawExternal)
  1057. {
  1058. // save column parameter for future use in drawing
  1059. BOOL bDraggingFromHeader = bDrawExternal && pColumn->IsDragging() &&
  1060. rcColumn.left == 0 && rcColumn.top == 0 && pHeader->IsDragHeader();
  1061. BOOL bPlainColumn = bDrawExternal && !bDraggingFromHeader;
  1062. BOOL bColumnPressed = pColumn->IsDragging() && !bDrawExternal && pHeader->IsDragHeader();
  1063. CRect rcColumn0 = rcColumn;
  1064. // draw
  1065. int nIconID = pColumn->GetIconID();
  1066. CString strCaption = pColumn->GetCaption();
  1067. int nShadowWidth = !bPlainColumn && m_columnStyle == xtpReportColumnShaded ? 4 : 0;
  1068. if (bPlainColumn)
  1069. {
  1070. if (m_columnStyle == xtpReportColumnOffice2007)
  1071. {
  1072. XTPDrawHelpers()->GradientFill(pDC, rcColumn, m_grcGradientColumn, FALSE);
  1073. pDC->Draw3dRect(rcColumn, m_clrGradientColumnShadow, m_clrGradientColumnShadow);
  1074. }
  1075. else
  1076. {
  1077. pDC->Draw3dRect(rcColumn, m_clrControlLightLight, m_clrControlDark);
  1078. pDC->MoveTo(rcColumn.left, rcColumn.bottom);
  1079. pDC->LineTo(rcColumn.right, rcColumn.bottom);
  1080. pDC->LineTo(rcColumn.right, rcColumn.top-1);
  1081. }
  1082. }
  1083. else
  1084. {
  1085. DrawColumnBackground(pDC, pColumn, rcColumn, bColumnPressed, pHeader);
  1086. }
  1087. pDC->SetBkColor(m_clrHeaderControl);
  1088. rcColumn.bottom = rcColumn.bottom - 1 - nShadowWidth;
  1089. CRect rcText(rcColumn);
  1090. if (!pColumn->IsAutoSize() && !bPlainColumn)
  1091. {
  1092. rcText.left += pColumn->GetIndent();
  1093. }
  1094. BOOL bHasSortTriangle = pColumn->HasSortTriangle() && !pDC->IsPrinting();
  1095. CXTPFontDC font(pDC, &m_fontCaption);
  1096. CSize sizeText = pDC->GetTextExtent(strCaption);
  1097. if (pColumn->GetHeaderAlignment() != DT_LEFT && !bPlainColumn)
  1098. {
  1099. int nLength = 6 + sizeText.cx;
  1100. if (nIconID != XTP_REPORT_NOICON)
  1101. {
  1102. nLength += DrawBitmap(NULL, pColumn->GetControl(), rcText, nIconID) + 2;
  1103. }
  1104. if (bHasSortTriangle)
  1105. nLength += 27;
  1106. if (rcText.Width() > nLength)
  1107. {
  1108. if (pColumn->GetHeaderAlignment() & DT_RIGHT)
  1109. rcText.left = rcText.right - nLength;
  1110. if (pColumn->GetHeaderAlignment() & DT_CENTER)
  1111. rcText.left = (rcText.left + rcText.right - nLength) / 2;
  1112. }
  1113. }
  1114. if (nIconID != XTP_REPORT_NOICON && !bPlainColumn)
  1115. {
  1116. CRect rcIcon(rcText);
  1117. rcIcon.bottom += nShadowWidth;
  1118. // shift column left by bitmap drawing place
  1119. //rcText.left += DrawBitmap(pDC, pColumn->GetControl(), rcIcon, nIconID);
  1120. rcText.left += DrawColumnIcon(pDC, pColumn, rcColumn0, rcIcon, nIconID);
  1121. // shift column left to the column right to disallow drawing text on Bitmap column headers
  1122. rcText.left += 2;
  1123. }
  1124. pDC->SetBkMode(TRANSPARENT);
  1125. rcText.DeflateRect(3, 0, 3, 0);
  1126. CRect rcTriangle(rcText);
  1127. if (strCaption.GetLength() > 0 && rcText.right > rcText.left)
  1128. {
  1129. // TODO: Markup support for columns
  1130. //      if (pColumn->m_pMarkupUIElement)
  1131. //      {
  1132. //          rcText.DeflateRect(2, 1, 2, 0);
  1133. //
  1134. //          XTPMarkupMeasureElement(pColumn->m_pMarkupUIElement, rcText.Width(), INT_MAX);
  1135. //
  1136. //          XTPMarkupSetDefaultFont(m_pRecord->GetRecords()->GetMarkupContext(), (HFONT)m_fontCaption->GetSafeHandle(), m_clrControlLightLight);
  1137. //          XTPMarkupRenderElement(m_pMarkupUIElement, pDC->GetSafeHdc(), &rcText);
  1138. //      }
  1139. //      else
  1140. {
  1141. pDC->SetTextColor(m_clrCaptionText);
  1142. if (m_bDrawSortTriangleAlways && bHasSortTriangle)
  1143. {
  1144. sizeText.cx = max(-5, min(sizeText.cx, rcText.Width() - 27));
  1145. rcText.right = min(rcText.right, rcText.left + sizeText.cx + 8);
  1146. }
  1147. UINT uFlags = DT_END_ELLIPSIS | DT_NOPREFIX;
  1148. if (pColumn->GetHeaderAlignment() & DT_WORDBREAK)
  1149. {
  1150. uFlags |= DT_WORDBREAK;
  1151. if (pColumn->GetHeaderAlignment() & DT_RIGHT)
  1152. uFlags |= DT_RIGHT;
  1153. // try to center vertically because DT_VCENTER works only for DT_SINGLELINE;
  1154. CRect rcTextReal = rcText;
  1155. pDC->DrawText(strCaption, rcTextReal, uFlags | DT_CALCRECT);
  1156. int nHeightDiff = rcText.Height() - rcTextReal.Height();
  1157. if (nHeightDiff > 1)
  1158. {
  1159. rcText.top += nHeightDiff/2;
  1160. }
  1161. }
  1162. else
  1163. {
  1164. uFlags |= DT_SINGLELINE | DT_VCENTER;
  1165. }
  1166. pDC->DrawText(strCaption, rcText, uFlags);
  1167. rcTriangle.left += sizeText.cx;
  1168. }
  1169. }
  1170. if (bHasSortTriangle)
  1171. {
  1172. rcTriangle.left += (bPlainColumn ? 17 : 10);
  1173. DrawTriangle(pDC, rcTriangle, pColumn->IsSortedDecreasing());
  1174. }
  1175. if (bColumnPressed && m_bInvertColumnOnClick)
  1176. {
  1177. rcColumn.bottom += nShadowWidth;
  1178. pDC->InvertRect(&rcColumn);
  1179. }
  1180. }
  1181. int CXTPReportPaintManager::CalcColumnHeight(CDC* pDC, CXTPReportColumn* pColumn,
  1182. int nTotalWidth)
  1183. {
  1184. int nIconID = pColumn->GetIconID();
  1185. CString strCaption = pColumn->GetCaption();
  1186. int nWidth = pDC->IsPrinting() ? pColumn->GetPrintWidth(nTotalWidth) : pColumn->GetWidth();
  1187. CRect rcColumn = pColumn->GetRect();
  1188. rcColumn.right = rcColumn.left + nWidth;
  1189. CRect rcText(rcColumn);
  1190. if (!pColumn->IsAutoSize())
  1191. {
  1192. rcText.left += pColumn->GetIndent();
  1193. }
  1194. BOOL bHasSortTriangle = pColumn->HasSortTriangle() && !pDC->IsPrinting();
  1195. CXTPFontDC font(pDC, &m_fontCaption);
  1196. CSize sizeText = pDC->GetTextExtent(strCaption);
  1197. if (nIconID != XTP_REPORT_NOICON)
  1198. {
  1199. // shift column left by bitmap drawing place
  1200. rcText.left += DrawBitmap(NULL, pColumn->GetControl(), rcText, nIconID);
  1201. // shift column left to the column right to disallow drawing text on Bitmap column headers
  1202. rcText.left += 2;
  1203. }
  1204. rcText.DeflateRect(3, 0, 3, 0);
  1205. if (strCaption.GetLength() > 0 && rcText.right > rcText.left)
  1206. {
  1207. if (m_bDrawSortTriangleAlways && bHasSortTriangle)
  1208. {
  1209. sizeText.cx = max(-5, min(sizeText.cx, rcText.Width() - 27));
  1210. rcText.right = min(rcText.right, rcText.left + sizeText.cx + 8);
  1211. }
  1212. UINT uFlags = DT_END_ELLIPSIS | DT_VCENTER | DT_NOPREFIX;
  1213. uFlags |= (pColumn->GetHeaderAlignment() & DT_WORDBREAK) ? DT_WORDBREAK : DT_SINGLELINE;
  1214. uFlags |= DT_CALCRECT;
  1215. pDC->DrawText(strCaption, rcText, uFlags);
  1216. return m_pHeaderHeightFormula->Calculate(rcText.Height());
  1217. }
  1218. return 8;
  1219. }
  1220. void CXTPReportPaintManager::FillGroupByControl(CDC* pDC, CRect& rcGroupBy)
  1221. {
  1222. pDC->FillSolidRect(rcGroupBy, m_clrGroupBoxBack);
  1223. }
  1224. void CXTPReportPaintManager::DrawConnector(CDC* pDC, CPoint ptFrom, CPoint ptTo)
  1225. {
  1226. COLORREF crConnector = RGB(0, 0, 0);
  1227. DrawVerticalLine(pDC, ptFrom.x, ptFrom.y, ptTo.y - ptFrom.y, crConnector);
  1228. DrawHorizontalLine(pDC, ptFrom.x, ptTo.y, ptTo.x - ptFrom.x, crConnector);
  1229. }
  1230. void CXTPReportPaintManager::DrawFocusedRow(CDC* pDC, CRect rcRow)
  1231. {
  1232. COLORREF clrTextColor = pDC->SetTextColor(m_clrControlBack);
  1233. COLORREF clrBkColor = pDC->SetBkColor(m_clrWindowText);
  1234. pDC->DrawFocusRect(rcRow);
  1235. pDC->SetTextColor(clrTextColor);
  1236. pDC->SetBkColor(clrBkColor);
  1237. }
  1238. int CXTPReportPaintManager::GetPreviewLinesCount(CDC* pDC, CRect& rcText, const CString& strText)
  1239. {
  1240. if (rcText.Width() < 1)
  1241. return 0;
  1242. if (pDC->GetTextExtent(strText).cx / rcText.Width() > m_nMaxPreviewLines)
  1243. return m_nMaxPreviewLines;
  1244. CRect rcCalc(rcText.left, 0, rcText.right, 0);
  1245. pDC->DrawText(strText, rcCalc, DT_WORDBREAK | DT_CALCRECT | DT_NOPREFIX);
  1246. return min(rcCalc.Height() / pDC->GetTextExtent(_T(" "), 1).cy, m_nMaxPreviewLines);
  1247. }
  1248. void CXTPReportPaintManager::SetTextFont(LOGFONT& lf)
  1249. {
  1250. m_fontText.DeleteObject();
  1251. m_fontBoldText.DeleteObject();
  1252. m_fontText.CreateFontIndirect(&lf);
  1253. lf.lfWeight = FW_BOLD;
  1254. m_fontBoldText.CreateFontIndirect(&lf);
  1255. CWindowDC dc (NULL);
  1256. CXTPFontDC font(&dc, &m_fontText);
  1257. int nFontHeight = dc.GetTextExtent(_T(" "), 1).cy;
  1258. m_nRowHeight = max(18, nFontHeight + 4);
  1259. }
  1260. void CXTPReportPaintManager::SetCaptionFont(LOGFONT& lf)
  1261. {
  1262. m_fontCaption.DeleteObject();
  1263. VERIFY(m_fontCaption.CreateFontIndirect(&lf));
  1264. CWindowDC dc (NULL);
  1265. CXTPFontDC font(&dc, &m_fontCaption);
  1266. font.SetFont(&m_fontCaption);
  1267. int nFontHeight = dc.GetTextExtent(_T(" "), 1).cy;
  1268. m_nHeaderHeight = m_pHeaderHeightFormula->Calculate(nFontHeight);
  1269. m_nFooterHeight = m_nHeaderHeight;
  1270. }
  1271. int CXTPReportPaintManager::GetFooterHeight(CXTPReportControl* pControl, CDC* pDC, int nTotalWidth)
  1272. {
  1273. ASSERT(pControl && pDC);
  1274. if (!pControl || !pDC)
  1275. {
  1276. return m_nFooterHeight;
  1277. }
  1278. CXTPReportColumns* pColumns = pControl->GetColumns();
  1279. int nColumnCount = pColumns->GetCount();
  1280. int nHeight = 22;
  1281. CXTPFontDC font(pDC);
  1282. for (int nColumn = 0; nColumn < nColumnCount; nColumn++)
  1283. {
  1284. CXTPReportColumn* pColumn = pColumns->GetAt(nColumn);
  1285. if (pColumn && pColumn->IsVisible())
  1286. {
  1287. CString strCaption = pColumn->GetFooterText();
  1288. int nWidth = pDC->IsPrinting() ? pColumn->GetPrintWidth(nTotalWidth) : pColumn->GetWidth();
  1289. CRect rcText(0, 0, nWidth, 22);
  1290. rcText.DeflateRect(3, 0, 3, 0);
  1291. UINT uFlags = DT_CALCRECT | DT_END_ELLIPSIS | DT_VCENTER | DT_NOPREFIX;
  1292. if (!m_bFixedRowHeight && (pColumn->GetFooterAlignment() & DT_WORDBREAK))
  1293. uFlags |= DT_WORDBREAK;
  1294. else
  1295. uFlags |= DT_SINGLELINE;
  1296. font.SetFont(pColumn->GetFooterFont());
  1297. pDC->DrawText(strCaption, rcText, uFlags);
  1298. nHeight = max(nHeight, rcText.Height() + 8);
  1299. }
  1300. }
  1301. return  nHeight;
  1302. }
  1303. int CXTPReportPaintManager::GetHeaderHeight(CXTPReportControl* pControl,
  1304. CDC* pDC, int nTotalWidth)
  1305. {
  1306. ASSERT(pControl && pDC);
  1307. if (m_bFixedRowHeight || !pControl || !pDC)
  1308. {
  1309. return GetHeaderHeight();
  1310. }
  1311. CXTPReportColumns* pColumns = pControl->GetColumns();
  1312. int nColumnCount = pColumns->GetCount();
  1313. int nHeight = m_nHeaderHeight;
  1314. for (int nColumn = 0; nColumn < nColumnCount; nColumn++)
  1315. {
  1316. CXTPReportColumn* pColumn = pColumns->GetAt(nColumn);
  1317. if (pColumn && pColumn->IsVisible())
  1318. {
  1319. if (pColumn->GetHeaderAlignment() & DT_WORDBREAK)
  1320. {
  1321. int nColHeight = CalcColumnHeight(pDC, pColumn, nTotalWidth);
  1322. nHeight = max(nHeight, nColHeight);
  1323. }
  1324. // calculate icon height.
  1325. int nIconID = pColumn->GetIconID();
  1326. if (nIconID != XTP_REPORT_NOICON)
  1327. {
  1328. CXTPImageManagerIcon* pIcon = pColumn->GetControl()->
  1329. GetImageManager()->GetImage(nIconID, 0);
  1330. if (pIcon)
  1331. {
  1332. nHeight = max(nHeight, pIcon->GetHeight() + 2);
  1333. }
  1334. }
  1335. }
  1336. }
  1337. return nHeight;
  1338. }
  1339. void CXTPReportPaintManager::SetPreviewIndent(int nLeft, int nTop, int nRight, int nBottom)
  1340. {
  1341. m_rcPreviewIndent.SetRect(nLeft, nTop, nRight, nBottom);
  1342. }
  1343. void CXTPReportPaintManager::DrawInplaceButton(CDC* pDC, CXTPReportInplaceButton* pButton)
  1344. {
  1345. CXTPClientRect rect((CWnd*)pButton);
  1346. BOOL bButtonIconDrawn = FALSE;
  1347. if (m_bThemedInplaceButtons)
  1348. {
  1349. if (pButton->GetID() == XTP_ID_REPORT_COMBOBUTTON && m_themeCombo.IsAppThemed())
  1350. {
  1351. m_themeCombo.DrawThemeBackground(*pDC, CP_DROPDOWNBUTTON,
  1352. pButton->IsPressed() ? CBXS_PRESSED:  CBXS_NORMAL, rect, 0);
  1353. return;
  1354. }
  1355. if (pButton->GetID() == XTP_ID_REPORT_EXPANDBUTTON  && m_themeButton.IsAppThemed())
  1356. {
  1357. pDC->FillSolidRect(rect, GetXtremeColor(COLOR_3DFACE));
  1358. m_themeButton.DrawThemeBackground(*pDC, BP_PUSHBUTTON, pButton->IsPressed() ? PBS_PRESSED :
  1359. CWnd::GetFocus() == pButton ? PBS_DEFAULTED : PBS_NORMAL, rect, 0);
  1360. if(!DrawInplaceButtonIcon(pDC, pButton))
  1361. {
  1362. // draw dots
  1363. pDC->Rectangle(rect.left + 3, rect.bottom -5, rect.left + 5, rect.bottom -3);
  1364. pDC->Rectangle(rect.left + 7, rect.bottom -5, rect.left + 9, rect.bottom -3);
  1365. pDC->Rectangle(rect.left + 11, rect.bottom -5, rect.left + 13, rect.bottom -3);
  1366. }
  1367. return;
  1368. }
  1369. if (pButton->GetID() == XTP_ID_REPORT_SPINBUTTON && m_themeSpin.IsAppThemed())
  1370. {
  1371. int nHeight = rect.Height() / 2;
  1372. rect.bottom -= nHeight;
  1373. m_themeSpin.DrawThemeBackground(*pDC, SPNP_UP, pButton->GetState() == SPNP_UP ? UPS_PRESSED : UPS_NORMAL, rect, 0);
  1374. rect.OffsetRect(0, nHeight);
  1375. m_themeSpin.DrawThemeBackground(*pDC, SPNP_DOWN, pButton->GetState() == SPNP_DOWN ? UPS_PRESSED : UPS_NORMAL, rect, 0);
  1376. return;
  1377. }
  1378. }
  1379. if (pButton->GetID() == XTP_ID_REPORT_COMBOBUTTON)
  1380. {
  1381. DrawInplaceButtonFrame(pDC, pButton);
  1382. }
  1383. else if (pButton->GetID() == XTP_ID_REPORT_EXPANDBUTTON)
  1384. {
  1385. DrawInplaceButtonFrame(pDC, pButton);
  1386. bButtonIconDrawn = DrawInplaceButtonIcon(pDC, pButton);
  1387. }
  1388. else if(pButton->GetID() == XTP_ID_REPORT_SPINBUTTON)
  1389. {
  1390. CXTPClientRect rect((CWnd*)pButton);
  1391. int nHeight = rect.Height() / 2;
  1392. rect.bottom -= nHeight;
  1393. for(int i = 0; i < 2; i++)
  1394. {
  1395. pDC->FillSolidRect(rect, GetXtremeColor(COLOR_3DFACE));
  1396. if (i == 0 && pButton->GetState() == SPNP_UP || i == 1 && pButton->GetState() == SPNP_DOWN)
  1397. {
  1398. pDC->Draw3dRect(rect, GetXtremeColor(COLOR_3DDKSHADOW), GetXtremeColor(COLOR_WINDOW));
  1399. }
  1400. else
  1401. {
  1402. pDC->Draw3dRect(rect, GetXtremeColor(COLOR_3DFACE), GetXtremeColor(COLOR_3DDKSHADOW));
  1403. rect.DeflateRect(1, 1);
  1404. pDC->Draw3dRect(rect, GetXtremeColor(COLOR_WINDOW), GetXtremeColor(COLOR_3DSHADOW));
  1405. rect.InflateRect(1, 1);
  1406. }
  1407. rect.OffsetRect(0, nHeight);
  1408. }
  1409. }
  1410. CXTPPenDC pen (*pDC, GetXtremeColor(COLOR_BTNTEXT));
  1411. CXTPBrushDC brush (*pDC, GetXtremeColor(COLOR_BTNTEXT));
  1412. if (pButton->GetID() == XTP_ID_REPORT_COMBOBUTTON)
  1413. {
  1414. CPoint pt = rect.CenterPoint();
  1415. CPoint pts[3];
  1416. pts[0] = CPoint(pt.x -3, pt.y -1);
  1417. pts[1] = CPoint(pt.x + 3, pt.y -1);
  1418. pts[2] = CPoint(pt.x, pt.y +2);
  1419. pDC->Polygon(pts, 3);
  1420. }
  1421. if (pButton->GetID() == XTP_ID_REPORT_EXPANDBUTTON && !bButtonIconDrawn)
  1422. {
  1423. pDC->Rectangle(rect.left + 3, rect.bottom -5, rect.left + 5, rect.bottom -3);
  1424. pDC->Rectangle(rect.left + 7, rect.bottom -5, rect.left + 9, rect.bottom -3);
  1425. pDC->Rectangle(rect.left + 11, rect.bottom -5, rect.left + 13, rect.bottom -3);
  1426. }
  1427. if (pButton->GetID() == XTP_ID_REPORT_SPINBUTTON)
  1428. {
  1429. CPoint pt = rect.CenterPoint();
  1430. pt.y -= rect.Height() / 4;
  1431. CPoint pts[3];
  1432. pts[0] = CPoint(pt.x - 2, pt.y + 1);
  1433. pts[1] = CPoint(pt.x + 2, pt.y + 1);
  1434. pts[2] = CPoint(pt.x, pt.y - 1);
  1435. pDC->Polygon(pts, 3);
  1436. pt.y += rect.Height() / 2;
  1437. pts[0] = CPoint(pt.x - 2, pt.y - 1);
  1438. pts[1] = CPoint(pt.x + 2, pt.y - 1);
  1439. pts[2] = CPoint(pt.x, pt.y + 1);
  1440. pDC->Polygon(pts, 3);
  1441. }
  1442. }
  1443. void CXTPReportPaintManager::DrawInplaceButtonFrame(CDC* pDC, CXTPReportInplaceButton* pButton)
  1444. {
  1445. CXTPClientRect rect((CWnd*)pButton);
  1446. pDC->FillSolidRect(rect, GetXtremeColor(COLOR_3DFACE));
  1447. if (pButton->IsPressed())
  1448. {
  1449. pDC->Draw3dRect(rect, GetXtremeColor(COLOR_3DDKSHADOW), GetXtremeColor(COLOR_WINDOW));
  1450. }
  1451. else
  1452. {
  1453. pDC->Draw3dRect(rect, GetXtremeColor(COLOR_3DFACE), GetXtremeColor(COLOR_3DDKSHADOW));
  1454. rect.DeflateRect(1, 1);
  1455. pDC->Draw3dRect(rect, GetXtremeColor(COLOR_WINDOW), GetXtremeColor(COLOR_3DSHADOW));
  1456. }
  1457. }
  1458. BOOL CXTPReportPaintManager::DrawInplaceButtonIcon(CDC* pDC, CXTPReportInplaceButton* pButton)
  1459. {
  1460. CXTPClientRect rect((CWnd*)pButton);
  1461. int nIconIndex = pButton->GetIconIndex();
  1462. if(nIconIndex == XTP_REPORT_NOICON)
  1463. return FALSE;
  1464. CXTPImageManagerIcon* pIcon = pButton->pControl->GetImageManager()->GetImage(nIconIndex, 0);
  1465. if(!pIcon)
  1466. return FALSE;
  1467. CSize szImage(pIcon->GetWidth(), pIcon->GetHeight());
  1468. CPoint ptIcon(max(rect.left, rect.left + (rect.Width() - szImage.cx) / 2),
  1469. max(rect.top, rect.top + (rect.Height() - szImage.cy) / 2));
  1470. szImage.cx = min(szImage.cx, rect.Width());
  1471. szImage.cy = min(szImage.cy, rect.Height());
  1472. pIcon->Draw(pDC, ptIcon, pIcon->GetIcon(), szImage);
  1473. return TRUE;
  1474. }
  1475. void CXTPReportPaintManager::DrawTreeStructureLine(CDC* pDC, int x, int y, int cx, int cy, COLORREF clr)
  1476. {
  1477. if (m_treeStructureStyle == xtpReportTreeStructureDots)
  1478. {
  1479. const unsigned short _cb[] = {0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55};
  1480. DrawGridPat(pDC, &m_brushTreeStructure, CRect(x, y, x + cx, y + cy), _cb, m_clrControlDark);
  1481. }
  1482. else
  1483. {
  1484. pDC->FillSolidRect(x, y, cx, cy, clr);
  1485. }
  1486. }
  1487. void CXTPReportPaintManager::DrawTreeStructure(XTP_REPORTRECORDITEM_DRAWARGS* pDrawArgs, XTP_REPORTRECORDITEM_METRICS* pMetrics, CRect rcItem, CSize sizeGlyph)
  1488. {
  1489. if (m_treeStructureStyle == xtpReportTreeStructureNone)
  1490. return;
  1491. CDC* pDC = pDrawArgs->pDC;
  1492. CXTPReportRow* pRow = pDrawArgs->pRow;
  1493. COLORREF clrTreeStructure = pMetrics->clrForeground;
  1494. if(pDrawArgs->pControl->IsVirtualMode())
  1495. {
  1496. if(pMetrics->nVirtRowLevel == 0)
  1497. return;
  1498. }
  1499. else
  1500. {
  1501. if (pRow->IsGroupRow() || (m_nTreeStructureStyle == 0 && (!pRow->GetParentRow() || pRow->GetParentRow()->IsGroupRow())))
  1502. return;
  1503. }
  1504. int nTreeIndent = pDrawArgs->pControl->GetPaintManager()->m_nTreeIndent;
  1505. int nHeight = rcItem.Height();
  1506. LONG lHorLineOffset = nHeight / 2;
  1507. int nIconAlign = pDrawArgs->nTextAlign & xtpColumnIconMask;
  1508. switch(nIconAlign)
  1509. {
  1510. case xtpColumnIconTop:
  1511. lHorLineOffset = sizeGlyph.cy / 2;
  1512. break;
  1513. case xtpColumnIconBottom:
  1514. lHorLineOffset = rcItem.bottom - rcItem.top - 2 - sizeGlyph.cy / 2;
  1515. break;
  1516. }
  1517. if(m_nTreeStructureStyle > 0)
  1518. rcItem.OffsetRect((sizeGlyph.cy + 1) / 2 + 2, 0);
  1519. BOOL bSiblingRow = pDrawArgs->pControl->IsVirtualMode() ? !(pMetrics->nVirtRowFlags & xtpVirtRowLastChild) : !!pRow->GetNextSiblingRow();
  1520. if (!bSiblingRow)
  1521. {
  1522. DrawTreeStructureLine(pDC, rcItem.left, rcItem.top - 1, 1, lHorLineOffset + 1, clrTreeStructure);
  1523. }
  1524. else
  1525. {
  1526. DrawTreeStructureLine(pDC, rcItem.left, rcItem.top - 1, 1, nHeight + 1, clrTreeStructure);
  1527. }
  1528. DrawTreeStructureLine(pDC, rcItem.left, rcItem.top + lHorLineOffset, sizeGlyph.cx / 2 + 1, 1, clrTreeStructure);
  1529. for (;;)
  1530. {
  1531. pRow = pRow->GetParentRow();
  1532. if (pRow == NULL || pRow->IsGroupRow() || (m_nTreeStructureStyle == 0 && (pRow->GetParentRow() == 0 || pRow->GetParentRow()->IsGroupRow())))
  1533. break;
  1534. rcItem.OffsetRect(-nTreeIndent, 0);
  1535. if (pRow->GetNextSiblingRow())
  1536. {
  1537. DrawTreeStructureLine(pDC, rcItem.left, rcItem.top - 1, 1, rcItem.Height() + 1, clrTreeStructure);
  1538. }
  1539. }
  1540. }
  1541. int CXTPReportPaintManager::DrawString(int* pnCurrDrawPos, CDC* pDC, const CString& strDraw, CRect rcDraw, UINT nFormat)
  1542. {
  1543. int nCharCount = 0;
  1544. switch (nFormat)
  1545. {
  1546. case DT_END_ELLIPSIS:
  1547. {
  1548. // in this case char count only for identify if string printed partially
  1549. *pnCurrDrawPos += GetTextExtentX(pDC,strDraw);
  1550. if (*pnCurrDrawPos >= rcDraw.right)
  1551. nCharCount = - 1;
  1552. else
  1553. nCharCount = strDraw.GetLength();
  1554. pDC->DrawText(strDraw, rcDraw, DT_LEFT | DT_END_ELLIPSIS | DT_NOPREFIX);
  1555. break;
  1556. }
  1557. case DT_WORDBREAK:
  1558. {
  1559. const TCHAR seps[] = _T(" tn");
  1560. TCHAR* lpszContext = 0;
  1561. CString strOut = _T("");
  1562. CString strSrc = strDraw;
  1563. TCHAR* szWord = STRTOK_S(strSrc.GetBuffer(strSrc.GetLength()), seps, &lpszContext);
  1564. int nRightStrMargin = GetTextExtentX(pDC, CString(szWord));
  1565. if (nRightStrMargin > rcDraw.Width())
  1566. {
  1567. strOut = szWord;
  1568. }
  1569. else
  1570. {
  1571. while (szWord != NULL && nRightStrMargin < rcDraw.Width())
  1572. {
  1573. strOut = strOut + szWord + _T(" ");
  1574. szWord = STRTOK_S(NULL, seps, &lpszContext);
  1575. nRightStrMargin = GetTextExtentX(pDC,strOut + szWord);
  1576. }
  1577. }
  1578. nCharCount = strOut.GetLength();
  1579. *pnCurrDrawPos += GetTextExtentX(pDC,strOut);
  1580. pDC->DrawText(strOut, rcDraw, DT_LEFT | DT_NOPREFIX);
  1581. break;
  1582. }
  1583. case DT_LEFT:
  1584. case DT_RIGHT:
  1585. case DT_CENTER:
  1586. {
  1587. *pnCurrDrawPos += GetTextExtentX(pDC,strDraw);
  1588. if (*pnCurrDrawPos >= rcDraw.right)
  1589. nCharCount = - 1;
  1590. else
  1591. nCharCount = strDraw.GetLength();
  1592. pDC->DrawText(strDraw, rcDraw, nFormat  | DT_NOPREFIX);
  1593. break;
  1594. }
  1595. } // switch
  1596. return nCharCount;
  1597. }
  1598. int CXTPReportPaintManager::DrawLink(int* pnCurrDrawPos, XTP_REPORTRECORDITEM_DRAWARGS* pDrawArgs, CXTPReportHyperlink* pHyperlink,
  1599. CString strText, CRect rcLink, int nFlag)
  1600. {
  1601. return DrawLink2(pnCurrDrawPos, pDrawArgs, pHyperlink, strText, rcLink, nFlag);
  1602. }
  1603. void CXTPReportPaintManager::DrawTextLine(XTP_REPORTRECORDITEM_DRAWARGS* pDrawArgs, const CString& strText,
  1604. CRect rcItem, int nFlag, int& nCharCounter, int& nHyperlikCounter)
  1605. {
  1606. CDC* pDC = pDrawArgs->pDC;
  1607. CXTPReportRecordItem* pItem = pDrawArgs->pItem;
  1608. UINT nAlingFlag = 0;
  1609. int nHyperlink = nHyperlikCounter; // Hyperlink index
  1610. int nCharCount = nCharCounter; // Number of actually printed chars
  1611. CXTPReportHyperlink* pHl = NULL;
  1612. int nHyperlinks = pItem->GetHyperlinksCount();
  1613. int nCurrStrPos = nCharCount;
  1614. CRect rcText;
  1615. rcText.CopyRect(&rcItem);
  1616. if (nHyperlinks == 0)
  1617. {
  1618. pDC->DrawText(strText, rcText, pDrawArgs->nTextAlign | nFlag | DT_NOPREFIX | DT_SINGLELINE);
  1619. return;
  1620. }
  1621. // calculate rect for drawing text for text alignment feature
  1622. pDC->DrawText(strText, rcText, DT_CALCRECT | DT_NOPREFIX | DT_SINGLELINE);
  1623. if (rcText.Width() < rcItem.Width())
  1624. {
  1625. switch (pDrawArgs->nTextAlign & (DT_RIGHT|DT_CENTER))
  1626. {
  1627. case DT_RIGHT :
  1628. rcText.left = rcItem.right - rcText.Width();
  1629. break;
  1630. case DT_CENTER :
  1631. rcText.left = rcItem.left + (rcItem.Width() - rcText.Width())/2;
  1632. break;
  1633. }
  1634. }
  1635. rcText.right = rcItem.right;
  1636. int nCurrDrawPos = rcText.left;
  1637. while (strText.GetLength() > nCurrStrPos && nCurrDrawPos < rcText.right)
  1638. {
  1639. CString strOut;
  1640. if (nHyperlinks > nHyperlink)
  1641. {
  1642. pHl = pItem->GetHyperlinkAt(nHyperlink);
  1643. strOut = strText.Mid(nCurrStrPos, pHl->m_nHyperTextBegin - nCurrStrPos);
  1644. if (strOut.GetLength() > 0) // print str
  1645. {
  1646. // replace LF, CR characters (if any)
  1647. REMOVE_S(strOut, _T('n'));
  1648. REMOVE_S(strOut, _T('r'));
  1649. nCharCount = DrawString(&nCurrDrawPos, pDC, strOut, rcText, nFlag);
  1650. rcText.left = nCurrDrawPos > rcText.right ? rcText.right : nCurrDrawPos;
  1651. // if previous string was cut - stop draw
  1652. if (nCharCount < strOut.GetLength())
  1653. {
  1654. nCharCount += nCurrStrPos;
  1655. break;
  1656. }
  1657. }
  1658. // print link
  1659. nCharCount = DrawLink(&nCurrDrawPos, pDrawArgs, pHl, strText, rcText, nFlag);
  1660. rcText.left = nCurrDrawPos > rcText.right ? rcText.right : nCurrDrawPos;
  1661. // update current position in string
  1662. nCurrStrPos = pHl->m_nHyperTextBegin + pHl->m_nHyperTextLen;
  1663. nHyperlink++;
  1664. // if previous string was cut - stop draw
  1665. if (nCharCount < (pHl->m_nHyperTextLen))
  1666. {
  1667. nCharCount += nCurrStrPos;
  1668. break;
  1669. }
  1670. }
  1671. else
  1672. {
  1673. // print whole string without links or tail of string
  1674. strOut = strText.Mid(nCurrStrPos, strText.GetLength() - nCurrStrPos);
  1675. nCharCount = DrawString(&nCurrDrawPos, pDC, strOut, rcText, nFlag);
  1676. nCharCount += nCurrStrPos;
  1677. break; // all was drawn!
  1678. }
  1679. }
  1680. pDC->SetTextAlign(nAlingFlag);
  1681. nCharCounter = nCharCount;
  1682. }
  1683. void CXTPReportPaintManager::DrawItemCaption(XTP_REPORTRECORDITEM_DRAWARGS* pDrawArgs, XTP_REPORTRECORDITEM_METRICS* pMetrics)
  1684. {
  1685. CString strText = pMetrics->strText;
  1686. CRect& rcItem = pDrawArgs->rcItem;
  1687. rcItem.DeflateRect(2, 1, 2, 0);
  1688. // draw item text
  1689. if (!strText.IsEmpty())
  1690. {
  1691. if (!m_bFixedRowHeight)// && (pDrawArgs->nTextAlign & DT_WORDBREAK))
  1692. {
  1693. BOOL bWordBreak = !!(pDrawArgs->nTextAlign & DT_WORDBREAK);
  1694. if (pDrawArgs->nTextAlign & DT_VCENTER)
  1695. {
  1696. // try to center vertically because DT_VCENTER works only for DT_SINGLELINE;
  1697. ReplaceInHyperLinks(pDrawArgs->pItem, strText, XTP_HLINK_SPACE_X);
  1698. int nHeightRequired = CalculateRowHeight(pDrawArgs->pDC, strText, rcItem.Width(), bWordBreak);
  1699. int nHeightDiff = rcItem.Height() - nHeightRequired;
  1700. if (nHeightDiff >= 4)
  1701. {
  1702. rcItem.top += nHeightDiff/2 - 2;
  1703. }
  1704. strText = pMetrics->strText;
  1705. }
  1706. DrawMultiLineText(pDrawArgs, strText, rcItem, bWordBreak);
  1707. }
  1708. else
  1709. {
  1710. int nCharCount = 0;
  1711. int nHyperlink = 0;
  1712. DrawTextLine(pDrawArgs, strText, rcItem, DT_END_ELLIPSIS, nCharCount, nHyperlink);
  1713. }
  1714. }
  1715. }
  1716. void CXTPReportPaintManager::DrawItemControl(XTP_REPORTRECORDITEM_DRAWARGS* pDrawArgs, CXTPReportRecordItemControl* pControl, CRect& rcItem)
  1717. {
  1718. if(!pControl)
  1719. return;
  1720. CXTPFontDC dc(pDrawArgs->pDC, pControl->GetFont(), pControl->GetCaptionColor());
  1721. CRect rcControl = rcItem;
  1722. // calculate control's rectangle
  1723. // horizontal
  1724. int nControlWidth = pControl->GetSize().cx;
  1725. if(nControlWidth > 0)
  1726. {
  1727. if(pControl->GetAlignment() == xtpItemControlRight)
  1728. {
  1729. rcControl.left = rcControl.right - nControlWidth;
  1730. rcItem.right -= nControlWidth;
  1731. }
  1732. else
  1733. {
  1734. rcControl.right = rcControl.left + nControlWidth;
  1735. rcItem.left += nControlWidth;
  1736. }
  1737. }
  1738. else
  1739. {
  1740. rcItem.right = rcItem.left;
  1741. }
  1742. // vertical
  1743. int nControlHeight = pControl->GetSize().cy;
  1744. if(nControlHeight > 0 && nControlHeight < rcItem.Height())
  1745. {
  1746. rcControl.top = rcItem.top + (rcItem.Height() - nControlHeight) / 2;
  1747. rcControl.bottom = rcControl.top + nControlHeight;
  1748. }
  1749. //  else
  1750. //      rcControl.DeflateRect(0, 1);
  1751. // handle alignment
  1752. // set control's rectangle
  1753. pControl->SetRect(rcControl);
  1754. switch (pControl->GetType())
  1755. {
  1756. case xtpItemControlTypeButton :
  1757. {
  1758. // draw button
  1759. CXTPReportRecordItemButton* pButton = DYNAMIC_DOWNCAST(CXTPReportRecordItemButton, pControl);
  1760. ASSERT(pButton);
  1761. pDrawArgs->pDC->FillSolidRect(rcControl, GetXtremeColor(COLOR_3DFACE));
  1762. int nState = pButton->GetEnable() ? pButton->GetState() : PBS_DISABLED;
  1763. if(pButton->GetThemed())
  1764. {
  1765. m_themeButton.DrawThemeBackground(*pDrawArgs->pDC, BP_PUSHBUTTON, nState, rcControl, 0);
  1766. }
  1767. else
  1768. {
  1769. //              pDrawArgs->pDC->DrawFrameControl(&rcControl, DFC_BUTTON, DFCS_BUTTONPUSH | (nState == PBS_PRESSED ? DFCS_PUSHED : 0));
  1770. if (nState == PBS_PRESSED)
  1771. {
  1772. pDrawArgs->pDC->Draw3dRect(rcControl, GetXtremeColor(COLOR_3DDKSHADOW), GetXtremeColor(COLOR_WINDOW));
  1773. }
  1774. else
  1775. {
  1776. pDrawArgs->pDC->Draw3dRect(rcControl, GetXtremeColor(COLOR_3DFACE), GetXtremeColor(COLOR_3DDKSHADOW));
  1777. rcControl.DeflateRect(1, 1);
  1778. pDrawArgs->pDC->Draw3dRect(rcControl, GetXtremeColor(COLOR_WINDOW), GetXtremeColor(COLOR_3DSHADOW));
  1779. }
  1780. }
  1781. // calculate rectangle for drawing icon or caption
  1782. if(nState == PBS_PRESSED)
  1783. rcControl.DeflateRect(3, 3, 1, 1);
  1784. else
  1785. rcControl.DeflateRect(1, 1);
  1786. // draw button icon
  1787. int nIconIndex = pButton->GetIconIndex(nState);
  1788. if(nIconIndex != XTP_REPORT_NOICON)
  1789. {
  1790. //              DrawBitmap(pDrawArgs->pDC, pDrawArgs->pControl, rcControl, nIconIndex);
  1791. CXTPImageManagerIcon* pIcon = pDrawArgs->pControl->GetImageManager()->GetImage(nIconIndex, 0);
  1792. if(pIcon)
  1793. {
  1794. CSize szImage(pIcon->GetWidth(), pIcon->GetHeight());
  1795. CPoint ptIcon(max(rcControl.left, rcControl.left + (rcControl.Width() - szImage.cx) / 2),
  1796. max(rcControl.top, rcControl.top + (rcControl.Height() - szImage.cy) / 2));
  1797. szImage.cx = min(szImage.cx, rcControl.Width());
  1798. szImage.cy = min(szImage.cy, rcControl.Height());
  1799. if(pDrawArgs->pDC->IsPrinting())
  1800. {
  1801. CBitmap bmp;
  1802. bmp.CreateCompatibleBitmap(pDrawArgs->pDC, szImage.cx, szImage.cy);
  1803. CXTPCompatibleDC dcMem(NULL, &bmp);
  1804. dcMem.FillSolidRect(0, 0, szImage.cx, szImage.cy, GetXtremeColor(COLOR_3DFACE));
  1805. pIcon->Draw(&dcMem, CPoint(0, 0), pIcon->GetIcon());
  1806. pDrawArgs->pDC->BitBlt(ptIcon.x, ptIcon.y, szImage.cx, szImage.cy, &dcMem, 0, 0, SRCCOPY);
  1807. }
  1808. else
  1809. pIcon->Draw(pDrawArgs->pDC, ptIcon, pIcon->GetIcon(), szImage);
  1810. }
  1811. }
  1812. // draw button caption
  1813. if(!pButton->GetCaption().IsEmpty())
  1814. {
  1815. COLORREF clrPrev = pDrawArgs->pDC->SetTextColor(pButton->GetEnable() ? pButton->GetCaptionColor() : GetXtremeColor(XPCOLOR_GRAYTEXT));
  1816. pDrawArgs->pDC->DrawText(pButton->GetCaption(), rcControl, DT_CENTER | DT_VCENTER | DT_NOPREFIX | DT_SINGLELINE);
  1817. pDrawArgs->pDC->SetTextColor(clrPrev);
  1818. }
  1819. break;
  1820. }
  1821. }
  1822. }
  1823. void CXTPReportPaintManager::ReplaceInHyperLinks(CXTPReportRecordItem* pItem, CString& rstrText, TCHAR chReplace )
  1824. {
  1825. ASSERT(pItem);
  1826. if (!pItem)
  1827. return;
  1828. int nHyperlinks = pItem->GetHyperlinksCount();
  1829. for (int nHLink = 0; nHLink < nHyperlinks; nHLink++)
  1830. {
  1831. CXTPReportHyperlink* pHLink = pItem->GetHyperlinkAt(nHLink);
  1832. ASSERT(pHLink);
  1833. if (!pHLink)
  1834. continue;
  1835. int nI0 = max(0, min(pHLink->m_nHyperTextBegin, rstrText.GetLength()-1));
  1836. int nI1 = max(0, min(pHLink->m_nHyperTextBegin + pHLink->m_nHyperTextLen, rstrText.GetLength()));
  1837. for (int i = nI0; i < nI1; i++)
  1838. {
  1839. if(rstrText.GetAt(i) == _T(' '))
  1840. {
  1841. rstrText.SetAt(i, chReplace);
  1842. }
  1843. }
  1844. }
  1845. }
  1846. void CXTPReportPaintManager::DrawMultiLineText(XTP_REPORTRECORDITEM_DRAWARGS* pDrawArgs, const CString& strText,
  1847. CRect rcItem, BOOL bWordBreak)
  1848. {
  1849. CDC* pDC = pDrawArgs->pDC;
  1850. CXTPReportRecordItem* pItem = pDrawArgs->pItem;
  1851. int nCurrStrPos = 0, nStringWidth = 0, nWordWidth = 0;
  1852. int nStartString = -1, nEndString = -1;
  1853. CRect rcText;
  1854. rcText.CopyRect(&rcItem);
  1855. if (0 == pItem->GetHyperlinksCount())
  1856. {
  1857. // no hyperlinks
  1858. pDC->DrawText(strText, rcText, DT_NOPREFIX | pDrawArgs->nTextAlign | DT_WORD_ELLIPSIS | (bWordBreak ?  DT_WORDBREAK : 0));
  1859. return;
  1860. }
  1861. int nLineHeight = pDC->GetTextExtent(_T(" "), 1).cy;
  1862. CString strSrc = strText + _T(" ");
  1863. REPLACE_S(strSrc, _T('r'), _T(' '));
  1864. ReplaceInHyperLinks(pItem, strSrc, XTP_HLINK_SPACE_X);
  1865. CString strWord, strString;
  1866. int nTextLength = strSrc.GetLength();
  1867. TCHAR* lpszBuff = strSrc.GetBuffer(nTextLength + 1);
  1868. TCHAR  cChar = lpszBuff[nCurrStrPos];
  1869. int     nWordLength = 0;
  1870. TCHAR*  lpszWord = strWord.GetBuffer(nTextLength + 1);
  1871. // parsing for the words (tokens)
  1872. while (_T('') != (cChar = lpszBuff[nCurrStrPos++]))
  1873. {
  1874. if (cChar == _T(' ') || cChar == _T('t') || cChar == _T('n'))
  1875. {
  1876. if (lpszWord[0] == _T('') && cChar != _T('n'))
  1877. continue;
  1878. if (strString.IsEmpty())
  1879. {
  1880. nStartString = nCurrStrPos - nWordLength;
  1881. nEndString = nCurrStrPos;
  1882. }
  1883. nWordWidth = GetTextExtentX(pDC, lpszWord, nWordLength);
  1884. if (nWordWidth > rcItem.Width() && bWordBreak || cChar == _T('n'))
  1885. {
  1886. if (!strString.IsEmpty())
  1887. {
  1888. DrawSingleLineText(pDrawArgs,  strSrc , rcText, nStartString-1, nEndString-1,
  1889. GetTextExtentX(pDC,strString));
  1890. rcText.top += nLineHeight;
  1891. rcText.left = rcItem.left;
  1892. }
  1893. // the word exceeds the cell's width
  1894. DrawSingleLineText(pDrawArgs, strSrc , rcText, nCurrStrPos - nWordLength -1, nCurrStrPos -1, nWordWidth);
  1895. if((nCurrStrPos - nWordLength) != nCurrStrPos)
  1896. {
  1897. rcText.top += nLineHeight;
  1898. rcText.left = rcItem.left;
  1899. }
  1900. strString.Empty();
  1901. lpszWord[0] = _T('');
  1902. nWordLength = 0;
  1903. continue;
  1904. }
  1905. int nPrevStringWidth = GetTextExtentX(pDC,strString);
  1906. if (!strString.IsEmpty())
  1907. strString += _T(" ");
  1908. strString += lpszWord;
  1909. nStringWidth = GetTextExtentX(pDC,strString);
  1910. if (nStringWidth > rcItem.Width() && bWordBreak)
  1911. {
  1912. DrawSingleLineText(pDrawArgs,  strSrc , rcText, nStartString-1, nEndString-1,
  1913. nPrevStringWidth);
  1914. rcText.top += nLineHeight;
  1915. rcText.left = rcItem.left;
  1916. nStartString = nCurrStrPos - nWordLength;
  1917. strString = lpszWord;
  1918. }
  1919. nEndString = nCurrStrPos;
  1920. lpszWord[0] = _T('');
  1921. nWordLength = 0;
  1922. continue;
  1923. }
  1924. ASSERT(nWordLength <= nTextLength);
  1925. lpszWord[nWordLength] = cChar;
  1926. lpszWord[nWordLength + 1] = _T('');
  1927. ++nWordLength;
  1928. }
  1929. // the rest of the string
  1930. if (strString.GetLength())
  1931. {
  1932. DrawSingleLineText(pDrawArgs,  strSrc , rcText, nStartString-1, strText.GetLength(),
  1933. GetTextExtentX(pDC,strString));
  1934. }
  1935. }
  1936. void CXTPReportPaintManager::DrawSingleLineText(XTP_REPORTRECORDITEM_DRAWARGS* pDrawArgs,const CString& strText,
  1937. CRect rcItem, int nStartPos, int nEndPos,int nActualWidth )
  1938. {
  1939. CDC* pDC = pDrawArgs->pDC;
  1940. CXTPReportRecordItem* pItem = pDrawArgs->pItem;
  1941. CXTPReportHyperlink* pHl = NULL;
  1942. // alignment
  1943. CRect   rcText(rcItem);
  1944. int nFlag = pDrawArgs->nTextAlign & (DT_LEFT | DT_RIGHT | DT_CENTER);
  1945. if (nFlag & DT_RIGHT)
  1946. rcText.left = rcText.right - nActualWidth;
  1947. else
  1948. if (nFlag & DT_CENTER)
  1949. rcText.left += (rcText.Width() - nActualWidth) / 2;
  1950. // Left align the string, that exceeds the cell's width.
  1951. rcText.left = max(rcText.left, rcItem.left);
  1952. int nCurrDrawPos = rcText.left;
  1953. int nHyperlink = 0; // Hyperlink index
  1954. int nCurrStrPos = nStartPos;
  1955. int nBeginHyperlink = 0xFFFF;
  1956. int nHyperlinks = pItem->GetHyperlinksCount();
  1957. CString strWord, strPre, strPost, strSrc = strText + _T(" ");
  1958. TCHAR* lpszBuff = strSrc.GetBuffer(strSrc.GetLength());
  1959. TCHAR  cChar = lpszBuff[nCurrStrPos];
  1960. BOOL  bNeedsBlank = FALSE;
  1961. int   nBlankWidth = GetTextExtentX(pDC, _T(" "), 1);
  1962. while (nCurrStrPos <= nEndPos && _T('') != (cChar = lpszBuff[nCurrStrPos++]))
  1963. {
  1964. if (cChar == _T(' ') || cChar == _T('t') || cChar == _T('n'))
  1965. {
  1966. if (strWord.IsEmpty())
  1967. continue;
  1968. if (bNeedsBlank)
  1969. {
  1970. // between words
  1971. pDC->DrawText(_T(" "), rcText, DT_LEFT);
  1972. rcText.left += nBlankWidth;
  1973. }
  1974. // as hyperlinks are not sorted in the array, check all
  1975. for (nHyperlink = 0; nHyperlink < nHyperlinks; ++nHyperlink)
  1976. {
  1977. pHl = pItem->GetHyperlinkAt(nHyperlink);
  1978. nBeginHyperlink = pHl->m_nHyperTextBegin;
  1979. // validate the hyperlink
  1980. if (nBeginHyperlink >= 0 &&
  1981. nBeginHyperlink <= strText.GetLength() - 1                  &&
  1982. pHl->m_nHyperTextLen > 1                                    &&
  1983. nBeginHyperlink + pHl->m_nHyperTextLen <= strText.GetLength())
  1984. {
  1985. // particular case: hyperlink begins with blank(s)
  1986. BOOL bInclude = FALSE;
  1987. if (nStartPos > nBeginHyperlink )
  1988. {
  1989. CString strExtracted = strText.Mid(nBeginHyperlink, nStartPos - nBeginHyperlink);
  1990. if (_tcsspnp(strExtracted.GetBuffer(strExtracted.GetLength()),_T(" ")) == NULL)
  1991. bInclude = TRUE;
  1992. }
  1993. // does the hyperlink belong to the string
  1994. if (nBeginHyperlink >= nStartPos &&
  1995. nBeginHyperlink + pHl->m_nHyperTextLen <= nEndPos ||
  1996. bInclude)
  1997. {
  1998. // does the word contain the hyperlink
  1999. CString strExtracted = strText.Mid(nBeginHyperlink,pHl->m_nHyperTextLen);
  2000. strExtracted.TrimLeft();
  2001. if (strWord.Find(strExtracted) != -1)
  2002. {
  2003. if (nBeginHyperlink < nCurrStrPos)
  2004. {
  2005. // before hyperlink
  2006. strPre = strWord.Mid(0,strWord.GetLength() - (nCurrStrPos - nBeginHyperlink - 1));
  2007. if (!strPre.IsEmpty())
  2008. {
  2009. pDC->DrawText(strPre, rcText, DT_LEFT | DT_END_ELLIPSIS | DT_NOPREFIX);
  2010. rcText.left += GetTextExtentX(pDC,strPre);
  2011. }
  2012. // the hyperlink
  2013. nCurrDrawPos = rcText.left;
  2014. DrawLink2(&nCurrDrawPos,pDrawArgs,pHl,strText,rcText, DT_LEFT | DT_END_ELLIPSIS, TRUE);
  2015. rcText.left = nCurrDrawPos;
  2016. // after hyperlink
  2017. int n = strWord.GetLength() - (nCurrStrPos - (nBeginHyperlink+pHl->m_nHyperTextLen +1));
  2018. if (n >=0 && (strWord.GetLength() - n) > 0)
  2019. {
  2020. strPost = strWord.Mid(n,strWord.GetLength() - n);
  2021. if (!strPost.IsEmpty())
  2022. {
  2023. pDC->DrawText(strPost, rcText, DT_LEFT | DT_END_ELLIPSIS | DT_NOPREFIX);
  2024. rcText.left += GetTextExtentX(pDC,strPost);
  2025. }
  2026. }
  2027. strWord.Empty();
  2028. bNeedsBlank = TRUE;
  2029. continue;
  2030. }
  2031. }
  2032. }
  2033. }
  2034. } // the hyperlink validation
  2035. // non-hyperlink words
  2036. pDC->DrawText(strWord, rcText, DT_LEFT | DT_END_ELLIPSIS | DT_NOPREFIX);
  2037. rcText.left += GetTextExtentX(pDC,strWord);
  2038. strWord.Empty();
  2039. bNeedsBlank = TRUE;
  2040. continue;
  2041. }
  2042. strWord += cChar;
  2043. }
  2044. }
  2045. int CXTPReportPaintManager::CalculateRowHeight(CDC* pDC, const CString& strText, int nMaxWidth, BOOL bWordBreak)
  2046. {
  2047. CString strWord, strBuff(strText);
  2048. strBuff += _T(" ");
  2049. int     nLineHeight = pDC->GetTextExtent(_T(" "),1).cy;
  2050. int     nRowHeight = 0;
  2051. int     nCurrXPos = 0;
  2052. int     nCurrStrPos = 0;
  2053. int     nBlanksWidth = 0;
  2054. // just calculate new line characters
  2055. if (!bWordBreak)
  2056. {
  2057. int nCount = 0, nPos = -1;
  2058. do
  2059. {
  2060. nCount++;
  2061. nPos = FIND_S(strBuff, _T('n'), nPos + 1);
  2062. }
  2063. while(nPos != -1);
  2064. return nLineHeight * nCount;
  2065. }
  2066. int     nWordLength = 0;
  2067. BOOL    bNeedsLine = TRUE;
  2068. int     nBlankWidth = GetTextExtentX(pDC, _T(" "), 1);
  2069. int     nTextLength = strBuff.GetLength();
  2070. TCHAR*  lpszBuff = strBuff.GetBuffer(nTextLength + 1);
  2071. TCHAR   cChar = lpszBuff[nCurrStrPos];
  2072. TCHAR*  lpszWord = strWord.GetBuffer(nTextLength + 1);
  2073. // breaking the text by words
  2074. while (_T('') != (cChar = lpszBuff[nCurrStrPos++]))
  2075. {
  2076. if (cChar == _T(' ') || cChar == _T('t') || cChar == _T('n'))
  2077. {
  2078. nBlanksWidth += nBlankWidth;
  2079. if (lpszWord[0] == _T('') && cChar != _T('n'))
  2080. continue;
  2081. int nWordWidth = GetTextExtentX(pDC, lpszWord, nWordLength);
  2082. if (nWordWidth >= nMaxWidth)
  2083. {
  2084. // the word exceeds the cell's width
  2085. nRowHeight += nLineHeight;
  2086. if (nCurrXPos > 0)
  2087. nRowHeight += nLineHeight; // for the preceding line (regardless of its size)
  2088. bNeedsLine = FALSE;
  2089. nCurrXPos = 0;
  2090. nBlanksWidth = 0;
  2091. lpszWord[0] = _T('');
  2092. nWordLength = 0;
  2093. continue;
  2094. }
  2095. if (nCurrXPos + nWordWidth >= nMaxWidth)
  2096. {
  2097. nCurrXPos = nWordWidth + nBlanksWidth;
  2098. nRowHeight += nLineHeight;
  2099. }
  2100. else
  2101. {
  2102. nCurrXPos += nWordWidth + nBlanksWidth;
  2103. bNeedsLine = TRUE;
  2104. }
  2105. if (cChar == _T('n')) // a new line is forced
  2106. {
  2107. nRowHeight += nLineHeight;
  2108. nCurrXPos = 0;
  2109. }
  2110. nBlanksWidth = 0;
  2111. lpszWord[0] = _T('');
  2112. nWordLength = 0;
  2113. continue;
  2114. }
  2115. ASSERT(nWordLength <= nTextLength);
  2116. lpszWord[nWordLength] = cChar;
  2117. lpszWord[nWordLength+1] = _T('');
  2118. ++nWordLength;
  2119. }
  2120. if (bNeedsLine)
  2121. nRowHeight += nLineHeight;
  2122. return nRowHeight;
  2123. }
  2124. int CXTPReportPaintManager::DrawLink2(int* pnCurrDrawPos, XTP_REPORTRECORDITEM_DRAWARGS* pDrawArgs, CXTPReportHyperlink* pHyperlink,
  2125. CString strText, CRect rcLink, int nFlag, BOOL bTrim )
  2126. {
  2127. int nCount = pHyperlink->m_nHyperTextLen;
  2128. int nDiff = pHyperlink->m_nHyperTextBegin + pHyperlink->m_nHyperTextLen - strText.GetLength();
  2129. if (nDiff > 0)
  2130. nCount = max(0, pHyperlink->m_nHyperTextLen - nDiff);
  2131. if (pHyperlink->m_nHyperTextBegin < 0 || pHyperlink->m_nHyperTextBegin >= strText.GetLength() ||
  2132. nCount <= 0)
  2133. return 0;
  2134. CDC* pDC = pDrawArgs->pDC;
  2135. CString strOut = strText.Mid(pHyperlink->m_nHyperTextBegin, nCount);
  2136. if (bTrim)
  2137. {
  2138. strOut.TrimLeft();
  2139. strOut.TrimRight();
  2140. }
  2141. REPLACE_S(strOut, XTP_HLINK_SPACE_X, _T(' '));
  2142. BOOL bSelected = pDrawArgs->pRow->IsSelected() && pDrawArgs->pRow->GetControl()->HasFocus() &&
  2143. (!pDrawArgs->pColumn || !pDrawArgs->pRow->GetControl()->GetFocusedColumn() ||
  2144.   pDrawArgs->pColumn != pDrawArgs->pRow->GetControl()->GetFocusedColumn());
  2145. COLORREF clrPrev = pDC->SetTextColor(bSelected ? m_clrHighlightText : m_clrHyper);
  2146. TEXTMETRIC textMetrics;
  2147. pDC->GetTextMetrics(&textMetrics);
  2148. int nCharCount = 0;
  2149. //!pHyperlink->m_rcHyperSpot.left = pDC->GetCurrentPosition().x; // update hyperlink left bound before drawing
  2150. pHyperlink->m_rcHyperSpot.left = *pnCurrDrawPos;
  2151. nCharCount = DrawString(pnCurrDrawPos, pDC, strOut, rcLink, nFlag);
  2152. // update hyperlink spot
  2153. pHyperlink->m_rcHyperSpot.top = rcLink.top;
  2154. //!pHyperlink->m_rcHyperSpot.right = pDC->GetCurrentPosition().x;
  2155. pHyperlink->m_rcHyperSpot.right = *pnCurrDrawPos;
  2156. pHyperlink->m_rcHyperSpot.bottom = rcLink.top + textMetrics.tmHeight;
  2157. pDC->SetTextColor(clrPrev);
  2158. return nCharCount;
  2159. }
  2160. void CXTPReportPaintManager::DrawFixedRowsDivider(CDC* pDC, const CRect& rc, CXTPReportControl* pControl, BOOL bHeaderRows, BOOL bVScrollBarVisible)
  2161. {
  2162. int nDividerStyle = bHeaderRows ? m_HeaderRowsDividerStyle : m_FooterRowsDividerStyle;
  2163. COLORREF clr =  bHeaderRows ? m_clrHeaderRowsDivider : m_clrFooterRowsDivider;
  2164. if (nDividerStyle == xtpReportFixedRowsDividerNone)
  2165. return;
  2166. if (nDividerStyle & xtpReportFixedRowsDividerOutlook)
  2167. {
  2168. if (m_columnStyle == xtpReportColumnShaded)
  2169. {
  2170. pDC->FillSolidRect(rc, m_clrHeaderControl);
  2171. DrawHorizontalLine(pDC, rc.left, rc.bottom - 2, rc.Width(), MixColor(m_clrHeaderControl, m_clrControlDark, 0.4));
  2172. DrawHorizontalLine(pDC, rc.left, rc.bottom - 1, rc.Width(), MixColor(m_clrHeaderControl, m_clrControlDark, 0.6));
  2173. }
  2174. else if (m_columnStyle == xtpReportColumnOffice2003)
  2175. {
  2176. XTPDrawHelpers()->GradientFill(pDC, rc,m_grcGradientColumn.clrLight, m_grcGradientColumn.clrDark,FALSE);
  2177. DrawHorizontalLine(pDC, rc.left, rc.bottom - 1, rc.Width(), m_clrGradientColumnShadow);
  2178. }
  2179. else if (m_columnStyle == xtpReportColumnOffice2007)
  2180. {
  2181. pDC->FillSolidRect(rc,  MixColor(m_grcGradientColumn.clrLight, m_grcGradientColumn.clrDark, 0.4));
  2182. DrawHorizontalLine(pDC, rc.left, rc.top, rc.Width(), RGB(255, 255, 255));
  2183. DrawHorizontalLine(pDC, rc.left, rc.bottom - 1, rc.Width(), m_clrGradientColumnSeparator);
  2184. }
  2185. else if (m_columnStyle == xtpReportColumnExplorer)
  2186. {
  2187. pDC->FillSolidRect(rc, m_clrHeaderControl);
  2188. pDC->Draw3dRect(rc, m_clrControlLightLight, m_clrBtnText);
  2189. CRect rcTmp(rc);
  2190. rcTmp.DeflateRect(1, 1);
  2191. pDC->Draw3dRect(rcTmp, m_clrHeaderControl, m_clrControlDark);
  2192. }
  2193. else
  2194. {
  2195. pDC->FillSolidRect(rc, m_clrHeaderControl);
  2196. pDC->Draw3dRect(rc, m_clrControlLightLight, m_clrControlDark);
  2197. }
  2198. }
  2199. else
  2200. {
  2201. if (nDividerStyle & xtpReportFixedRowsDividerThin || nDividerStyle & xtpReportFixedRowsDividerBold)
  2202. {
  2203. pDC->FillSolidRect(rc, clr);
  2204. }
  2205. }
  2206. // draw shade (if necessary)
  2207. int nScrollPos = pControl->GetScrollPos(SB_VERT);
  2208. int nScrollLimit = pControl->GetScrollLimit(SB_VERT);
  2209. SCROLLINFO si;
  2210. pControl->GetScrollInfo(SB_VERT,&si);
  2211. if (nDividerStyle & xtpReportFixedRowsDividerShade)
  2212. {
  2213. if (bHeaderRows)
  2214. {
  2215. // header rows
  2216. if (nScrollPos)
  2217. {
  2218. CRect rcShade(rc);
  2219. rcShade.top = rcShade.bottom;
  2220. rcShade.bottom += 4;
  2221. XTPDrawHelpers()->GradientFill(pDC, rcShade, clr, RGB(255, 255, 255), FALSE);
  2222. }
  2223. }
  2224. else
  2225. // footer rows
  2226. if (bVScrollBarVisible && nScrollPos != nScrollLimit) // && (UINT)si.nMax != si.nPage)
  2227. {
  2228. CRect rcShade(rc);
  2229. rcShade.bottom = rcShade.top;
  2230. rcShade.top -= 4;
  2231. XTPDrawHelpers()->GradientFill(pDC, rcShade, RGB(255, 255, 255), clr, FALSE);
  2232. }
  2233. }
  2234. }
  2235. int CXTPReportPaintManager::GetHeaderRowsDividerHeight()
  2236. {
  2237. int nHeight = 0;
  2238. switch(m_HeaderRowsDividerStyle & ~xtpReportFixedRowsDividerShade)
  2239. {
  2240. case xtpReportFixedRowsDividerNone:     nHeight = 0; break;
  2241. case xtpReportFixedRowsDividerThin:     nHeight = 1; break;
  2242. case xtpReportFixedRowsDividerBold:     nHeight = 2; break;
  2243. case xtpReportFixedRowsDividerOutlook:  nHeight = 8; break;
  2244. }
  2245. return nHeight;
  2246. }
  2247. int CXTPReportPaintManager::GetFooterRowsDividerHeight()
  2248. {
  2249. int nHeight = 0;
  2250. switch(m_FooterRowsDividerStyle & ~xtpReportFixedRowsDividerShade)
  2251. {
  2252. case xtpReportFixedRowsDividerNone:     nHeight = 0; break;
  2253. case xtpReportFixedRowsDividerThin:     nHeight = 1; break;
  2254. case xtpReportFixedRowsDividerBold:     nHeight = 2; break;
  2255. case xtpReportFixedRowsDividerOutlook:  nHeight = 8; break;
  2256. }
  2257. return nHeight;
  2258. }