Win API函数SetWindowOrgEx与SetViewportOrgEx
OffsetWindowOrgEx - 移動窗口坐標原點
引用自:http://www.cnblogs.com/aoniao/archive/2012/06/18/2553762.html
在閱讀學習Charles Petzold大牛名作《Programming Windows,5th Edition》過程中,對于第5章中講解的SetWindowOrgEx與SetViewportOrgEx一直不明不白,文中所說的坐標系的移動之類更是弄得我一頭霧水。閱讀完該章節后,想想似乎只是明白了一點,再想想似乎只是更加糊涂一點。
在MM_TEXT映射模式下,假設cxClient和cyClient分別為客戶區x軸和y軸的長度。
使用以下參數調用SetViewportOrgEx函數SetViewportOrgEx (hdc, cxClient / 2, cyClient / 2, NULL) ;則調用函數后,logical point(0,0)將映射到device point(cxClient/2, cyClient/2)。原來坐標系統系統(圖一)將變為新的坐標系統(圖二)。對于這點想想似乎明白。
?
?????????????????????????????????????????????????????????????????????
????????????????????????????????????????????圖一 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 圖二
使用以下參數調用SetWindowOrgEx (hdc, -cxClient / 2, -cyClient / 2, NULL) ;則調用函數后,所得結果同上述調用SetViewportOrgEx 函數。坐標系的變換同圖一坐標系統到圖二坐標系統的變化。對于這點想想似乎糊涂。
引用《Programming Windows,5th Edition》書中第5章的一段
If you change the viewport origin to (xViewOrg, yViewOrg), the logical point (0, 0) will be mapped to the device point (xViewOrg, yViewOrg). If you change the window origin to (xWinOrg, yWinOrg), the logical point (xWinOrg, yWinOrg) will be mapped to the device point (0, 0), which is the upper left corner. Regardless of ?any changes you make to the window and viewport origins, the device point (0, 0) is always the upper left corner of the client area.
這段話描述的是這兩個函數的作用,讀起來一知半解,或許個人的理解能力有待進一步提高吧。不理解,于是求助谷歌。原來不理解這兩個函數的人不只是我一個人,很多人都已經討論過,在博客上,在論壇上。瀏覽開始的一些討論文章,情況還停留在即解卻尚未解的狀態。直到最后閱讀了以下的一篇文章《SetViewportOrgEx與SetWindowOrgEx》,然后再在騎車回家的路上一想,恍然大悟,原來是可以這樣簡單的理解。
在《Programming Windows,5th Edition》書中第5章的The Viewport and the Window一節,講解了何謂Viewport,何謂Window。因為沒有自己的理解頓悟,接下來的SetViewportOrgEx和SetWindowOrgEx函數的迷惑也就理所當然。參考了“包子的小窩~~結廬在人境”的文章后,下面說下自己對于Viewport和 Window的理解:Viewport與屏幕設備相關,或者說同程序的客戶區大小相關。在一應用程序當中,不管你調整程序的大小如何,你沒有拖動滾動條所能完整看到的客戶區內容的大小即是Viewport的大小。
Window與客戶區內包含界面大小相關。在一應用程序當中,把滾動條從最左邊拖動到最右邊,從最上面個拖動到最下面,在這期間你所看到的客戶區內全部內容的大小即是Window的大小。它們的關系就如同你從一扇可以平行移動的窗戶觀看外面的美麗風景。Viewport即是在這扇平行移動窗戶靜止時,你從這個窗口看出去所能看到的大小(類似滾動條靜止你所看到整個客戶區)。Window即是在這扇平行移動窗戶從可以移動的初始位置移動到最終位置期間你所看到的大小(類似滾動條從左到右從上到下你所看到的內同)。
如果對于Viewport和Window這兩個術語有了理解,理解SetViewPortOrgEx和SetWindowOrgEx函數也就順理成章了。
不管是SetViewportOrgEx函數,還是SetWindowOrgEx函數,調用后的結果都是移動上面Viewport和Window所表示區域原點的相對位置。在MM_TEXT映射模式下,沒有調用這兩個函數前,Windows操作系統應用程序客戶區所表示的Viewport和Window的原點(0,0)均位于客戶區最左最頂一角。若調用SetViewportOrgEx函數,則移動Viewport所表示區域坐標系相對Window所表示區域坐標系統相應參數個長度距離。若調用SetWindowOrgEx函數,則移動Window所表示區域坐標系相對Viewport所表示區域坐標系統相應參數個長度距離。不知道大家是否回憶起小時候數學學習的坐標系統移動的經歷。若使用正值作為參數移動某個坐標系統,則這個坐標系統相對另外的坐標系統將左移上移某個單位距離;若使用負值作為參數移動某個坐標系統,則這個坐標系統相對另外的坐標系統將右移下移某個單位距離。不管坐標系怎樣移動,Window所對應的邏輯坐標系的原點都是固定不變,即你用相應的輸出函數在相應的邏輯坐標系上輸出的內容仍然是在原來的地方,只是相對于Viewport坐標系的移動,你所能看到的內容有所不同。
以下是根據我的理解調用相應函數的截圖。
本程序在客戶區輸出左上角和右下角分別輸出兩個圓形(Viewport區域和Window區域一樣大小),沒調用SetViewportOrgEx函數和SetViewportOrgEx函數,截圖如圖三。
???????????????????????????????????????????????????????????????????? 圖三
調用SetViewportOrgEx(hdc, cxClient / 2, cyClient / 2, NULL);即是Viewport區域左移上移相應參數長度,于是看到將是原先左上角的圓形將在右下角出現,截圖如圖四。
????????????????????????????????????????????????????????????????????????? ?? 圖四
調用SetWindowOrgEx(hdc, cxClient / 2, cyClient / 2, NULL);即是Window區域左移上移相應參數長度,于是看到的將是原右下角的圓形將在左上角出現,截圖如圖五
???????????????????????????????????????????????????????????????? ?圖五
(全文完)
下面引用自:http://hi.baidu.com/05104106/item/8df5b417f5b2d24be75e069c
GDI繪圖中調整窗口與視口的坐標原點,相當于定位笛卡爾邏輯坐標系。
先說一下自己對窗口與視口的理解:
窗口(Window),是指整個程序界面,比如一個帶滾動條IE瀏覽器中,頁面內容很長,所有內容構成窗口;視口(Viewport),指的是當前屏幕看到的那一塊,即滾動條所處的可見位置。
視口,與屏幕設備相關,用設備坐標;窗口,與設備無關,用邏輯坐標。TextOut等大部分GDI函數都用邏輯坐標。要講的兩個函數,作用即是兩坐標的映射調整。
引用Charlez的《Windows程序設計》一下,有點暈:
如果將視口原點改變為(xViewOrg,yViewOrg),則邏輯點(0.0)就會映像為設備點(xViewOrg,yViewOrg)。如果將窗口原點改變為(xWinOrg,yWinOrg),則邏輯點(xWinOrg,yWinOrg)將會映像為設備點(0,0),即左上角。不管對窗口和視端口原點作什么改變,設備點(0,0)始終是顯示區域的左上角。
這里,Set不是“設置”,而是“調整”。初始時,視口與窗口原點重合,都在左上角。都是“被調整主體”上移。
SetViewPortOrgEx(x,y) ——調整視口,令視口原點調整為現在的(x,y)
SetWindowOrgEx(x,y)?? ——調整窗口,令窗口原點調整為現在的(x,y)
具體過程如文末圖所示。
我們知道,原始坐標如左圖所示,向下向右為正,如果想要變為右圖所示,應如何調整?視口上調了,SetViewPortOrgEx(x,y);或者說窗口下調了,SetWindowOrgEx(-x,-y)。它們執行的是相反操作。
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的Win API函数SetWindowOrgEx与SetViewportOrgEx的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用串口模拟printf函数输出
- 下一篇: linux中的umask命令