GridCellBase.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870
  1. #include "pch.h"
  2. #include "GridCtrl.h"
  3. #include "GridCellBase.h"
  4. IMPLEMENT_DYNAMIC(CGridCellBase, CObject)
  5. /////////////////////////////////////////////////////////////////////////////
  6. // GridCellBase
  7. CGridCellBase::CGridCellBase()
  8. {
  9. Reset();
  10. }
  11. CGridCellBase::~CGridCellBase()
  12. {
  13. }
  14. /////////////////////////////////////////////////////////////////////////////
  15. // GridCellBase Operations
  16. void CGridCellBase::Reset()
  17. {
  18. m_Hide = false;
  19. m_nState = 0;
  20. m_MergeRange.Set();
  21. m_IsMergeWithOthers = false;
  22. m_MergeCellID.row = -1;
  23. m_MergeCellID.col = -1;
  24. }
  25. //Used for merge cells,remove const
  26. //by Huang Wei
  27. void CGridCellBase::operator=(CGridCellBase& cell)
  28. {
  29. if (this == &cell) return;
  30. SetGrid(cell.GetGrid()); // do first in case of dependencies
  31. SetText(cell.GetText());
  32. SetImage(cell.GetImage());
  33. SetData(cell.GetData());
  34. SetState(cell.GetState());
  35. SetFormat(cell.GetFormat());
  36. SetTextClr(cell.GetTextClr());
  37. SetBackClr(cell.GetBackClr());
  38. SetBorder(cell.GetBorder());
  39. SetBorderClr(cell.GetBorderClr());
  40. SetFont(cell.IsDefaultFont() ? NULL : cell.GetFont());
  41. SetMargin(cell.GetMargin());
  42. //Used for merge cells
  43. //by Huang Wei
  44. SetMergeCellID(cell.GetMergeCellID());
  45. SetMergeRange(cell.GetMergeRange());
  46. Show(cell.IsShow());
  47. }
  48. /////////////////////////////////////////////////////////////////////////////
  49. // CGridCellBase Attributes
  50. // Returns a pointer to a cell that holds default values for this particular type of cell
  51. CGridCellBase* CGridCellBase::GetDefaultCell() const
  52. {
  53. if (GetGrid())
  54. return GetGrid()->GetDefaultCell(IsFixedRow(), IsFixedCol());
  55. return NULL;
  56. }
  57. /////////////////////////////////////////////////////////////////////////////
  58. // CGridCellBase Operations
  59. // EFW - Various changes to make it draw cells better when using alternate
  60. // color schemes. Also removed printing references as that's now done
  61. // by PrintCell() and fixed the sort marker so that it doesn't draw out
  62. // of bounds.
  63. BOOL CGridCellBase::Draw(CDC* pDC, int nRow, int nCol, CRect rect, BOOL bEraseBkgnd /*=TRUE*/)
  64. {
  65. // Note - all through this function we totally brutalise 'rect'. Do not
  66. // depend on it's value being that which was passed in.
  67. //Used for merge cells
  68. //by Huang Wei
  69. if (m_Hide && !IsMerged())
  70. {
  71. return TRUE;
  72. }
  73. CGridCtrl* pGrid = GetGrid();
  74. ASSERT(pGrid);
  75. if (!pGrid || !pDC)
  76. return FALSE;
  77. if (rect.Width() <= 0 || rect.Height() <= 0) // prevents imagelist item from drawing even
  78. return FALSE; // though cell is hidden
  79. //TRACE3("Drawing %scell %d, %d\n", IsFixed()? _T("Fixed ") : _T(""), nRow, nCol);
  80. int nSavedDC = pDC->SaveDC();
  81. pDC->SetBkMode(TRANSPARENT);
  82. // Get the default cell implementation for this kind of cell. We use it if this cell
  83. // has anything marked as "default"
  84. CGridDefaultCell *pDefaultCell = (CGridDefaultCell*)GetDefaultCell();
  85. if (!pDefaultCell)
  86. return FALSE;
  87. // Set up text and background colours
  88. COLORREF TextClr, TextBkClr;
  89. TextClr = (GetTextClr() == CLR_DEFAULT) ? pDefaultCell->GetTextClr() : GetTextClr();
  90. if (GetBackClr() == CLR_DEFAULT)
  91. TextBkClr = pDefaultCell->GetBackClr();
  92. else
  93. {
  94. bEraseBkgnd = TRUE;
  95. TextBkClr = GetBackClr();
  96. }
  97. // Draw cell background and highlighting (if necessary)
  98. if (IsFocused() || IsDropHighlighted())
  99. {
  100. // Always draw even in list mode so that we can tell where the
  101. // cursor is at. Use the highlight colors though.
  102. if (GetState() & GVIS_SELECTED)
  103. {
  104. TextBkClr = ::GetSysColor(COLOR_HIGHLIGHT);
  105. TextClr = ::GetSysColor(COLOR_HIGHLIGHTTEXT);
  106. bEraseBkgnd = TRUE;
  107. }
  108. rect.right++; rect.bottom++; // FillRect doesn't draw RHS or bottom
  109. if (bEraseBkgnd)
  110. {
  111. TRY
  112. {
  113. CBrush brush(TextBkClr);
  114. pDC->FillRect(rect, &brush);
  115. }
  116. CATCH(CResourceException, e)
  117. {
  118. //e->ReportError();
  119. }
  120. END_CATCH
  121. }
  122. // Don't adjust frame rect if no grid lines so that the
  123. // whole cell is enclosed.
  124. if (pGrid->GetGridLines() != GVL_NONE)
  125. {
  126. rect.right--;
  127. rect.bottom--;
  128. }
  129. if (pGrid->GetFrameFocusCell())
  130. {
  131. // Use same color as text to outline the cell so that it shows
  132. // up if the background is black.
  133. TRY
  134. {
  135. CBrush brush(TextClr);
  136. pDC->FrameRect(rect, &brush);
  137. }
  138. CATCH(CResourceException, e)
  139. {
  140. //e->ReportError();
  141. }
  142. END_CATCH
  143. }
  144. pDC->SetTextColor(TextClr);
  145. // Adjust rect after frame draw if no grid lines
  146. if (pGrid->GetGridLines() == GVL_NONE)
  147. {
  148. rect.right--;
  149. rect.bottom--;
  150. }
  151. rect.DeflateRect(0, 1, 1, 1);
  152. }
  153. else if ((GetState() & GVIS_SELECTED))
  154. {
  155. rect.right++; rect.bottom++; // FillRect doesn't draw RHS or bottom
  156. pDC->FillSolidRect(rect, ::GetSysColor(COLOR_HIGHLIGHT));
  157. rect.right--; rect.bottom--;
  158. pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
  159. }
  160. else
  161. {
  162. if (bEraseBkgnd)
  163. {
  164. rect.right++; rect.bottom++; // FillRect doesn't draw RHS or bottom
  165. CBrush brush(TextBkClr);
  166. pDC->FillRect(rect, &brush);
  167. rect.right--; rect.bottom--;
  168. }
  169. pDC->SetTextColor(TextClr);
  170. }
  171. // Draw lines only when wanted
  172. if (IsFixed() && pGrid->GetGridLines() != GVL_NONE)
  173. {
  174. CCellID FocusCell = pGrid->GetFocusCell();
  175. // As above, always show current location even in list mode so
  176. // that we know where the cursor is at.
  177. BOOL bHiliteFixed = pGrid->GetTrackFocusCell() && pGrid->IsValid(FocusCell) &&
  178. (FocusCell.row == nRow || FocusCell.col == nCol);
  179. // If this fixed cell is on the same row/col as the focus cell,
  180. // highlight it.
  181. if (bHiliteFixed)
  182. {
  183. rect.right++; rect.bottom++;
  184. pDC->DrawEdge(rect, BDR_SUNKENINNER /*EDGE_RAISED*/, BF_RECT);
  185. rect.DeflateRect(1, 1);
  186. }
  187. else
  188. {
  189. CPen lightpen(PS_SOLID, 1, ::GetSysColor(COLOR_3DHIGHLIGHT)),
  190. darkpen(PS_SOLID, 1, ::GetSysColor(COLOR_3DDKSHADOW)),
  191. *pOldPen = pDC->GetCurrentPen();
  192. pDC->SelectObject(&lightpen);
  193. pDC->MoveTo(rect.right, rect.top);
  194. pDC->LineTo(rect.left, rect.top);
  195. pDC->LineTo(rect.left, rect.bottom);
  196. pDC->SelectObject(&darkpen);
  197. pDC->MoveTo(rect.right, rect.top);
  198. pDC->LineTo(rect.right, rect.bottom);
  199. pDC->LineTo(rect.left, rect.bottom);
  200. pDC->SelectObject(pOldPen);
  201. rect.DeflateRect(1, 1);
  202. }
  203. }
  204. else if (pGrid->GetGridLines() == GVL_NONE) // Render Borders HYF
  205. {
  206. CPen bPen(PS_SOLID, 1, GetBorderClr());
  207. CPen *pOldPen = pDC->GetCurrentPen();
  208. pDC->SelectObject(&bPen);
  209. if (GetBorder() & GVIS_BDR_TOP)
  210. {
  211. pDC->MoveTo(rect.right, rect.top);
  212. pDC->LineTo(rect.left, rect.top);
  213. }
  214. if (GetBorder() & GVIS_BDR_LEFT)
  215. {
  216. pDC->MoveTo(rect.left, rect.top);
  217. pDC->LineTo(rect.left, rect.bottom);
  218. }
  219. if (GetBorder() & GVIS_BDR_BOTTOM)
  220. {
  221. pDC->MoveTo(rect.left, rect.bottom);
  222. pDC->LineTo(rect.right, rect.bottom);
  223. }
  224. if (GetBorder() & GVIS_BDR_RIGHT)
  225. {
  226. pDC->MoveTo(rect.right, rect.top);
  227. pDC->LineTo(rect.right, rect.bottom);
  228. }
  229. pDC->SelectObject(pOldPen);
  230. rect.DeflateRect(1, 1);
  231. }
  232. // Draw Text and image
  233. #if !defined(_WIN32_WCE_NO_PRINTING) && !defined(GRIDCONTROL_NO_PRINTING)
  234. if (!pDC->m_bPrinting)
  235. #endif
  236. {
  237. CFont *pFont = GetFontObject();
  238. ASSERT(pFont);
  239. if (pFont)
  240. pDC->SelectObject(pFont);
  241. }
  242. rect.DeflateRect(GetMargin(), 0);
  243. if (pGrid->GetImageList() && GetImage() >= 0)
  244. {
  245. IMAGEINFO Info;
  246. if (pGrid->GetImageList()->GetImageInfo(GetImage(), &Info))
  247. {
  248. // would like to use a clipping region but seems to have issue
  249. // working with CMemDC directly. Instead, don't display image
  250. // if any part of it cut-off
  251. //
  252. // CRgn rgn;
  253. // rgn.CreateRectRgnIndirect(rect);
  254. // pDC->SelectClipRgn(&rgn);
  255. // rgn.DeleteObject();
  256. int nImageWidth = Info.rcImage.right - Info.rcImage.left + 1;
  257. int nImageHeight = Info.rcImage.bottom - Info.rcImage.top + 1;
  258. if (nImageWidth + rect.left <= rect.right + (int)(2 * GetMargin())
  259. && nImageHeight + rect.top <= rect.bottom + (int)(2 * GetMargin()))
  260. {
  261. pGrid->GetImageList()->Draw(pDC, GetImage(), rect.TopLeft(), ILD_NORMAL);
  262. }
  263. //rect.left += nImageWidth+GetMargin();
  264. }
  265. }
  266. // Draw sort arrow
  267. if (pGrid->GetSortColumn() == nCol && nRow == 0)
  268. {
  269. CSize size = pDC->GetTextExtent(_T("M"));
  270. int nOffset = 2;
  271. // Base the size of the triangle on the smaller of the column
  272. // height or text height with a slight offset top and bottom.
  273. // Otherwise, it can get drawn outside the bounds of the cell.
  274. size.cy -= (nOffset * 2);
  275. if (size.cy >= rect.Height())
  276. size.cy = rect.Height() - (nOffset * 2);
  277. size.cx = size.cy; // Make the dimensions square
  278. // Kludge for vertical text
  279. BOOL bVertical = (GetFont()->lfEscapement == 900);
  280. // Only draw if it'll fit!
  281. if (size.cx + rect.left < rect.right + (int)(2 * GetMargin()))
  282. {
  283. int nTriangleBase = rect.bottom - nOffset - size.cy; // Triangle bottom right
  284. //int nTriangleBase = (rect.top + rect.bottom - size.cy)/2; // Triangle middle right
  285. //int nTriangleBase = rect.top + nOffset; // Triangle top right
  286. //int nTriangleLeft = rect.right - size.cx; // Triangle RHS
  287. //int nTriangleLeft = (rect.right + rect.left - size.cx)/2; // Triangle middle
  288. //int nTriangleLeft = rect.left; // Triangle LHS
  289. int nTriangleLeft;
  290. if (bVertical)
  291. nTriangleLeft = (rect.right + rect.left - size.cx) / 2; // Triangle middle
  292. else
  293. nTriangleLeft = rect.right - size.cx; // Triangle RHS
  294. CPen penShadow(PS_SOLID, 0, ::GetSysColor(COLOR_3DSHADOW));
  295. CPen penLight(PS_SOLID, 0, ::GetSysColor(COLOR_3DHILIGHT));
  296. if (pGrid->GetSortAscending())
  297. {
  298. // Draw triangle pointing upwards
  299. CPen *pOldPen = (CPen*)pDC->SelectObject(&penLight);
  300. pDC->MoveTo(nTriangleLeft + 1, nTriangleBase + size.cy + 1);
  301. pDC->LineTo(nTriangleLeft + (size.cx / 2) + 1, nTriangleBase + 1);
  302. pDC->LineTo(nTriangleLeft + size.cx + 1, nTriangleBase + size.cy + 1);
  303. pDC->LineTo(nTriangleLeft + 1, nTriangleBase + size.cy + 1);
  304. pDC->SelectObject(&penShadow);
  305. pDC->MoveTo(nTriangleLeft, nTriangleBase + size.cy);
  306. pDC->LineTo(nTriangleLeft + (size.cx / 2), nTriangleBase);
  307. pDC->LineTo(nTriangleLeft + size.cx, nTriangleBase + size.cy);
  308. pDC->LineTo(nTriangleLeft, nTriangleBase + size.cy);
  309. pDC->SelectObject(pOldPen);
  310. }
  311. else
  312. {
  313. // Draw triangle pointing downwards
  314. CPen *pOldPen = (CPen*)pDC->SelectObject(&penLight);
  315. pDC->MoveTo(nTriangleLeft + 1, nTriangleBase + 1);
  316. pDC->LineTo(nTriangleLeft + (size.cx / 2) + 1, nTriangleBase + size.cy + 1);
  317. pDC->LineTo(nTriangleLeft + size.cx + 1, nTriangleBase + 1);
  318. pDC->LineTo(nTriangleLeft + 1, nTriangleBase + 1);
  319. pDC->SelectObject(&penShadow);
  320. pDC->MoveTo(nTriangleLeft, nTriangleBase);
  321. pDC->LineTo(nTriangleLeft + (size.cx / 2), nTriangleBase + size.cy);
  322. pDC->LineTo(nTriangleLeft + size.cx, nTriangleBase);
  323. pDC->LineTo(nTriangleLeft, nTriangleBase);
  324. pDC->SelectObject(pOldPen);
  325. }
  326. if (!bVertical)
  327. rect.right -= size.cy;
  328. }
  329. }
  330. // We want to see '&' characters so use DT_NOPREFIX
  331. GetTextRect(rect);
  332. DrawText(pDC->m_hDC, GetText(), -1, rect, GetFormat() | DT_NOPREFIX);
  333. pDC->RestoreDC(nSavedDC);
  334. return TRUE;
  335. }
  336. /////////////////////////////////////////////////////////////////////////////
  337. // CGridCellBase Mouse and Cursor events
  338. // Not yet implemented
  339. void CGridCellBase::OnMouseEnter()
  340. {
  341. TRACE0("Mouse entered cell\n");
  342. }
  343. void CGridCellBase::OnMouseOver()
  344. {
  345. //TRACE0("Mouse over cell\n");
  346. }
  347. // Not Yet Implemented
  348. void CGridCellBase::OnMouseLeave()
  349. {
  350. TRACE0("Mouse left cell\n");
  351. }
  352. void CGridCellBase::OnClick(CPoint PointCellRelative)
  353. {
  354. UNUSED_ALWAYS(PointCellRelative);
  355. TRACE2("Mouse Left btn up in cell at x=%i y=%i\n", PointCellRelative.x, PointCellRelative.y);
  356. }
  357. void CGridCellBase::OnClickDown(CPoint PointCellRelative)
  358. {
  359. UNUSED_ALWAYS(PointCellRelative);
  360. TRACE2("Mouse Left btn down in cell at x=%i y=%i\n", PointCellRelative.x, PointCellRelative.y);
  361. }
  362. void CGridCellBase::OnRClick(CPoint PointCellRelative)
  363. {
  364. UNUSED_ALWAYS(PointCellRelative);
  365. TRACE2("Mouse right-clicked in cell at x=%i y=%i\n", PointCellRelative.x, PointCellRelative.y);
  366. }
  367. void CGridCellBase::OnDblClick(CPoint PointCellRelative)
  368. {
  369. UNUSED_ALWAYS(PointCellRelative);
  370. TRACE2("Mouse double-clicked in cell at x=%i y=%i\n", PointCellRelative.x, PointCellRelative.y);
  371. }
  372. // Return TRUE if you set the cursor
  373. BOOL CGridCellBase::OnSetCursor()
  374. {
  375. #ifndef _WIN32_WCE_NO_CURSOR
  376. SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
  377. #endif
  378. return TRUE;
  379. }
  380. /////////////////////////////////////////////////////////////////////////////
  381. // CGridCellBase editing
  382. void CGridCellBase::OnEndEdit()
  383. {
  384. ASSERT(FALSE);
  385. }
  386. BOOL CGridCellBase::ValidateEdit(LPCTSTR str)
  387. {
  388. UNUSED_ALWAYS(str);
  389. return TRUE;
  390. }
  391. /////////////////////////////////////////////////////////////////////////////
  392. // CGridCellBase Sizing
  393. BOOL CGridCellBase::GetTextRect(LPRECT pRect) // i/o: i=dims of cell rect; o=dims of text rect
  394. {
  395. if (GetImage() >= 0)
  396. {
  397. IMAGEINFO Info;
  398. CGridCtrl* pGrid = GetGrid();
  399. CImageList* pImageList = pGrid->GetImageList();
  400. if (pImageList && pImageList->GetImageInfo(GetImage(), &Info))
  401. {
  402. int nImageWidth = Info.rcImage.right - Info.rcImage.left + 1;
  403. pRect->left += nImageWidth + GetMargin();
  404. }
  405. }
  406. return TRUE;
  407. }
  408. // By default this uses the selected font (which is a bigger font)
  409. CSize CGridCellBase::GetTextExtent(LPCTSTR szText, CDC* pDC /*= NULL*/)
  410. {
  411. CGridCtrl* pGrid = GetGrid();
  412. ASSERT(pGrid);
  413. BOOL bReleaseDC = FALSE;
  414. if (pDC == NULL || szText == NULL)
  415. {
  416. if (szText)
  417. pDC = pGrid->GetDC();
  418. if (pDC == NULL || szText == NULL)
  419. {
  420. CGridDefaultCell* pDefCell = (CGridDefaultCell*)GetDefaultCell();
  421. ASSERT(pDefCell);
  422. return CSize(pDefCell->GetWidth(), pDefCell->GetHeight());
  423. }
  424. bReleaseDC = TRUE;
  425. }
  426. CFont *pOldFont = NULL,
  427. *pFont = GetFontObject();
  428. if (pFont)
  429. pOldFont = pDC->SelectObject(pFont);
  430. CSize size;
  431. int nFormat = GetFormat();
  432. // If the cell is a multiline cell, then use the width of the cell
  433. // to get the height
  434. if ((nFormat & DT_WORDBREAK) && !(nFormat & DT_SINGLELINE))
  435. {
  436. CString str = szText;
  437. int nMaxWidth = 0;
  438. while (TRUE)
  439. {
  440. int nPos = str.Find(_T('\n'));
  441. CString TempStr = (nPos < 0) ? str : str.Left(nPos);
  442. int nTempWidth = pDC->GetTextExtent(TempStr).cx;
  443. if (nTempWidth > nMaxWidth)
  444. nMaxWidth = nTempWidth;
  445. if (nPos < 0)
  446. break;
  447. str = str.Mid(nPos + 1); // Bug fix by Thomas Steinborn
  448. }
  449. CRect rect;
  450. rect.SetRect(0, 0, nMaxWidth + 1, 0);
  451. pDC->DrawText(szText, -1, rect, nFormat | DT_CALCRECT);
  452. size = rect.Size();
  453. }
  454. else
  455. size = pDC->GetTextExtent(szText, (int)_tcslen(szText));
  456. TEXTMETRIC tm;
  457. pDC->GetTextMetrics(&tm);
  458. size.cx += (tm.tmOverhang);
  459. if (pOldFont)
  460. pDC->SelectObject(pOldFont);
  461. size += CSize(4 * GetMargin(), 2 * GetMargin());
  462. // Kludge for vertical text
  463. LOGFONT *pLF = GetFont();
  464. if (pLF->lfEscapement == 900 || pLF->lfEscapement == -900)
  465. {
  466. int nTemp = size.cx;
  467. size.cx = size.cy;
  468. size.cy = nTemp;
  469. size += CSize(0, 4 * GetMargin());
  470. }
  471. if (bReleaseDC)
  472. pGrid->ReleaseDC(pDC);
  473. return size;
  474. }
  475. CSize CGridCellBase::GetCellExtent(CDC* pDC)
  476. {
  477. CSize size = GetTextExtent(GetText(), pDC);
  478. CSize ImageSize(0, 0);
  479. int nImage = GetImage();
  480. if (nImage >= 0)
  481. {
  482. CGridCtrl* pGrid = GetGrid();
  483. ASSERT(pGrid);
  484. if (pGrid->GetImageList())
  485. {
  486. IMAGEINFO Info;
  487. if (pGrid->GetImageList()->GetImageInfo(nImage, &Info))
  488. ImageSize = CSize(Info.rcImage.right - Info.rcImage.left + 1,
  489. Info.rcImage.bottom - Info.rcImage.top + 1);
  490. }
  491. }
  492. return CSize(size.cx + ImageSize.cx, max(size.cy, ImageSize.cy));
  493. }
  494. // EFW - Added to print cells so that grids that use different colors are
  495. // printed correctly.
  496. BOOL CGridCellBase::PrintCell(CDC* pDC, int /*nRow*/, int /*nCol*/, CRect rect)
  497. {
  498. //Used for merge cells
  499. //by Huang Wei
  500. if (m_Hide && !IsMerged())
  501. {
  502. return TRUE;
  503. }
  504. #if defined(_WIN32_WCE_NO_PRINTING) || defined(GRIDCONTROL_NO_PRINTING)
  505. return FALSE;
  506. #else
  507. COLORREF crFG, crBG;
  508. GV_ITEM Item;
  509. CGridCtrl* pGrid = GetGrid();
  510. if (!pGrid || !pDC)
  511. return FALSE;
  512. if (rect.Width() <= 0
  513. || rect.Height() <= 0) // prevents imagelist item from drawing even
  514. return FALSE; // though cell is hidden
  515. int nSavedDC = pDC->SaveDC();
  516. pDC->SetBkMode(TRANSPARENT);
  517. //Used for merge cells
  518. //by Huang Wei
  519. //rect.InflateRect(1, 1);
  520. ///// pDC->Rectangle(rect);
  521. //rect.DeflateRect(1, 1);
  522. if (pGrid->GetShadedPrintOut())
  523. {
  524. // Get the default cell implementation for this kind of cell. We use it if this cell
  525. // has anything marked as "default"
  526. CGridDefaultCell *pDefaultCell = (CGridDefaultCell*)GetDefaultCell();
  527. if (!pDefaultCell)
  528. return FALSE;
  529. // Use custom color if it doesn't match the default color and the
  530. // default grid background color. If not, leave it alone.
  531. if (IsFixed())
  532. crBG = (GetBackClr() != CLR_DEFAULT) ? GetBackClr() : pDefaultCell->GetBackClr();
  533. else
  534. crBG = (GetBackClr() != CLR_DEFAULT && GetBackClr() != pDefaultCell->GetBackClr()) ?
  535. GetBackClr() : CLR_DEFAULT;
  536. // Use custom color if the background is different or if it doesn't
  537. // match the default color and the default grid text color.
  538. if (IsFixed())
  539. crFG = (GetBackClr() != CLR_DEFAULT) ? GetTextClr() : pDefaultCell->GetTextClr();
  540. else
  541. crFG = (GetBackClr() != CLR_DEFAULT) ? GetTextClr() : pDefaultCell->GetTextClr();
  542. // If not printing on a color printer, adjust the foreground color
  543. // to a gray scale if the background color isn't used so that all
  544. // colors will be visible. If not, some colors turn to solid black
  545. // or white when printed and may not show up. This may be caused by
  546. // coarse dithering by the printer driver too (see image note below).
  547. if (pDC->GetDeviceCaps(NUMCOLORS) == 2 && crBG == CLR_DEFAULT)
  548. crFG = RGB(GetRValue(crFG) * 0.30, GetGValue(crFG) * 0.59,
  549. GetBValue(crFG) * 0.11);
  550. // Only erase the background if the color is not the default
  551. // grid background color.
  552. if (crBG != CLR_DEFAULT)
  553. {
  554. CBrush brush(crBG);
  555. rect.right++; rect.bottom++;
  556. pDC->FillRect(rect, &brush);
  557. rect.right--; rect.bottom--;
  558. }
  559. }
  560. else
  561. {
  562. crBG = CLR_DEFAULT;
  563. crFG = RGB(0, 0, 0);
  564. }
  565. pDC->SetTextColor(crFG);
  566. CFont *pFont = GetFontObject();
  567. if (pFont)
  568. pDC->SelectObject(pFont);
  569. /*
  570. // ***************************************************
  571. // Disabled - if you need this functionality then you'll need to rewrite.
  572. // Create the appropriate font and select into DC.
  573. CFont Font;
  574. // Bold the fixed cells if not shading the print out. Use italic
  575. // font it it is enabled.
  576. const LOGFONT* plfFont = GetFont();
  577. if(IsFixed() && !pGrid->GetShadedPrintOut())
  578. {
  579. Font.CreateFont(plfFont->lfHeight, 0, 0, 0, FW_BOLD, plfFont->lfItalic, 0, 0,
  580. ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
  581. #ifndef _WIN32_WCE
  582. PROOF_QUALITY,
  583. #else
  584. DEFAULT_QUALITY,
  585. #endif
  586. VARIABLE_PITCH | FF_SWISS, plfFont->lfFaceName);
  587. }
  588. else
  589. Font.CreateFontIndirect(plfFont);
  590. pDC->SelectObject(&Font);
  591. // ***************************************************
  592. */
  593. // Draw lines only when wanted on fixed cells. Normal cell grid lines
  594. // are handled in OnPrint.
  595. if (pGrid->GetGridLines() != GVL_NONE && IsFixed())
  596. {
  597. CPen lightpen(PS_SOLID, 1, ::GetSysColor(COLOR_3DHIGHLIGHT)),
  598. darkpen(PS_SOLID, 1, ::GetSysColor(COLOR_3DDKSHADOW)),
  599. *pOldPen = pDC->GetCurrentPen();
  600. pDC->SelectObject(&lightpen);
  601. pDC->MoveTo(rect.right, rect.top);
  602. pDC->LineTo(rect.left, rect.top);
  603. pDC->LineTo(rect.left, rect.bottom);
  604. pDC->SelectObject(&darkpen);
  605. pDC->MoveTo(rect.right, rect.top);
  606. pDC->LineTo(rect.right, rect.bottom);
  607. pDC->LineTo(rect.left, rect.bottom);
  608. rect.DeflateRect(1, 1);
  609. pDC->SelectObject(pOldPen);
  610. }
  611. else if (pGrid->GetGridLines() == GVL_NONE) // Render Borders HYF
  612. {
  613. CPen bPen(PS_SOLID, 1, GetBorderClr());
  614. CPen *pOldPen = pDC->GetCurrentPen();
  615. pDC->SelectObject(&bPen);
  616. if (GetBorder() & GVIS_BDR_TOP)
  617. {
  618. pDC->MoveTo(rect.right, rect.top);
  619. pDC->LineTo(rect.left, rect.top);
  620. }
  621. if (GetBorder() & GVIS_BDR_LEFT)
  622. {
  623. pDC->MoveTo(rect.left, rect.top);
  624. pDC->LineTo(rect.left, rect.bottom);
  625. }
  626. if (GetBorder() & GVIS_BDR_BOTTOM)
  627. {
  628. pDC->MoveTo(rect.left, rect.bottom);
  629. pDC->LineTo(rect.right, rect.bottom);
  630. }
  631. if (GetBorder() & GVIS_BDR_RIGHT)
  632. {
  633. pDC->MoveTo(rect.right, rect.top);
  634. pDC->LineTo(rect.right, rect.bottom);
  635. }
  636. pDC->SelectObject(pOldPen);
  637. rect.DeflateRect(1, 1);
  638. }
  639. rect.DeflateRect(GetMargin(), 0);
  640. if (pGrid->GetImageList() && GetImage() >= 0)
  641. {
  642. // NOTE: If your printed images look like fuzzy garbage, check the
  643. // settings on your printer driver. If it's using coarse
  644. // dithering and/or vector graphics, they may print wrong.
  645. // Changing to fine dithering and raster graphics makes them
  646. // print properly. My HP 4L had that problem.
  647. IMAGEINFO Info;
  648. if (pGrid->GetImageList()->GetImageInfo(GetImage(), &Info))
  649. {
  650. int nImageWidth = Info.rcImage.right - Info.rcImage.left;
  651. pGrid->GetImageList()->Draw(pDC, GetImage(), rect.TopLeft(), ILD_NORMAL);
  652. rect.left += nImageWidth + GetMargin();
  653. }
  654. }
  655. // Draw without clipping so as not to lose text when printed for real
  656. // DT_NOCLIP removed 01.01.01. Slower, but who cares - we are printing!
  657. DrawText(pDC->m_hDC, GetText(), -1, rect,
  658. GetFormat() | /*DT_NOCLIP | */ DT_NOPREFIX);
  659. pDC->RestoreDC(nSavedDC);
  660. return TRUE;
  661. #endif
  662. }
  663. /*****************************************************************************
  664. Callable by derived classes, only
  665. *****************************************************************************/
  666. LRESULT CGridCellBase::SendMessageToParent(int nRow, int nCol, int nMessage)
  667. {
  668. CGridCtrl* pGrid = GetGrid();
  669. if (pGrid)
  670. return pGrid->SendMessageToParent(nRow, nCol, nMessage);
  671. else
  672. return 0;
  673. }
  674. //Used for merge cells
  675. //by Huang Wei
  676. void CGridCellBase::Show(bool IsShow)
  677. {
  678. m_Hide = !IsShow;
  679. }
  680. //Used for merge cells
  681. //by Huang Wei
  682. void CGridCellBase::SetMergeRange(CCellRange range)
  683. {
  684. m_MergeRange = range;
  685. }
  686. //Used for merge cells
  687. //by Huang Wei
  688. CCellRange CGridCellBase::GetMergeRange()
  689. {
  690. return m_MergeRange;
  691. }
  692. //Used for merge cells
  693. //by Huang Wei
  694. bool CGridCellBase::IsMerged()
  695. {
  696. return m_MergeRange.Count() > 1;
  697. }
  698. //Used for merge cells
  699. //by Huang Wei
  700. void CGridCellBase::SetMergeCellID(CCellID cell)
  701. {
  702. m_MergeCellID = cell;
  703. if (cell.row != -1)
  704. m_IsMergeWithOthers = true;
  705. else
  706. m_IsMergeWithOthers = false;
  707. }
  708. //Used for merge cells
  709. //by Huang Wei
  710. CCellID CGridCellBase::GetMergeCellID()
  711. {
  712. return m_MergeCellID;
  713. }
  714. //Used for merge cells
  715. //by Huang Wei
  716. bool CGridCellBase::IsMergeWithOthers()
  717. {
  718. return m_IsMergeWithOthers;
  719. }
  720. //Used for merge cells
  721. //by Huang Wei
  722. bool CGridCellBase::IsShow()
  723. {
  724. return !m_Hide;
  725. }
  726. //Used for merge cells
  727. //by Huang Wei
  728. void CGridCellBase::UnMerge()
  729. {
  730. m_Hide = false;
  731. m_MergeRange.Set();
  732. m_IsMergeWithOthers = false;
  733. m_MergeCellID.row = -1;
  734. m_MergeCellID.col = -1;
  735. }