VC打印實戰(zhàn)淺談
發(fā)表時間:2023-07-29 來源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]經(jīng)常看到VC論壇中一些朋友問關(guān)于打印的問題,好多是問過好多遍的,其實搜索一下原來的帖子可以找到好多,而且都是給了正確的解決方法的。但我搜了一下文檔中心,發(fā)現(xiàn)好象關(guān)于一下我要講的內(nèi)容的還沒有。所以我決...
經(jīng)?吹絍C論壇中一些朋友問關(guān)于打印的問題,好多是問過好多遍的,其實搜索一下原來的帖子可以找到好多,而且都是給了正確的解決方法的。但我搜了一下文檔中心,發(fā)現(xiàn)好象關(guān)于一下我要講的內(nèi)容的還沒有。所以我決定把自己在做程序時遇到的問題,及實現(xiàn)方法和心得體會寫下來,重在交流。文中如有疏漏之處,請各位朋友及時指出,以免我落個誤人誤己的下場。
在做打印模塊時,經(jīng)常會出于不同的目的改變打印機的默認配置。對于打印機配置最重要的一個結(jié)構(gòu)就是DEVMODE結(jié)構(gòu)(結(jié)構(gòu)的具體構(gòu)成請MSDN),該結(jié)構(gòu)中幾乎包含了打印機的所有配置信息。下面將給出幾個經(jīng)常要用到的配置項的實現(xiàn)。
PRINTDLG pd; //該結(jié)構(gòu)包含打印對話框中的所有信息
LPDEVMODE lpDevMode;
if(AfxGetApp()->GetPrinterDeviceDefaults(&pd)) //獲得默認的打印機的信息
{
lpDevMode=(LPDEVMODE)GlobalLock(pd.hDevMode);
if(lpDevMode)
{
lpDevMode->dmPaperSize=DMPAPER_A4; //將打印紙設(shè)置為A4
lpDevMode->dmOrientation=DMORIENT_LANDSCAPE; //將打印機設(shè)置為橫向打印。
lpDevMode->dmPrintQuality=600 //打印分辨率為600dpi
}
GlobalUnlock(pd.hDevMode);
}
其實,看看MSDN中DEVMODE結(jié)構(gòu)的文檔,套用上面這個模式,你就可以隨便配置你的打印機了。如果你想配置完成后,還為用戶顯示打印對話框的話?梢詫d替換為printDlg.m_pd,當(dāng)然你要事先定義printDlg。實現(xiàn)語言為“CPrintDialog printDlg(FALSE);”。
下面要講的內(nèi)容才是我要寫本文的初衷,這是我剛剛解決的問題,在網(wǎng)上貼帖子沒有人能回答的出,所以將它寫出來同各位朋友共享。
我寫的打印程序,在我的機器上打印正常,可是到了某些機器上打印就不正常了,打印的字體比我的大,整個版面都亂了。這下我可給搞糊涂了,同是一臺打印機,程序中我也設(shè)置了映射模式為MM_TEXT,怎么可能出現(xiàn)這種情況呢?后來同事發(fā)現(xiàn)了問題的所在,因為打印時采用的分辨率不同。由于我們不同的機器上裝的是不同版本的打印驅(qū)動程序,他們默認的打印分辨率也不相同。我的機器上的打印驅(qū)動默認的是1200dpi的分辨率,而出問題的打印機的分辨率為600dpi。所以打出來的字體比原來大了兩倍。下面我來分析一下原因:
WINDOWS中的字體的高度,寬度是用邏輯單元(Logical units)來表示的,邏輯單元本身并不是一種長度單位。但字體可以通過它按照一定的映射模式,經(jīng)過計算后顯示在不同的設(shè)備終端上。比如:有一個高為240個邏輯單元的字體,系統(tǒng)的映射模式為MM_TEXT(即一個邏輯單元對應(yīng)一個設(shè)備像素),那么字體在屏幕的輸出為240個像素高,如果換為其他的映射模式那么它就會在屏幕輸出不同的大小。如果我們改變了顯示器的分辨率,將它的分辨率調(diào)高,相應(yīng)的每個像素大小就會變小。那么再按照MM_TEXT映射模式,將字體顯示在顯示器上,那么此時字體也會比剛才看著小。
同樣,這中情況也適于打印機,打印機的設(shè)備像素是點。1200dpi表示打印機每英寸可以打1200個點。600dpi表示每英寸可以打600個點。顯然對于任何字體,在分辨率為600dpi的打印機上打印的大小是在1200dpi分辨率打印機上打印大小的兩倍。所以為了處理這個問題我設(shè)置了一個打印系數(shù),對于所有的打印排版所用的
參數(shù)都乘以這個系數(shù),這樣問題就迎刃而解了。下面是得到打印系數(shù)的實現(xiàn):
#define PRINT_DPI_DEFAULT 1200 //我調(diào)好的程序分辨率為1200dpi
m_fXCoefficient=1;//初始化打印系數(shù)
PRINTDLG pd;
LPDEVMODE lpDevMode;
double fXDPI=PRINT_DPI_DEFAULT; //
CPrintDialog printDlg(FALSE);
if(AfxGetApp()->GetPrinterDeviceDefaults(&pd))
{
lpDevMode=(LPDEVMODE)GlobalLock(pd.hDevMode);
if(lpDevMode)
{
lpDevMode->dmPaperSize=DMPAPER_A4;
}
GlobalUnlock(pd.hDevMode);
}
printDlg.m_pd.hDevMode=pd.hDevMode;
if (printDlg.DoModal() == IDCANCEL)
return;
fXDPI=(double)lpDevMode->dmPrintQuality;
if(fXDPI>0)
{
m_fXCoefficient=fXDPI/PRINT_DPI_DEFAULT;
}