在VC中所見即所得列印的簡易實現 (轉)
在VC++6.0中用應用嚮導(AppWizard)生成的單文件或多文件程式提供了對列印功能的實現,但遺憾的是如果對自動生成的程式不做任何改進,列印出來的文件或圖形和螢幕上的顯示相比就會特別小。為什麼會這樣呢?
本文對這種現象的原因和MFC的印表機制進行了深入的分析,並提出了一種特別簡單的方法,在原有的程式中只需加入幾行程式碼就能解決這一問題,實現所見即所得的列印。
首先,分析MFC的印表機制,把原理弄清楚了,就不難明白現象形成的原因和提出解決辦法。MFC應用程式的核心是文件以及相關的檢視視窗的概念,即CDocument類和CView類的構成和關係,簡單地說CDocument類負責資料的生成和儲存,CView類負責資料的顯示和互動。輸出到螢幕和輸出到印表機都是資料的顯示,實質上是一樣的,所以列印功能也是由CView類來實現的。
在CView類中由應用程式嚮導自動生成的提供了一個OnDraw(CDC* pDC)的,透過過載這個函式,利用它提供的pDC(裝置上下文)指標,可以在螢幕上顯示各種圖形和資料。CView類的列印是透過OnPrint(CDC* pDC, CPrintInfo* pInfo)這個函式實現的,應用程式嚮導自動生成的原始碼中沒有這個函式的框架,而這個函式對列印的實現就是簡單地OnDraw(CDC* pDC)這個函式,把印表機的裝置上下文指標pDC傳遞給OnDraw(CDC* pDC)函式。
可見CView類對輸出到螢幕和輸出到印表機的處理都是一樣的,只是換了一個裝置上下文而已,那麼為什麼輸出到印表機的影像特別小呢?
這與VC採用的預設的座標對映方式MM_TEXT有關,這種方式的好處是使用者圖形座標和裝置的象素完全一致。但是在螢幕的象素大小為800*600時,每邏輯英寸包含的螢幕象素為96,而印表機的點數卻要多好幾倍,如當印表機為HP LaserJet 6L時每邏輯英寸包含的印表機點數為600,也就是說印表機的清晰度比螢幕要高得多。
這樣的後果就是在螢幕上顯示出來的滿屏影像在列印出來的紙上卻只有一點點大,怎麼解決這個問題呢?一種簡單的方法就是轉換座標對映方式,使得列印時採用的座標比例比顯示時採用的座標比例相應地大若干倍,就可以解決這一問題。
下面將給出詳細的方法。
注意到CView類在進行顯示和列印之前都會呼叫virtual void OnPrepareDC( CDC* pDC, CPrintInfo* pInfo = NULL )這個虛擬成員函式來準備裝置上下文,我們可以在CView類中過載這個虛擬成員函式,進行座標轉換。
首先用VC的ClassWizard實現對OnPrepareDC( CDC* pDC, CPrintInfo* pInfo = NULL )函式的過載,ClassWizard生成的原始碼如下:
void CTempView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)
{ // TODO: Add your specialized code here and /or call the base class
CView::OnPrepareDC(pDC, pInfo);
}
我們只需在原始碼中加入以下幾行程式碼即可,如下:
void CPrintSameView::OnPrepareDC
(CDC* pDC, CPrintInfo* pInfo)
{ CView::OnPrepareDC(pDC, pInfo);
pDC->SetMapMode(MM_ANISOTROPIC); //轉換座標對映方式
CSize size = CSize(800, 560);
pDC->SetWindowExt(size);
//確定視窗大小 //得到實際裝置每邏輯英寸的象素數量 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軸的邏輯單位可以進行任意的縮放。改變座標對映方式後,就要確定視窗大小和視口大小,注意視窗大小就是我們在螢幕上所見的尺寸,而視口大小則是實際裝置,如印表機等,和顯示器裝置每邏輯英寸的象素數量比較所得的比例尺寸。透過函式得到顯示器和印表機每邏輯英寸的象素數量,然後對視口大小進行相應的縮放,就可以使得螢幕上的顯示和印表機的輸出是一致的了。
這樣,只透過幾行簡單的程式碼,我們就實現了所見即所得的列印。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-962889/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 利用VC++開發所見即所得的列印程式 (轉)
- 所見即所得富文字編輯器實現原理
- VC列印實踐淺談 (轉)
- 利用JavaScript所見即所得的生成Excel表格JavaScriptExcel
- 花樣玩轉“所見即所得”的視覺化開發UI視覺化UI
- 頁面錄製服務上線:RESTful API 呼叫實現,所見所錄即所得RESTAPI
- 在java中實現對FORM的列印功能 (轉)JavaORM
- 在C#裡實現DATAGRID的列印預覽和列印 (轉)C#
- 在VC中實現程式在啟動時隱藏 (轉)
- 幾款所見即所得視覺化UML工具介紹視覺化
- Hallo.js:一款所見即所得的Web編輯器JSWeb
- namedtuple簡易實現
- 所見即所得 HTML 編輯器 Froala Editor 3.1.1 破解過程HTML
- 在VC++6.0開發中實現全屏顯示 (轉)C++
- 在VC 5.0中實現基於MFC的元件的本地化 (轉)元件
- 簡易版 vue實現Vue
- 實現一個簡易的vueVue
- 所見即所得:七大無需程式設計的DIY開發工具程式設計
- Win32全域性鉤子在VC5中的實現 (轉)Win32
- 影像平滑滾動效果的VC實現 (轉)
- SNMP用VC++6.0實現的方法 (轉)C++
- 使用 HttpClient 和 HtmlParser 實現簡易爬蟲(轉載)HTTPclientHTML爬蟲
- 基於Vue的簡易MVVM實現VueMVVM
- KOA的簡易模板引擎實現方式
- 基於Websocket的簡易webshell實現Webshell
- node的讀寫流簡易實現
- 簡易實現一個expressExpress
- 簡易RPC框架實現RPC框架
- 簡易 Vue 評論框架的實現————父元件的實現Vue框架元件
- 玩轉iOS開發 - 簡易的實現2種抽屜效果iOS
- VC中實現多格式影像的靈活轉換 (轉)
- VC實現動畫應用兩則 (轉)動畫
- VC實現螢幕變暗效果 (轉)
- Go 實現簡易的 Redis 客戶端GoRedis客戶端
- 基於react的hash路由簡易實現React路由
- 來實現一個簡易版的 PromisePromise
- 實現一個簡易版WebpackWeb
- Go 實現簡易 RPC 框架GoRPC框架