簡體   English   中英

如何在win32 c ++中打印預覽?

[英]how do I do print preview in win32 c++?

我有一個繪圖功能,只需要一個HDC。 但是我需要展示一個精確版本的打印版本。

所以目前,我使用帶有打印機HDC的CreateCompatibleDC()和帶有打印機HDC的CreateCompatibleBitmap()。

我這樣想DC會有打印機的確切寬度和高度。 當我在這個HDC中選擇字體時,文本將與打印機完全一樣。

不幸的是,我不能讓StretchBlt()將這個HDC的像素復制到控件的HDC中,因為我猜它們是不同的HDC類型。

如果我從具有相同w,h和打印機頁面的HDC窗口創建“內存畫布”,那么這些字體會因為縮放屏幕而不是頁面而顯示出來。

我應該從窗口的DC和CreateCompatibleBitmap()創建CompatibleDC()來自打印機的DC還是什么?

如果有人可以解釋這樣做的正確方法。 (並且仍然有像打印機那樣看起來很完美的東西)......

好吧,我很感激!!

...史蒂夫

根據您想要的准確程度,這可能會變得困難。

有很多方法。 聽起來你正試圖繪制一個打印機大小的位圖,然后縮小它。 這樣做的步驟是:

  1. 為打印機創建DC(或更好的IC,信息上下文)。
  2. 查詢打印機DC以查找分辨率,頁面大小,物理偏移等。
  3. 為窗口/屏幕創建DC。
  4. 創建兼容的DC(內存DC)。
  5. 為窗口/屏幕創建兼容的位圖,但大小應該是打印機頁面的像素大小。 (這種方法的問題是這是一個巨大的位圖,它可能會失敗。)
  6. 在存儲器DC中選擇兼容的位圖。
  7. 繪制到內存DC,使用與繪制到實際打印機時相同的坐標。 (當您選擇字體時,請確保將它們縮放到打印機的邏輯英寸,而不是屏幕的邏輯英寸。)
  8. StretchBlt內存DC到窗口,這將縮小整個圖像。 您可能希望嘗試拉伸模式,以查看哪種圖像最適合您要顯示的圖像。
  9. 釋放所有資源。

但在你走向這個方向之前,請考慮其他選擇。 這種方法涉及分配一個巨大的屏幕外位圖。 這可能會在資源匱乏的計算機上失敗。 即使它沒有,你可能會餓死其他應用程序。

另一個答案中給出的元文件方法對於許多應用程序來說是一個很好的選擇 我從這開始。

另一種方法是在一些虛構的高分辨率單元中找出所有尺寸。 例如,假設一切都在千分之一英寸。 然后,您的繪圖例程會將此虛構單位縮放到目標設備使用的實際dpi。

最后一種方法(可能還有元文件)的問題在於GDI字體不能完全線性擴展。 根據目標分辨率調整各個字符的寬度。 在高分辨率設備(如300+ dpi激光打印機)上,這種調整很少。 但是在96-dpi的屏幕上,調整可能會在一條線的長度上產生明顯的誤差。 因此,預覽窗口中的文本可能與打印頁面上的文本不成比例(通常更寬)。

因此,硬核方法是在打印機上下文中測量文本,並在屏幕上下文中再次測量,並調整差異。 例如(使用虛擬數字),您可以測量打印機上下文中某些文本的寬度,它可以達到900個打印機像素。 假設打印機像素與屏幕像素的比率為3:1。 您希望屏幕上的相同文本寬度為300像素。 但是你在屏幕上下文中測量,你得到一個像325屏幕像素的值。 當您繪制到屏幕時,您必須以某種方式使文本縮小25像素。 您可以將字符拉近,或選擇稍小的字體,然后將其拉伸。

硬核方法涉及更多復雜性。 例如,您可能會嘗試檢測打印機驅動程序所做的字體替換,並盡可能與可用的屏幕字體進行匹配。

我很喜歡大位圖和硬核方法的混合體。 我沒有為整個頁面創建一個巨大的位圖,而是為一行文本創建了一個足夠大的位圖。 然后,我在畫打印機尺寸屏幕外的位圖和StretchBlt下來到屏幕大小。 這消除了在略微降低字體質量時處理尺寸差異。 它適用於實際的打印預覽,但您不希望像這樣構建WYSIWYG編輯器。 單行位圖足夠小,可以實現這一點。

好消息是文字很難。 所有其他繪圖都是坐標和大小的簡單縮放。

我沒有太多使用GDI +,但我認為它取消了非線性字體縮放。 因此,如果您使用的是GDI +,則只需縮放坐標即可。 缺點是我不認為GDI +上的字體質量一樣好。

最后,如果您是Vista或更高版本的本機應用程序,請確保您已將您的流程標記為“支持DPI ”。 否則,如果用戶處於高DPI屏幕上,Windows將對您撒謊並聲稱分辨率僅為96 dpi,然后對您繪制的任何內容進行模糊放大。 這會降低視覺質量,並使調試打印預覽變得更加復雜。 由於許多程序無法很好地適應更高的DPI屏幕,因此微軟默認在Vista中添加了“高DPI縮放”。

編輯添加

另一個警告:如果您使用打印機大小的位圖選擇HFONT到內存DC中,則可能會獲得與在實際打印機DC中選擇相同的HFONT時所獲得的字體不同的字體。 這是因為某些打印機驅動程序會將常用字體替換為內存字體。 例如,某些PostScript打印機會將內部PostScript字體替換為某些常見的TrueType字體。

您可以先將HFONT選擇到打印機IC中,然后使用GDI函數(如GetTextFaceGetTextMetricsGetOutlineTextMetrics來查找所選的實際字體。 然后,您可以創建一個新的LOGFONT,以嘗試更緊密地匹配打印機將使用的內容,將其轉換為HFONT,並將其選擇到您的內存DC中。 這是一個非常好的實現的標志。

可能值得嘗試的一件事是創建增強的圖元文件DC,正常繪制它,然后使用打印機指標縮放此圖元文件。 這是WTL BmpView示例使用的方法 - 我不知道這將是多么准確,但它可能值得一看(將相關類移植到Win32應該很容易,但WTL是Win32編程的一個很好的替代品,所以可能值得利用。)

好吧它看起來不一樣,因為你在打印機DC中有更高的分辨率,所以你必須編寫各種轉換函數。 我會使用你必須工作的方法,但文本太小,只是將每個位置/字體大小乘以打印機窗口寬度並除以源窗口寬度。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM