📄 preview.cpp
字号:
this->DrawFrame(pDC);
this->DrawSelectRect(pDC);
this->DrawPrint(pDC);
}
BOOL CPreView::SetPrintView(CMyView *pPrintView)
{
ASSERT_VALID(pPrintView);
m_pPrintView = pPrintView;
// allocate preview info
m_pPreviewInfo = new CPrintInfo;
m_pPreviewInfo->m_pPD->SetHelpID(AFX_IDD_PRINTSETUP);
m_pPreviewInfo->m_pPD->m_pd.Flags |= PD_PRINTSETUP;
m_pPreviewInfo->m_pPD->m_pd.Flags &= ~PD_RETURNDC;
m_pPreviewInfo->m_bPreview = TRUE; // signal that this is preview
ASSERT(m_pPreviewInfo->m_pPD != NULL);
m_pPreviewDC = new CPreviewDC; // must be created before any
// possible error returns
if(!m_pPrintView->OnPreparePrinting(m_pPreviewInfo))
return FALSE;
#ifdef _DEBUG
if (m_pPreviewInfo->m_pPD->m_pd.hDC == NULL)
{
TRACE0("Error: hDC not set for printing --\n");
TRACE0("\tDid you remember to call DoPreparePrinting?\n");
ASSERT(FALSE); // common mistake gets trapped here
}
#endif //_DEBUG
// 得到打印机相关的CDC
m_dcPrint.Attach(m_pPreviewInfo->m_pPD->m_pd.hDC);
m_pPreviewDC->SetAttribDC(m_pPreviewInfo->m_pPD->m_pd.hDC);
m_pPreviewDC->m_bPrinting = TRUE; // CDC::m_bPrinting
m_dcPrint.m_bPrinting = TRUE;
// m_dcPrint.SaveDC(); // Save pristine state of DC
//
//在用户Override OnBeginPrinting函数时起作用
//
HDC hDC = ::GetDC(m_hWnd);
m_pPreviewDC->SetOutputDC(hDC);
m_pPrintView->OnBeginPrinting(m_pPreviewDC, m_pPreviewInfo);
m_pPreviewDC->ReleaseOutputDC();
::ReleaseDC(m_hWnd, hDC);
// most recently saved device context is restored.
// m_dcPrint.RestoreDC(-1);
this->m_sizePhysicalPage.cx=m_dcPrint.GetDeviceCaps(PHYSICALWIDTH);
this->m_sizePhysicalPage.cy=m_dcPrint.GetDeviceCaps(PHYSICALHEIGHT);
m_nCurrentPage=this->m_pPreviewInfo->GetMinPage();
return TRUE;
}
//pagenumber, row , column base on 0
int CPreView::GetPageNumber(int row, int column)
{
if((row<0&&row>=m_nRows)||
(column<0&&column>=this->m_nColumns))
{
MessageBox("行列数不对","错误!");
return -1;
}
return (column+(row)*m_nColumns);
}
void CPreView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
this->RefreshPreview();
}
// CPoint(this->m_rectClient.Width()/2-this->m_nColumns*this->m_rectPage.Width()/2,
// this->m_rectClient.Height()/2-this->m_nRows*this->m_rectPage.Height()/2);m_rectShowPages
void CPreView::SetPagePosition()
{
CPoint ptLeftTopPage1=
CPoint(this->m_rectClient.Width()/2-this->m_nColumns*this->m_rectPage.Width()/2,
this->m_rectClient.Height()/2-this->m_nRows*this->m_rectPage.Height()/2);
this->m_rectPage.OffsetRect(ptLeftTopPage1-m_rectPage.TopLeft());
this->m_rectDisplayPage1=m_rectPage;
m_rectDisplayPage1.right-=this->m_iSpaceBetweenl2*2;
m_rectDisplayPage1.bottom-=m_iSpaceBetweenl2*2;
m_rectDisplayPage1.OffsetRect(m_iSpaceBetweenl2,m_iSpaceBetweenl2);
}
//开始进行比例显示的计算工作
void CPreView::BeginScale(int scale)
{
CString str;
str.Format("%d",scale);
this->m_pToolBar->GetDlgItem(IDC_EDIT_SCALE)->SetWindowText(str);
this->m_iScale=scale;
this->SetScale(scale);
this->m_nColumns=this->m_rectShowPages.Width()/m_rectPage.Width();
this->m_nRows =this->m_rectShowPages.Height()/m_rectPage.Height();
if(!m_nColumns)m_nColumns=1;
if(!m_nRows) m_nRows=1;
str.Format("%d",m_nRows);
this->m_pToolBar->GetDlgItem(IDC_EDIT_ROWS)->SetWindowText(str);
str.Format("%d",m_nColumns);
this->m_pToolBar->GetDlgItem(IDC_EDIT_COLUMNS)->SetWindowText(str);
this->SetPagePosition();
this->m_opState=OP_SCALE_ING;
if(this->m_rectDisplayPage1.top<this->m_rectClient.top||
m_rectDisplayPage1.bottom>m_rectClient.bottom)
{
this->SetScrollSizes(MM_TEXT,
CSize(this->m_rectDisplayPage1.Width(),this->m_rectDisplayPage1.Height()),
CSize(this->m_rectShowPages.Width(),m_rectShowPages.Height())
);
this->SetScrollPos(SB_VERT,0);
this->SetScrollPos(SB_HORZ,0);
}
else{
this->SetMultiPageScroll();
}
this->Invalidate();
}
void CPreView::OnGetRowColumn()
{
CString str1,str2;int rows;int columns;
try{
this->m_pToolBar->GetDlgItem(IDC_EDIT_ROWS)->GetWindowText(str1);
if(str1=="")return;
rows=atoi(str1);
this->m_pToolBar->GetDlgItem(IDC_EDIT_COLUMNS)->GetWindowText(str2);
if(str2=="")return;
columns=atoi(str2);
}
catch(...)
{
return;
}
if(rows==this->m_nRows&&columns==this->m_nColumns)return;
if(rows<0||columns<0||rows>50||columns>50){
MessageBox("错误的行列数","错误");
return ;
}
afxDump<<"\n m_nMaxRows"<<m_nMaxRows;
afxDump<<"\n m_nMaxColumns"<<m_nMaxColumns;
if(rows>this->m_nMaxRows||columns>this->m_nMaxColumns)
{
MessageBox("请减小行列数,以保证放大比例大于10%","注意!");
return ;
}
m_nUserRows=rows;
m_nUserColumns=columns;
this->BeginRowColumn(rows,columns);
}
void CPreView::BeginRowColumn(int rows,int columns)
{
while(rows>this->m_nMaxRows)rows--;
while(columns>this->m_nMaxColumns)columns--;
this->m_nColumns=columns;
this->m_nRows=rows;
CString str;
str.Format("%d",m_nRows);
this->m_pToolBar->GetDlgItem(IDC_EDIT_ROWS)->SetWindowText(str);
str.Format("%d",m_nColumns);
this->m_pToolBar->GetDlgItem(IDC_EDIT_COLUMNS)->SetWindowText(str);
//确定物理映射比例,逻辑映射比例
//计算:
// m_nMaxColumns/columns <> m_nMaxRows/rows;
//
//在指定的行列数下,确定可以用来显示的页的大小
//物理(像素)比:m_sizePhysicalPage.cx/this->m_rectDisplayPage1.Width();
//m_rectShowPages.Width()/columns*m_sizePhysicalPage.cy
//m_rectShowPages.Height()/rows*m_sizePhysicalPage.cx
int yPage,xPage;
if((float)m_rectShowPages.Width()*rows*m_sizePhysicalPage.cy>
(float)m_rectShowPages.Height()*columns*m_sizePhysicalPage.cx)
// if(m_nMaxColumns*rows>m_nMaxRows*columns)//按行计算;
{
yPage=m_rectShowPages.Height()/rows; //页空间高
xPage=MulDiv(yPage, this->m_sizePhysicalPage.cx,this->m_sizePhysicalPage.cy);
}
else //a
{
xPage=m_rectShowPages.Width()/columns; //页空间宽
yPage=MulDiv(xPage, this->m_sizePhysicalPage.cy,this->m_sizePhysicalPage.cx);
}
this->m_rectPage.SetRect(CPoint(0,0),CPoint(xPage,yPage));
// 空白的计算公式:
//
// (xDisplayPage+yDisplayPage)+4*m_iSpaceBetweenl2=xPage+yPage;
// m_iSpaceBetweenl2=(xDisplayPage+yDisplayPage)/mc_iPageHW7Between
//
this->m_iSpaceBetweenl2=(xPage+yPage)/(this->mc_iPageHW7Between+4);
this->SetPagePosition();
int scale=m_rectDisplayPage1.Width()*100/MulDiv(m_sizePhysicalPage.cx,afxData.cxPixelsPerInch,
::GetDeviceCaps(this->m_pPreviewDC->m_hAttribDC, LOGPIXELSX));
// afxDump<<"\n BeginRowColumn(int rows,int columns) scale="<<scale;
if(scale<10)
{
scale=10;
}
str.Format("%d",scale);
this->m_pToolBar->GetDlgItem(IDC_EDIT_SCALE)->SetWindowText(str);
this->m_iScale=scale;
this->SetScale(scale);
this->SetPagePosition();
m_opState=OP_ROWCOLUMN_ING;
SetMultiPageScroll();
this->Invalidate();
}
bool CPreView::FindPageRect(CPoint &point, int &row, int &column)
{
CRect DisplayPage=m_rectDisplayPage1;
CSize offset;int i;int j;
for(i=0;i<this->m_nRows;i++)
{
for(j=0;j<this->m_nColumns;j++)
{
offset=CSize(this->m_rectPage.Width()*j,this->m_rectPage.Height()*i);
DisplayPage.OffsetRect(offset);
if(DisplayPage.PtInRect(point))
{
row=i;
column=j;
int page=this->m_nCurrentPage+row*m_nColumns+column;
if(page>this->m_pPreviewInfo->GetMaxPage())return false;
return true;
}
DisplayPage=m_rectDisplayPage1;
}
}
return false;
}
void CPreView::RefreshPreview()
{
this->GetClientRect(&m_rectClient);
this->m_rectShowPages=m_rectClient;
m_rectShowPages.right-=this->mc_iMargin;
m_rectShowPages.bottom-=this->mc_iMargin;
m_rectShowPages.left+=this->mc_iMargin;
m_rectShowPages.top+=this->mc_iMargin;
//确定在这个打印机页面下可显示的最大行,列数,(放大比为10:100)
if(m_pPreviewDC!=NULL)
{
this->SetScale(10);
m_nMaxColumns=this->m_rectShowPages.Width()/m_rectPage.Width();
m_nMaxRows=this->m_rectShowPages.Height()/m_rectPage.Height();
if(!m_nMaxColumns)m_nMaxColumns=1;
if(!m_nMaxRows) m_nMaxRows=1;
if(this->IsWindowVisible())
{
if(m_opState==OP_SCALE_ING)
this->BeginScale(this->m_iScale);
else if(m_opState==OP_SELECTED_ING)
{
this->BeginScale(this->m_psPageSelected.m_nZoomInScale);
this->m_opState=OP_SELECTED_ING;
}
else
this->BeginRowColumn(m_nUserRows,m_nUserColumns);
}
}
}
void CPreView::SetCurrentPage(int nPage)
{
if(nPage<0)nPage=0;
if (nPage > m_pPreviewInfo->GetMaxPage())
nPage=m_pPreviewInfo->GetMaxPage();
if (nPage < m_pPreviewInfo->GetMinPage())
nPage = m_pPreviewInfo->GetMinPage();
if(m_nCurrentPage==nPage)
return;
m_nCurrentPage = nPage;
if(m_nCurrentPage>m_iMaxCurPage+m_pPreviewInfo->GetMaxPage())m_nCurrentPage=m_iMaxCurPage;
SetScrollPos(SB_VERT, ((m_nCurrentPage-m_pPreviewInfo->GetMinPage())/this->m_nColumns)*this->m_rectClient.Height());
Invalidate(TRUE);
}
void CPreView::DrawFrame(CDC *pDC)
{
//设定笔的颜色;
CSize offset;int i;int j;
CPen rectPen;
CPen shadowPen;
rectPen.CreatePen(PS_ENDCAP_FLAT|PS_STYLE_MASK, 1, GetSysColor(COLOR_WINDOWFRAME));
shadowPen.CreatePen(PS_ENDCAP_FLAT , 2, GetSysColor(COLOR_WINDOWFRAME));//COLOR_BTNSHADOW
CRect DisplayPage=m_rectDisplayPage1;
int SaveDC=pDC->SaveDC();
for(i=0;i<this->m_nRows;i++)
{
for(j=0;j<this->m_nColumns;j++)
{
UINT page=this->m_nCurrentPage+this->GetPageNumber(i,j);
if(page>this->m_pPreviewInfo->GetMaxPage())
return;
offset=CSize(this->m_rectPage.Width()*j,this->m_rectPage.Height()*i);
DisplayPage.OffsetRect(offset);
pDC->SelectStockObject(HOLLOW_BRUSH);
//画显示页的边框
pDC->SelectObject(&rectPen);
DisplayPage=DisplayPage+CRect(1,1,1,1);
pDC->Rectangle(DisplayPage);
//画显示页的右下阴影
DisplayPage=DisplayPage+CRect(-1,-1,-1,-1);
DisplayPage.OffsetRect(2,2);
pDC->SelectObject(&shadowPen);
pDC->Rectangle(DisplayPage);
DisplayPage.OffsetRect(-2,-2);
//白板
::FillRect(pDC->m_hDC, DisplayPage, (HBRUSH)GetStockObject(WHITE_BRUSH));
DisplayPage=m_rectDisplayPage1;
}
}
pDC->RestoreDC(-1); // restore to synchronized state
}
void CPreView::DrawSelectRect(CDC *pDC)
{
CRect DisplayPage=m_rectDisplayPage1;
CSize offset;
if(m_psPageSelected.m_bSelected&&
this->m_nCurrentPage<=this->m_psPageSelected.m_nPageNumber&&
(m_psPageSelected.m_nPageNumber-m_nCurrentPage)<m_nRows*m_nColumns)
{
int row=(m_psPageSelected .m_nPageNumber-m_nCurrentPage)/m_nColumns;
int column=(m_psPageSelected.m_nPageNumber-m_nCurrentPage)%m_nColumns;
DisplayPage=m_rectDisplayPage1;
offset=CSize(this->m_rectPage.Width()*column,
this->m_rectPage.Height()*row);
DisplayPage.OffsetRect(offset);
DisplayPage=DisplayPage+CRect(1,1,1,1);
pDC->Draw3dRect(&DisplayPage,RGB(254,254,254),RGB(254,254,254));
}
}
void CPreView::DrawPrint(CDC *pDC)
{
CSize offset;int i;int j;
int nSavedState;
CSize PrintOffset(0,0);
const CPoint ptTopLeftDisplayPage1=m_rectDisplayPage1.TopLeft();
CPoint ptTopLeftCurPage=ptTopLeftDisplayPage1;
for(i=0;i<this->m_nRows;i++)
{
for(j=0;j<this->m_nColumns;j++)
{
UINT page=this->GetPageNumber(i,j);
if(page>this->m_pPreviewInfo->GetMaxPage())
return;
nSavedState = m_dcPrint.SaveDC(); // Save pristine state of DC
m_pPreviewDC->SetOutputDC(pDC->GetSafeHdc());
m_pPreviewInfo->m_nCurPage = m_nCurrentPage + page;
if (m_nCurrentPage + page <= m_pPreviewInfo->GetMaxPage())
m_pPrintView->OnPrepareDC(m_pPreviewDC, m_pPreviewInfo);
m_pPreviewInfo->m_rectDraw.SetRect(0, 0,
m_pPreviewDC->GetDeviceCaps(HORZRES), //HORZRES得到当前View的长宽信息
m_pPreviewDC->GetDeviceCaps(VERTRES));//VERTREScxPixelsPerInch
m_pPreviewDC->DPtoLP(&m_pPreviewInfo->m_rectDraw);
if (!m_pPreviewInfo->m_bContinuePrinting ||
m_nCurrentPage + page > m_pPreviewInfo->GetMaxPage())
{
m_pPreviewDC->ReleaseOutputDC();
m_dcPrint.RestoreDC(nSavedState); // restore to untouched state
return;
}
//得到打印机页的MARGIN
PrintOffset=CPoint(0,0);
VERIFY(m_pPreviewDC->Escape(GETPRINTINGOFFSET, 0, NULL, (LPVOID)&PrintOffset));
m_pPreviewDC->PrinterDPtoScreenDP((LPPOINT)&PrintOffset);
offset=CSize(this->m_rectPage.Width()*j,this->m_rectPage.Height()*i);
ptTopLeftCurPage.Offset(offset);
PrintOffset += (CSize)ptTopLeftCurPage;
//设置打印显示页viewport
m_pPreviewDC->SetTopLeftOffset(PrintOffset);
m_pPreviewDC->ClipToPage();
m_pPrintView->OnPrint(m_pPreviewDC, m_pPreviewInfo);
m_pPreviewDC->ReleaseOutputDC();
m_dcPrint.RestoreDC(nSavedState); // restore to untouched state
ptTopLeftCurPage=ptTopLeftDisplayPage1;
}
}
}
void CPreView::SetSinglePageScroll(CDC *pDC)
{
CPoint ViewportOrg = pDC->GetViewportOrg();//用旧的视角原点初始化该变量;
CPoint ptLeftTopPage1=this->m_rectPage.TopLeft();
if(this->m_rectDisplayPage1.top<this->m_rectClient.top||
m_rectDisplayPage1.bottom>m_rectClient.bottom)
{
ViewportOrg += -GetDeviceScrollPosition();
m_rectDisplayPage1.OffsetRect(-m_rectDisplayPage1.TopLeft().x,
-m_rectDisplayPage1.TopLeft().y);
if(m_rectDisplayPage1.Width()<this->m_rectClient.Width())
{
int i=(m_rectClient.Width()-m_rectDisplayPage1.Width())/2;
m_rectDisplayPage1.OffsetRect(i,0);
}
m_rectDisplayPage1.OffsetRect(ViewportOrg);
}
}
void CPreView::SetMultiPageScroll()
{
int min=1;
int max=(m_pPreviewInfo->GetMaxPage()-m_pPreviewInfo->GetMinPage()+1)/this->m_nColumns;
int yu=((m_pPreviewInfo->GetMaxPage()-m_pPreviewInfo->GetMinPage()+1)%this->m_nColumns)?1:0;
max+=yu;
max=max-this->m_nRows+1;
this->m_iMaxCurPage=(max-1)*m_nColumns+m_pPreviewInfo->GetMinPage();
if(max<1)max=1;
this->SetScrollSizes(MM_TEXT,CSize(0,
(max)*this->m_rectClient.Height()),
CSize(10,m_rectClient.Height()*m_nRows)
,CSize(5,m_rectClient.Height()));
if(max<2)
{
SetScrollPos(SB_VERT, 0);
m_nCurrentPage=m_pPreviewInfo->GetMinPage();
}
else
SetScrollPos(SB_VERT,((m_nCurrentPage-m_pPreviewInfo->GetMinPage())/this->m_nColumns)*this->m_rectClient.Height());
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -