MFC ViewPort與Window 座標轉換

2021-07-15 13:38:46 字數 2273 閱讀 6290

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的座標轉換為什麼不同了。

win98與win7共享檔案

請不要懷疑這篇文章是不是 10年前的文章 no win98這個系統還真是有人用 雖然用不了迅雷 用不了qq了 不過有些舊式的程式還是挺好的執行在這個環境的 比如vc6 比如win32的各種函式 囧 說白點吧 實際上莪用這個傢伙是因為盛行於c 程式設計的年代就是在2000年初這斷時間 所有關於win3...

win與linux互傳檔案

需要安裝工具 yum install lrzsz 使用 securecrt 等工具連線伺服器 rz e 上傳到伺服器 sz命令 用途說明 sz命令是利用zmodem協議來從linux伺服器傳送檔案到本地,一次可以傳送乙個或多個檔案。相對應的從本地上傳檔案到linux伺服器,可以使用rz命令。常用引數...

linux與win分割槽格式詳解

win常用的分割槽格式有三種,分別是fat16 fat32 ntfs格式。在linux作業系統裡有ext2 ext3 linux swap和vfat四種格式。fat16 作為一種檔名稱,fat file allocation table,檔案分配表 自1981年問世以來,已經成為乙個計算機術語。由於...