VC++6.0中用應用向導生成新程序時,可以在應用向導Step4對話框中選擇Printing and Print preview選擇包括了基本打印和打印預覽支持。但這些打印功能在MM_TEXT模式下打印出的文件尺寸大小發生了變化,比屏幕上顯示的小得多。
我們在VC++中實現繪圖時最方便、最常用的繪圖模式為MM_TEXT。如何對打印輸出進行有效的控制?尤其是在GIS中,是我們經常所面臨的問題。筆者通過實踐,提出了自己的做法,再此與廣大讀者共同探討。
首先明確的是在MM_TEXT模式下很難實現象素坐標與常用的長度單位(如毫米)的轉換關系,因此有必要對繪圖模式進行改變,同時不能影響以前的工作。筆者的模式設置為SetMapMode(MM_LOMETRIC),屏幕顯示模式為SetMapMode(MM_TEXT),對繪圖顯示函數DrawVectorMap(const char *MapFile)進行重載為DrawVectorMap(const char *MapFile,CDC* pDC),為打印輸出傳遞pDC指針,在重載函數中進行坐標變換為:
void CBoundaryView::DrawVectorMap(const char *MapFile,CDC* pDC)
{ …………………….
for(i=0;i<(int)m4;i++)
{
fread(&xn[i],4,1,fp); fread(&yn[i],4,1,fp);
//地圖打印****坐標變換
xn[i]=(float)((xn[i]-printstartx)*print_scale+page_left*100.0)//在MM_TEXT下
//每個單位為0.01cm;
yn[i]=(float)((yn[i]-printstarty)*print_scale-map_heigh*100-page_up*100.0);
}
}
其中printstartx 、printstarty 為設定的輸出原點坐標,print_scale 、map_heigh、page_left、page_up分別為打印比例、打印圖高、打印圖距圖紙原點的左、上邊距。完成此工作後就可以進行打印控制。
一、圖幅尺寸與邊距控制
生成圖幅設置對話框類,設置對話框為CmapSetup,實現尺寸控制。
void CBoundaryView::OnPrintMapsetup() //圖幅設置(對話框參數)
{
// TODO: Add your command handler code here
CMapSetup mapsizesetup; //圖幅設置(對話框參數)
//對話框初始化///////////////////////////
……………………………
/////////////////////////////////////////
mapsizesetup.DoModal();
map_wide=mapsizesetup.m_Page1.m_mapwide;
page_up=mapsizesetup.m_Page2.m_pageup;
page_left=mapsizesetup.m_Page2.m_pageleft;
}
根據圖幅寬度計算圖幅高度;
BOOL CBoundaryView::OnPreparePrinting(CPrintInfo* pInfo)
{
xwide=(int)(map_wide*10.0);//圖幅尺寸(mm)
if(!print_selection)//全圖打印
{
map_heigh=map_wide*((ymax-ymin)/(xmax-xmin));//(cm)
}
else if(print_selection)//選擇區域打印
{ //計算圖幅高度
map_heigh=map_wide*(print_y1-print_y2)/(print_x2-print_x1);//(cm)
}
yhigh=(int)(map_heigh*10.0);
return DoPreparePrinting(pInfo);
}
二、分頁控制
分頁方法為從左至右,從上到下;
void CBoundaryView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
{
// 獲取頁面高、寬
mpageheight=pDC->GetDeviceCaps(VERTSIZE);//單位為毫米
mpagewidth=pDC->GetDeviceCaps(HORZSIZE);
xpage=mpagewidth;
ypage=mpageheight;
//計算打印頁數
npagex=(int)xwide/xpage+(xwide>xpage*(int)(xwide/xpage));
npagey=(int)yhigh/ypage+(yhigh>ypage*(int)(yhigh/ypage));
npage=npagex*npagey;
pInfo->SetMinPage(1);
pInfo->SetMaxPage(npage);
}
計算每頁的打印原點
void CBoundaryView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)
{
// TODO: Add your specialized code here and/or call the base class
int nrow,ncol;
if(pInfo==NULL)
return;
ncol=(pInfo->m_nCurPage-1)%npagex+1;//列位置
if(pInfo->m_nCurPage%npagex==0)
nrow=pInfo->m_nCurPage/npagex;
else
nrow=pInfo->m_nCurPage/npagex+1;//行位置
//////////////////////////////////////計算打印起始點坐標
if(!print_selection)//全圖打印
{
printstartx=xmin+(float)((ncol-1)*(double)((xmax-xmin)/(float)npagex));//獲取打
//印起始點坐標
printstarty=ymin-(float)((nrow-1)*(double)((ymax-ymin)/(float)npagey));
}//xmin、ymin為全圖的最小坐標,xmax、ymax為全圖的最大坐標
else if(print_selection)//選擇區域打印輸出
{ //計算打印起始點坐標
printstartx=print_x1+(float)((ncol-1)*(double)((print_x2-print_x1)/(float)npagex));
printstarty=print_y2-(float)((nrow-1)*(double)((print_y1-print_y2)/(float)npagey));
}// print_x1、print_y2為選擇區域的最小坐標,print_x2、print_y1為選擇區域的最
//大坐標
CView::OnPrepareDC(pDC, pInfo);
}
三、屏幕選擇區域、全圖打印
定義選擇區域打印函數
void CBoundaryView::OnPrintSelection() //選擇區域打印
{
draw_selection=1; //選擇區域打印標志
………………………
print_selection=1;//設置為選擇打印
}
通過撲獲鼠標信息獲取選擇區域的最小、最大坐標,經坐標變換得到print_x1、print_y2、print_x2、print_y1,利用裁剪函數進行圖幅裁剪,將裁剪區域進行輸出,這裡不在贅述。
屏幕選擇區域、全圖打印通過OnDraw(CDC* pDC)來實現,具體定義如下:
void CBoundaryView::OnDraw(CDC* pDC)
{
…………………………
if(pDC->IsPrinting())
{
pDC->SetMapMode(MM_LOMETRIC);
print_flag=1; //打印標志
if(!print_selection)//全圖輸出時
{ //因為1個單位為0.01厘米
print_scale=(float)(100.0*map_wide/(xmax-xmin));//坐標變換比例
}
else if(print_selection) //選擇區域打印時
{
print_scale=(float)(100.0*map_wide/(print_x2-print_x1));
}
}
else //非打印時
{
print_scale=1;
print_flag=0;
}
…………………………
if(print_flag==0)
{
DrawVectorMap(const char *MapFile);
}
else if(print_flag==1) //打印輸出時
{
DrawVectorMap(const char *MapFile,CDC* pDC);
}
……………………
}
打印結束後,恢復屏幕視圖
void CBoundaryView::OnEndPrinting(CDC* pDC, CPrintInfo* pInfo)
{
DrawVectorMap(const char *MapFile);//恢復當前屏幕
InvalidateRect(NULL,TRUE);
print_flag=0;
print_selection=0;
…………………