討論區快速選單
知識庫快速選單
政府補助!學嵌入式+物聯網 網路投保旅行平安險 討論區最近新進100則主題
[ 回上頁 ] [ 討論區發言規則 ]
列印和預覽的問題
更改我的閱讀文章字型大小
作者 : sunyear(coco) VC++卓越專家C++頂尖高手貼文超過2000則
[ 貼文 2421 | 人氣 1485 | 評價 6060 | 評價/貼文 2.5 | 送出評價 5 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/10/19 下午 04:30:51
我在一個MFC 的project裡,要實現把文件(CDocument object)縮放到一個列印頁印出。
所以我在CMyView::OnPrepareDC設定Window和ViewPort的比例如下:

void CMyView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)
{
CScrollView::OnPrepareDC(pDC, pInfo);
if (pInfo)
{
CeBrushDoc* pDoc = GetDocument();
if (pDoc)
{
int HRes= pDC->GetDeviceCaps(HORZRES);//return 4961(on 600 dpi printer)
int VRes= pDC->GetDeviceCaps(VERTRES);//return 7016(on 600 dpi printer)
pDC->SetViewportExt(HRes, VRes);
pDC->SetWindowExt(pDoc->GetDocSize().cx,pDoc->GetDocSize().cy);
}
}
else {:::::::::::::::::::::::::::::}

}
結果,預覽列印時,看起來是對的(表示程式邏輯是正確的),但列表機印出來的文件卻是比預期放大了
約6倍( 因此只有少部份文件被印出)。為什麼會這樣?Preview和Print應該要一致才對啊!
之後我做一個測試,把程式改成下面:
the program work fine in print preview but the printed image is enlarged 6 times.

So I wrote a test function as:

void CMyView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)
{
CScrollView::OnPrepareDC(pDC, pInfo);
if (pInfo)
{
CeBrushDoc* pDoc = GetDocument();
if (pDoc)
{
int HRes= pDC->GetDeviceCaps(HORZRES);//return 4961(on 600 dpi printer)
int VRes= pDC->GetDeviceCaps(VERTRES);//return 7016(on 600 dpi printer)
if (pInfo->m_bPreview)
{
pDC->SetViewportExt(HRes, VRes);
pDC->SetWindowExt(pDoc->GetDocSize().cx,pDoc->GetDocSize().cy);
}
else
{
pDC->SetViewportExt(HRes/6, VRes/6);
pDC->SetWindowExt(pDoc->GetDocSize().cx,pDoc->GetDocSize().cy);
}
}
}
else {:::::::::::::::::::::::::::::}
}
結果預覽和列印都是正常的。
但那pDC->SetViewportExt(HRes/6, VRes/6);實在不合理,有人可以解釋嗎?
作者 : sunyear(coco) VC++卓越專家C++頂尖高手貼文超過2000則
[ 貼文 2421 | 人氣 1485 | 評價 6060 | 評價/貼文 2.5 | 送出評價 5 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2012/11/1 下午 07:56:43
該寫的東東都完成了,回來程設看看,還是沒有人給答案。
看來得要自己面對問題了 :(
以前也寫過列印的功能,並沒有類似的問題,差別應該是我用了GDI+繪圖的關係吧!
再多看了GDI+文件幾眼後,發現了Graphics有兩個相關(但有點奇怪)的成員函式:
SetPageUnit,SetPageScale(說奇怪是因為好像和SetMapMode等函式的功能重覆)
雖然不是很懂Page Unit,但參數有
UnitDisplay
Specifies display units. for example, if the display device is a monitor, then the unit is 1 pixel.
UnitPixel
Specifies that a unit is 1 pixel.
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
預設是UnitDisplay,當DC是瑩幕是,映射是1 pixel,但若不是瑩幕呢?
沒有交待...但從字義看,應該是1 pixel的長為一個瑩幕的一個像素長。
這解釋了,為什麼我的程式View和PrintPreView都是對的,但列印尺吋卻是錯的。
我的座標轉換都是以pixle為單位縮放的,所以直覺就設Page Unit為UnitPixel:
SetPageUnit(Gdiplus::UnitPixel);
測試的結果,令人失望,還是不對。
東改西改了半天,徒勞無功!
然後在網路大搜索,查了好幾個小時,終於把 Word,Page,Device,Physical四個座標系,弄得不懂也通一半了^^
很可惜的是,網路真正言之有物的文章不多,SetMapMode和SetPageUnit, SetViewExtend和SetPageScale之間的
關係都沒有人著墨。進入GDI+以後,Windows的座標轉換複雜了很多。但我綜合了解後,對我的應用很賭定應該
就是SetPageUnit(Gdiplus::UnitPixel); 就可以了。
所以再試試看,咦?對了!列印尺吋完全正確如預期。
之前為什麼一行?真是有鬼^^
VC的文件應該有這一條警告:
請注意:當你對所撰寫的程式一知半解時,即時程式寫對了,跑起來也是錯的。
如果,有人和我有一樣的問題,而SetPageUnit(Gdiplus::UnitPixel);還是解不了時。
唯一的辦法就是:趕快多吸收相關知識的日月精華,當累積到一定火候時,
SetPageUnit(Gdiplus::UnitPixel);就管用了XD
 板主 : 青衫 , Raymond
 > Visual C++ - 討論區
 - 最近熱門問答精華集
 - 全部歷史問答精華集
 - Visual C++ - 知識庫
  ■ 全站最新Post列表
  ■ 我的文章收藏
  ■ 我最愛的作者
  ■ 全站文章收藏排行榜
  ■ 全站最愛作者排行榜
  ■  月熱門主題
  ■  季熱門主題
  ■  熱門主題Top 20
  ■  本區Post排行榜
  ■  本區評價排行榜
  ■  全站專家名人榜
  ■  全站Post排行榜
  ■  全站評價排行榜
  ■  全站人氣排行榜
 請輸入關鍵字 
  開始搜尋
 
Top 10
評價排行
Visual C++
1 青衫 11070 
2 Raymond 10090 
3 Clier 7630 
4 小約翰 2500 
5 Cog 2030 
6 coco 1870 
7 aming 1410 
8 牧童哥 1400 
9 r2109 1380 
10 Akira 1350 
Visual C++
  專家等級 評價  
  一代宗師 10000  
  曠世奇才 5000  
  頂尖高手 3000  
  卓越專家 1500  
  優秀好手 750  
Microsoft Internet Explorer 6.0. Screen 1024x768 pixel. High Color (16 bit).
2000-2019 程式設計俱樂部 http://www.programmer-club.com.tw/
0.1396484