MFC列印和列印預覽

2022-09-02 13:51:04 字數 2917 閱讀 5291

**

mfc提供了乙個框架性的列印和列印預覽功能**,它的基本思想是將實際顯示和列印文件的**合二為一,即都由此文件關聯的cview中的ondraw(cdc *pdc)來處理,由mfc框架根據使用者的操作來決定傳進來的pdc是指向螢幕還是印表機,當pdc指向螢幕裝置,就在螢幕上顯示文件,當指向印表機裝置時就列印文件。這些都很好理解,但是,當我們要列印預覽時,傳進來的pdc就有些特別了。因為列印預覽是在螢幕上進行的,所以通常我們會認為這時傳進來的pdc一定也是屬於螢幕dc一類的。但是其實不然,這個pdc是根據當前預設的印表機的屬性來構造的。舉個例子,我的計算機上安裝了乙個印表機,它的預設列印紙是a4大小(210mm x 297mm),而它的預設解析度是1200dpi。當列印預覽時cview::ondraw函式中的pdc指向的就是那個用來預覽輸出的dc,現在我們呼叫pdc->getdevicecaps(horzsize),pdc->getdevicecaps(vertsize),這兩個函式用來取得dc顯示區域的大小,以公釐為單位,得到的返回值為210和297,這恰好就是a4紙的大小。接著再呼叫pdc->getdevicecaps(horzres),pdc->getdevicecaps(vertres),這兩個呼叫返回的也是dc顯示區域的大小,不過單位是象素(或者說是點dot),得到的值是9917和14031。讓我們看看這兩個值與上面的210和297有什麼關係。1英吋等於25.4公釐,那麼210公釐的長度按照1200dpi的解析度能容納多少點?當然是210/25.4×1200,算算看等於多少?沒錯,就是9917左右(實際是9921.259……),同樣可以將297換算成14031。

現在來看看另外乙個問題。當我們用memdc.createcompatibledc(pdc)來建立乙個與pdc相容的記憶體dc時,呼叫getdevicecaps(horzsize)等函式得到的值是否與pdc的一樣呢?答案是不一樣。對記憶體dc呼叫上述4個函式得到的值分別是320和240(windows一般固定返回這兩個數值),1024和768(這正是螢幕的解析度)。假如pdc的對映模式是mm_lometric,那麼memdc的對映模式會和它一樣嗎?還是不一樣。memdc在剛建立的時候對映模式就是預設的mm_text,而不會和pdc一樣。那麼當執行如下操作:pdc->setmapmode(mm_lometric);memdc.setmapmode(mm_lometric);後,對同乙個crect進行dptolp,或者lptodp得到的結果一樣嗎?仍然不一樣,為什麼對映模式相同了,座標轉換的結果還是不一樣?

我們來弄清楚windows的對映模式到底怎麼一回事。對於dc來說有兩個區域,乙個叫「視口」(viewport),乙個叫「視窗」(window,與普通的顯示出的視窗不一樣,只是乙個概念)。你可以把「視窗」想象成乙個邏輯上的繪圖區域,而所謂的邏輯座標系就是基於「視窗」的。假設以dc的(0,0)點為左上頂點畫乙個20×20的矩形,你就可以把它理解成在「視窗」中畫的,可是度量單位是什麼呢?那就要根據dc的當前對映模式來定了,比如現在的模式是mm_lometric,那麼單位就是0.1mm,也就是我們在這個dc上畫了乙個2mm×2mm大小的矩形。「視口」是乙個與實際顯示裝置緊密相連的概念,它對應著實際的輸出區域,裝置座標系就是基於它的,而度量單位則永遠是象素。dc根據視口和視窗的屬性產生一種規則保證把乙個視窗恰好對映為乙個視口。待我們真正要顯示或列印圖形的時候,dc實際上用這種規則把window座標(邏輯座標)對映為viewport座標(裝置座標)進行輸出,至於dc會把2mm的線段轉換為多少象素長的線段,我們無需關心,windows自會料理一切。cdc分別提供getviewportorg(),getwindoworg()來取得viewport和window的原點座標(相對於乙個假想的中立的座標系),還有getviewportext(),getwindowext()來取得viewport和window大小(分別基於他們各自的度量單位)。那麼dptolp和lptodp到底做了些什麼呢?其實很簡單,拿lptodp來說就是執行了這樣乙個運算:

xviewport=(xwindow-oxwindow)×cxviewport/cxwindow+oxviewport

yviewport=(ywindow-oywindow)×cyviewport/cywindow+oyviewport

而dptolp則是上述運算的逆運算。還拿剛才的pdc,memdc來說,對映模式都是mm_lometric,列印設定不變。對pdc呼叫getviewportorg等函式得到viewport原點為(0,0),大小為9917×-14031象素(沒錯,是負的,因為mm_lometric下y軸方向朝上),window原點為(0,0),大小為2099×2970(0.1mm);同樣得到memdc的viewport原點為(0,0),大小為1024×-768象素,window原點為(0,0),大小為3200×2400(0.1mm)。這就可以解釋pdc和memdc的座標轉換為什麼不同了。  

·          

·          

int xlogpixperinch = pdc-> getdevicecaps(logpixelsx);

int ylogpixperinch = pdc- >getdevicecaps(logpixelsy);

//得到裝置座標和邏輯座標的比例

long xext = (long)size.cx * xlogpixperinch/96 ;

long yext = (long)size.cy * ylogpixperinch/96 ;

pdc->setviewportext((int)xext, (int)yext);

//確定視口大小 }

如上所示,首先將座標對映方式改變為mm_anisotropic方式,即各向異性的意思,在這種座標方式下,x軸和y軸的邏輯單位可以進行任意的縮放。改變座標對映方式後,就要確定視窗大小和視口大小,注意視窗大小就是我們在螢幕上所見的尺寸,而視口大小則是實際裝置,如印表機等,和顯示器裝置每邏輯英吋的象素數量比較所得的比例尺寸。通過函式得到顯示器和印表機每邏輯英吋的象素數量,然後對視口大小進行相應的縮放,就可以使得螢幕上的顯示和印表機的輸出是一致的了。

這樣,只通過幾行簡單的**,我們就實現了所見即所得的列印。

DataGrid的列印預覽和列印

using system using system.drawing using system.collections using system.componentmodel using system.windows.forms using system.data using system.data....

JavaScript 實現列印,列印預覽,列印設定

一 webbrowser控制項 二 webbrowder控制項的方法 列印 webbrowser1.execwb 6,1 列印設定 webbrowser1.execwb 8,1 列印預覽 webbrowser1.execwb 7,1 關於這個元件還有其他的用法,列舉如下 webbrowser.exe...

js實現列印 列印預覽 列印設定

一 webbrowser控制項 二 webbrowder控制項的方法 列印 webbrowser1.execwb 6,1 列印設定 webbrowser1.execwb 8,1 列印預覽 webbrowser1.execwb 7,1 關於這個元件還有其他的用法,列舉如下 webbrowser.exe...