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

对话框与窗口

开发平台:

Visual C++

  1. // top
  2. default :
  3. break;
  4. }
  5. }
  6. CXTPCompatibleDC memWatermarkDC(&dc, m_hbmpWatermark);
  7. COLORREF clrBk = GetPaintManager()->m_clrControlBack;
  8. CRect rcReport00(0, 0, rc.Width(), rc.Height());
  9. CBitmap bmpTmp;
  10. bmpTmp.CreateCompatibleBitmap(&dc, rc.Width(), rc.Height());
  11. CXTPCompatibleDC memDCtmp(&dc, &bmpTmp);
  12. memDCtmp.FillSolidRect(&rcReport00, clrBk);
  13. if(GetWatermarkAlignment() & xtpReportWatermarkStretch)
  14. {
  15. CBitmap bmpWatermarkTmp;
  16. bmpWatermarkTmp.CreateCompatibleBitmap(&dc, rc.Width(), rc.Height());
  17. CXTPCompatibleDC memWatermarkDCtmp(&dc, &bmpWatermarkTmp);
  18. memWatermarkDCtmp.FillSolidRect(&rc, RGB(255, 255, 255));
  19. memWatermarkDCtmp.SetStretchBltMode(HALFTONE);
  20. memWatermarkDCtmp.StretchBlt(rcDst.left, rcDst.top, rcDst.Width(), rcDst.Height(), &memWatermarkDC, 0, 0, rcSrc.Width(), rcSrc.Height(), SRCCOPY);
  21. XTPImageManager()->AlphaBlend2(memDCtmp, rc, memWatermarkDCtmp, rc, m_WatermarkTransparency);
  22. }
  23. else
  24. {
  25. XTPImageManager()->AlphaBlend2(memDCtmp, rcDst, memWatermarkDC, rcSrc, m_WatermarkTransparency);
  26. }
  27. XTPImageManager()->TransparentBlt(memDCtmp, rcReport00, memDC, rcReport00, clrBk);
  28. memDC.BitBlt(0, 0, rc.right, rc.bottom, &memDCtmp, 0, 0, SRCCOPY);
  29. }
  30. dc.BitBlt(0, 0, rc.right, rc.bottom, &memDC, 0, 0, SRCCOPY);
  31. memDC.SelectObject(pOldBitmap);
  32. }
  33. else
  34. {
  35. CXTPCompatibleDC memDC(&dc, &m_bmpCache);
  36. dc.BitBlt(0, 0, rc.right, rc.bottom, &memDC, 0, 0, SRCCOPY);
  37. }
  38. // count drawing time
  39. #ifdef XTP_DEBUG
  40. LARGE_INTEGER iEndCount;
  41. QueryPerformanceCounter(&iEndCount);
  42. XTP_TRACE(_T("Draw counter ticks: %dn"), iEndCount.LowPart-iStartCount.LowPart);
  43. #endif
  44. }
  45. LRESULT CXTPReportControl::OnPrintClient(WPARAM wParam, LPARAM /*lParam*/)
  46. {
  47. CDC* pDC = CDC::FromHandle((HDC)wParam);
  48. if (pDC)
  49. {
  50. if (m_bmpCache.GetSafeHandle() == 0)
  51. OnDraw(pDC);
  52. else
  53. {
  54. CXTPCompatibleDC memDC(pDC, &m_bmpCache);
  55. CXTPClientRect rc(this);
  56. pDC->BitBlt(0, 0, rc.right, rc.bottom, &memDC, 0, 0, SRCCOPY);
  57. }
  58. }
  59. return TRUE;
  60. }
  61. BOOL CXTPReportControl::OnEraseBkgnd(CDC* /*pDC*/)
  62. {
  63. return TRUE;    // Don't erase the background.
  64. }
  65. void CXTPReportControl::OnDraw(CDC* pDC)
  66. {
  67. if (GetExStyle() & WS_EX_RTLREADING)
  68. {
  69. pDC->SetTextAlign(TA_RTLREADING);
  70. }
  71. // draw new image
  72. pDC->FillSolidRect(CXTPClientRect(this), GetPaintManager()->GetControlBackColor(this));
  73. CXTPReportHeader* pHeader = GetReportHeader();
  74. CRect rcHeader = m_rcHeaderArea;
  75. rcHeader.right = rcHeader.left + pHeader->GetWidth();
  76. // draw header
  77. if (pHeader)
  78. pHeader->Draw(pDC, rcHeader, m_nLeftOffset);
  79. // draw group by box
  80. if (pHeader)
  81. pHeader->DrawGroupByControl(pDC, m_rcGroupByArea);
  82. DrawRows(pDC, m_rcReportArea);
  83. if (m_bHeaderRecordsVisible && m_pHeaderRows->GetCount() > 0)
  84. {
  85. DrawFixedRows(pDC, m_rcHeaderRecordsArea, m_pHeaderRows);
  86. DrawFixedRecordsDivider(pDC, m_rcHeaderRecordsDividerArea, TRUE);
  87. }
  88. if (m_bFooterRecordsVisible && m_pFooterRows->GetCount() > 0)
  89. {
  90. DrawFixedRows(pDC, m_rcFooterRecordsArea, m_pFooterRows);
  91. DrawFixedRecordsDivider(pDC, m_rcFooterRecordsDividerArea, FALSE);
  92. }
  93. CRect rcFooter = m_rcFooterArea;
  94. if (rcFooter.Height() > 0)
  95. pHeader->DrawFooter(pDC, rcFooter, m_nLeftOffset);
  96. if (m_nDropPos != -1)
  97. {
  98. DrawDropMarker(pDC);
  99. }
  100. // update flag
  101. SetChanged(FALSE);
  102. }
  103. void CXTPReportControl::DrawDropMarker(CDC* pDC)
  104. {
  105. CRect rc(m_rcReportArea.left, m_nDropPos, m_rcReportArea.right, m_nDropPos + 1);
  106. pDC->FillSolidRect(rc, GetPaintManager()->m_clrHotDivider);
  107. CXTPPenDC pen (*pDC, GetPaintManager()->m_clrHotDivider);
  108. CXTPBrushDC brush (*pDC, GetPaintManager()->m_clrHotDivider);
  109. int x = rc.left;
  110. int y = m_nDropPos;
  111. POINT ptsLeftArrow[] =
  112. {
  113. {x, y - 2}, {x + 2, y - 2}, {x + 2, y - 5}, {x + 7, y},
  114. {x + 2, y + 5}, {x + 2, y + 2}, {x, y + 2}
  115. };
  116. pDC->Polygon(ptsLeftArrow, 7);
  117. x = rc.right - 1;
  118. POINT ptsRightArrow[] =
  119. {
  120. {x, y - 2}, {x - 2, y - 2}, {x - 2, y - 5}, {x - 7, y},
  121. {x - 2, y + 5}, {x - 2, y + 2}, {x, y + 2}
  122. };
  123. pDC->Polygon(ptsRightArrow, 7);
  124. }
  125. void CXTPReportControl::OnSize(UINT nType, int cx, int cy)
  126. {
  127. if (m_bOnSizeRunning)
  128. return;
  129. m_bOnSizeRunning = TRUE;
  130. CWnd::OnSize(nType, cx, cy);
  131. AdjustLayout();
  132. AdjustScrollBars();
  133. m_bOnSizeRunning = FALSE;
  134. }
  135. void CXTPReportControl::OnRButtonDown(UINT nFlags, CPoint point)
  136. {
  137. CWnd::OnRButtonDown(nFlags, point);
  138. }
  139. void CXTPReportControl::OnRButtonUp(UINT nFlags, CPoint point)
  140. {
  141. HWND hWnd = m_hWnd;
  142. CWnd::OnRButtonUp(nFlags, point);
  143. if (!IsWindow(hWnd)) // Can be destroyed in WM_CONTEXTMENU
  144. return;
  145. }
  146. void CXTPReportControl::OnLButtonDown(UINT nFlags, CPoint point)
  147. {
  148. CWnd::OnLButtonDown(nFlags, point);
  149. SetFocus();
  150. EditItem(NULL);
  151. // columns processing
  152. CXTPReportHeader* pHeader = GetReportHeader();
  153. if (pHeader)
  154. {
  155. pHeader->OnLButtonDown(point);
  156. }
  157. // rows selection
  158. CXTPReportRow* pRow = HitTest(point);
  159. if (pRow)
  160. {
  161. XTP_REPORTRECORDITEM_CLICKARGS clickArgs;
  162. clickArgs.pControl = this;
  163. clickArgs.pRow = pRow;
  164. clickArgs.ptClient = point;
  165. clickArgs.pColumn = NULL;
  166. // find clicked item
  167. clickArgs.pItem = pRow->HitTest(point, &clickArgs.rcItem, &clickArgs.pColumn);
  168. if (pRow->OnLButtonDown(&clickArgs))
  169. return;
  170. // some rows may be unaccessible for end user
  171. if (pRow->GetType() == xtpRowTypeHeader && !m_bHeaderRowsAllowAccess)
  172. return;
  173. if (pRow->GetType() == xtpRowTypeFooter && !m_bFooterRowsAllowAccess)
  174. return;
  175. bool bIgnoreSelection = GetKeyState(VK_CONTROL) < 0 || IsMultiSelectionMode();
  176. bool bSelectBlock = GetKeyState(VK_SHIFT) < 0;
  177. BOOL bFocusChanged = TRUE;
  178. CXTPReportColumn* pFocusedColumn = clickArgs.pColumn;
  179. CUpdateContext updateContext(this);
  180. if (m_bFocusSubItems && pFocusedColumn && pRow->GetRecord() && pRow->GetRecord()->GetItem(pFocusedColumn)->IsFocusable())
  181. {
  182. SetFocusedColumn(pFocusedColumn);
  183. }
  184. if (pRow->IsSelected() && !bIgnoreSelection && !bSelectBlock)
  185. {
  186. m_pSelectOnUpRow = pRow;
  187. }
  188. else
  189. {
  190. bFocusChanged = SetFocusedRow(pRow, bSelectBlock, bIgnoreSelection);
  191. }
  192. BOOL bSelectionChanged = m_pSelectedRows->IsChanged();
  193. if (bFocusChanged && bIgnoreSelection && IsSelectionEnabled())
  194. {
  195. m_pSelectedRows->Invert(pRow);
  196. if(!bSelectionChanged && m_pSelectedRows->IsChanged())
  197. OnSelectionChanged();
  198. }
  199. m_pointDrag = point;
  200. m_bPrepareDrag = TRUE;
  201. }
  202. }
  203. void CXTPReportControl::OnLButtonUp(UINT nFlags, CPoint point)
  204. {
  205. CWnd::OnLButtonUp(nFlags, point);
  206. m_bPrepareDrag = FALSE;
  207. EnsureStopAutoVertScroll();
  208. // columns processing
  209. CXTPReportHeader* pHeader = GetReportHeader();
  210. if (pHeader)
  211. {
  212. pHeader->OnLButtonUp(nFlags, point);
  213. }
  214. CXTPReportRow* pRow = HitTest(point);
  215. if (pRow)
  216. {
  217. if (pRow == m_pSelectOnUpRow)
  218. {
  219. SetFocusedRow(pRow, FALSE, FALSE);
  220. }
  221. XTP_REPORTRECORDITEM_CLICKARGS clickArgs;
  222. clickArgs.pControl = this;
  223. clickArgs.pRow = pRow;
  224. clickArgs.ptClient = point;
  225. clickArgs.pColumn = NULL;
  226. // find clicked item
  227. clickArgs.pItem = pRow->HitTest(point, &clickArgs.rcItem, &clickArgs.pColumn);
  228. pRow->OnLButtonUp(&clickArgs);
  229. }
  230. m_pSelectOnUpRow = NULL;
  231. if (!m_bMultipleSelection || (GetKeyState(VK_SHIFT) >= 0 && (GetKeyState(VK_CONTROL) >= 0 && !IsMultiSelectionMode())))
  232. {
  233. // rows processing
  234. if (pRow && pRow->IsFocused())
  235. {
  236. pRow->OnClick(point);
  237. }
  238. }
  239. }
  240. void CXTPReportControl::OnLButtonDblClk(UINT nFlags, CPoint ptDblClick)
  241. {
  242. CWnd::OnLButtonDblClk(nFlags, ptDblClick);
  243. // columns processing
  244. CXTPReportHeader* pHeader = GetReportHeader();
  245. if (pHeader)
  246. {
  247. pHeader->OnLButtonDblClk(ptDblClick);
  248. }
  249. // rows processing
  250. CXTPReportRow* pRow = HitTest(ptDblClick);
  251. if (pRow)
  252. {
  253. pRow->OnDblClick(ptDblClick);
  254. }
  255. else
  256. {
  257. // just notify parent
  258. SendMessageToParent(NULL, NULL, NULL, NM_DBLCLK, &ptDblClick);
  259. }
  260. }
  261. void CXTPReportControl::OnContextMenu(CWnd* /*pWnd*/, CPoint pos)
  262. {
  263. if (GetMouseMode() != xtpReportMouseNothing)
  264. return;
  265. CPoint ptClient = pos;
  266. ScreenToClient(&ptClient);
  267. // call context menu handler for report header if clicked inside
  268. if (m_rcHeaderArea.PtInRect(ptClient) ||
  269. m_rcGroupByArea.PtInRect(ptClient))
  270. {
  271. CXTPReportHeader* pHeader = GetReportHeader();
  272. if (pHeader)
  273. pHeader->OnContextMenu(ptClient);
  274. return;
  275. }
  276. // call context menu handler for report area if clicked inside
  277. if (m_rcReportArea.PtInRect(ptClient)           ||
  278. m_rcHeaderRecordsArea.PtInRect(ptClient)    ||
  279. m_rcFooterRecordsArea.PtInRect(ptClient))
  280. {
  281. // rows processing
  282. CXTPReportRow* pRow = HitTest(ptClient);
  283. if (pRow)
  284. {
  285. SetFocusedRow(pRow, pRow->IsSelected());
  286. pRow->OnContextMenu(ptClient);
  287. }
  288. else
  289. {
  290. SendMessageToParent(NULL, NULL, NULL, NM_RCLICK, &pos);
  291. }
  292. return;
  293. }
  294. if (pos == CPoint(-1, -1))
  295. {
  296. CXTPReportRow* pFocusedRow = GetFocusedRow();
  297. if (pFocusedRow)
  298. {
  299. ptClient = CPoint(pFocusedRow->GetRect().left, pFocusedRow->GetRect().bottom);
  300. pFocusedRow->OnContextMenu(ptClient);
  301. }
  302. else
  303. {
  304. pos = m_rcReportArea.TopLeft();
  305. ClientToScreen(&pos);
  306. SendMessageToParent(NULL, NULL, NULL, NM_RCLICK, &pos);
  307. }
  308. }
  309. }
  310. CXTPReportColumn* CXTPReportControl::GetNextFocusableColumn(CXTPReportRow* pRow, int nColumnIndex, int nDirection)
  311. {
  312. if (!pRow->GetRecord())
  313. return NULL;
  314. for (;;)
  315. {
  316. CXTPReportColumn* pColumn = GetReportHeader()->GetNextVisibleColumn(nColumnIndex, nDirection);
  317. if (!pColumn)
  318. return NULL;
  319. CXTPReportRecordItem* pItem = pRow->GetRecord()->GetItem(pColumn);
  320. if (pItem && pItem->IsFocusable())
  321. return pColumn;
  322. nColumnIndex = pColumn->GetIndex();
  323. }
  324. }
  325. BOOL CXTPReportControl::OnPreviewKeyDown(UINT& rnChar, UINT nRepCnt, UINT nFlags)
  326. {
  327. XTP_NM_REPORTPREVIEWKEYDOWN nmParams;
  328. ::ZeroMemory(&nmParams, sizeof(nmParams));
  329. nmParams.nChar = rnChar;
  330. nmParams.nRepCnt = nRepCnt;
  331. nmParams.nFlags = nFlags;
  332. nmParams.bCancel = FALSE;
  333. SendNotifyMessage(XTP_NM_REPORT_PREVIEWKEYDOWN, (NMHDR*)&nmParams);
  334. rnChar = nmParams.nChar;
  335. return !nmParams.bCancel;
  336. }
  337. void CXTPReportControl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
  338. {
  339. //  TRACE(_T("ReportControl, OnKeyDown('%d') n"), nChar);
  340. // Moved to PreTranslateMessage
  341. //  if (!OnPreviewKeyDown(nChar, nRepCnt, nFlags))
  342. //  {
  343. //      return;
  344. //  }
  345. CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
  346. BOOL  bSelectBlock = GetKeyState(VK_SHIFT) < 0;
  347. BOOL  bSignoreSelection = GetKeyState(VK_CONTROL) < 0 || IsMultiSelectionMode();
  348. CXTPReportRow* pFocusedRow = GetFocusedRow();
  349. CXTPDrawHelpers::KeyToLayout(this, nChar);
  350. if (m_pRows->GetCount() != 0)
  351. switch (nChar)
  352. {
  353. case VK_ADD:
  354. if (bSignoreSelection)
  355. ExpandAll();
  356. else if (pFocusedRow && pFocusedRow->HasChildren() && !pFocusedRow->IsExpanded())
  357. {
  358. pFocusedRow->SetExpanded(TRUE);
  359. }
  360. break;
  361. case VK_SUBTRACT:
  362. if (bSignoreSelection)
  363. CollapseAll();
  364. else if (pFocusedRow && pFocusedRow->HasChildren() && pFocusedRow->IsExpanded())
  365. {
  366. pFocusedRow->SetExpanded(FALSE);
  367. }
  368. break;
  369. case VK_RIGHT:
  370. if (pFocusedRow && pFocusedRow->HasChildren() && !pFocusedRow->IsExpanded())
  371. {
  372. pFocusedRow->SetExpanded(TRUE);
  373. break;
  374. }
  375. if (pFocusedRow && m_bFocusSubItems && m_pFocusedColumn)
  376. {
  377. CXTPReportColumn* pColumn = GetNextFocusableColumn(pFocusedRow, m_pFocusedColumn->GetIndex(), +1);
  378. if (pColumn)
  379. {
  380. SetFocusedColumn(pColumn);
  381. SetFocusedRow(GetFocusedRow());
  382. }
  383. break;
  384. }
  385. case VK_DOWN:
  386. GetNavigator()->MoveDown(bSelectBlock, bSignoreSelection);
  387. break;
  388. case  VK_LEFT:
  389. if (pFocusedRow && pFocusedRow->HasChildren() && pFocusedRow->IsExpanded())
  390. {
  391. pFocusedRow->SetExpanded(FALSE);
  392. break;
  393. }
  394. if (pFocusedRow && m_bFocusSubItems && m_pFocusedColumn)
  395. {
  396. CXTPReportColumn* pColumn = GetNextFocusableColumn(pFocusedRow, m_pFocusedColumn->GetIndex(), -1);
  397. if (pColumn)
  398. {
  399. SetFocusedColumn(pColumn);
  400. SetFocusedRow(GetFocusedRow());
  401. }
  402. break;
  403. }
  404. if (pFocusedRow && !pFocusedRow->HasChildren() && pFocusedRow->GetParentRow() && !bSelectBlock)
  405. {
  406. SetFocusedRow(pFocusedRow->GetParentRow());
  407. pFocusedRow->SetExpanded(FALSE);
  408. break;
  409. }
  410. case VK_UP:
  411. GetNavigator()->MoveUp(bSelectBlock, bSignoreSelection);
  412. break;
  413. case VK_HOME:
  414. GetNavigator()->MoveFirstRow(bSelectBlock, FALSE);
  415. break;
  416. case VK_END:
  417. GetNavigator()->MoveLastRow(bSelectBlock, FALSE);
  418. break;
  419. case VK_NEXT:
  420. GetNavigator()->MovePageDown(bSelectBlock, FALSE);
  421. break;
  422. case VK_PRIOR:
  423. GetNavigator()->MovePageUp(bSelectBlock, FALSE);
  424. break;
  425. case VK_RETURN:
  426. if (pFocusedRow && pFocusedRow->HasChildren())
  427. {
  428. pFocusedRow->SetExpanded(!pFocusedRow->IsExpanded());
  429. }
  430. break;
  431. case VK_ESCAPE:
  432. if (m_mouseMode != xtpReportMouseNothing)
  433. {
  434. GetReportHeader()->CancelMouseMode();
  435. }
  436. break;
  437. case VK_F2:
  438. GetNavigator()->BeginEdit();
  439. break;
  440. case VK_SPACE:
  441. if(IsSelectionEnabled() && bSignoreSelection && pFocusedRow)
  442. {
  443. //              m_pSelectedRows->Invert(pFocusedRow);
  444. if(pFocusedRow->IsSelected())
  445. m_pSelectedRows->Remove(pFocusedRow);
  446. else
  447. m_pSelectedRows->Add(pFocusedRow);
  448. OnSelectionChanged();
  449. }
  450. break;
  451. }
  452. NMKEY nmgv;
  453. nmgv.nVKey = nChar;
  454. nmgv.uFlags = nFlags;
  455. SendNotifyMessage(NM_KEYDOWN, (NMHDR*)&nmgv);
  456. }
  457. void CXTPReportControl::OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
  458. {
  459. CWnd::OnSysKeyDown(nChar, nRepCnt, nFlags);
  460. }
  461. void CXTPReportControl::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
  462. {
  463. CWnd::OnKeyUp(nChar, nRepCnt, nFlags);
  464. }
  465. void CXTPReportControl::OnSysKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
  466. {
  467. CWnd::OnSysKeyUp(nChar, nRepCnt, nFlags);
  468. }
  469. void CXTPReportControl::OnChar(UINT nChar, UINT nRepCntr, UINT nFlags)
  470. {
  471. //  TRACE(_T("ReportControl, OnChar('%d') n"), nChar);
  472. // Moved to PreTranslateMessage
  473. //  if (!OnPreviewKeyDown(nChar, nRepCntr, nFlags))
  474. //  {
  475. //      return;
  476. //  }
  477. NMCHAR nmgv;
  478. ZeroMemory(&nmgv, sizeof(NMCHAR));
  479. nmgv.ch = nChar;
  480. SendNotifyMessage(NM_CHAR, (NMHDR*)&nmgv);
  481. CXTPReportRow* pFocusedRow = GetFocusedRow();
  482. if (m_bFocusSubItems && pFocusedRow && (nChar == VK_TAB))
  483. {
  484. EditItem(NULL);
  485. BOOL bBack = GetKeyState(VK_SHIFT) < 0;
  486. GetNavigator()->MoveLeftRight(bBack);
  487. return;
  488. }
  489. if (m_pFocusedColumn && pFocusedRow && pFocusedRow->GetRecord() && (nChar != VK_RETURN) && (nChar != VK_ESCAPE))
  490. {
  491. XTP_REPORTRECORDITEM_ARGS itemArgs(this, pFocusedRow, m_pFocusedColumn) ;
  492. if (itemArgs.pItem && itemArgs.pItem->OnChar(&itemArgs, nChar))
  493. return;
  494. }
  495. CWnd::OnChar(nChar, nRepCntr, nFlags);
  496. }
  497. void CXTPReportControl::OnCaptureChanged(CWnd* pWnd)
  498. {
  499. if (m_mouseMode != xtpReportMouseNothing)
  500. {
  501. GetReportHeader()->CancelMouseMode();
  502. }
  503. CWnd::OnCaptureChanged(pWnd);
  504. }
  505. void CXTPReportControl::OnEnable(BOOL bEnable)
  506. {
  507. UNREFERENCED_PARAMETER(bEnable);
  508. AdjustScrollBars();
  509. }
  510. void CXTPReportControl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
  511. {
  512. if (pScrollBar != NULL)
  513. {
  514. CWnd::OnVScroll(nSBCode, nPos, pScrollBar);
  515. return;
  516. }
  517. int nCurPos = m_nTopRow;
  518. // decide what to do for each diffrent scroll event
  519. switch (nSBCode)
  520. {
  521. case SB_TOP: nCurPos = 0; break;
  522. case SB_BOTTOM: nCurPos = GetScrollLimit(SB_VERT); break;
  523. case SB_LINEUP: nCurPos = max(nCurPos - 1, 0); break;
  524. case SB_LINEDOWN: nCurPos = min(nCurPos + 1, GetScrollLimit(SB_VERT)); break;
  525. case SB_PAGEUP: nCurPos = max(nCurPos - GetReportAreaRows(nCurPos, false), 0); break;
  526. case SB_PAGEDOWN: nCurPos = min(nCurPos + GetReportAreaRows(nCurPos, true), GetScrollLimit(SB_VERT)); break;
  527. case SB_THUMBTRACK:
  528. case SB_THUMBPOSITION:
  529. {
  530. SCROLLINFO si;
  531. ZeroMemory(&si, sizeof(SCROLLINFO));
  532. si.cbSize = sizeof(SCROLLINFO);
  533. si.fMask = SIF_TRACKPOS;
  534. if (!GetScrollInfo(SB_VERT, &si))
  535. return;
  536. nCurPos = si.nTrackPos;
  537. }
  538. break;
  539. }
  540. SetTopRow(nCurPos);
  541. }
  542. void CXTPReportControl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
  543. {
  544. if (pScrollBar != NULL)
  545. {
  546. CWnd::OnHScroll(nSBCode, nPos, pScrollBar);
  547. return;
  548. }
  549. int nCurPos = m_nLeftOffset;
  550. // FCS - full column scrolling
  551. int nLeftOffset_new = m_nLeftOffset;
  552. CXTPReportColumn *pPrev = NULL, *pCurr = NULL, *pNext = NULL;
  553. int nScrollPos = 0, nScrollMax = 0;
  554. int nFreezOffset = 0;
  555. if (m_bFullColumnScrolling)
  556. nFreezOffset = GetReportHeader()->GetFulColScrollInfo(pPrev, pCurr, pNext, nScrollPos, nScrollMax);
  557. // decide what to do for each different scroll event
  558. switch (nSBCode)
  559. {
  560. case SB_TOP:
  561. nCurPos = 0;
  562. nLeftOffset_new = 0;
  563. nScrollPos = 0;
  564. break;
  565. case SB_BOTTOM:
  566. nCurPos = GetScrollLimit(SB_HORZ);
  567. if (m_bFullColumnScrolling)
  568. {
  569. int nVisColCount = GetColumns()->GetVisibleColumnsCount();
  570. CXTPReportColumn *pLast = GetColumns()->GetVisibleAt(max(nVisColCount-1, 0));
  571. ASSERT(pLast);
  572. if (!pLast)
  573. return;
  574. nLeftOffset_new = labs(GetReportHeader()->m_rcHeader.left - pLast->GetRect().left) - nFreezOffset;
  575. nScrollPos = max(nScrollMax - 1, 0);
  576. }
  577. break;
  578. case SB_LINEUP:
  579. nCurPos = max(nCurPos - m_nHScrollStep, 0);
  580. if (m_bFullColumnScrolling && pPrev)
  581. {
  582. nLeftOffset_new = labs(GetReportHeader()->m_rcHeader.left - pPrev->GetRect().left) - nFreezOffset;
  583. nScrollPos = max(nScrollPos - 1, 0);
  584. }
  585. break;
  586. case SB_LINEDOWN:
  587. nCurPos = min(nCurPos + m_nHScrollStep, GetScrollLimit(SB_HORZ));
  588. if (m_bFullColumnScrolling && pNext)
  589. {
  590. nLeftOffset_new = labs(GetReportHeader()->m_rcHeader.left - pNext->GetRect().left) - nFreezOffset;
  591. nScrollPos = nScrollPos + 1;
  592. }
  593. break;
  594. case SB_PAGEUP:
  595. nCurPos = max(nCurPos - m_rcReportArea.Width(), 0);
  596. if (m_bFullColumnScrolling && pPrev)
  597. {
  598. nLeftOffset_new = labs(GetReportHeader()->m_rcHeader.left - pPrev->GetRect().left) - nFreezOffset;
  599. nScrollPos = max(nScrollPos - 1, 0);
  600. }
  601. break;
  602. case SB_PAGEDOWN:
  603. nCurPos = min(nCurPos + m_rcReportArea.Width(), GetScrollLimit(SB_HORZ));
  604. if (m_bFullColumnScrolling && pNext)
  605. {
  606. nLeftOffset_new = labs(GetReportHeader()->m_rcHeader.left - pNext->GetRect().left) - nFreezOffset;
  607. nScrollPos = nScrollPos + 1;
  608. }
  609. break;
  610. case SB_THUMBTRACK:
  611. case SB_THUMBPOSITION:
  612. nCurPos = nPos;
  613. if (m_bFullColumnScrolling)
  614. {
  615. int nVisColCount = GetColumns()->GetVisibleColumnsCount();
  616. int nCurrCol = nVisColCount - nScrollMax + nPos;
  617. CXTPReportColumn *pCurrScroll = GetColumns()->GetVisibleAt(nCurrCol);
  618. ASSERT(pCurrScroll);
  619. if (!pCurrScroll)
  620. return;
  621. nLeftOffset_new = labs(GetReportHeader()->m_rcHeader.left - pCurrScroll->GetRect().left) - nFreezOffset;
  622. nScrollPos = nPos;
  623. }
  624. break;
  625. }
  626. if (m_bFullColumnScrolling)
  627. {
  628. SetLeftOffset(nLeftOffset_new);
  629. SetScrollPos(SB_HORZ, nScrollPos);
  630. }
  631. else
  632. {
  633. SetLeftOffset(nCurPos);
  634. }
  635. }
  636. UINT CXTPReportControl::GetMouseScrollLines()
  637. {
  638. int nScrollLines = 3; // default value
  639. if (XTPSystemVersion()->IsWin95())
  640. {
  641. HKEY hKey;
  642. if (ERROR_SUCCESS == RegOpenKeyEx(
  643. HKEY_CURRENT_USER, _T("Control Panel\Desktop"), 0, KEY_QUERY_VALUE, &hKey))
  644. {
  645. TCHAR szData[128];
  646. DWORD dwKeyDataType;
  647. DWORD dwDataBufSize = sizeof(szData);
  648. if (ERROR_SUCCESS == RegQueryValueEx(
  649. hKey, _T("WheelScrollLines"), NULL, &dwKeyDataType, (LPBYTE) &szData, &dwDataBufSize))
  650. {
  651. nScrollLines = _tcstoul(szData, NULL, 10);
  652. }
  653. RegCloseKey(hKey);
  654. }
  655. }
  656. // win98 or greater
  657. else
  658. SystemParametersInfo (SPI_GETWHEELSCROLLLINES, 0, &nScrollLines, 0);
  659. return nScrollLines;
  660. }
  661. BOOL CXTPReportControl::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
  662. {
  663. if (!m_bVScrollBarVisible)
  664. return CWnd::OnMouseWheel(nFlags, zDelta, pt);
  665. UINT uiMsg;
  666. int nScrollsCount = 0;
  667. // calculate what should be sent
  668. if (m_nRowsPerWheel == -1)
  669. {
  670. // A m_nRowsPerWheel value less than 0 indicates that the mouse wheel scrolls whole pages, not just lines.
  671. int nPagesScrolled = zDelta / 120;
  672. uiMsg = nPagesScrolled > 0 ? SB_PAGEUP : SB_PAGEDOWN;
  673. nScrollsCount = nPagesScrolled > 0 ? nPagesScrolled : -nPagesScrolled;
  674. }
  675. else
  676. {
  677. int nRowsScrolled = m_nRowsPerWheel * zDelta / 120;
  678. uiMsg = nRowsScrolled > 0 ? SB_LINEUP : SB_LINEDOWN;
  679. nScrollsCount = nRowsScrolled > 0 ? nRowsScrolled : -nRowsScrolled;
  680. }
  681. BeginUpdate();
  682. // send scroll messages
  683. for (int i = 0; i < nScrollsCount; i++)
  684. {
  685. OnVScroll(uiMsg, 0, NULL);
  686. }
  687. EndUpdate();
  688. UpdateWindow();
  689. return CWnd::OnMouseWheel(nFlags, zDelta, pt);
  690. }
  691. void CXTPReportControl::OnMouseLeave()
  692. {
  693. OnMouseMove(0, CPoint(-1, -1));
  694. }
  695. void CXTPReportControl::OnMouseMove(UINT nFlags, CPoint point)
  696. {
  697. CWnd::OnMouseMove(nFlags, point);
  698. CXTPReportHeader* pHeader = GetReportHeader();
  699. if (pHeader)
  700. {
  701. pHeader->OnMouseMove(nFlags, point);
  702. }
  703. if (GetMouseMode() == xtpReportMouseNothing)
  704. {
  705. CXTPReportRow* pRow = HitTest(point);
  706. if (pRow)
  707. {
  708. pRow->OnMouseMove(nFlags, point);
  709. if (m_bShowTooltips && nFlags == 0)
  710. {
  711. pRow->ShowToolTip(point, &m_wndTip);
  712. }
  713. }
  714. if (m_pHotRow != pRow)
  715. {
  716. TRACKMOUSEEVENT tme =
  717. {
  718. sizeof(TRACKMOUSEEVENT), TME_LEAVE, GetSafeHwnd(), 0
  719. };
  720. _TrackMouseEvent (&tme);
  721. m_pHotRow = pRow;
  722. }
  723. // If mouse moved some since down...
  724. if (m_bPrepareDrag && (labs (point.x - m_pointDrag.x) > 3 ||
  725. labs (point.y - m_pointDrag.y) > 3))
  726. {
  727. // Prevent duplicate
  728. m_bPrepareDrag = FALSE;
  729. m_pSelectOnUpRow = NULL;
  730. // Begin a drag operation
  731. OnBeginDrag(m_pointDrag);
  732. }
  733. }
  734. }
  735. void CXTPReportControl::OnBeginDrag(CPoint point)
  736. {
  737. if (SendMessageToParent(NULL, NULL, NULL, LVN_BEGINDRAG, &point))
  738. return;
  739. if (m_cfReport ==  NULL)
  740. return;
  741. CXTPReportSelectedRows* pSelectedRows = GetSelectedRows();
  742. if (!pSelectedRows)
  743. return;
  744. if ((m_dwDragDropFlags & xtpReportAllowDrag) == 0)
  745. return;
  746. int nCount = pSelectedRows->GetCount();
  747. for (int i = nCount - 1; i >= 0; i--)
  748. {
  749. CXTPReportRow* pRow = pSelectedRows->GetAt(i);
  750. if (pRow->IsGroupRow())
  751. {
  752. pRow->SetExpanded(TRUE);
  753. pRow->SelectChilds();
  754. }
  755. }
  756. COleDataSource ds;
  757. int nRowsCount = pSelectedRows->GetCount();
  758. if (nRowsCount < 1)
  759. return;
  760. // minimize memory reallocs to improve performance
  761. UINT nAveRecordsSize = 1500; // bytes
  762. UINT nGrowBytes = ((nRowsCount * nAveRecordsSize) / 4096 + 1) * 4096;
  763. UINT nAllocFlags = GMEM_MOVEABLE | GMEM_DDESHARE | GMEM_ZEROINIT;
  764. CSharedFile fileRecords(nAllocFlags, nGrowBytes);
  765. BOOL bSucceed = FALSE;
  766. //------------------------------------------------------------------------
  767. const int cErrTextSize = 1024;
  768. TCHAR szErrText[cErrTextSize + 1];
  769. CXTPReportRecords* pDragRecords = new CXTPReportRecords(TRUE);
  770. if (!_GetSelectedRows(pDragRecords))
  771. {
  772. CMDTARGET_RELEASE(pDragRecords);
  773. return;
  774. }
  775. try
  776. {
  777. CArchive ar(&fileRecords, CArchive::store);
  778. CXTPPropExchangeArchive px(ar);
  779. bSucceed = _WriteRecordsData(&px, pDragRecords);
  780. ar.Close(); // perform Flush() and detach from file
  781. }
  782. catch(CArchiveException* pE)
  783. {
  784. if (pE->GetErrorMessage(szErrText, cErrTextSize))
  785. {
  786. TRACE(_T("EXCEPTION: CXTPReportControl::Copy() - %sn"), szErrText);
  787. }
  788. pE->Delete();
  789. }
  790. catch(CFileException* pE)
  791. {
  792. if (pE->GetErrorMessage(szErrText, cErrTextSize))
  793. {
  794. TRACE(_T("EXCEPTION: CXTPReportControl::Copy() - %sn"), szErrText);
  795. }
  796. pE->Delete();
  797. }
  798. catch(...)
  799. {
  800. TRACE(_T("EXCEPTION: CXTPReportControl::Copy() - Unhandled Exception!n"));
  801. }
  802. if (!bSucceed)
  803. {
  804. CMDTARGET_RELEASE(pDragRecords);
  805. return;
  806. }
  807. HGLOBAL hGlobal = fileRecords.Detach();
  808. m_bDragMode = TRUE;
  809. DROPEFFECT dropEffectMask =
  810. ((m_dwDragDropFlags & xtpReportAllowDragCopy) ? DROPEFFECT_COPY : 0) +
  811. ((m_dwDragDropFlags & xtpReportAllowDragMove) ? DROPEFFECT_MOVE : 0);
  812. XTP_NM_REPORTDRAGDROP nmData;
  813. ZeroMemory(&nmData, sizeof(nmData));
  814. nmData.pRecords = pDragRecords;
  815. if (SendNotifyMessage(XTP_NM_REPORT_BEGINDRAG, (NMHDR*)&nmData) == -1)
  816. return;
  817. ds.CacheGlobalData (m_cfReport, hGlobal);
  818. DROPEFFECT dropEffect = ds.DoDragDrop(dropEffectMask);
  819. m_bDragMode = FALSE;
  820. nmData.dropEffect = dropEffect;
  821. SendNotifyMessage(XTP_NM_REPORT_DRAGDROP_COMPLETED, (NMHDR*)&nmData);
  822. if ((dropEffect == DROPEFFECT_MOVE) && (dropEffectMask & DROPEFFECT_MOVE))
  823. {
  824. Cut();
  825. }
  826. CMDTARGET_RELEASE(pDragRecords);
  827. EnsureStopAutoVertScroll();
  828. }
  829. DROPEFFECT CXTPReportControl::OnDragOver(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point, int nState)
  830. {
  831. DROPEFFECT dropEffect = DROPEFFECT_MOVE;
  832. BOOL bAbove = TRUE;
  833. CXTPReportRecord* pTargetRecord = NULL;
  834. if ((dwKeyState & MK_CONTROL) == MK_CONTROL)
  835. dropEffect = DROPEFFECT_COPY;
  836. if (!m_nOLEDropMode)
  837. {
  838. if (m_cfReport == NULL)
  839. dropEffect = DROPEFFECT_NONE;
  840. if ((m_dwDragDropFlags & xtpReportAllowDrop) == 0)
  841. dropEffect = DROPEFFECT_NONE;
  842. if ((dropEffect != DROPEFFECT_NONE) && (!pDataObject || !pDataObject->IsDataAvailable(m_cfReport)))
  843. dropEffect = DROPEFFECT_NONE;
  844. }
  845. int nDropPos = m_nDropPos;
  846. m_nDropPos = -1;
  847. if (dropEffect != DROPEFFECT_NONE)
  848. {
  849. DoAutoVertScrollIfNeed(m_pointDrag, point);
  850. if (GetColumns()->GetSortOrder()->GetCount() == 0 && GetColumns()->GetGroupsOrder()->GetCount() == 0)
  851. {
  852. CXTPReportRow* pRow = HitTest(point);
  853. if (pRow && pRow->GetRecord())
  854. {
  855. bAbove = pRow->GetRect().CenterPoint().y < point.y ? FALSE : TRUE;
  856. pTargetRecord = pRow->GetRecord();
  857. m_nDropPos = (pRow->GetRect().CenterPoint().y < point.y ? pRow->GetRect().bottom - 1: pRow->GetRect().top - 1);
  858. }
  859. }
  860. }
  861. if(nState == 0)
  862. {
  863. // entering, get report records
  864. CMDTARGET_RELEASE(m_pDropRecords);
  865. CFile* pFile = m_cfReport ? pDataObject->GetFileData(m_cfReport) : NULL;
  866. if (pFile)
  867. {
  868. m_pDropRecords = new CXTPReportRecords();
  869. const int cErrTextSize = 1024;
  870. TCHAR szErrText[cErrTextSize + 1];
  871. try
  872. {
  873. CArchive ar(pFile, CArchive::load);
  874. CXTPPropExchangeArchive px(ar);
  875. if (!_ReadRecodsFromData(&px, *m_pDropRecords))
  876. {
  877. m_pDropRecords->RemoveAll();
  878. }
  879. ar.Close(); // detach from file
  880. }
  881. catch(CArchiveException* pE)
  882. {
  883. if (pE->GetErrorMessage(szErrText, cErrTextSize))
  884. {
  885. TRACE(_T("EXCEPTION: CXTPReportControl::Paste() - %sn"), szErrText);
  886. }
  887. pE->Delete();
  888. }
  889. catch(CFileException* pE)
  890. {
  891. if (pE->GetErrorMessage(szErrText, cErrTextSize))
  892. {
  893. TRACE(_T("EXCEPTION: CXTPReportControl::Paste() - %sn"), szErrText);
  894. }
  895. pE->Delete();
  896. }
  897. catch(...)
  898. {
  899. TRACE(_T("EXCEPTION: CXTPReportControl::Paste() - Unhandled Exception!n"));
  900. }
  901. delete pFile;
  902. }
  903. }
  904. else if(nState == 1)
  905. {
  906. // leaving, release drop records
  907. CMDTARGET_RELEASE(m_pDropRecords);
  908. }
  909. XTP_NM_REPORTDRAGDROP nmData;
  910. nmData.pRecords = m_pDropRecords;
  911. nmData.pTargetRecord = pTargetRecord;
  912. nmData.bAbove = bAbove;
  913. nmData.dropEffect = dropEffect;
  914. nmData.pt = point;
  915. nmData.nState = nState;
  916. SendNotifyMessage(XTP_NM_REPORT_DRAGOVER, (NMHDR*)&nmData);
  917. if (m_nDropPos != nDropPos)
  918. {
  919. RedrawControl();
  920. }
  921. return dropEffect;
  922. }
  923. void CXTPReportControl::OnTimer(UINT_PTR uTimerID)
  924. {
  925. if (m_uAutoScrollTimerID == uTimerID)
  926. {
  927. CPoint ptMouse;
  928. if (::GetCursorPos(&ptMouse))
  929. {
  930. ScreenToClient(&ptMouse);
  931. DoAutoVertScrollIfNeed(m_pointDrag, ptMouse);
  932. }
  933. //TRACE(_T("AutoScrollTimer n"));
  934. }
  935. CWnd::OnTimer(uTimerID);
  936. }
  937. void CXTPReportControl::EnsureStopAutoVertScroll()
  938. {
  939. if (m_uAutoScrollTimerID)
  940. {
  941. KillTimer(m_uAutoScrollTimerID);
  942. m_uAutoScrollTimerID = 0;
  943. //TRACE(_T("AutoScroll STOP n"));
  944. }
  945. }
  946. void CXTPReportControl::EnsureStartAutoVertScroll()
  947. {
  948. if (!m_uAutoScrollTimerID)
  949. {
  950. m_uAutoScrollTimerID = SetTimer(XTP_REPORT_AUTO_SCROLL_TIMER_ID, XTP_REPORT_AUTO_SCROLL_TIMER_RESOLUTION_MS, NULL);
  951. }
  952. }
  953. void CXTPReportControl::DoAutoVertScrollIfNeed(CPoint ptClick, CPoint pt)
  954. {
  955. if (!m_arrScreenRows.GetCount())
  956. {
  957. EnsureStopAutoVertScroll();
  958. return;
  959. }
  960. CXTPReportRow* pRow0 = m_arrScreenRows.GetAt(0);
  961. CXTPReportRow* pRow1 = m_arrScreenRows.GetAt(m_arrScreenRows.GetCount() - 1);
  962. if (!pRow0 || !pRow1)
  963. {
  964. EnsureStopAutoVertScroll();
  965. return;
  966. }
  967. int nDirection = 0;
  968. CRect rc0 = m_rcReportArea;   //pRow0->GetRect();
  969. CRect rc1 = m_rcReportArea;   //pRow1->GetRect();
  970. rc0.bottom = m_rcReportArea.top + 20;
  971. rc1.top = m_rcReportArea.bottom - 20;
  972. if (rc0.PtInRect(pt))
  973. nDirection = -1;
  974. else if (rc1.PtInRect(pt))
  975. nDirection = 1;
  976. if (!nDirection ||
  977. m_bDragMode &&
  978. (nDirection == 1 && pt.y - ptClick.y < 3 ||
  979.  nDirection == -1 && ptClick.y - pt.y < 3)
  980.    )
  981. {
  982. EnsureStopAutoVertScroll();
  983. return;
  984. }
  985. //-----------------------------------------------------
  986. int nTopRow = GetTopRowIndex();
  987. int nRowsCount = m_pRows->GetCount();
  988. if (nDirection == -1 && nTopRow > 0 ||
  989. nDirection == 1 &&
  990. (pRow1->GetIndex() < nRowsCount ||
  991.  pRow1->GetRect().bottom > m_rcReportArea.bottom)
  992. )
  993. {
  994. //TRACE(_T("AutoScroll direction=%d, nextRow=%dn"), nDirection, nTopRow+nDirection);
  995. SetTopRow(nTopRow + nDirection);
  996. EnsureStartAutoVertScroll();
  997. return;
  998. }
  999. EnsureStopAutoVertScroll();
  1000. }
  1001. BOOL CXTPReportControl::OnDrop(COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point)
  1002. {
  1003. CMDTARGET_RELEASE(m_pDropRecords);
  1004. EnsureStopAutoVertScroll();
  1005. CUpdateContext updateContext(this);
  1006. int nDropPos = m_nDropPos;
  1007. m_nDropPos = -1;
  1008. if (dropEffect != DROPEFFECT_COPY && dropEffect != DROPEFFECT_MOVE)
  1009. return FALSE;
  1010. if (IsVirtualMode())
  1011. return FALSE;
  1012. if (!pDataObject || !pDataObject->IsDataAvailable(m_cfReport))
  1013. return FALSE;
  1014. if ((m_dwDragDropFlags & xtpReportAllowDrop) == 0)
  1015. return FALSE;
  1016. int nInsert = GetRecords()->GetCount();
  1017. BOOL bAbove = TRUE;
  1018. CXTPReportRecord* pTargetRecord = NULL;
  1019. CXTPReportRow* pRow = HitTest(point);
  1020. if (pRow)
  1021. {
  1022. bAbove = pRow->GetRect().CenterPoint().y < point.y ? FALSE : TRUE;
  1023. pTargetRecord = pRow->GetRecord();
  1024. if(pTargetRecord)
  1025. nInsert = pTargetRecord->GetIndex() + (bAbove ? 0 : 1);
  1026. }
  1027. if (m_bDragMode && dropEffect == DROPEFFECT_MOVE)
  1028. {
  1029. if (nDropPos == -1)
  1030. return FALSE;
  1031. CXTPReportRecords* pDropRecords = new CXTPReportRecords(TRUE);
  1032. if (!_GetSelectedRows(pDropRecords))
  1033. {
  1034. CMDTARGET_RELEASE(pDropRecords);
  1035. return FALSE;
  1036. }
  1037. XTP_NM_REPORTDRAGDROP nmData;
  1038. nmData.pRecords = pDropRecords;
  1039. nmData.pTargetRecord = pTargetRecord;
  1040. nmData.bAbove = bAbove;
  1041. nmData.dropEffect = dropEffect;
  1042. CMDTARGET_ADDREF(pTargetRecord);
  1043. if (SendNotifyMessage(XTP_NM_REPORT_DROP, (NMHDR*)&nmData) == -1)
  1044. {
  1045. CMDTARGET_RELEASE(pDropRecords);
  1046. return FALSE;
  1047. }
  1048. GetRecords()->Move(nInsert, pDropRecords);
  1049. Populate();
  1050. _SelectRows(pDropRecords);
  1051. RedrawControl();
  1052. SendNotifyMessage(XTP_NM_REPORT_RECORDS_DROPPED, (NMHDR*)&nmData);
  1053. CMDTARGET_RELEASE(pDropRecords);
  1054. CMDTARGET_RELEASE(pTargetRecord);
  1055. return FALSE;
  1056. }
  1057. CFile* pFile = pDataObject->GetFileData(m_cfReport);
  1058. if (!pFile)
  1059. return FALSE;
  1060. CXTPReportRecords* pDropRecords = new CXTPReportRecords();
  1061. const int cErrTextSize = 1024;
  1062. TCHAR szErrText[cErrTextSize + 1];
  1063. try
  1064. {
  1065. CArchive ar(pFile, CArchive::load);
  1066. CXTPPropExchangeArchive px(ar);
  1067. if (!_ReadRecodsFromData(&px, *pDropRecords))
  1068. {
  1069. pDropRecords->RemoveAll();
  1070. }
  1071. ar.Close(); // detach from file
  1072. }
  1073. catch(CArchiveException* pE)
  1074. {
  1075. if (pE->GetErrorMessage(szErrText, cErrTextSize))
  1076. {
  1077. TRACE(_T("EXCEPTION: CXTPReportControl::Paste() - %sn"), szErrText);
  1078. }
  1079. pE->Delete();
  1080. }
  1081. catch(CFileException* pE)
  1082. {
  1083. if (pE->GetErrorMessage(szErrText, cErrTextSize))
  1084. {
  1085. TRACE(_T("EXCEPTION: CXTPReportControl::Paste() - %sn"), szErrText);
  1086. }
  1087. pE->Delete();
  1088. }
  1089. catch(...)
  1090. {
  1091. TRACE(_T("EXCEPTION: CXTPReportControl::Paste() - Unhandled Exception!n"));
  1092. }
  1093. delete pFile;
  1094. XTP_NM_REPORTDRAGDROP nmData;
  1095. nmData.pRecords = pDropRecords;
  1096. nmData.pTargetRecord = pTargetRecord;
  1097. nmData.bAbove = bAbove;
  1098. nmData.dropEffect = dropEffect;
  1099. if (SendNotifyMessage(XTP_NM_REPORT_DROP, (NMHDR*)&nmData) == -1)
  1100. {
  1101. CMDTARGET_RELEASE(pDropRecords);
  1102. return FALSE;
  1103. }
  1104. // Add and Populate records
  1105. int nRecordsCount = pDropRecords->GetCount();
  1106. if (nRecordsCount > 0)
  1107. {
  1108. // Add
  1109. for (int i = 0; i < nRecordsCount; i++)
  1110. {
  1111. CXTPReportRecord* pRecord = pDropRecords->GetAt(i);
  1112. if (pRecord)
  1113. {
  1114. CMDTARGET_ADDREF(pRecord);
  1115. m_pRecords->InsertAt(nInsert, pRecord);
  1116. nInsert++;
  1117. }
  1118. }
  1119. Populate();
  1120. _SelectRows(pDropRecords);
  1121. RedrawControl();
  1122. SendNotifyMessage(XTP_NM_REPORT_RECORDS_DROPPED, (NMHDR*)&nmData);
  1123. }
  1124. CMDTARGET_RELEASE(pDropRecords);
  1125. return TRUE;
  1126. }
  1127. BOOL CXTPReportControl::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
  1128. {
  1129. if (nHitTest == HTCLIENT)
  1130. {
  1131. switch (m_mouseMode)
  1132. {
  1133. case xtpReportMouseOverColumnDivide:
  1134. SetCursor(GetReportHeader()->m_hResizeCursor);
  1135. return TRUE;
  1136. }
  1137. }
  1138. return CWnd::OnSetCursor(pWnd, nHitTest, message);
  1139. }
  1140. LRESULT CXTPReportControl::SendNotifyMessage(UINT nMessage, NMHDR* pNMHDR) const
  1141. {
  1142. if (!IsWindow(m_hWnd))
  1143. return 0;
  1144. NMHDR nmhdr;
  1145. if (pNMHDR == NULL)
  1146. pNMHDR = &nmhdr;
  1147. pNMHDR->hwndFrom = GetSafeHwnd();
  1148. pNMHDR->idFrom = GetDlgCtrlID();
  1149. pNMHDR->code = nMessage;
  1150. CWnd *pOwner = GetOwner();
  1151. if (pOwner && IsWindow(pOwner->m_hWnd))
  1152. return pOwner->SendMessage(WM_NOTIFY, pNMHDR->idFrom, (LPARAM)pNMHDR);
  1153. else
  1154. return 0;
  1155. }
  1156. LRESULT CXTPReportControl::SendMessageToParent(CXTPReportRow* pRow, CXTPReportRecordItem* pItem, CXTPReportColumn* pColumn, UINT nMessage, CPoint* pPoint, int nHyperlink) const
  1157. {
  1158. if (!IsWindow(m_hWnd))
  1159. return 0;
  1160. XTP_NM_REPORTRECORDITEM nmgv;
  1161. nmgv.pItem = pItem;
  1162. nmgv.pColumn = pColumn;
  1163. nmgv.pRow = pRow;
  1164. nmgv.nHyperlink = nHyperlink;
  1165. nmgv.pt.x = 0;
  1166. nmgv.pt.y = 0;
  1167. if (pPoint)
  1168. {
  1169. nmgv.pt = *pPoint;
  1170. }
  1171. return SendNotifyMessage(nMessage, (NMHDR*)&nmgv);
  1172. }
  1173. void CXTPReportControl::DoPropExchange(CXTPPropExchange* pPX)
  1174. {
  1175. TRY
  1176. {
  1177. pPX->ExchangeSchemaSafe();
  1178. CXTPPropExchangeSection secColumns(pPX->GetSection(_T("Columns")));
  1179. m_pColumns->DoPropExchange(&secColumns);
  1180. PX_Bool(pPX, _T("ShowGroupBox"), m_bGroupByEnabled, FALSE);
  1181. PX_Int(pPX, _T("FreezeColumnsCount"), m_nFreezeColumnsCount, 0);
  1182. if (pPX->GetSchema() >= _XTP_SCHEMA_110)
  1183. {
  1184. PX_Bool(pPX, _T("FullColumnScrolling"), m_bFullColumnScrolling, FALSE);
  1185. PX_Int(pPX, _T("HScrollStep"), m_nHScrollStep, XTP_REPORT_HSCROLL_STEP);
  1186. }
  1187. CXTPPropExchangeSection secHeader(pPX->GetSection(_T("Header")));
  1188. GetReportHeader()->DoPropExchange(&secHeader);
  1189. if (pPX->IsLoading())
  1190. {
  1191. GetReportHeader()->OnColumnsChanged();
  1192. Populate();
  1193. }
  1194. }
  1195. CATCH(CArchiveException, e)
  1196. {
  1197. }
  1198. END_CATCH
  1199. }
  1200. void CXTPReportControl::SerializeState(CArchive& ar)
  1201. {
  1202. CXTPPropExchangeArchive px(ar);
  1203. DoPropExchange(&px);
  1204. }
  1205. void CXTPReportControl::CollapseAll()
  1206. {
  1207. BeginUpdate();
  1208. for (int i = m_pRows->GetCount() - 1; i >= 0; i--)
  1209. m_pRows->GetAt(i)->SetExpanded(FALSE);
  1210. EndUpdate();
  1211. EnsureVisible(GetFocusedRow());
  1212. }
  1213. void CXTPReportControl::ExpandAll()
  1214. {
  1215. BeginUpdate();
  1216. for (int i = m_pRows->GetCount() - 1; i >= 0; i--)
  1217. m_pRows->GetAt(i)->SetExpanded(TRUE);
  1218. EndUpdate();
  1219. EnsureVisible(GetFocusedRow());
  1220. }
  1221. void CXTPReportControl::SetMouseMode(XTPReportMouseMode nMode)
  1222. {
  1223. XTP_TRACE(_T("SetMouseMode: Switching from %d to %dn"), m_mouseMode, nMode);
  1224. m_mouseMode = nMode;
  1225. }
  1226. void CXTPReportControl::RelayToolTipEvent(UINT message)
  1227. {
  1228. if (m_wndTip.GetSafeHwnd() && m_wndTip.IsWindowVisible())
  1229. {
  1230. CPoint pt;
  1231. GetCursorPos(&pt);
  1232. if (!m_wndTip.GetHoverRect().PtInRect(pt))
  1233. {
  1234. m_wndTip.SetTooltipText(NULL);
  1235. m_wndTip.Activate(FALSE, FALSE);
  1236. }
  1237. switch (message)
  1238. {
  1239. case WM_MOUSEWHEEL:
  1240. case WM_KEYDOWN:
  1241. case WM_SYSKEYDOWN:
  1242. case WM_LBUTTONDOWN:
  1243. case WM_RBUTTONDOWN:
  1244. case WM_MBUTTONDOWN:
  1245. case WM_LBUTTONUP:
  1246. case WM_RBUTTONUP:
  1247. case WM_MBUTTONUP:
  1248. case WM_MOUSELEAVE:
  1249. m_wndTip.Activate(FALSE, FALSE);
  1250. }
  1251. }
  1252. }
  1253. BOOL CXTPReportControl::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
  1254. {
  1255. static BOOL bRelay = FALSE;
  1256. if (m_wndTip.GetSafeHwnd() && m_wndTip.IsWindowVisible() && !bRelay)
  1257. {
  1258. bRelay = TRUE;
  1259. RelayToolTipEvent(message);
  1260. bRelay = FALSE;
  1261. }
  1262. if (m_pToolTipContext && m_bShowTooltips)
  1263. {
  1264. m_pToolTipContext->FilterToolTipMessage(this, message, wParam, lParam);
  1265. }
  1266. return CWnd::OnWndMsg(message, wParam, lParam, pResult);
  1267. }
  1268. void CXTPReportControl::OnSysColorChange()
  1269. {
  1270. CWnd::OnSysColorChange();
  1271. m_pPaintManager->RefreshMetrics();
  1272. RedrawControl();
  1273. }
  1274. UINT CXTPReportControl::OnGetDlgCode()
  1275. {
  1276. return (m_bFocusSubItems ? DLGC_WANTTAB :0) | DLGC_WANTARROWS | DLGC_WANTCHARS;
  1277. }
  1278. void CXTPReportControl::OnSetFocus(CWnd* pOldWnd)
  1279. {
  1280. CWnd::OnSetFocus(pOldWnd);
  1281. RedrawControl();
  1282. }
  1283. void CXTPReportControl::OnKillFocus (CWnd* pNewWnd)
  1284. {
  1285. CWnd::OnKillFocus(pNewWnd);
  1286. EnsureStopAutoVertScroll();
  1287. RedrawControl();
  1288. }
  1289. int CXTPReportControl::GetHeaderIndent() const
  1290. {
  1291. return GetIndent(GetReportHeader()->m_nIndentLevel);
  1292. }
  1293. CXTPReportRow* CXTPReportControl::CreateRow()
  1294. {
  1295. return new CXTPReportRow_Batch();
  1296. }
  1297. CXTPReportGroupRow* CXTPReportControl::CreateGroupRow()
  1298. {
  1299. return new CXTPReportGroupRow_Batch();
  1300. }
  1301. CXTPReportRow* CXTPReportControl::CreateHeaderFooterRow()
  1302. {
  1303. return new CXTPHeapObjectT<CXTPReportRow, CXTPReportAllocatorDefault>;
  1304. }
  1305. void CXTPReportControl::EditItem(XTP_REPORTRECORDITEM_ARGS* pItemArgs)
  1306. {
  1307. CXTPReportRecordItem* pItem = pItemArgs ? pItemArgs->pItem : NULL;
  1308. if (m_pActiveItem != NULL)
  1309. {
  1310. m_pActiveItem->OnCancelEdit(this, TRUE);
  1311. m_pActiveItem = NULL;
  1312. if (!m_bFocusSubItems)
  1313. {
  1314. SetFocusedColumn(NULL);
  1315. }
  1316. }
  1317. CMDTARGET_RELEASE(m_ptrVirtualEditingRow);
  1318. if (pItem && pItemArgs && pItemArgs->pRow)
  1319. {
  1320. if (!HasFocus())
  1321. SetFocus();
  1322. if (!IsVirtualMode())
  1323. {
  1324. AdjustScrollBars();
  1325. RedrawControl();
  1326. UpdateWindow();
  1327. }
  1328. if (IsVirtualMode())
  1329. {
  1330. int nRowIndex = pItemArgs->pRow->GetIndex();
  1331. EnsureVisible(pItemArgs->pRow);
  1332. RedrawControl();
  1333. UpdateWindow();
  1334. pItemArgs->pRow = NULL; // RedrawControl delete and re-create new screen rows
  1335. BOOL bMapped = FALSE;
  1336. int nScrCount = m_arrScreenRows.GetCount();
  1337. for (int i = 0; i < nScrCount; i++)
  1338. {
  1339. CXTPReportRow* pRow = m_arrScreenRows.GetAt(i);
  1340. if (pRow->GetIndex() == nRowIndex)
  1341. {
  1342. pItemArgs->pRow = pRow;
  1343. bMapped = TRUE;
  1344. ASSERT(m_ptrVirtualEditingRow == NULL);
  1345. m_ptrVirtualEditingRow = pRow;
  1346. CMDTARGET_ADDREF(m_ptrVirtualEditingRow);
  1347. break;
  1348. }
  1349. }
  1350. ASSERT(bMapped);
  1351. if (!bMapped)
  1352. return;
  1353. }
  1354. else if (GetFocusedRow() != pItemArgs->pRow)
  1355. {
  1356. SetFocusedRow(pItemArgs->pRow);
  1357. UpdateWindow();
  1358. }
  1359. pItemArgs->rcItem = pItemArgs->pRow->GetItemRect(pItem);
  1360. if(SetFocusedColumn(pItemArgs->pColumn))
  1361. {
  1362. m_pActiveItem = pItem;
  1363. pItem->OnBeginEdit(pItemArgs);
  1364. }
  1365. }
  1366. RedrawControl();
  1367. }
  1368. BOOL CXTPReportControl::HasFocus() const
  1369. {
  1370. const CWnd* pFocusWnd = GetFocus();
  1371. if (!pFocusWnd)
  1372. return FALSE;
  1373. return (pFocusWnd->GetSafeHwnd() == m_hWnd) || (pFocusWnd->GetParent()->GetSafeHwnd() == m_hWnd) || (pFocusWnd->GetOwner()->GetSafeHwnd() == m_hWnd);
  1374. }
  1375. void CXTPReportControl::ReleaseItem(int nIndex)
  1376. {
  1377. int i;
  1378. for (i = 0; i < m_pRecords->GetCount(); i++)
  1379. {
  1380. CXTPReportRecord* pRecord = m_pRecords->GetAt(i);
  1381. pRecord->m_arrItems[nIndex]->InternalRelease();
  1382. pRecord->m_arrItems.RemoveAt(nIndex);
  1383. }
  1384. CXTPReportColumns* pColumns = GetColumns();
  1385. CXTPReportColumn* pColumnToRemove = NULL;
  1386. int nColumnsCount = pColumns->GetCount();
  1387. for (i = 0; i < nColumnsCount; i++)
  1388. {
  1389. CXTPReportColumn* pColumn = pColumns->GetAt(i);
  1390. if (pColumn->m_nItemIndex > nIndex)
  1391. {
  1392. pColumn->m_nItemIndex--;
  1393. }
  1394. else if (pColumn->m_nItemIndex == nIndex)
  1395. {
  1396. pColumnToRemove = pColumn;
  1397. }
  1398. }
  1399. if (pColumnToRemove)
  1400. pColumns->Remove(pColumnToRemove);
  1401. }
  1402. void CXTPReportControl::SetVirtualMode(CXTPReportRecord* pVirtualRecord, int nCount)
  1403. {
  1404. if (m_pRecords)
  1405. m_pRecords->SetVirtualMode(pVirtualRecord, nCount);
  1406. }
  1407. BOOL CXTPReportControl::IsVirtualMode() const
  1408. {
  1409. return m_pRecords ? m_pRecords->IsVirtualMode() : FALSE;
  1410. }
  1411. CXTPReportRow* CXTPReportControl::GetFocusedRow() const
  1412. {
  1413. if (m_nFocusedRow != -1)
  1414. return m_pRows ? m_pRows->GetAt(m_nFocusedRow) : NULL;
  1415. if (m_nFocusedHeaderRow != -1)
  1416. return m_pHeaderRows ? m_pHeaderRows->GetAt(m_nFocusedHeaderRow) : NULL;
  1417. if (m_nFocusedFooterRow != -1)
  1418. return m_pFooterRows ? m_pFooterRows->GetAt(m_nFocusedFooterRow) : NULL;
  1419. return NULL;
  1420. }
  1421. void CXTPReportControl::OnStyleChanged(int nStyleType, LPSTYLESTRUCT lpStyleStruct)
  1422. {
  1423. CWnd::OnStyleChanged(nStyleType, lpStyleStruct);
  1424. RedrawControl();
  1425. }
  1426. CXTPToolTipContext* CXTPReportControl::GetToolTipContext() const
  1427. {
  1428. return m_pToolTipContext;
  1429. }
  1430. INT_PTR CXTPReportControl::OnToolHitTest(CPoint point, TOOLINFO* pTI) const
  1431. {
  1432. ASSERT_VALID(this);
  1433. ASSERT(::IsWindow(m_hWnd));
  1434. // check child windows first by calling CControlBar
  1435. INT_PTR nHit = CWnd::OnToolHitTest(point, pTI);
  1436. if (nHit != -1)
  1437. return nHit;
  1438. nHit = GetReportHeader()->OnToolHitTest(point, pTI);
  1439. if (nHit != -1)
  1440. return nHit;
  1441. CXTPReportRow* pRow = HitTest(point);
  1442. if (pRow)
  1443. {
  1444. nHit = pRow->OnToolHitTest(point, pTI);
  1445. }
  1446. return nHit;
  1447. }
  1448. void CXTPReportControl::SetLayoutRTL(BOOL bRightToLeft)
  1449. {
  1450. if (!XTPSystemVersion()->IsLayoutRTLSupported())
  1451. return;
  1452. if (!m_hWnd)
  1453. return;
  1454. ModifyStyleEx(bRightToLeft ? 0 : WS_EX_LAYOUTRTL, !bRightToLeft ? 0 : WS_EX_LAYOUTRTL);
  1455. GetImageManager()->DrawReverted(bRightToLeft);
  1456. GetInplaceEdit()->DestroyWindow();
  1457. AdjustLayout();
  1458. }
  1459. BOOL CXTPReportControl::IsLayoutRTL()
  1460. {
  1461. if (!XTPSystemVersion()->IsLayoutRTLSupported())
  1462. return FALSE;
  1463. if (!m_hWnd)
  1464. return FALSE;
  1465. return !!(GetWindowLong(m_hWnd, GWL_EXSTYLE) & WS_EX_LAYOUTRTL);
  1466. }
  1467. //////////////////////////////////////////////////////////////////////////
  1468. // Clipboard operations
  1469. BOOL CXTPReportControl::CanCopy()
  1470. {
  1471. // Check whether are there any selected rows to be copied
  1472. CXTPReportSelectedRows* pSelRows = GetSelectedRows();
  1473. if ((pSelRows != NULL) && (pSelRows->GetCount() > 0))
  1474. {
  1475. return TRUE;
  1476. }
  1477. return FALSE;
  1478. }
  1479. BOOL CXTPReportControl::CanCut()
  1480. {
  1481. if (IsVirtualMode())
  1482. return FALSE;
  1483. return CanCopy();
  1484. }
  1485. BOOL CXTPReportControl::CanPaste()
  1486. {
  1487. if (IsVirtualMode())
  1488. return FALSE;
  1489. CLIPFORMAT uCF_Records = (CLIPFORMAT)::RegisterClipboardFormat(XTPREPORTCTRL_CF_RECORDS);
  1490. BOOL bCan = FALSE;
  1491. COleDataObject odj;
  1492. if (odj.AttachClipboard())
  1493. {
  1494. bCan = odj.IsDataAvailable(CF_TEXT)
  1495. || odj.IsDataAvailable(CF_UNICODETEXT)
  1496. || odj.IsDataAvailable(uCF_Records) ;
  1497. }
  1498. return bCan;
  1499. }
  1500. void CXTPReportControl::Cut()
  1501. {
  1502. CWaitCursor _WC;
  1503. // Copy selected data into the clipboard
  1504. Copy();
  1505. if (IsVirtualMode())
  1506. return;
  1507. // Delete selected rows
  1508. CXTPInternalCollectionT<CXTPReportRow> arSelectedRows;
  1509. _GetSelectedRows(NULL, &arSelectedRows);
  1510. int nSelRowsCount = (int)arSelectedRows.GetSize();
  1511. int nFirstSelRow = INT_MAX;
  1512. for (int i = nSelRowsCount - 1; i >= 0 ; i--)
  1513. {
  1514. CXTPReportRow* pRow = arSelectedRows.GetAt(i, FALSE);
  1515. if (pRow)
  1516. {
  1517. nFirstSelRow = min(nFirstSelRow, pRow->GetIndex());
  1518. VERIFY(RemoveRowEx(pRow, FALSE));
  1519. }
  1520. arSelectedRows.RemoveAt(i);
  1521. }
  1522. if (GetSelectedRows())
  1523. {
  1524. GetSelectedRows()->Clear();
  1525. if (nFirstSelRow != INT_MAX)
  1526. {
  1527. m_nFocusedRow = min(nFirstSelRow, GetRows()->GetCount() - 1);
  1528. if (GetFocusedRow())
  1529. {
  1530. SetFocusedRow(GetFocusedRow());
  1531. GetSelectedRows()->Add(GetFocusedRow());
  1532. }
  1533. }
  1534. }
  1535. AdjustScrollBars();
  1536. RedrawControl();
  1537. }
  1538. // We support text format with t dividers for record items and
  1539. // rn dividers for records (simple tab-separated text).
  1540. // Such format is also supported by Excel and some other applications.
  1541. void CXTPReportControl::Copy()
  1542. {
  1543. CWaitCursor _WC;
  1544. int nRowsCount = GetSelectedRows() ? GetSelectedRows()->GetCount() : 1;
  1545. // minimize memory reallocs to improve performance
  1546. UINT nAveRecordsSize = 1500; // bytes
  1547. UINT nGrowBytes = ((nRowsCount * nAveRecordsSize) / 4096 + 1) * 4096;
  1548. UINT nAllocFlags = GMEM_MOVEABLE | GMEM_DDESHARE | GMEM_ZEROINIT;
  1549. CSharedFile fileRecords(nAllocFlags, nGrowBytes);
  1550. BOOL bIsRecordsData = FALSE;
  1551. //------------------------------------------------------------------------
  1552. const int cErrTextSize = 1024;
  1553. TCHAR szErrText[cErrTextSize + 1];
  1554. try
  1555. {
  1556. CArchive ar(&fileRecords, CArchive::store);
  1557. CXTPPropExchangeArchive px(ar);
  1558. bIsRecordsData = _WriteSelectedRowsData(&px);
  1559. ar.Close(); // perform Flush() and detach from file
  1560. }
  1561. catch(CArchiveException* pE)
  1562. {
  1563. if (pE->GetErrorMessage(szErrText, cErrTextSize))
  1564. {
  1565. TRACE(_T("EXCEPTION: CXTPReportControl::Copy() - %sn"), szErrText);
  1566. }
  1567. pE->Delete();
  1568. }
  1569. catch(CFileException* pE)
  1570. {
  1571. if (pE->GetErrorMessage(szErrText, cErrTextSize))
  1572. {
  1573. TRACE(_T("EXCEPTION: CXTPReportControl::Copy() - %sn"), szErrText);
  1574. }
  1575. pE->Delete();
  1576. }
  1577. catch(...)
  1578. {
  1579. TRACE(_T("EXCEPTION: CXTPReportControl::Copy() - Unhandled Exception!n"));
  1580. }
  1581. //*****
  1582. CString strClipText = _GetSelectedRowsVisibleColsText();
  1583. CLIPFORMAT uCF_Records = (CLIPFORMAT)::RegisterClipboardFormat(XTPREPORTCTRL_CF_RECORDS);
  1584. // Put prepared text into the clipboard
  1585. if (OpenClipboard())
  1586. {
  1587. ::EmptyClipboard();
  1588. // 1 - Text
  1589. int nLen = (strClipText.GetLength() + 1) * sizeof(TCHAR);
  1590. HGLOBAL hText = ::GlobalAlloc(nAllocFlags, nLen);
  1591. if (hText != NULL)
  1592. {
  1593. LPTSTR lptstrCopy = (TCHAR*)GlobalLock(hText);
  1594. STRCPY_S(lptstrCopy, strClipText.GetLength() + 1, (LPCTSTR)strClipText);
  1595. GlobalUnlock(hText);
  1596. #ifndef _UNICODE
  1597. ::SetClipboardData(CF_TEXT, hText);
  1598. #else
  1599. ::SetClipboardData(CF_UNICODETEXT, hText);
  1600. #endif
  1601. }
  1602. // 2 - Blob data
  1603. if (bIsRecordsData)
  1604. {
  1605. HGLOBAL hData = fileRecords.Detach();
  1606. ::GlobalUnlock(hData); // unlock data
  1607. ::SetClipboardData(uCF_Records, hData);
  1608. }
  1609. //-----------------
  1610. ::CloseClipboard();
  1611. }
  1612. }
  1613. void CXTPReportControl::Paste()
  1614. {
  1615. if (IsVirtualMode())
  1616. return;
  1617. CWaitCursor _WC;
  1618. CLIPFORMAT uCF_Records = (CLIPFORMAT)::RegisterClipboardFormat(XTPREPORTCTRL_CF_RECORDS);
  1619. CXTPReportRecords arRecords;
  1620. BOOL bTryPasteFromText = TRUE;
  1621. // Retrieve text from the clipboard
  1622. if (!OpenClipboard())
  1623. return;
  1624. if (::IsClipboardFormatAvailable(uCF_Records))
  1625. {
  1626. HGLOBAL hPasteData = ::GetClipboardData(uCF_Records);
  1627. if (hPasteData)
  1628. {
  1629. bTryPasteFromText = FALSE;
  1630. const int cErrTextSize = 1024;
  1631. TCHAR szErrText[cErrTextSize + 1];
  1632. CSharedFile fileSahred;
  1633. fileSahred.SetHandle(hPasteData, FALSE);
  1634. CArchive ar(&fileSahred, CArchive::load);
  1635. try
  1636. {
  1637. CXTPPropExchangeArchive px(ar);
  1638. if (!_ReadRecodsFromData(&px, arRecords))
  1639. {
  1640. arRecords.RemoveAll();
  1641. }
  1642. }
  1643. catch(CArchiveException* pE)
  1644. {
  1645. if (pE->GetErrorMessage(szErrText, cErrTextSize))
  1646. {
  1647. TRACE(_T("EXCEPTION: CXTPReportControl::Paste() - %sn"), szErrText);
  1648. }
  1649. pE->Delete();
  1650. }
  1651. catch(CFileException* pE)
  1652. {
  1653. if (pE->GetErrorMessage(szErrText, cErrTextSize))
  1654. {
  1655. TRACE(_T("EXCEPTION: CXTPReportControl::Paste() - %sn"), szErrText);
  1656. }
  1657. pE->Delete();
  1658. }
  1659. catch(...)
  1660. {
  1661. TRACE(_T("EXCEPTION: CXTPReportControl::Paste() - Unhandled Exception!n"));
  1662. }
  1663. //*********
  1664. ar.Close(); // detach from file
  1665. fileSahred.Detach(); //detach from data
  1666. ::GlobalUnlock(hPasteData); // unlock data
  1667. }
  1668. }
  1669. UINT uCF_TText = sizeof(TCHAR) == 2 ? CF_UNICODETEXT : CF_TEXT;
  1670. if (bTryPasteFromText && ::IsClipboardFormatAvailable(uCF_TText))
  1671. {
  1672. // Try to get text data from the clipboard
  1673. HGLOBAL hglbPaste = ::GetClipboardData(uCF_TText);
  1674. // Import Text data into the control
  1675. if (hglbPaste != NULL)
  1676. {
  1677. TCHAR* lpszClipboard = (TCHAR*)GlobalLock(hglbPaste);
  1678. if (!_ReadRecodsFromText(lpszClipboard, arRecords))
  1679. {
  1680. arRecords.RemoveAll();
  1681. }
  1682. ::GlobalUnlock(hglbPaste);
  1683. }
  1684. }
  1685. ::CloseClipboard();
  1686. //////////////////////////////////////////////////////////////////////////
  1687. CUpdateContext updateContext(this);
  1688. // Add and Populate records
  1689. int nRecordsCount = arRecords.GetCount();
  1690. if (nRecordsCount > 0)
  1691. {
  1692. // Add
  1693. for (int i = 0; i < nRecordsCount; i++)
  1694. {
  1695. CXTPReportRecord* pRecord = arRecords.GetAt(i);
  1696. if (pRecord)
  1697. {
  1698. CMDTARGET_ADDREF(pRecord);
  1699. AddRecord(pRecord);
  1700. }
  1701. }
  1702. Populate();
  1703. // Select added records
  1704. _SelectRows(&arRecords);
  1705. }
  1706. }
  1707. // We support text format with t dividers for record items and
  1708. // rn dividers for records (simple tab-separated text).
  1709. // Such format is also supported by Excel and some other applications.
  1710. CString CXTPReportControl::_GetSelectedRowsVisibleColsText()
  1711. {
  1712. CString strSelText;
  1713. CXTPReportColumns* pColumns = GetColumns();
  1714. if (NULL == pColumns)
  1715. return _T("");
  1716. const int nColumnCount = pColumns->GetVisibleColumnsCount();
  1717. // Iterate over the selected rows and prepare corresponding records text
  1718. CXTPReportSelectedRows* pSelectedRows = GetSelectedRows();
  1719. if ((pSelectedRows != NULL) && (pSelectedRows->GetCount() > 0))
  1720. {
  1721. POSITION pos = pSelectedRows->GetFirstSelectedRowPosition();
  1722. while (pos)
  1723. {
  1724. CXTPReportRow* pRow = pSelectedRows->GetNextSelectedRow(pos);
  1725. if (NULL == pRow)
  1726. break;
  1727. CXTPReportRecord* pRecord = pRow->GetRecord();
  1728. if (NULL == pRecord)
  1729. continue;
  1730. CStringArray arStrings;
  1731. for (int nCol = 0; nCol < nColumnCount; nCol++)
  1732. {
  1733. CXTPReportColumn* pColumn = pColumns->GetVisibleAt(nCol);
  1734. CXTPReportRecordItem* pItem = pRecord->GetItem(pColumn);
  1735. if (NULL == pItem)
  1736. continue;
  1737. arStrings.Add(pItem->GetCaption(pColumn));
  1738. }
  1739. //===============================================================
  1740. BOOL bCanceled = OnBeforeCopyToText(pRecord, arStrings);
  1741. if (bCanceled)
  1742. {
  1743. continue;
  1744. }
  1745. strSelText += XTPStrMake(arStrings, _T("t"));
  1746. strSelText += _T("rn");
  1747. }
  1748. }
  1749. return strSelText;
  1750. }
  1751. BOOL CXTPReportControl::_ReadRecodsFromText(LPCTSTR pcszText,
  1752. CXTPReportRecords& rarRecords)
  1753. {
  1754. //////////////////////////////////////////////////////////////////////////
  1755. // Insert retrieved text into the control
  1756. CStringArray arRecordsStrings;
  1757. XTPStrSplit(pcszText, _T("rn"), arRecordsStrings);
  1758. int nCount = (int)arRecordsStrings.GetSize();
  1759. for (int i = 0; i < nCount; i++)
  1760. {
  1761. CString strRecord = arRecordsStrings[i];
  1762. if (strRecord.IsEmpty())
  1763. {
  1764. continue;
  1765. }
  1766. CXTPReportRecord* pNewRec = _CreateRecodFromText(strRecord);
  1767. // pNewRec = NULL - paste was handled by the user
  1768. if (pNewRec)
  1769. {
  1770. rarRecords.Add(pNewRec);
  1771. }
  1772. }
  1773. return TRUE;
  1774. }
  1775. CXTPReportRecord* CXTPReportControl::_CreateRecodFromText(LPCTSTR pcszRecord)
  1776. {
  1777. if (!GetColumns())
  1778. {
  1779. ASSERT(FALSE);
  1780. return NULL;
  1781. }
  1782. CStringArray arStrings;
  1783. // Read each field from the initial string and set visible field one by one
  1784. XTPStrSplit(pcszRecord, _T("t"), arStrings);
  1785. //=======================================================================
  1786. CXTPReportRecord* pRecord = NULL;
  1787. BOOL bHandled = OnBeforePasteFromText(arStrings, &pRecord);
  1788. if (bHandled)
  1789. {
  1790. return pRecord;
  1791. }
  1792. #if _MFC_VER >= 0x0600 // Not supported by Visual Studio 5.0
  1793. if (!pRecord)
  1794. {
  1795. pRecord = new CXTPReportRecord();
  1796. if (!pRecord)
  1797. {
  1798. return NULL;
  1799. }
  1800. int nDataCount = (int)arStrings.GetSize();
  1801. // Fill record with all items
  1802. int nCount = GetColumns()->GetCount();
  1803. for (int i = 0; i < nCount; i++)
  1804. {
  1805. COleVariant varItem(_T(""));
  1806. CXTPReportRecordItem* pItem = new CXTPReportRecordItemVariant(varItem);
  1807. if (!pItem)
  1808. {
  1809. CMDTARGET_RELEASE(pRecord);
  1810. return NULL;
  1811. }
  1812. pRecord->AddItem(pItem);
  1813. }
  1814. // Iterate all visible columns and set text for each next
  1815. const int nColumnCount = GetColumns()->GetVisibleColumnsCount();
  1816. for (int nCol = 0; nCol < nColumnCount; nCol++)
  1817. {
  1818. COleVariant varItem(nCol < nDataCount ? (LPCTSTR)arStrings[nCol] : _T(""));
  1819. CXTPReportColumn* pColumn = GetColumns()->GetVisibleAt(nCol);
  1820. CXTPReportRecordItem* pItem = pRecord->GetItem(pColumn);
  1821. ASSERT(pItem);
  1822. if (NULL == pItem)
  1823. continue;
  1824. CXTPReportRecordItemVariant* pItemVar = DYNAMIC_DOWNCAST(CXTPReportRecordItemVariant, pItem);
  1825. ASSERT(pItemVar);
  1826. if (pItemVar)
  1827. {
  1828. pItemVar->m_oleValue = varItem;
  1829. }
  1830. }
  1831. }
  1832. #endif
  1833. return pRecord;
  1834. }
  1835. BOOL CXTPReportControl::_WriteRecordsData(CXTPPropExchange* pPX, CXTPReportRecords* pRecords)
  1836. {
  1837. if (!pRecords)
  1838. return FALSE;
  1839. long nSchema = XTP_REPORT_CB_RECORDS_DATA_VER;
  1840. PX_Long(pPX, _T("Version"), (long&)nSchema);
  1841. pPX->ExchangeLocale();
  1842. CXTPPropExchangeSection secRecords(pPX->GetSection(_T("ReportRecords")));
  1843. int nRecordsCount = (int)pRecords->GetCount();
  1844. CXTPPropExchangeEnumeratorPtr pEnumRecords(secRecords->GetEnumerator(_T("Record")));
  1845. POSITION posRecord = pEnumRecords->GetPosition((DWORD)nRecordsCount);
  1846. for (int i = 0; i < nRecordsCount; i++)
  1847. {
  1848. CXTPPropExchangeSection secRecord(pEnumRecords->GetNext(posRecord));
  1849. CXTPReportRecord* pRecord = pRecords->GetAt(i);
  1850. PX_Object(&secRecord, pRecord, RUNTIME_CLASS(CXTPReportRecord));
  1851. }
  1852. return TRUE;
  1853. }
  1854. void CXTPReportControl::_SelectRows(CXTPReportRecords* pRecords)
  1855. {
  1856. CXTPReportRows* pRows = GetRows();
  1857. CXTPReportSelectedRows* pSelRows = GetSelectedRows();
  1858. if (!pRows || !pSelRows)
  1859. return;
  1860. pSelRows->Clear();
  1861. int nRecordsCount = pRecords->GetCount();
  1862. for (int nNewRecNr = 0; nNewRecNr < nRecordsCount; nNewRecNr++)
  1863. {
  1864. CXTPReportRecord* pRec = pRecords->GetAt(nNewRecNr);
  1865. CXTPReportRow* pRow = pRows->Find(pRec);
  1866. if (pRow)
  1867. {
  1868. pSelRows->Add(pRow);
  1869. if (nNewRecNr == nRecordsCount - 1)
  1870. SetFocusedRow(pRow, TRUE);
  1871. }
  1872. }
  1873. }
  1874. BOOL CXTPReportControl::_GetSelectedRows(CXTPReportRecords* pRecords,
  1875.  CXTPInternalCollectionT<CXTPReportRow> *pRows)
  1876. {
  1877. ASSERT(!pRecords || pRecords->m_bArray == TRUE);
  1878. CXTPReportSelectedRows* pSelectedRows = GetSelectedRows();
  1879. if (!pSelectedRows || !pSelectedRows->GetCount() || (!pRecords && !pRows))
  1880. {
  1881. return FALSE;
  1882. }
  1883. POSITION pos = pSelectedRows->GetFirstSelectedRowPosition();
  1884. while (pos)
  1885. {
  1886. CXTPReportRow* pRow = pSelectedRows->GetNextSelectedRow(pos);
  1887. CXTPReportRecord* pRecord = pRow ? pRow->GetRecord() : NULL;
  1888. if (NULL == pRow)
  1889. {
  1890. break;
  1891. }
  1892. if (pRecord && pRecords)
  1893. {
  1894. pRecords->Add(pRecord);
  1895. }
  1896. if (pRow && pRows)
  1897. {
  1898. pRows->AddPtr(pRow, TRUE);
  1899. }
  1900. }
  1901. return TRUE;
  1902. }
  1903. BOOL CXTPReportControl::_WriteSelectedRowsData(CXTPPropExchange* pPX)
  1904. {
  1905. if (!pPX || !pPX->IsStoring())
  1906. {
  1907. ASSERT(FALSE);
  1908. return FALSE;
  1909. }
  1910. CXTPReportRecords* pSelectedRecords= new CXTPReportRecords(TRUE);
  1911. if (!_GetSelectedRows(pSelectedRecords) || !_WriteRecordsData(pPX, pSelectedRecords))
  1912. {
  1913. CMDTARGET_RELEASE(pSelectedRecords);
  1914. return FALSE;
  1915. }
  1916. CMDTARGET_RELEASE(pSelectedRecords);
  1917. return TRUE;
  1918. }
  1919. BOOL CXTPReportControl::_ReadRecodsFromData(CXTPPropExchange* pPX,
  1920. CXTPReportRecords& rarRecords)
  1921. {
  1922. rarRecords.RemoveAll();
  1923. if (!pPX || !pPX->IsLoading())
  1924. {
  1925. ASSERT(FALSE);
  1926. return FALSE;
  1927. }
  1928. CXTPPropExchangeSection secRecords(pPX->GetSection(_T("ReportRecords")));
  1929. long nSchema = 0;
  1930. PX_Long(pPX, _T("Version"), (long&)nSchema);
  1931. pPX->ExchangeLocale();
  1932. if (nSchema != XTP_REPORT_CB_RECORDS_DATA_VER)
  1933. {
  1934. ASSERT(FALSE);
  1935. return FALSE;
  1936. }
  1937. CXTPPropExchangeEnumeratorPtr pEnumRecords(secRecords->GetEnumerator(_T("Record")));
  1938. POSITION posRecord = pEnumRecords->GetPosition();
  1939. while (posRecord)
  1940. {
  1941. CXTPPropExchangeSection secRecord(pEnumRecords->GetNext(posRecord));
  1942. CXTPReportRecord* pRecord = NULL;
  1943. PX_Object(&secRecord, pRecord, RUNTIME_CLASS(CXTPReportRecord));
  1944. if (!pRecord)
  1945. {
  1946. AfxThrowArchiveException(CArchiveException::badClass);
  1947. }
  1948. CXTPReportRecord* pRecord2 = pRecord;
  1949. BOOL bCanceled = OnBeforePaste(&pRecord2);
  1950. if (bCanceled || pRecord2 != pRecord)
  1951. {
  1952. CMDTARGET_RELEASE(pRecord);
  1953. }
  1954. if (bCanceled)
  1955. {
  1956. continue;
  1957. }
  1958. rarRecords.Add(pRecord2);
  1959. }
  1960. return TRUE;
  1961. }
  1962. BOOL CXTPReportControl::OnBeforeCopyToText(CXTPReportRecord* pRecord, CStringArray& rarStrings)
  1963. {
  1964. XTP_NM_REPORT_BEFORE_COPYPASTE nmParams;
  1965. ::ZeroMemory(&nmParams, sizeof(nmParams));
  1966. CXTPReportRecord* pRecordTmp = pRecord;
  1967. nmParams.ppRecord = &pRecordTmp;
  1968. nmParams.parStrings = &rarStrings;
  1969. LRESULT lResult = SendNotifyMessage(XTP_NM_REPORT_BEFORE_COPY_TOTEXT, (NMHDR*)&nmParams);
  1970. return lResult != 0;
  1971. }
  1972. BOOL CXTPReportControl::OnBeforePasteFromText(CStringArray& arStrings,
  1973. CXTPReportRecord** ppRecord)
  1974. {
  1975. XTP_NM_REPORT_BEFORE_COPYPASTE nmParams;
  1976. ::ZeroMemory(&nmParams, sizeof(nmParams));
  1977. nmParams.parStrings = &arStrings;
  1978. nmParams.ppRecord = ppRecord;
  1979. LRESULT lResult = SendNotifyMessage(XTP_NM_REPORT_BEFORE_PASTE_FROMTEXT, (NMHDR*)&nmParams);
  1980. return lResult != 0;
  1981. }
  1982. BOOL CXTPReportControl::OnBeforePaste(CXTPReportRecord** ppRecord)
  1983. {
  1984. XTP_NM_REPORT_BEFORE_COPYPASTE nmParams;
  1985. ::ZeroMemory(&nmParams, sizeof(nmParams));
  1986. nmParams.ppRecord = ppRecord;
  1987. LRESULT lResult = SendNotifyMessage(XTP_NM_REPORT_BEFORE_PASTE, (NMHDR*)&nmParams);
  1988. return lResult != 0;
  1989. }
  1990. int CXTPReportControl::OnGetColumnDataBestFitWidth(CXTPReportColumn* pColumn)
  1991. {
  1992. CXTPReportPaintManager* pPaintManager = GetPaintManager();
  1993. if (!pColumn || !pPaintManager)
  1994. {
  1995. ASSERT(FALSE);
  1996. return 0;
  1997. }
  1998. if(pColumn->GetBestFitMode() != xtpColumnBestFitModeAllData)
  1999. return 0;
  2000. CClientDC dc(this);
  2001. CXTPFontDC autoFont(&dc, pPaintManager->GetTextFont()); // to reset selected font on exit
  2002. int nDataWidth = OnGetItemsCaptionMaxWidth(&dc, GetRows(), pColumn);
  2003. return nDataWidth;
  2004. }
  2005. int CXTPReportControl::OnGetItemsCaptionMaxWidth(CDC* pDC, CXTPReportRows* pRows,
  2006. CXTPReportColumn* pColumn)
  2007. {
  2008. CXTPReportPaintManager* pPaintManager = GetPaintManager();
  2009. if(!pDC || !pRows || !pColumn || !pPaintManager)
  2010. {
  2011. ASSERT(FALSE);
  2012. return 0;
  2013. }
  2014. XTP_REPORTRECORDITEM_DRAWARGS drawArgs;
  2015. drawArgs.pDC = pDC;
  2016. drawArgs.pControl = this;
  2017. drawArgs.pColumn = pColumn;
  2018. drawArgs.rcItem = pColumn->GetRect();
  2019. XTP_REPORTRECORDITEM_METRICS* pMetrics = new XTP_REPORTRECORDITEM_METRICS();
  2020. int nMaxWidth = 0;
  2021. int nItemIndex = pColumn->GetItemIndex();
  2022. int nCount = pRows->GetCount();
  2023. for (int i = 0; i < nCount; i++)
  2024. {
  2025. CXTPReportRow* pRow = pRows->GetAt(i);
  2026. ASSERT(pRow);
  2027. if (pRow && pRow->IsGroupRow())
  2028. continue;
  2029. CXTPReportRecord* pRec = pRow ? pRow->GetRecord() : NULL;
  2030. CXTPReportRecordItem* pItem = pRec ? pRec->GetItem(nItemIndex) : NULL;
  2031. ASSERT(pItem);
  2032. if (!pItem)
  2033. continue;
  2034. drawArgs.pRow = pRow;
  2035. drawArgs.pItem = pItem;
  2036. pMetrics->strText = pItem->GetCaption(pColumn);
  2037. pRow->GetItemMetrics(&drawArgs, pMetrics);
  2038. pDC->SelectObject(pMetrics->pFont);
  2039. int nWidth = pDC->GetTextExtent(pMetrics->strText).cx + 7;
  2040. nMaxWidth = max(nMaxWidth, nWidth);
  2041. }
  2042. CMDTARGET_RELEASE(pMetrics);
  2043. return nMaxWidth;
  2044. }
  2045. BOOL CXTPReportControl::IsEditMode()
  2046. {
  2047. CXTPReportInplaceEdit* pEdit = GetInplaceEdit();
  2048. BOOL bEditMode = pEdit && pEdit->GetSafeHwnd() && pEdit->IsWindowVisible();
  2049. bEditMode |= GetInplaceList() && GetInplaceList()->GetSafeHwnd() && GetInplaceList()->IsWindowVisible();
  2050. return bEditMode;
  2051. }
  2052. int CXTPReportControl::GetRowsHeight(CXTPReportRows* pRows, int nTotalWidth, int nMaxHeight)
  2053. {
  2054. int nRowsHeight = 0;
  2055. CWindowDC dc (this);
  2056. for(int i = 0; i < pRows->GetCount(); ++i)
  2057. {
  2058. nRowsHeight += GetPaintManager()->GetRowHeight(&dc, pRows->GetAt(i), nTotalWidth);
  2059. if (nMaxHeight >= 0 && nRowsHeight > nMaxHeight)
  2060. return nRowsHeight;
  2061. }
  2062. return nRowsHeight;
  2063. }
  2064. int CXTPReportControl::GetHeaderRowsDividerHeight()
  2065. {
  2066. return GetPaintManager()->GetHeaderRowsDividerHeight();
  2067. }
  2068. int CXTPReportControl::GetFooterRowsDividerHeight()
  2069. {
  2070. return GetPaintManager()->GetFooterRowsDividerHeight();
  2071. }
  2072. void CXTPReportControl::DrawDefaultGrid(CDC* pDC, CRect rcClient, int nRowHeight, int nLeftOffset)
  2073. {
  2074. if (nRowHeight <= 0)
  2075. return;
  2076. //  int y = rcClient.top;
  2077. int nFreezeCols = m_nFreezeColumnsCount;
  2078. CRect rcClipBox = GetReportRectangle();
  2079. CRect rcRow;
  2080. rcRow = rcClient;
  2081. rcRow.left -= nLeftOffset;
  2082. rcRow.right -= nLeftOffset;
  2083. rcRow.bottom = rcClient.top + nRowHeight;
  2084. int nIndentWidth = GetHeaderIndent();
  2085. CXTPReportPaintManager* pPaintManager = GetPaintManager();
  2086. CXTPReportColumns arrVisibleColumns(this);
  2087. GetColumns()->GetVisibleColumns(arrVisibleColumns);
  2088. int nVisColCount = arrVisibleColumns.GetCount();
  2089. nFreezeCols = min(nFreezeCols, nVisColCount);
  2090. // fill the empty space
  2091. while(rcRow.top < rcClient.bottom)
  2092. {
  2093. CRect rcItem(rcRow.left, rcRow.top, rcRow.right, rcRow.bottom);
  2094. CRect rcIndent(nFreezeCols ? rcRow : rcRow); /////////////////////
  2095. rcIndent.right = rcIndent.left + nIndentWidth;
  2096. int xMinCol_0 = rcRow.left + nIndentWidth;
  2097. for (int nColumn = nVisColCount-1; nColumn >= 0; nColumn--)
  2098. {
  2099. BOOL bFreezeCol = nColumn < nFreezeCols;
  2100. int nColIdx = bFreezeCol ? nFreezeCols - 1 - nColumn : nColumn;
  2101. CXTPReportColumn* pColumn = arrVisibleColumns.GetAt(nColIdx);
  2102. ASSERT(pColumn && pColumn->IsVisible());
  2103. if (pColumn)
  2104. {
  2105. rcItem.left = pColumn->GetRect().left;
  2106. if (nColIdx == 0)
  2107. {
  2108. rcItem.left = max(xMinCol_0, rcItem.left);
  2109. }
  2110. rcItem.right = pColumn->GetRect().right;
  2111. if (!CRect().IntersectRect(rcClipBox, rcItem))
  2112. continue;
  2113. if (bFreezeCol)
  2114. {
  2115. CRect rcFreeze(rcItem);
  2116. rcFreeze.top +=1;
  2117. pDC->FillSolidRect(rcFreeze, pPaintManager->GetControlBackColor(this));
  2118. }
  2119. CRect rcGridItem(rcItem);
  2120. rcGridItem.left--;
  2121. pPaintManager->DrawGrid(pDC, FALSE, rcGridItem);
  2122. pPaintManager->DrawGrid(pDC, TRUE, rcGridItem);
  2123. if (nColIdx == nFreezeCols - 1)
  2124. pPaintManager->DrawFreezeColsDivider(pDC, rcGridItem, this);
  2125. }
  2126. }
  2127. if (nIndentWidth > 0)
  2128. {
  2129. // draw indent column
  2130. pPaintManager->FillIndent(pDC, rcIndent);
  2131. }
  2132. rcRow.top += nRowHeight;
  2133. rcRow.bottom += nRowHeight;
  2134. }
  2135. }
  2136. BOOL CXTPReportControl::PreTranslateMessage(MSG* pMsg)
  2137. {
  2138. if (pMsg->message == WM_KEYDOWN)
  2139. {
  2140. if (!OnPreviewKeyDown((UINT&)pMsg->wParam, LOWORD(pMsg->lParam), HIWORD(pMsg->lParam)) )
  2141. {
  2142. TRACE(_T("ReportControl, PreTranslateMessagem-OnPreviewKeyDown('%d') = CANCEL  n"), pMsg->wParam);
  2143. return TRUE;
  2144. }
  2145. }
  2146. return CWnd::PreTranslateMessage(pMsg);
  2147. }
  2148. BOOL CXTPReportControl::OnConstraintSelecting(CXTPReportRow* pRow, CXTPReportRecordItem* pItem, CXTPReportColumn* pColumn,
  2149. CXTPReportRecordItemConstraint* pConstraint)
  2150. {
  2151. XTP_NM_REPORTCONSTRAINTSELECTING    nmConstraint;
  2152. ::ZeroMemory(&nmConstraint, sizeof(nmConstraint));
  2153. nmConstraint.pRow = pRow;
  2154. nmConstraint.pColumn = pColumn;
  2155. nmConstraint.pItem = pItem;
  2156. nmConstraint.pConstraint = pConstraint;
  2157. LRESULT lResult = SendNotifyMessage(XTP_NM_REPORT_CONSTRAINT_SELECTING, (NMHDR*)&nmConstraint);
  2158. return lResult != 0;
  2159. }
  2160. const XTP_NM_REPORTTOOLTIPINFO& CXTPReportControl::OnGetToolTipInfo(CXTPReportRow* pRow, CXTPReportRecordItem* pItem, CString& rstrToolTipText)
  2161. {
  2162. ::ZeroMemory(m_pCachedToolTipInfo, sizeof(XTP_NM_REPORTTOOLTIPINFO));
  2163. m_pCachedToolTipInfo->pRow = pRow;
  2164. m_pCachedToolTipInfo->pItem = pItem;
  2165. m_pCachedToolTipInfo->pstrText = &rstrToolTipText;
  2166. SendNotifyMessage(XTP_NM_REPORT_GETTOOLTIPINFO, (NMHDR*)m_pCachedToolTipInfo);
  2167. return *m_pCachedToolTipInfo;
  2168. }
  2169. CRect CXTPReportControl::GetElementRect(int nElement) const
  2170. {
  2171. switch(nElement)
  2172. {
  2173. case xtpReportElementRectGroupByArea : return m_rcGroupByArea; break;
  2174. case xtpReportElementRectHeaderArea : return m_rcHeaderArea; break;
  2175. case xtpReportElementRectFooterArea : return m_rcFooterArea; break;
  2176. case xtpReportElementRectHeaderRecordsArea : return m_rcHeaderRecordsArea; break;
  2177. case xtpReportElementRectFooterRecordsArea : return m_rcFooterRecordsArea; break;
  2178. case xtpReportElementRectHeaderRecordsDividerArea : return m_rcHeaderRecordsDividerArea; break;
  2179. case xtpReportElementRectFooterRecordsDividerArea : return m_rcFooterRecordsDividerArea; break;
  2180. default : return m_rcReportArea; break;
  2181. }
  2182. }
  2183. void CXTPReportControl::EnableMarkup(BOOL bEnable)
  2184. {
  2185. m_pRecords->EnableMarkup(bEnable);
  2186. }
  2187. CXTPMarkupContext* CXTPReportControl::GetMarkupContext() const
  2188. {
  2189. return m_pRecords->GetMarkupContext();
  2190. }