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