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

对话框与窗口

开发平台:

Visual C++

  1. // XTPReportView.cpp : implementation of the CXTPReportView class.
  2. //
  3. // This file is a part of the XTREME REPORTCONTROL MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. #include "XTPReportView.h"
  22. #include "XTPReportColumn.h"
  23. #include "XTPReportColumns.h"
  24. #include "XTPReportRecordItem.h"
  25. #include "XTPReportRecordItemText.h"
  26. #include "XTPReportInplaceControls.h"
  27. #include "XTPReportRecord.h"
  28. #include "XTPReportRecords.h"
  29. #include "Common/XTPVC80Helpers.h"
  30. #include "Common/XTPResourceManager.h"
  31. #include "Common/XTPImageManager.h"
  32. #include "Common/Resource.h"
  33. #ifdef _DEBUG
  34. #define new DEBUG_NEW
  35. #undef THIS_FILE
  36. static char THIS_FILE[] = __FILE__;
  37. #endif
  38. /////////////////////////////////////////////////////////////////////////////
  39. BEGIN_MESSAGE_MAP(CXTPReportPageSetupDialog, CPageSetupDialog)
  40. ON_BN_CLICKED(XTP_IDC_HEADER_FORMAT_BTN, OnBnClickedHeaderFormat)
  41. ON_BN_CLICKED(XTP_IDC_FOOTER_FORMAT_BTN, OnBnClickedFooterFormat)
  42. END_MESSAGE_MAP()
  43. CXTPReportPageSetupDialog::CXTPReportPageSetupDialog(
  44. CXTPReportViewPrintOptions* pOptions,
  45. DWORD dwFlags, CWnd* pParentWnd)
  46. : CPageSetupDialog(dwFlags, pParentWnd)
  47. {
  48. ASSERT(pOptions);
  49. m_pOptions = pOptions;
  50. if (m_pOptions)
  51. {
  52. BOOL bIsInches = m_pOptions->IsMarginsMeasureInches();
  53. DWORD dwMeasure = bIsInches ? PSD_INTHOUSANDTHSOFINCHES : PSD_INHUNDREDTHSOFMILLIMETERS;
  54. m_psd.Flags &= ~PSD_INWININIINTLMEASURE;
  55. m_psd.Flags |= dwMeasure;
  56. }
  57. m_psd.Flags |= PSD_ENABLEPAGESETUPTEMPLATEHANDLE;
  58. m_psd.hPageSetupTemplate = XTPResourceManager()->LoadDialogTemplate2(MAKEINTRESOURCE(IDD));
  59. ASSERT(m_psd.hPageSetupTemplate);
  60. if (m_pOptions)
  61. {
  62. m_psd.rtMargin = m_pOptions->m_rcMargins;
  63. }
  64. m_nIDHelp = CXTPReportPageSetupDialog::IDD;
  65. }
  66. CXTPReportPageSetupDialog::~CXTPReportPageSetupDialog()
  67. {
  68. }
  69. #ifndef rad1
  70. #define rad1        0x0420
  71. #define rad2        0x0421
  72. #define grp4        0x0433
  73. #endif
  74. BOOL CXTPReportPageSetupDialog::OnInitDialog ()
  75. {
  76. CPageSetupDialog::OnInitDialog();
  77. ASSERT(m_pOptions);
  78. VERIFY( m_ctrlHeaderFormat.SubclassDlgItem(XTP_IDC_HEADER_FORMAT, this) );
  79. VERIFY( m_ctrlFooterFormat.SubclassDlgItem(XTP_IDC_FOOTER_FORMAT, this) );
  80. VERIFY( m_ctrlHeaderFormatBtn.SubclassDlgItem(XTP_IDC_HEADER_FORMAT_BTN, this) );
  81. VERIFY( m_ctrlFooterFormatBtn.SubclassDlgItem(XTP_IDC_FOOTER_FORMAT_BTN, this) );
  82. if(m_pOptions && m_pOptions->GetPageHeader())
  83. {
  84. m_ctrlHeaderFormat.SetWindowText(m_pOptions->GetPageHeader()->m_strFormatString);
  85. }
  86. if(m_pOptions && m_pOptions->GetPageFooter())
  87. {
  88. m_ctrlFooterFormat.SetWindowText(m_pOptions->GetPageFooter()->m_strFormatString);
  89. }
  90. if (GetDlgItem(rad1))
  91. GetDlgItem(rad1)->EnableWindow(TRUE); //1056 Portrait
  92. if (GetDlgItem(rad2))
  93. GetDlgItem(rad2)->EnableWindow(TRUE); //1057 Landscape
  94. BOOL bIsInches = m_pOptions ? m_pOptions->IsMarginsMeasureInches() : FALSE;
  95. UINT uStrID = bIsInches ? XTP_IDS_REPORT_MARGINS_INCH : XTP_IDS_REPORT_MARGINS_MM;
  96. CString strCaption;
  97. VERIFY(XTPResourceManager()->LoadString(&strCaption, uStrID));
  98. if (!strCaption.IsEmpty() && GetDlgItem(grp4))
  99. {
  100. GetDlgItem(grp4)->SetWindowText(strCaption);
  101. }
  102. HICON hBtnIcon = XTPResourceManager()->LoadIcon(XTP_IDI_BTN_ARROW_R, CSize(0,0));
  103. ASSERT(hBtnIcon);
  104. if (hBtnIcon)
  105. {
  106. m_ctrlHeaderFormatBtn.SetIcon(hBtnIcon);
  107. m_ctrlFooterFormatBtn.SetIcon(hBtnIcon);
  108. }
  109. return FALSE;
  110. }
  111. void CXTPReportPageSetupDialog::OnOK()
  112. {
  113. if(m_pOptions && m_pOptions->GetPageHeader())
  114. {
  115. m_ctrlHeaderFormat.GetWindowText(m_pOptions->GetPageHeader()->m_strFormatString);
  116. }
  117. if(m_pOptions && m_pOptions->GetPageFooter())
  118. {
  119. m_ctrlFooterFormat.GetWindowText(m_pOptions->GetPageFooter()->m_strFormatString);
  120. }
  121. if (m_pOptions) m_pOptions->m_rcMargins = m_psd.rtMargin;
  122. CPageSetupDialog::OnOK();
  123. }
  124. void CXTPReportPageSetupDialog::OnBnClickedHeaderFormat()
  125. {
  126. CXTPPrintPageHeaderFooter::DoInsertHFFormatSpecifierViaMenu(
  127. this, &m_ctrlHeaderFormat, &m_ctrlHeaderFormatBtn);
  128. }
  129. void CXTPReportPageSetupDialog::OnBnClickedFooterFormat()
  130. {
  131. CXTPPrintPageHeaderFooter::DoInsertHFFormatSpecifierViaMenu(
  132. this, &m_ctrlFooterFormat, &m_ctrlFooterFormatBtn);
  133. }
  134. /////////////////////////////////////////////////////////////////////////////
  135. // CXTPReportView
  136. IMPLEMENT_DYNCREATE(CXTPReportView, CView)
  137. CXTPReportView::CXTPReportView()
  138. {
  139. m_pReport = NULL;
  140. m_pPrintOptions = new CXTPReportViewPrintOptions();
  141. m_bPrintSelection = FALSE;
  142. m_bPrintDirect = FALSE;
  143. m_bResizeControlWithView = TRUE;
  144. m_bAllowCut = TRUE;
  145. m_bAllowPaste = TRUE;
  146. m_pScrollBar = NULL;
  147. }
  148. CXTPReportView::~CXTPReportView()
  149. {
  150. CMDTARGET_RELEASE(m_pPrintOptions);
  151. SAFE_DELETE(m_pReport);
  152. }
  153. CXTPReportControl& CXTPReportView::GetReportCtrl() const
  154. {
  155. return m_pReport == NULL ? (CXTPReportControl&)m_wndReport : *m_pReport;
  156. }
  157. void CXTPReportView::SetReportCtrl(CXTPReportControl* pReport)
  158. {
  159. if (::IsWindow(m_wndReport.GetSafeHwnd()))
  160. m_wndReport.DestroyWindow();
  161. m_pReport = pReport;
  162. }
  163. void CXTPReportView::SetScrollBarCtrl(CScrollBar* pScrollBar)
  164. {
  165. m_pScrollBar = pScrollBar;
  166. }
  167. BEGIN_MESSAGE_MAP(CXTPReportView, CView)
  168. //{{AFX_MSG_MAP(CXTPReportView)
  169. ON_WM_ERASEBKGND()
  170. ON_WM_SIZE()
  171. ON_WM_CREATE()
  172. ON_WM_SETFOCUS()
  173. ON_WM_PAINT()
  174. ON_COMMAND(ID_FILE_PRINT, OnFilePrint)
  175. ON_COMMAND(ID_EDIT_CUT, OnEditCut)
  176. ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
  177. ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
  178. ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, OnUpdateEditPaste)
  179. ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateEditCopy)
  180. ON_UPDATE_COMMAND_UI(ID_EDIT_CUT, OnUpdateEditCut)
  181. ON_WM_VSCROLL()
  182. //}}AFX_MSG_MAP
  183. END_MESSAGE_MAP()
  184. /////////////////////////////////////////////////////////////////////////////
  185. // CXTPReportView drawing
  186. void CXTPReportView::OnDraw(CDC* /*pDC*/)
  187. {
  188. }
  189. void CXTPReportView::OnPaint()
  190. {
  191. Default();
  192. }
  193. /////////////////////////////////////////////////////////////////////////////
  194. // CXTPReportView diagnostics
  195. #ifdef _DEBUG
  196. void CXTPReportView::AssertValid() const
  197. {
  198. CView::AssertValid();
  199. }
  200. void CXTPReportView::Dump(CDumpContext& dc) const
  201. {
  202. CView::Dump(dc);
  203. }
  204. #endif //_DEBUG
  205. /////////////////////////////////////////////////////////////////////////////
  206. // CXTPReportView message handlers
  207. BOOL CXTPReportView::OnEraseBkgnd(CDC*)
  208. {
  209. return TRUE;
  210. }
  211. CScrollBar* CXTPReportView::GetScrollBarCtrl(int nBar) const
  212. {
  213. if (nBar == SB_VERT && m_pScrollBar)
  214. return m_pScrollBar;
  215. return CView::GetScrollBarCtrl(nBar);
  216. }
  217. void CXTPReportView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
  218. {
  219. if (m_pScrollBar && pScrollBar == m_pScrollBar)
  220. GetReportCtrl().OnVScroll(nSBCode, nPos, 0);
  221. CView::OnVScroll(nSBCode, nPos, pScrollBar);
  222. }
  223. void CXTPReportView::OnSize(UINT nType, int cx, int cy)
  224. {
  225. CView::OnSize(nType, cx, cy);
  226. if (m_pScrollBar && m_pScrollBar->GetSafeHwnd())
  227. {
  228. int nScroll = GetSystemMetrics(SM_CXVSCROLL);
  229. m_pScrollBar->MoveWindow(cx - nScroll, 0, nScroll, cy);
  230. cx -= nScroll;
  231. }
  232. if (m_bResizeControlWithView && GetReportCtrl().GetSafeHwnd())
  233. {
  234. GetReportCtrl().MoveWindow(0, 0, cx, cy);
  235. }
  236. }
  237. int CXTPReportView::OnCreate(LPCREATESTRUCT lpCreateStruct)
  238. {
  239. if (CView::OnCreate(lpCreateStruct) == -1)
  240. return -1;
  241. if (!GetReportCtrl().Create(WS_CHILD | WS_TABSTOP | WS_VISIBLE ,
  242. CRect(0, 0, 0, 0), this, XTP_ID_REPORT_CONTROL))
  243. {
  244. TRACE(_T("Failed to create report control windown"));
  245. return -1;
  246. }
  247. return 0;
  248. }
  249. void CXTPReportView::OnSetFocus(CWnd* pOldWnd)
  250. {
  251. CView::OnSetFocus(pOldWnd);
  252. if(IsWindow(GetReportCtrl().GetSafeHwnd()))
  253. GetReportCtrl().SetFocus();
  254. }
  255. /////////////////////////////////////////////////////////////////////////////
  256. // CReportSampleView printing
  257. BOOL CXTPReportView::OnPreparePrinting(CPrintInfo* pInfo)
  258. {
  259. if (GetReportCtrl().GetSelectedRows()->GetCount() > 0)
  260. {
  261. pInfo->m_pPD->m_pd.Flags &= ~PD_NOSELECTION;
  262. }
  263. pInfo->m_bDirect = m_bPrintDirect;
  264. // default preparation
  265. if (!DoPreparePrinting(pInfo))
  266. return FALSE;
  267. m_bPrintSelection = pInfo->m_pPD->PrintSelection();
  268. return TRUE;
  269. }
  270. void CXTPReportView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
  271. {
  272. ASSERT(m_aPageStart.GetSize() == 0);
  273. m_aPageStart.RemoveAll();
  274. m_aPageStart.Add(0);
  275. CString str1, str2;
  276. if (m_pPrintOptions && m_pPrintOptions->GetPageHeader())
  277. str1 = m_pPrintOptions->GetPageHeader()->m_strFormatString;
  278. if (m_pPrintOptions && m_pPrintOptions->GetPageFooter())
  279. str2 = m_pPrintOptions->GetPageFooter()->m_strFormatString;
  280. if (str1.Find(_T("&P")) >= 0 || str2.Find(_T("&P")) >= 0)
  281. {
  282. int nCurPage = pInfo->m_nCurPage;
  283. pInfo->m_nCurPage = 65535;
  284. if (PaginateTo(pDC, pInfo))
  285. {
  286. pInfo->SetMaxPage((int)m_aPageStart.GetSize() - 1);
  287. }
  288. pInfo->m_nCurPage = nCurPage;
  289. }
  290. }
  291. void CXTPReportView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  292. {
  293. m_aPageStart.RemoveAll();
  294. m_bmpGrayDC.DeleteObject();
  295. }
  296. CXTPReportPaintManager* CXTPReportView::GetPaintManager() const
  297. {
  298. return GetReportCtrl().GetPaintManager();
  299. }
  300. int CXTPReportView::GetColumnWidth(CXTPReportColumn* pColumnTest, int nTotalWidth)
  301. {
  302. return pColumnTest->GetPrintWidth(nTotalWidth);
  303. }
  304. void CXTPReportView::PrintHeader(CDC* pDC, CRect rcHeader)
  305. {
  306. GetPaintManager()->FillHeaderControl(pDC, rcHeader);
  307. int x = rcHeader.left;
  308. CXTPReportColumns* pColumns = GetReportCtrl().GetColumns();
  309. for (int i = 0; i < pColumns->GetCount(); i++)
  310. {
  311. CXTPReportColumn* pColumn = pColumns->GetAt(i);
  312. if (!pColumn->IsVisible())
  313. continue;
  314. int nWidth = GetColumnWidth(pColumn, rcHeader.Width());
  315. CRect rcItem(x, rcHeader.top, x + nWidth, rcHeader.bottom);
  316. GetPaintManager()->DrawColumn(pDC, pColumn, GetReportCtrl().GetReportHeader(), rcItem);
  317. x += nWidth;
  318. }
  319. }
  320. void CXTPReportView::PrintFooter(CDC* pDC, CRect rcFooter)
  321. {
  322. GetPaintManager()->FillFooter(pDC, rcFooter);
  323. int x = rcFooter.left;
  324. CXTPReportColumns* pColumns = GetReportCtrl().GetColumns();
  325. for (int i = 0; i < pColumns->GetCount(); i++)
  326. {
  327. CXTPReportColumn* pColumn = pColumns->GetAt(i);
  328. if (!pColumn->IsVisible())
  329. continue;
  330. int nWidth = GetColumnWidth(pColumn, rcFooter.Width());
  331. CRect rcItem(x, rcFooter.top, x + nWidth, rcFooter.bottom);
  332. GetPaintManager()->DrawColumnFooter(pDC, pColumn, GetReportCtrl().GetReportHeader(), rcItem);
  333. x += nWidth;
  334. }
  335. }
  336. void CXTPReportView::PrintRow(CDC* pDC, CXTPReportRow* pRow, CRect rcRow, int nPreviewHeight)
  337. {
  338. if (pRow->IsGroupRow())
  339. {
  340. pRow->Draw(pDC, rcRow, 0);
  341. return;
  342. }
  343. CXTPReportControl& wndReport = GetReportCtrl();
  344. XTP_REPORTRECORDITEM_DRAWARGS drawArgs;
  345. drawArgs.pDC = pDC;
  346. drawArgs.pControl = &wndReport;
  347. drawArgs.pRow = pRow;
  348. int nIndentWidth = wndReport.GetHeaderIndent();
  349. CXTPReportPaintManager* pPaintManager = GetPaintManager();
  350. CXTPReportColumns* pColumns = wndReport.GetColumns();
  351. int nColumnCount = pColumns->GetCount();
  352. // paint row background
  353. pPaintManager->FillRow(pDC, pRow, rcRow);
  354. CRect rcItem(rcRow);
  355. rcItem.bottom = rcItem.bottom - nPreviewHeight;
  356. CXTPReportRecord* pRecord = pRow->GetRecord();
  357. if (pRecord) // if drawing record, not group
  358. {
  359. BOOL bFirstVisibleColumn = TRUE;
  360. int x = rcRow.left;
  361. // paint record items
  362. for (int nColumn = 0; nColumn < nColumnCount; nColumn++)
  363. {
  364. CXTPReportColumn* pColumn = pColumns->GetAt(nColumn);
  365. if (pColumn && pColumn->IsVisible() && pRow->IsItemsVisible())
  366. {
  367. rcItem.left = x;
  368. x = rcItem.right = rcItem.left + GetColumnWidth(pColumn, rcRow.Width());
  369. if (bFirstVisibleColumn)
  370. {
  371. rcItem.left += nIndentWidth;
  372. bFirstVisibleColumn = FALSE;
  373. }
  374. CRect rcGridItem(rcItem);
  375. rcGridItem.left--;
  376. CXTPReportRecordItem* pItem = pRecord->GetItem(pColumn);
  377. if (pItem)
  378. {
  379. // draw item
  380. drawArgs.pColumn = pColumn;
  381. drawArgs.rcItem = rcItem;
  382. drawArgs.nTextAlign = pColumn->GetAlignment();
  383. drawArgs.pItem = pItem;
  384. // draw item
  385. pItem->Draw(&drawArgs);
  386. }
  387. // customize grid (is vertical grid required)
  388. if (pRow->GetType() == xtpRowTypeHeader)
  389. {
  390. if (pColumn->GetDrawHeaderRowsVGrid())
  391. pPaintManager->DrawGrid(pDC, TRUE, rcGridItem);
  392. }
  393. else if (pRow->GetType() == xtpRowTypeFooter)
  394. {
  395. if (pColumn->GetDrawFooterRowsVGrid())
  396. pPaintManager->DrawGrid(pDC, TRUE, rcGridItem);
  397. }
  398. else
  399. {
  400. pPaintManager->DrawGrid(pDC, TRUE, rcGridItem);
  401. }
  402. }
  403. }
  404. if (nIndentWidth > 0)
  405. {
  406. // draw indent column
  407. CRect rcIndent(rcRow);
  408. rcIndent.right = rcRow.left + nIndentWidth;
  409. pPaintManager->FillIndent(pDC, rcIndent);
  410. }
  411. if (pRow->IsPreviewVisible())
  412. {
  413. CXTPReportRecordItemPreview* pItem = pRecord->GetItemPreview();
  414. CRect rcPreviewItem(rcRow);
  415. rcPreviewItem.DeflateRect(nIndentWidth, rcPreviewItem.Height() - nPreviewHeight, 0, 0);
  416. drawArgs.rcItem = rcPreviewItem;
  417. drawArgs.nTextAlign = DT_LEFT;
  418. drawArgs.pItem = pItem;
  419. drawArgs.pColumn = NULL;
  420. drawArgs.pItem->Draw(&drawArgs);
  421. }
  422. }
  423. BOOL bGridVisible = pPaintManager->IsGridVisible(FALSE);
  424. CRect rcFocus(rcRow.left, rcRow.top, rcRow.right, rcRow.bottom - (bGridVisible ? 1 : 0));
  425. if (pRow->GetIndex() < wndReport.GetRows()->GetCount() - 1 && nIndentWidth > 0)
  426. {
  427. CXTPReportRow* pNextRow = wndReport.GetRows()->GetAt(pRow->GetIndex() + 1);
  428. ASSERT(pNextRow);
  429. if (pNextRow) rcFocus.left = rcRow.left +  min(nIndentWidth, pPaintManager->m_nTreeIndent * pNextRow->GetTreeDepth());
  430. }
  431. pPaintManager->DrawGrid(pDC, FALSE, rcFocus);
  432. }
  433. int CXTPReportView::PrintRows(CDC* pDC, CRect rcClient, long nIndexStart, int* pnPrintedRowsHeight)
  434. {
  435. int y = rcClient.top;
  436. CXTPReportRows* pRows = GetReportCtrl().GetRows();
  437. for (; nIndexStart < pRows->GetCount(); nIndexStart++)
  438. {
  439. CXTPReportRow* pRow = pRows->GetAt(nIndexStart);
  440. if (m_bPrintSelection && !pRow->IsSelected())
  441. {
  442. continue;
  443. }
  444. int nHeight = pRow->GetHeight(pDC, rcClient.Width());
  445. int nPreviewHeight = 0;
  446. if (pRow->IsPreviewVisible())
  447. {
  448. CXTPReportRecordItemPreview* pItem = pRow->GetRecord()->GetItemPreview();
  449. nPreviewHeight = pItem->GetPreviewHeight(pDC, pRow, rcClient.Width());
  450. nPreviewHeight = GetReportCtrl().GetPaintManager()->GetPreviewItemHeight(pDC, pRow, rcClient.Width(), nPreviewHeight);
  451. nHeight += nPreviewHeight;
  452. }
  453. CRect rcRow(rcClient.left, y, rcClient.right, y + nHeight);
  454. if (rcRow.bottom > rcClient.bottom)
  455. break;
  456. PrintRow(pDC, pRow, rcRow, nPreviewHeight);
  457. y += rcRow.Height();
  458. }
  459. if(pnPrintedRowsHeight != NULL)
  460. *pnPrintedRowsHeight = y - rcClient.top; // height of the printed rows
  461. return nIndexStart;
  462. }
  463. long CXTPReportView::PrintReport(CDC* pDC, CPrintInfo* /*pInfo*/, CRect rcPage, long nIndexStart)
  464. {
  465. int nHeaderHeight = 0;
  466. int nFooterHeight = 0;
  467. if (GetReportCtrl().IsHeaderVisible())
  468. nHeaderHeight = GetPaintManager()->GetHeaderHeight(&GetReportCtrl(), pDC, rcPage.Width()-2);
  469. if (GetReportCtrl().IsFooterVisible())
  470. nFooterHeight = GetPaintManager()->GetFooterHeight(&GetReportCtrl(), pDC, rcPage.Width()-2);
  471. CRect rcHeader(rcPage.left + 1, rcPage.top + 1, rcPage.right - 1, rcPage.top + 1 + nHeaderHeight);
  472. CRect rcFooter(rcPage.left + 1, rcPage.bottom - nFooterHeight - 1, rcPage.right - 1, rcPage.bottom - 1);
  473. if (nHeaderHeight)
  474. PrintHeader(pDC, rcHeader);
  475. CRect rcRows(rcHeader.left, rcHeader.bottom, rcHeader.right, rcFooter.top);
  476. // print header rows (if exist and visible)
  477. if (GetReportCtrl().GetHeaderRows()->GetCount() > 0 && GetReportCtrl().IsHeaderRowsVisible())
  478. {
  479. // print on the first page, at least
  480. if (0 == nIndexStart || m_pPrintOptions->m_bRepeatHeaderRows)
  481. {
  482.  rcRows.top += PrintFixedRows(pDC, rcRows, TRUE);
  483. // print divider
  484. rcRows.top += PrintFixedRowsDivider(pDC, rcRows, TRUE);
  485. }
  486. }
  487. // calculate space for footer rows
  488. int nNeedForFooterRows = 0;
  489. if (GetReportCtrl().GetFooterRows()->GetCount() > 0 && GetReportCtrl().IsFooterRowsVisible())
  490. {
  491. nNeedForFooterRows = GetReportCtrl().GetRowsHeight(GetReportCtrl().GetFooterRows(), rcRows.Width());
  492. nNeedForFooterRows += GetPaintManager()->GetFooterRowsDividerHeight();
  493. if (m_pPrintOptions->m_bRepeatFooterRows)
  494. {
  495. // decrease space for body rows, if footer rows to be repeated on every page.
  496. rcRows.bottom = rcFooter.top - nNeedForFooterRows;
  497. }
  498. }
  499. // print body rows
  500. int nPrintedBodyRowsHeight = 0;
  501. nIndexStart = PrintRows(pDC, rcRows, nIndexStart, &nPrintedBodyRowsHeight);
  502. // print footer rows (if exist and visible)
  503. if (nNeedForFooterRows > 0)
  504. {
  505. CRect rcFooterRows(rcRows);
  506. rcFooterRows.top = rcRows.top + nPrintedBodyRowsHeight; //immediately after body rows
  507. rcFooterRows.bottom = rcFooter.top;
  508. // one more check, if there is enough space for footer divider + footer rows
  509. if (rcFooterRows.Height() > nNeedForFooterRows)
  510. {
  511. // print divider
  512. rcFooterRows.top += PrintFixedRowsDivider(pDC, rcFooterRows, FALSE);
  513. // print footer rows
  514. PrintFixedRows(pDC, rcFooterRows, FALSE);
  515. }
  516. }
  517. if (nFooterHeight)
  518. PrintFooter(pDC, rcFooter);
  519. pDC->Draw3dRect(rcPage, 0, 0);
  520. return nIndexStart;
  521. }
  522. int CXTPReportView::PrintFixedRowsDivider(CDC* pDC, const CRect& rc, BOOL bHeaderRows)
  523. {
  524. CRect rcDiv(rc);
  525. // get divider's height
  526. int nHeight = bHeaderRows ? GetPaintManager()->GetHeaderRowsDividerHeight() : GetPaintManager()->GetFooterRowsDividerHeight();
  527. rcDiv.bottom = rcDiv.top + nHeight;
  528. GetPaintManager()->DrawFixedRowsDivider(pDC, rcDiv, &GetReportCtrl(), bHeaderRows, FALSE);
  529. return nHeight;
  530. }
  531. long CXTPReportView::PrintPage(CDC* pDC, CPrintInfo* pInfo, CRect rcPage, long nIndexStart)
  532. {
  533. if (!m_pPrintOptions || !pDC || !pInfo)
  534. {
  535. ASSERT(FALSE);
  536. return INT_MAX;
  537. }
  538. CRect rcPageHeader = rcPage;
  539. CRect rcPageFooter = rcPage;
  540. CString strTitle = CXTPPrintPageHeaderFooter::GetParentFrameTitle(this);
  541. m_pPrintOptions->GetPageHeader()->FormatTexts(pInfo, strTitle);
  542. m_pPrintOptions->GetPageFooter()->FormatTexts(pInfo, strTitle);
  543. pDC->SetBkColor(RGB(255, 255, 255));
  544. m_pPrintOptions->GetPageFooter()->Draw(pDC, rcPageFooter, TRUE);
  545. m_pPrintOptions->GetPageHeader()->Draw(pDC, rcPageHeader);
  546. CRect rcReport = rcPage;
  547. rcReport.top += rcPageHeader.Height() + 2;
  548. rcReport.bottom -= rcPageFooter.Height() + 2;
  549. long nNextRow = PrintReport(pDC, pInfo, rcReport, nIndexStart);
  550. pDC->SetBkColor(RGB(255, 255, 255));
  551. m_pPrintOptions->GetPageFooter()->Draw(pDC, rcPageFooter);
  552. return nNextRow;
  553. }
  554. void CXTPReportView::OnPrint(CDC* pDC, CPrintInfo* pInfo)
  555. {
  556. if (!m_pPrintOptions || !pDC || !pInfo)
  557. {
  558. ASSERT(FALSE);
  559. return;
  560. }
  561. CRect rcMargins = m_pPrintOptions->GetMarginsLP(pDC);
  562. CRect rcPrint = pInfo->m_rectDraw;
  563. rcPrint.NormalizeRect();
  564. rcPrint.DeflateRect(rcMargins);
  565. //----------------------------------------------------------
  566. if (!m_pPrintOptions->m_bBlackWhitePrinting)
  567. {
  568. _OnPrint2(pDC, pInfo, rcPrint);
  569. }
  570. else
  571. {
  572. CRect rcPrint00(0, 0, rcPrint.Width(), rcPrint.Height());
  573. CDC memDC;
  574. VERIFY(memDC.CreateCompatibleDC(pDC));
  575. memDC.m_bPrinting = TRUE;
  576. if (!m_bmpGrayDC.m_hObject || m_bmpGrayDC.GetBitmapDimension() != rcPrint00.Size())
  577. {
  578. m_bmpGrayDC.DeleteObject();
  579. m_bmpGrayDC.CreateCompatibleBitmap(pDC, rcPrint00.Width(), rcPrint00.Height());
  580. }
  581. CXTPBitmapDC autpBmp(&memDC, &m_bmpGrayDC);
  582. //----------------------------------------------------
  583. memDC.FillSolidRect(rcPrint00, RGB(255, 255, 255));
  584. _OnPrint2(&memDC, pInfo, rcPrint00);
  585. int nCC = max(0, min(m_pPrintOptions->m_nBlackWhiteContrast, 255));
  586. XTPImageManager()->BlackWhiteBitmap(memDC, rcPrint00, nCC);
  587. pDC->BitBlt(rcPrint.left, rcPrint.top, rcPrint.Width(), rcPrint.Height(),
  588. &memDC, 0, 0, SRCCOPY);
  589. }
  590. }
  591. void CXTPReportView::_OnPrint2(CDC* pDC, CPrintInfo* pInfo, CRect rcPrint)
  592. {
  593. if (!m_pPrintOptions || !pDC || !pInfo)
  594. {
  595. ASSERT(FALSE);
  596. return;
  597. }
  598. UINT nPage = pInfo->m_nCurPage;
  599. ASSERT(nPage <= (UINT)m_aPageStart.GetSize());
  600. UINT nIndex = m_aPageStart[nPage-1];
  601. // print as much as possible in the current page.
  602. nIndex = PrintPage(pDC, pInfo, rcPrint, nIndex);
  603. // update pagination information for page just printed
  604. if (nPage == (UINT)m_aPageStart.GetSize())
  605. {
  606. m_aPageStart.Add(nIndex);
  607. }
  608. else
  609. {
  610. ASSERT(nPage < (UINT)m_aPageStart.GetSize());
  611. m_aPageStart[nPage] = nIndex;
  612. }
  613. }
  614. extern BOOL CALLBACK _XTPAbortProc(HDC, int);
  615. BOOL CXTPReportView::PaginateTo(CDC* pDC, CPrintInfo* pInfo)
  616. // attempts pagination to pInfo->m_nCurPage, TRUE == success
  617. {
  618. ASSERT_VALID(this);
  619. ASSERT_VALID(pDC);
  620. BOOL bAborted = FALSE;
  621. CXTPPrintingDialog dlgPrintStatus(this);
  622. CString strTemp;
  623. if (GetParentFrame())
  624. GetParentFrame()->GetWindowText(strTemp);
  625. dlgPrintStatus.SetWindowText(_T("Calculating pages..."));
  626. dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_DOCNAME, strTemp);
  627. dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_PRINTERNAME, pInfo->m_pPD->GetDeviceName());
  628. dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_PORTNAME, pInfo->m_pPD->GetPortName());
  629. dlgPrintStatus.ShowWindow(SW_SHOW);
  630. dlgPrintStatus.UpdateWindow();
  631. CRect rectSave = pInfo->m_rectDraw;
  632. UINT nPageSave = pInfo->m_nCurPage;
  633. BOOL bBlackWhiteSaved = m_pPrintOptions->m_bBlackWhitePrinting;
  634. m_pPrintOptions->m_bBlackWhitePrinting = FALSE;
  635. ASSERT(nPageSave > 1);
  636. ASSERT(nPageSave >= (UINT)m_aPageStart.GetSize());
  637. VERIFY(pDC->SaveDC() != 0);
  638. pDC->IntersectClipRect(0, 0, 0, 0);
  639. pInfo->m_nCurPage = (UINT)m_aPageStart.GetSize();
  640. while (pInfo->m_nCurPage < nPageSave)
  641. {
  642. ASSERT(pInfo->m_nCurPage == (UINT)m_aPageStart.GetSize());
  643. OnPrepareDC(pDC, pInfo);
  644. if (!pInfo->m_bContinuePrinting)
  645. break;
  646. strTemp.Format(_T("%d"), pInfo->m_nCurPage);
  647. dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_PAGENUM, strTemp);
  648. pInfo->m_rectDraw.SetRect(0, 0, pDC->GetDeviceCaps(HORZRES), pDC->GetDeviceCaps(VERTRES));
  649. pDC->DPtoLP(&pInfo->m_rectDraw);
  650. OnPrint(pDC, pInfo);
  651. //if (pInfo->m_nCurPage == (UINT)m_aPageStart.GetSize())
  652. //  break;
  653. ++pInfo->m_nCurPage;
  654. if(!_XTPAbortProc(0, 0))
  655. {
  656. bAborted = TRUE;
  657. break;
  658. }
  659. }
  660. dlgPrintStatus.DestroyWindow();
  661. BOOL bResult = !bAborted && (pInfo->m_nCurPage == nPageSave || nPageSave == 65535);
  662. pInfo->m_bContinuePrinting = bResult;
  663. pDC->RestoreDC(-1);
  664. m_pPrintOptions->m_bBlackWhitePrinting = bBlackWhiteSaved;
  665. pInfo->m_nCurPage = nPageSave;
  666. pInfo->m_rectDraw = rectSave;
  667. ASSERT_VALID(this);
  668. return bResult;
  669. }
  670. void CXTPReportView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)
  671. {
  672. ASSERT_VALID(this);
  673. ASSERT_VALID(pDC);
  674. ASSERT(pInfo != NULL);  // overriding OnPaint -- never get this.
  675. if (!pInfo)
  676. return;
  677. if (pInfo->m_nCurPage == 1 && GetReportCtrl().GetRows()->GetCount() == 0)
  678. {
  679. pInfo->m_bContinuePrinting = TRUE;
  680. }
  681. else if (pInfo->m_nCurPage == (UINT)m_aPageStart.GetSize() &&
  682. m_aPageStart[pInfo->m_nCurPage - 1] >= (UINT)GetReportCtrl().GetRows()->GetCount())
  683. {
  684. // can't paginate to that page, thus cannot print it.
  685. pInfo->m_bContinuePrinting = FALSE;
  686. }
  687. else if (pInfo->m_nCurPage > (UINT)m_aPageStart.GetSize() &&
  688. !PaginateTo(pDC, pInfo))
  689. {
  690. // can't paginate to that page, thus cannot print it.
  691. pInfo->m_bContinuePrinting = FALSE;
  692. }
  693. pDC->SetMapMode(MM_ANISOTROPIC);
  694. pDC->SetViewportExt(pDC->GetDeviceCaps(LOGPIXELSX),
  695. pDC->GetDeviceCaps(LOGPIXELSY));
  696. pDC->SetWindowExt(100, 100);
  697. // ptOrg is in logical coordinates
  698. pDC->OffsetWindowOrg(0, 0);
  699. if (GetReportCtrl().GetExStyle() & WS_EX_RTLREADING)
  700. {
  701. pDC->SetTextAlign(TA_RTLREADING);
  702. }
  703. if(GetReportCtrl().IsLayoutRTL())
  704. XTPDrawHelpers()->SetContextRTL(pDC, LAYOUT_RTL);
  705. }
  706. //////////////////////////////////////////////////////////////////////////
  707. // Clipboard operations
  708. void CXTPReportView::OnUpdateEditCopy(CCmdUI* pCmdUI)
  709. {
  710. pCmdUI->Enable(GetReportCtrl().CanCopy());
  711. }
  712. void CXTPReportView::OnUpdateEditCut(CCmdUI* pCmdUI)
  713. {
  714. pCmdUI->Enable(m_bAllowCut && GetReportCtrl().CanCut());
  715. }
  716. void CXTPReportView::OnUpdateEditPaste(CCmdUI* pCmdUI)
  717. {
  718. pCmdUI->Enable(m_bAllowPaste && GetReportCtrl().CanPaste());
  719. }
  720. void CXTPReportView::OnEditCut()
  721. {
  722. if (m_bAllowCut) GetReportCtrl().Cut();
  723. }
  724. void CXTPReportView::OnEditCopy()
  725. {
  726. GetReportCtrl().Copy();
  727. }
  728. void CXTPReportView::OnEditPaste()
  729. {
  730. if (m_bAllowPaste) GetReportCtrl().Paste();
  731. }
  732. void CXTPReportView::OnFilePageSetup()
  733. {
  734. DWORD dwFlags = PSD_MARGINS | PSD_INWININIINTLMEASURE;
  735. CXTPReportPageSetupDialog dlgPageSetup(GetPrintOptions(), dwFlags, this);
  736. XTPGetPrinterDeviceDefaults(dlgPageSetup.m_psd.hDevMode, dlgPageSetup.m_psd.hDevNames);
  737. int nDlgRes = (int)dlgPageSetup.DoModal();
  738. if (nDlgRes == IDOK)
  739. {
  740. AfxGetApp()->SelectPrinter(dlgPageSetup.m_psd.hDevNames, dlgPageSetup.m_psd.hDevMode, FALSE);
  741. }
  742. }
  743. int CXTPReportView::PrintFixedRows(CDC* pDC, CRect rcClient, BOOL bHeaderRows)
  744. {
  745. int y = rcClient.top;
  746. CXTPReportRows* pRows = bHeaderRows ? GetReportCtrl().GetHeaderRows() : GetReportCtrl().GetFooterRows();
  747. for (int i = 0; i < pRows->GetCount(); ++i)
  748. {
  749. CXTPReportRow* pRow = pRows->GetAt(i);
  750. int nHeight = pRow->GetHeight(pDC, rcClient.Width());
  751. CRect rcRow(rcClient.left, y, rcClient.right, y + nHeight);
  752. if (rcRow.bottom > rcClient.bottom)
  753. break;
  754. PrintRow(pDC, pRow, rcRow, 0);
  755. y += rcRow.Height();
  756. }
  757. return y - rcClient.top; // height of all printed rows
  758. }
  759. /////////////////////////////////////////////////////////////////////////////
  760. //class CXTPReportViewPrintOptions
  761. IMPLEMENT_DYNAMIC(CXTPReportViewPrintOptions, CXTPPrintOptions)
  762. CXTPReportViewPrintOptions::CXTPReportViewPrintOptions()
  763. {
  764. m_bRepeatHeaderRows = FALSE;
  765. m_bRepeatFooterRows = FALSE;
  766. }
  767. LCID CXTPReportViewPrintOptions::GetActiveLCID()
  768. {
  769. return CXTPReportControlLocale::GetActiveLCID();
  770. }
  771. void CXTPReportViewPrintOptions::Set(const CXTPReportViewPrintOptions* pSrc)
  772. {
  773. if (pSrc)
  774. {
  775. CXTPPrintOptions::Set(pSrc);
  776. m_bRepeatHeaderRows = pSrc->m_bRepeatHeaderRows;
  777. m_bRepeatFooterRows = pSrc->m_bRepeatFooterRows;
  778. }
  779. }