CRect rectClient;
GetClientRect(rectClient); pDC->SetMapMode(MM_ANISOTROPIC); pDC->SetWindowExt(CSize(1000,1000)); pDC->SetViewportExt(rectClient.right,-rectClient.bottom); pDC->SetViewportOrg(rectClient.right/2,rectClient.bottom/2); pDC->Ellipse(-500,-500,500,500);
可變比例映射模式,看到這一段的時候,一開始就把我的弄糊塗了。我一直沒弄明白中間加紅的幾行代碼是什麼意思。把其註釋掉,又沒有原先的效果。在網上百度了半天。得出以下注釋說明:
//SetWindowExe設定窗口尺寸,SetViewportExt設定視口尺寸。 //窗口尺寸以邏輯單位計算,視口尺寸以物理單位計算。 CRect rectClient;
GetClientRect(rectClient);//取窗口物理尺寸(單位:像素) pDC->SetMapMode(MM_ANISOTROPIC); pDC->SetWindowExt(1000, 1000);//窗口邏輯大小:1000*1000, pDC->SetViewportExt(rectClient.right, -rectClient.bottom);//改變Y座標方向--viewport使用物理大小 pDC->SetViewportOrg(rectClient.right / 2, rectClient.bottom / 2);//設置窗口中心點爲座標系原點--Viewport使用物理大小 pDC->Ellipse(CRect(-500, -500, 500, 500));//以邏輯單位畫圖---普通GDI API使用邏輯單位
//默認方式下,物理/邏輯值是1:1關係,可換用。但使用SetWindowExt/SetViewportExt後兩者不可混用。
以上紅色部分,我的解釋是以物理的原點爲座標系,以邏輯的大小爲單位畫圓。後面的代碼中會說明這一問題。 後來經過自己的捉摸,我想我終於搞清楚是怎麼一回事情了。 所謂映射就是物理和邏輯的映射。使用GetClientRect方法後,獲取到窗口的物理大小;然後再使用SetWindowExt,設置了窗口的邏輯大小,與之相對應的是SetViewportExt,也就是說在這裏作了一個映射。SetWindowExt中的第一個參數 cx X寬度(可以這麼理解嗎?)與 SetViewportExt中的第一個參數 Cx 相對應起來。好像中學的比例一樣。邏輯寬度和物理寬度映射,邏輯高度和物理高度映射。這樣,一旦映射關係確立之後,再使用後面的方法進一步的操作。
一開始的代碼是在窗口中顯示一個與之限定的圓,並且會隨着窗口大小的改變亦會跟着改變。
我現在稍稍把其中的參數改變一下。
CRect rectClient; GetClientRect(rectClient);
pDC->SetMapMode(MM_ANISOTROPIC); pDC->SetWindowExt(CSize(800,800)); pDC->SetViewportExt(rectClient.right,-rectClient.bottom); pDC->SetViewportOrg(rectClient.right/2,rectClient.bottom/2); pDC->Ellipse(-500,-500,500,500);
注意上面紅色突出顯示的代碼。我現在將邏輯大小變小了一些。現在注意一下實際在畫圖的代碼中(綠色顯示),我並沒有修改其參數。現在將其編譯運行。會發現,實現中的圓的軌跡會超出窗口。 只是把物理與邏輯之前的映射調整了一下。
CRect rectClient; GetClientRect(rectClient);
pDC->SetMapMode(MM_ANISOTROPIC); pDC->SetWindowExt(CSize(1000,1000)); pDC->SetViewportExt(rectClient.right,-rectClient.bottom); pDC->SetViewportOrg(rectClient.right/2,rectClient.bottom/2); pDC->Ellipse(0,0,500,500);
再調整一下參數,畫出來的圖你會發現,真正的成了二維座標圖。
經過以上一番測試,我想我應該明白每行代碼的意思了。轉換成自己的註釋,應該更容易理解和記憶些。
CRect rectClient; GetClientRect(rectClient); //獲取物理設備大小
pDC->SetMapMode(MM_ANISOTROPIC); //設置映射模式 pDC->SetWindowExt(CSize(1000,1000)); //設備邏輯窗口大小(可能與物理窗口大小不一樣) pDC->SetViewportExt(rectClient.right,-rectClient.bottom); //設置物理設備範圍,爲設定圓點作準備 pDC->SetViewportOrg(rectClient.right/2,rectClient.bottom/2); //設置物理設備座標原點,當然是在上一行代碼的基礎之上 pDC->Ellipse(-500,-500,500,500); //以物理設置座標原點爲基礎,以邏輯爲單位,畫圓。 可以改造一下,原來的代碼,使之後容易理解一些: CRect rectClient; GetClientRect(rectClient);
pDC->SetMapMode(MM_ANISOTROPIC); pDC->SetWindowExt(CSize(1000,1000)); pDC->SetViewportExt(rectClient.right,-rectClient.bottom); pDC->SetViewportOrg(rectClient.left,rectClient.bottom); //設置窗口左下角爲原點座標 pDC->Ellipse(0,0,1000,1000); |
SetWindowExt和SetViewportExt
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.