You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1107 lines
28 KiB
C++

2 years ago
// XTPReportView.cpp : implementation of the CXTPReportView class.
//
// This file is a part of the XTREME REPORTCONTROL MFC class library.
// (c)1998-2012 Codejock Software, All Rights Reserved.
//
// THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
// RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
// CONSENT OF CODEJOCK SOFTWARE.
//
// THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
// IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
// YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
// SINGLE COMPUTER.
//
// CONTACT INFORMATION:
// support@codejock.com
// http://www.codejock.com
//
/////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "Common/XTPDrawHelpers.h"
#include "Common/XTPImageManager.h"
#include "Common/XTPCustomHeap.h"
#include "Common/XTPSystemHelpers.h"
#include "Common/XTPSmartPtrInternalT.h"
#include "Common/XTPColorManager.h"
#include "Resource.h"
#include "XTPReportDefines.h"
#include "XTPReportControl.h"
#include "XTPReportView.h"
#include "XTPReportColumn.h"
#include "XTPReportColumns.h"
#include "XTPReportRows.h"
#include "XTPReportSection.h"
#include "XTPReportSelectedRows.h"
#include "XTPReportPaintManager.h"
#include "XTPReportPageSetupDialog.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CXTPReportView
IMPLEMENT_DYNCREATE(CXTPReportView, CView)
CXTPReportView::CXTPReportView()
: m_nColumnStart(0)
, m_nColumnEnd (0)
, m_pScrollBarVer(NULL)
, m_pScrollBarHor(NULL)
, m_pSlider (NULL)
{
m_pReport = NULL;
m_pPrintOptions = new CXTPReportViewPrintOptions();
m_bPrintSelection = FALSE;
m_bPaginated = FALSE;
m_bPrintDirect = FALSE;
m_bResizeControlWithView = TRUE;
m_bAllowCut = TRUE;
m_bAllowPaste = TRUE;
m_nStartIndex = 0;
m_bSwitchMode = FALSE;
}
CXTPReportView::~CXTPReportView()
{
CMDTARGET_RELEASE(m_pPrintOptions);
SAFE_DELETE(m_pReport);
}
CXTPReportControl& CXTPReportView::GetReportCtrl() const
{
return m_pReport == NULL ? (CXTPReportControl&)m_wndReport : *m_pReport;
}
void CXTPReportView::SetReportCtrl(CXTPReportControl* pReport)
{
if (::IsWindow(m_wndReport.GetSafeHwnd()))
m_wndReport.DestroyWindow();
m_pReport = pReport;
}
void CXTPReportView::SetScrollBarCtrl(CScrollBar* pScrollBar, BOOL bHor)
{
if (bHor)
{
m_pScrollBarHor = pScrollBar;
}
else
{
m_pScrollBarVer = pScrollBar;
}
}
void CXTPReportView::SetSliderCtrl(CSliderCtrl* pSlider)
{
m_pSlider = pSlider;
}
BEGIN_MESSAGE_MAP(CXTPReportView, CView)
//{{AFX_MSG_MAP(CXTPReportView)
ON_WM_ERASEBKGND()
ON_WM_SIZE()
ON_WM_CREATE()
ON_WM_SETFOCUS()
ON_WM_PAINT()
ON_WM_VSCROLL()
ON_WM_HSCROLL()
ON_COMMAND(ID_FILE_PRINT, OnFilePrint)
ON_COMMAND(ID_EDIT_CUT, OnEditCut)
ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, OnUpdateEditPaste)
ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateEditCopy)
ON_UPDATE_COMMAND_UI(ID_EDIT_CUT, OnUpdateEditCut)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CXTPReportView drawing
void CXTPReportView::OnDraw(CDC* pDC)
{
UNREFERENCED_PARAMETER(pDC);
}
void CXTPReportView::OnPaint()
{
Default();
}
BOOL CXTPReportView::OnEraseBkgnd(CDC* pDC)
{
UNREFERENCED_PARAMETER(pDC);
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CXTPReportView diagnostics
#ifdef _DEBUG
void CXTPReportView::AssertValid() const
{
CView::AssertValid();
}
void CXTPReportView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CXTPReportView message handlers
CScrollBar* CXTPReportView::GetScrollBarCtrl(int nBar) const
{
if (nBar == SB_VERT && m_pScrollBarVer)
return m_pScrollBarVer;
if (nBar == SB_HORZ && m_pScrollBarHor)
return m_pScrollBarHor;
return CView::GetScrollBarCtrl(nBar);
}
void CXTPReportView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
if (m_pScrollBarVer && pScrollBar == m_pScrollBarVer)
{
GetReportCtrl().OnVScroll(nSBCode, nPos, 0);
}
CView::OnVScroll(nSBCode, nPos, pScrollBar);
}
void CXTPReportView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
if (m_pScrollBarHor && pScrollBar == m_pScrollBarHor)
{
GetReportCtrl().OnHScroll(nSBCode, nPos, 0);
}
CView::OnHScroll(nSBCode, nPos, pScrollBar);
}
void CXTPReportView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
int nScroll = GetSystemMetrics(SM_CXVSCROLL);
//SM_CXVSCROLL SM_CYHSCROLL SM_CXBORDER SM_CYBORDER
int dx = 0;
if (GetPaintManager()->m_bMoveScrollbarOnFixedColumnsIndent)
dx = GetPaintManager()->m_nFixedColumnsIndent;
BOOL bV = (m_pScrollBarVer != NULL) && (m_pScrollBarVer->GetSafeHwnd() != NULL);
BOOL bH = (m_pScrollBarHor != NULL) && (m_pScrollBarHor->GetSafeHwnd() != NULL);
CRect rc; GetClientRect(&rc);
cx = rc.Width();
cy = rc.Height();
int CX = cx;
int CY = cy;
if (bV || bH)
{
if (bV && bH)
{
cx -= nScroll;
cy -= nScroll;
}
else if (bV)
{
cx -= nScroll;
}
else if (bH)
{
cy -= nScroll;
}
// Right-to-left
if (GetReportCtrl().IsLayoutRTL())
{
if (bV)
{
m_pScrollBarVer->MoveWindow(0, 0, nScroll, cy);
}
if (bH)
{
m_pScrollBarHor->MoveWindow(0, cy, CX - dx, nScroll);
if (WS_EX_LAYOUTRTL != (m_pScrollBarHor->GetExStyle() & WS_EX_LAYOUTRTL))
{
// Turn RTL on
m_pScrollBarHor->ModifyStyleEx(0, WS_EX_LAYOUTRTL);
}
}
if (m_pSlider)
{
if (dx)
{
m_pSlider->MoveWindow(CX - dx, cy, dx, nScroll);
m_pSlider->ShowWindow(SW_SHOW);
}
else
{
m_pSlider->MoveWindow(CX - dx, cy, dx, nScroll);
m_pSlider->ShowWindow(SW_HIDE);
}
}
}
// Left-to-right
else
{
if (bV)
{
m_pScrollBarVer->MoveWindow(cx, 0, nScroll, cy);
}
if (bH)
{
m_pScrollBarHor->MoveWindow(dx, cy, CX - dx, nScroll);
if (WS_EX_LAYOUTRTL == (m_pScrollBarHor->GetExStyle() & WS_EX_LAYOUTRTL))
{
// Turn RTL off
m_pScrollBarHor->ModifyStyleEx(WS_EX_LAYOUTRTL, 0);
}
}
if (m_pSlider)
{
if (dx)
{
m_pSlider->MoveWindow(0, cy, dx, nScroll);
m_pSlider->ShowWindow(SW_SHOW);
}
else
{
m_pSlider->MoveWindow(0, cy, dx, nScroll);
m_pSlider->ShowWindow(SW_HIDE);
}
}
}
}
else
nScroll = 0;
if (m_bResizeControlWithView && GetReportCtrl().GetSafeHwnd())
{
if (nScroll > 0)
{
if (GetReportCtrl().IsLayoutRTL())
{
if (bV)
GetReportCtrl().MoveWindow(nScroll, 0, cx, cy);
else
GetReportCtrl().MoveWindow(0, 0, cx, cy);
}
else
{
if (bV)
GetReportCtrl().MoveWindow(0, 0, cx, cy);
else
GetReportCtrl().MoveWindow(0, 0, cx, cy);
}
}
else
{
GetReportCtrl().MoveWindow(0, 0, CX, CY);
}
}
}
BOOL CXTPReportView::PreCreateWindow(CREATESTRUCT &cs)
{
cs.style |= WS_CLIPCHILDREN|WS_CLIPSIBLINGS;
return CView::PreCreateWindow(cs);
}
int CXTPReportView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
if (!GetReportCtrl().Create(WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_TABSTOP | WS_VISIBLE,
CRect(0, 0, 0, 0), this, XTP_ID_REPORT_CONTROL))
{
TRACE(_T("Failed to create report control window\n"));
return -1;
}
return 0;
}
void CXTPReportView::OnSetFocus(CWnd* pOldWnd)
{
CView::OnSetFocus(pOldWnd);
if (IsWindow(GetReportCtrl().GetSafeHwnd()))
GetReportCtrl().SetFocus();
}
/////////////////////////////////////////////////////////////////////////////
BOOL CXTPReportView::OnPreparePrinting(CPrintInfo* pInfo)
{
if (GetReportCtrl().IsIconView())
{
GetReportCtrl().SetIconView(FALSE);
m_bSwitchMode = TRUE;
}
m_bShowRowNumber = GetReportCtrl().IsShowRowNumber();
GetReportCtrl().ShowRowNumber(FALSE);
if (GetReportCtrl().GetSelectedRows()->GetCount() > 0)
pInfo->m_pPD->m_pd.Flags &= ~PD_NOSELECTION;
pInfo->m_bDirect = m_bPrintDirect;
// default preparation
if (!DoPreparePrinting(pInfo))
return FALSE;
m_bPrintSelection = pInfo->m_pPD->PrintSelection();
return TRUE;
}
void CXTPReportView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
m_aPageStart.RemoveAll();
if (m_pPrintOptions->m_bBlackWhitePrinting)
m_bmpGrayDC.DeleteObject();
if (m_bSwitchMode)
{
GetReportCtrl().SetIconView(TRUE);
m_bSwitchMode = FALSE;
}
GetReportCtrl().ShowRowNumber(m_bShowRowNumber);
}
CXTPReportPaintManager* CXTPReportView::GetPaintManager() const
{
return GetReportCtrl().GetPaintManager();
}
void CXTPReportView::PrintHeader(CDC *pDC, CRect rcHeader)
{
CXTPReportColumns *pColumns = GetReportCtrl().GetColumns();
GetPaintManager()->FillHeaderControl(pDC, rcHeader);
int x = rcHeader.left;
int nWidth;
for (int nColumn=m_nColumnStart; nColumn<m_nColumnEnd; nColumn++)
{
CXTPReportColumn *pColumn = pColumns->GetAt(nColumn);
if (pColumn->IsVisible())
{
if (GetPaintManager()->IsColumnWidthWYSIWYG())
{
nWidth = pColumn->GetWidth();
}
else
{
nWidth = pColumn->GetPrintWidth(rcHeader.Width());
}
CRect rcItem(x, rcHeader.top, x + nWidth, rcHeader.bottom);
GetPaintManager()->DrawColumn(pDC, pColumn, GetReportCtrl().GetReportHeader(), rcItem);
x += nWidth;
}
}
}
void CXTPReportView::PrintFooter(CDC* pDC, CRect rcFooter)
{
CXTPReportColumns* pColumns = GetReportCtrl().GetColumns();
GetPaintManager()->FillFooter(pDC, rcFooter);
int x = rcFooter.left;
int nWidth(0);
for (int nColumn=m_nColumnStart; nColumn<m_nColumnEnd; nColumn++)
{
CXTPReportColumn* pColumn = pColumns->GetAt(nColumn);
if (!pColumn->IsVisible())
continue;
if (GetPaintManager()->IsColumnWidthWYSIWYG())
nWidth = pColumn->GetWidth();
else
nWidth = pColumn->GetPrintWidth(rcFooter.Width());
CRect rcItem(x, rcFooter.top, x + nWidth, rcFooter.bottom);
GetPaintManager()->DrawColumnFooter(pDC, pColumn, GetReportCtrl().GetReportHeader(), rcItem);
x += nWidth;
}
}
int CXTPReportView::PrintReport(CDC *pDC, CPrintInfo *pInfo, CRect rcPage,
int nRowFrom, int nColumnFrom, int nColumnTo)
{
CXTPReportControl &wndReport = GetReportCtrl();
int nMaxPages = -1;
if (pInfo->GetMaxPage() != 65535)
nMaxPages = pInfo->GetMaxPage();
if (GetPaintManager()->m_bPrintWatermark)
{
CRect rcWater(rcPage);
CRect rcClient(0, 0, rcWater.Width(), rcWater.Height());
wndReport.DrawWatermark(pDC, rcWater, rcClient);
}
int nHeaderHeight = PrintPageHeader(pDC, pInfo, rcPage, FALSE,
pInfo->m_nCurPage, nMaxPages,
m_nStartIndex, (int) GetPaintManager()->m_arStartCol.GetSize() - 1);
int nFooterHeight = PrintPageFooter(pDC, pInfo, rcPage, FALSE,
pInfo->m_nCurPage, nMaxPages,
m_nStartIndex, (int) GetPaintManager()->m_arStartCol.GetSize() - 1);
CRect rcRows(rcPage);
if (GetPaintManager()->m_bPrintPageRectangle)
{
rcRows.DeflateRect(1,1);
}
rcRows.top += nHeaderHeight;
rcRows.bottom -= nFooterHeight;
int nFooterTop = rcRows.bottom;
// print header rows (if exist and visible)
if (wndReport.GetHeaderRows()->GetCount() > 0 && GetReportCtrl().IsHeaderRowsVisible())
{
// print on the first page, at least
if (0 == nRowFrom || m_pPrintOptions->m_bRepeatHeaderRows)
{
int nHeight = 0;
wndReport.DrawRows(pDC, rcRows, rcRows.top, wndReport.GetHeaderRows(), 0, nColumnFrom, nColumnTo, &nHeight);
rcRows.top += nHeight;
// print divider
rcRows.top += PrintFixedRowsDivider(pDC, rcRows, TRUE);
}
}
// calculate space for footer rows
int nNeedForFooterRows = 0;
if (wndReport.GetFooterRows()->GetCount() > 0 && GetReportCtrl().IsFooterRowsVisible())
{
nNeedForFooterRows = wndReport.GetRowsHeight(GetReportCtrl().GetFooterRows(), rcRows.Width());
nNeedForFooterRows += GetPaintManager()->GetSectionDividerHeight(wndReport.m_pSectionFooter->GetDividerStyle());
if (m_pPrintOptions->m_bRepeatFooterRows)
{
// decrease space for body rows, if footer rows to be repeated on every page.
rcRows.bottom = nFooterTop - nNeedForFooterRows;
}
}
// print body rows
int nPrintedBodyRowsHeight = 0;
nRowFrom = wndReport.DrawRows(pDC, rcRows, rcRows.top, wndReport.GetRows(), nRowFrom, nColumnFrom, nColumnTo, &nPrintedBodyRowsHeight);
// print footer rows (if exist and visible)
if (nNeedForFooterRows > 0)
{
CRect rcFooterRows(rcRows);
if (wndReport.IsFooterRowsPinnedPrinted())
{
rcFooterRows.top = rcRows.top + nPrintedBodyRowsHeight; //immediately after body rows
rcFooterRows.bottom = nFooterTop;
}
else
{
rcFooterRows.top = nFooterTop - nNeedForFooterRows;
rcFooterRows.bottom = nFooterTop;
}
// one more check, if there is enough space for footer divider + footer rows
if (rcFooterRows.Height() >= nNeedForFooterRows)
{
// print divider
rcFooterRows.top += PrintFixedRowsDivider(pDC, rcFooterRows, FALSE);
// print footer rows
int nHeight = 0;
wndReport.DrawRows(pDC, rcFooterRows, rcFooterRows.top, wndReport.GetFooterRows(), 0, nColumnFrom, nColumnTo, &nHeight);
}
}
if (GetPaintManager()->m_bPrintPageRectangle)
{
pDC->Draw3dRect(rcPage, 0, 0);
}
return nRowFrom;
}
int CXTPReportView::PrintFixedRowsDivider(CDC* pDC, const CRect& rc, BOOL bHeaderRows)
{
CRect rcDivider(rc);
XTPReportSectionDividerPosition dividerPosition = bHeaderRows
? GetReportCtrl().m_pSectionHeader->GetDividerPosition()
: GetReportCtrl().m_pSectionFooter->GetDividerPosition();
XTPReportFixedRowsDividerStyle dividerStyle = bHeaderRows
? GetReportCtrl().m_pSectionHeader->GetDividerStyle()
: GetReportCtrl().m_pSectionFooter->GetDividerStyle();
CXTPPaintManagerColor dividerColor = bHeaderRows
? GetReportCtrl().m_pSectionHeader->GetDividerColor()
: GetReportCtrl().m_pSectionHeader->GetDividerColor();
int nHeight = GetPaintManager()->GetSectionDividerHeight(dividerStyle);
rcDivider.bottom = rcDivider.top + nHeight;
GetPaintManager()->DrawSectionDivider(pDC, rcDivider, dividerPosition, dividerStyle, dividerColor);
return nHeight;
}
int CXTPReportView::PrintPage(CDC *pDC, CPrintInfo *pInfo, CRect rcPage,
int nRowFrom, int nColumnFrom, int nColumnTo)
{
if (!m_pPrintOptions || !pDC || !pInfo)
{
ASSERT(FALSE);
return INT_MAX;
}
CRect rcPageHeader = rcPage;
CRect rcPageFooter = rcPage;
CString strTitle = CXTPPrintPageHeaderFooter::GetParentFrameTitle(this);
int N = (int) GetPaintManager()->m_arStartCol.GetSize() - 1;
int nVirPage(0);
if (N > 0)
nVirPage = 1 + m_nStartIndex;
if (GetPaintManager()->m_bPrintVirtualPageNumber)
{
m_pPrintOptions->GetPageHeader()->FormatTexts(pInfo, strTitle, nVirPage);
m_pPrintOptions->GetPageFooter()->FormatTexts(pInfo, strTitle, nVirPage);
}
else
{
m_pPrintOptions->GetPageHeader()->FormatTexts(pInfo, strTitle);
m_pPrintOptions->GetPageFooter()->FormatTexts(pInfo, strTitle);
}
m_pPrintOptions->GetPageHeader()->Draw(pDC, rcPageHeader);
m_pPrintOptions->GetPageFooter()->Draw(pDC, rcPageFooter);
CRect rcReport = rcPage;
rcReport.top += rcPageHeader.Height() + 2;
rcReport.bottom -= rcPageFooter.Height() + 2;
nRowFrom = PrintReport(pDC, pInfo, rcReport, nRowFrom, nColumnFrom, nColumnTo);
return nRowFrom;
}
int CXTPReportView::PrintPageHeader(CDC* pDC, CPrintInfo* pInfo, CRect rcPage,
BOOL bOnlyCalculate, int nPageNumber, int nNumberOfPages,
int nHorizontalPageNumber, int nNumberOfHorizontalPages)
{
UNREFERENCED_PARAMETER(pInfo);
UNREFERENCED_PARAMETER(nPageNumber);
UNREFERENCED_PARAMETER(nNumberOfPages);
UNREFERENCED_PARAMETER(nHorizontalPageNumber);
UNREFERENCED_PARAMETER(nNumberOfHorizontalPages);
UNREFERENCED_PARAMETER(bOnlyCalculate);
UNREFERENCED_PARAMETER(nPageNumber);
UNREFERENCED_PARAMETER(nHorizontalPageNumber);
UNREFERENCED_PARAMETER(nNumberOfHorizontalPages);
int nHeaderHeight = 0;
if (GetPaintManager()->m_bPrintPageRectangle)
rcPage.DeflateRect(1,1);
if (GetReportCtrl().IsHeaderVisible())
nHeaderHeight = GetPaintManager()->GetHeaderHeight(&GetReportCtrl(), pDC, rcPage.Width());
rcPage.bottom = rcPage.top + nHeaderHeight;
if (nHeaderHeight)
PrintHeader(pDC, rcPage);
return nHeaderHeight;
}
int CXTPReportView::PrintPageFooter(CDC* pDC, CPrintInfo* pInfo, CRect rcPage,
BOOL bOnlyCalculate, int nPageNumber, int nNumberOfPages,
int nHorizontalPageNumber, int nNumberOfHorizontalPages)
{
UNREFERENCED_PARAMETER(pInfo);
UNREFERENCED_PARAMETER(nPageNumber);
UNREFERENCED_PARAMETER(nNumberOfPages);
UNREFERENCED_PARAMETER(nHorizontalPageNumber);
UNREFERENCED_PARAMETER(nNumberOfHorizontalPages);
UNREFERENCED_PARAMETER(bOnlyCalculate);
UNREFERENCED_PARAMETER(nPageNumber);
UNREFERENCED_PARAMETER(nHorizontalPageNumber);
UNREFERENCED_PARAMETER(nNumberOfHorizontalPages);
int nFooterHeight = 0;
if (GetPaintManager()->m_bPrintPageRectangle)
rcPage.DeflateRect(1,1);
if (GetReportCtrl().IsFooterVisible())
nFooterHeight = GetPaintManager()->GetFooterHeight(&GetReportCtrl(), pDC, rcPage.Width());
rcPage.top = rcPage.bottom - nFooterHeight;
if (nFooterHeight)
PrintFooter(pDC, rcPage);
return nFooterHeight;
}
int CXTPReportView::SetupStartCol(CDC* pDC, CPrintInfo* pInfo)
{
pDC->SetMapMode(MM_ANISOTROPIC);
pDC->SetViewportExt(pDC->GetDeviceCaps(LOGPIXELSX), pDC->GetDeviceCaps(LOGPIXELSY));
pDC->SetWindowExt(96, 96);
pDC->OffsetWindowOrg(0, 0);
pInfo->m_rectDraw.SetRect(0, 0, pDC->GetDeviceCaps(HORZRES), pDC->GetDeviceCaps(VERTRES));
pDC->DPtoLP(&pInfo->m_rectDraw);
CRect rcMargins = m_pPrintOptions->GetMarginsLP(pDC);
CRect rc = pInfo->m_rectDraw;
rc.DeflateRect(rcMargins);
GetPaintManager()->m_PrintPageWidth = rc.Width();
GetPaintManager()->m_arStartCol.RemoveAll();
GetPaintManager()->m_arStartCol.Add(0);
CXTPReportColumns* pColumns = GetReportCtrl().GetColumns();
int nColumnCount = pColumns->GetCount();
if (GetPaintManager()->IsColumnWidthWYSIWYG())
{
int x = 0;
for (int nColumn = 0; nColumn < nColumnCount; nColumn++)
{
CXTPReportColumn* pColumn = pColumns->GetAt(nColumn);
if (pColumn && pColumn->IsVisible())
{
int nWidth = pColumn->GetWidth();
if (x + nWidth <= GetPaintManager()->m_PrintPageWidth)
{
x += nWidth;
}
else
{
GetPaintManager()->m_arStartCol.Add(nColumn);
x = nWidth;
}
}
}
}
GetPaintManager()->m_arStartCol.Add(nColumnCount);
return (int) GetPaintManager()->m_arStartCol.GetSize() - 1;
}
//struct CPrintInfo // Printing information structure
// CPrintDialog* m_pPD; // pointer to print dialog
// BOOL m_bPreview; // TRUE if in preview mode
// BOOL m_bDirect; // TRUE if bypassing Print Dialog
// BOOL m_bContinuePrinting;// set to FALSE to prematurely end printing
// UINT m_nCurPage; // Current page
// UINT m_nNumPreviewPages; // Desired number of preview pages
// CString m_strPageDesc; // Format string for page number display
// void SetMinPage(UINT nMinPage);
// void SetMaxPage(UINT nMaxPage);
// UINT GetMinPage() const;
// UINT GetMaxPage() const;
// UINT GetFromPage() const;
// UINT GetToPage() const;
void CXTPReportView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
{
m_aPageStart.RemoveAll();
m_aPageStart.Add(0);
int nVirtualPages = SetupStartCol(pDC, pInfo);
if (pInfo->m_bPreview)
{
pInfo->m_nNumPreviewPages = 1;
AfxGetApp()->m_nNumPreviewPages = pInfo->m_nNumPreviewPages;
}
CString str1, str2;
if (m_pPrintOptions && m_pPrintOptions->GetPageHeader())
str1 = m_pPrintOptions->GetPageHeader()->m_strFormatString;
if (m_pPrintOptions && m_pPrintOptions->GetPageFooter())
str2 = m_pPrintOptions->GetPageFooter()->m_strFormatString;
if (nVirtualPages > 1 && m_pPrintOptions->GetPageHeader()->m_strFormatString.IsEmpty())
m_pPrintOptions->GetPageHeader()->m_strFormatString = _T(" &p/&P ");
UINT pFr = pInfo->GetFromPage();
UINT pTo = pInfo->GetToPage();
if (pFr > 0)
{
pInfo->SetMinPage(pFr);
pInfo->m_nCurPage = pFr;
}
if (pTo < 65535)
{
pInfo->SetMaxPage(pTo);
}
if (GetReportCtrl().m_bForcePagination)
{
m_bPaginated = FALSE;
}
if ((!pInfo->m_bPreview || GetReportCtrl().m_bForcePagination)
&& (str1.Find(_T("&P")) >= 0
|| nVirtualPages > 1
|| pFr > 1
|| pTo < 65535
|| str2.Find(_T("&P")) >= 0))
{
m_nStartIndex = 0;
m_nColumnStart = GetPaintManager()->m_arStartCol.GetAt(0);
m_nColumnEnd = GetPaintManager()->m_arStartCol.GetAt(1);
int nCurPage = pInfo->m_nCurPage;
pInfo->m_nCurPage = 65535;
if (PaginateTo(pDC, pInfo))
pInfo->SetMaxPage((int) m_aPageStart.GetSize() - 1 - m_nStartIndex);
pInfo->m_nCurPage = nCurPage;
if (GetReportCtrl().m_bForcePagination)
{
m_bPaginated = TRUE;
}
}
m_nStartIndex = 0;
m_nColumnStart = GetPaintManager()->m_arStartCol.GetAt(0);
m_nColumnEnd = GetPaintManager()->m_arStartCol.GetAt(1);
}
void CXTPReportView::OnPrint(CDC *pDC, CPrintInfo *pInfo)
{
if (!m_pPrintOptions || !pDC || !pInfo)
{
ASSERT(FALSE);
return;
}
CRect rcMargins = m_pPrintOptions->GetMarginsLP(pDC);
CRect rc = pInfo->m_rectDraw;
rc.DeflateRect(rcMargins);
UINT nVirtualPages = (UINT) GetPaintManager()->m_arStartCol.GetSize() - 1;
UINT nPage = pInfo->m_nCurPage;
int nSize = (int) m_aPageStart.GetSize();
ASSERT(nPage <= (UINT) nSize);
UINT nIndex = m_aPageStart[nPage - 1];
UINT mIndex(0);
//if (m_bPaginated)
{
m_nStartIndex = (pInfo->m_nCurPage - 1) % nVirtualPages;
m_nColumnStart = GetPaintManager()->m_arStartCol.GetAt(m_nStartIndex);
m_nColumnEnd = GetPaintManager()->m_arStartCol.GetAt(m_nStartIndex + 1);
}
//TRACE(_T("CXTPReportView::OnPrint %d %d %d %d %d\n"), pInfo->m_nCurPage, nVirtualPages, m_nStartIndex, m_nColumnStart, m_nColumnEnd);
if (!m_pPrintOptions->m_bBlackWhitePrinting)
{
mIndex = PrintPage(pDC, pInfo, rc, nIndex, m_nColumnStart, m_nColumnEnd);
}
else
{
CRect rc00(0, 0, rc.Width(), rc.Height());
CDC memDC;
VERIFY(memDC.CreateCompatibleDC(pDC));
memDC.m_bPrinting = TRUE;
if (!m_bmpGrayDC.m_hObject
|| m_bmpGrayDC.GetBitmapDimension() != rc00.Size())
{
m_bmpGrayDC.DeleteObject();
m_bmpGrayDC.CreateCompatibleBitmap(pDC, rc00.Width(), rc00.Height());
}
CXTPBitmapDC autpBmp(&memDC, &m_bmpGrayDC);
memDC.FillSolidRect(rc00, RGB(255, 255, 255));
mIndex = PrintPage(&memDC, pInfo, rc00, nIndex, m_nColumnStart, m_nColumnEnd);
int nCC = max(0, min(m_pPrintOptions->m_nBlackWhiteContrast, 255));
XTPImageManager()->BlackWhiteBitmap(memDC, rc00, nCC);
pDC->BitBlt(rc.left, rc.top, rc.Width(), rc.Height(), &memDC, 0, 0, SRCCOPY);
}
if (!m_bPaginated)
{
m_nStartIndex++;
if (m_nStartIndex >= nVirtualPages) //done with the page!
m_nStartIndex = 0;
m_nColumnStart = GetPaintManager()->m_arStartCol.GetAt(m_nStartIndex);
m_nColumnEnd = GetPaintManager()->m_arStartCol.GetAt(m_nStartIndex + 1);
if (m_nStartIndex > 0)
{
if (nPage == (UINT) nSize)
m_aPageStart.Add(nIndex);
else if (nPage < (UINT) nSize)
m_aPageStart[nPage] = nIndex;
}
else
{
if (nPage == (UINT) nSize)
m_aPageStart.Add(mIndex);
else if (nPage < (UINT) nSize)
m_aPageStart[nPage] = mIndex;
if ((int) mIndex == GetReportCtrl().GetRows()->GetCount())
pInfo->SetMaxPage(pInfo->m_nCurPage);
}
}
if (pInfo->m_bPreview)
{
pInfo->m_nCurPage++;
}
}
extern BOOL CALLBACK _XTPAbortProc(HDC, int);
BOOL CXTPReportView::PaginateTo(CDC* pDC, CPrintInfo* pInfo)
{
ASSERT_VALID(this);
ASSERT_VALID(pDC);
UINT nVirtualPages = (UINT) GetPaintManager()->m_arStartCol.GetSize() - 1;
BOOL bAborted = FALSE;
CXTPPrintingDialog PrintStatus(this);
CString strTemp;
if (GetParentFrame())
GetParentFrame()->GetWindowText(strTemp);
PrintStatus.SetWindowText(_T("Calculating pages..."));
PrintStatus.SetDlgItemText(AFX_IDC_PRINT_DOCNAME, strTemp);
PrintStatus.SetDlgItemText(AFX_IDC_PRINT_PRINTERNAME, pInfo->m_pPD->GetDeviceName());
PrintStatus.SetDlgItemText(AFX_IDC_PRINT_PORTNAME, pInfo->m_pPD->GetPortName());
PrintStatus.ShowWindow(SW_SHOW);
PrintStatus.UpdateWindow();
CRect rectSave = pInfo->m_rectDraw;
UINT nPageSave = pInfo->m_nCurPage;
BOOL bBlackWhiteSaved = m_pPrintOptions->m_bBlackWhitePrinting;
m_pPrintOptions->m_bBlackWhitePrinting = FALSE;
ASSERT(nPageSave > 1);
ASSERT(nPageSave >= (UINT) m_aPageStart.GetSize());
VERIFY(pDC->SaveDC() != 0);
pDC->IntersectClipRect(0, 0, 0, 0);
UINT nCurPage = (UINT) m_aPageStart.GetSize();
pInfo->m_nCurPage = nCurPage;
while (pInfo->m_nCurPage < nPageSave && pInfo->m_nCurPage <= pInfo->GetMaxPage())
{
if (pInfo->m_bPreview)
ASSERT(pInfo->m_nCurPage == (UINT) m_aPageStart.GetSize());
OnPrepareDC(pDC, pInfo);
if (!pInfo->m_bContinuePrinting)
break;
if (nVirtualPages > 1)
strTemp.Format(_T("%d [%d - %d]"),
pInfo->m_nCurPage,
1 + (pInfo->m_nCurPage / nVirtualPages),
1 + (pInfo->m_nCurPage % nVirtualPages));
else
strTemp.Format(_T("%d"), pInfo->m_nCurPage);
PrintStatus.SetDlgItemText(AFX_IDC_PRINT_PAGENUM, strTemp);
pInfo->m_rectDraw.SetRect(0, 0, pDC->GetDeviceCaps(HORZRES), pDC->GetDeviceCaps(VERTRES));
pDC->DPtoLP(&pInfo->m_rectDraw);
OnPrint(pDC, pInfo);
if (!pInfo->m_bPreview)
pInfo->m_nCurPage++;
if (pInfo->GetMaxPage() == 65535)
pInfo->SetMaxPage(max(pInfo->GetMaxPage(), pInfo->m_nCurPage));
if (!_XTPAbortProc(0, 0))
{
bAborted = TRUE;
break;
}
}
PrintStatus.DestroyWindow();
BOOL bResult = !bAborted
&& (pInfo->m_nCurPage == nPageSave || nPageSave == 65535);
pInfo->m_bContinuePrinting = bResult;
pDC->RestoreDC(-1);
m_pPrintOptions->m_bBlackWhitePrinting = bBlackWhiteSaved;
pInfo->m_nCurPage = nPageSave;
pInfo->m_rectDraw = rectSave;
ASSERT_VALID(this);
return bResult;
}
void CXTPReportView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)
{
ASSERT_VALID(this);
ASSERT_VALID(pDC);
if (!pInfo)
return;
if (!m_bPaginated)
{
int nRowCount = GetReportCtrl().GetRows()->GetCount();
int nSize = (int) m_aPageStart.GetSize();
int nPage = pInfo->m_nCurPage;
UINT nVirtualPages = (UINT) GetPaintManager()->m_arStartCol.GetSize() - 1;
UINT nVirPage(0);
if (nVirtualPages > 0)
nVirPage = 1 + m_nStartIndex;
if (nPage == 1 && nRowCount == 0) //First page?
pInfo->m_bContinuePrinting = TRUE;
else if (nVirPage > 0 && nVirPage < nVirtualPages) //not finished page
pInfo->m_bContinuePrinting = TRUE;
else if (nPage == nSize && m_aPageStart[nPage - 1] >= (UINT) nRowCount
&& m_nStartIndex >= nVirtualPages - 1) //Last page?
pInfo->m_bContinuePrinting = FALSE; // can't paginate to that page
else if (nPage > nSize
&& m_nStartIndex > nVirtualPages - 1
&& !PaginateTo(pDC, pInfo)) //Can be last page?
pInfo->m_bContinuePrinting = FALSE; // can't paginate to that page
if (pInfo->m_nCurPage > pInfo->GetMaxPage())
pInfo->m_bContinuePrinting = FALSE;
//TRACE(_T("OnPrepareDC pInfo->m_nCurPage=%d\n"), pInfo->m_nCurPage);
}
pDC->SetMapMode(MM_ANISOTROPIC);
pDC->SetViewportExt(pDC->GetDeviceCaps(LOGPIXELSX), pDC->GetDeviceCaps(LOGPIXELSY));
pDC->SetWindowExt(96, 96);
pDC->OffsetWindowOrg(0, 0);
if (pInfo->m_bPreview) //PRINT MODE in RTL does not work!
{
//------------------------------------------------------------
if (GetReportCtrl().GetExStyle() & WS_EX_RTLREADING)
pDC->SetTextAlign(TA_RTLREADING);
if (GetReportCtrl().GetExStyle() & WS_EX_LAYOUTRTL)
//if (GetReportCtrl().IsLayoutRTL())
XTPDrawHelpers()->SetContextRTL(pDC, LAYOUT_RTL);
//------------------------------------------------------------
}
}
//////////////////////////////////////////////////////////////////////////
// Clipboard operations
void CXTPReportView::OnUpdateEditCopy(CCmdUI* pCmdUI)
{
pCmdUI->Enable(GetReportCtrl().CanCopy());
}
void CXTPReportView::OnUpdateEditCut(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_bAllowCut && GetReportCtrl().CanCut());
}
void CXTPReportView::OnUpdateEditPaste(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_bAllowPaste && GetReportCtrl().CanPaste());
}
void CXTPReportView::OnEditCut()
{
if (m_bAllowCut) GetReportCtrl().Cut();
}
void CXTPReportView::OnEditCopy()
{
GetReportCtrl().Copy();
}
void CXTPReportView::OnEditPaste()
{
if (m_bAllowPaste) GetReportCtrl().Paste();
}
void CXTPReportView::OnFilePageSetup()
{
DWORD dwFlags = PSD_MARGINS | PSD_INWININIINTLMEASURE;
CXTPReportPageSetupDialog dlgPageSetup(GetPrintOptions(), dwFlags, this);
XTPGetPrinterDeviceDefaults(dlgPageSetup.m_psd.hDevMode, dlgPageSetup.m_psd.hDevNames);
int nDlgRes = (int) dlgPageSetup.DoModal();
if (nDlgRes == IDOK)
AfxGetApp()->SelectPrinter(dlgPageSetup.m_psd.hDevNames, dlgPageSetup.m_psd.hDevMode, FALSE);
}