(1)Windows坐標系統(tǒng)
Windows坐標系分為邏輯坐標系和設備坐標系兩種,GDI支持這兩種坐標系。
一般而言,GDI的文本和圖形輸出函數使用邏輯坐標,而在客戶區(qū)移動或按下鼠標的鼠標位置是采用設備坐標。
<1>邏輯坐標系是面向DC的坐標系,這種坐標不考慮具體的設備類型,在繪圖時,Windows會根據當前設置的映射模式將邏輯坐標轉換為設備坐標。
<2>設備坐標系是面向物理設備的坐標系,這種坐標以像素或設備所能表示的最小長度單位為單位,X軸方向向右,Y軸方向向下,設備坐標系的原點位置(0, 0)不限定在設備顯示區(qū)域的左上角。
設備坐標系分為屏幕坐標系、窗口坐標系和客戶區(qū)坐標系三種相互獨立的坐標系。
屏幕坐標系以屏幕左上角為原點,一些與整個屏幕有關的函數均采用屏幕坐標,如GetCursorPos()、SetCursorPos()、CreateWindow()、MoveWindow(),彈出式菜單使用的也是屏幕坐標。
窗口坐標系以窗口左上角為坐標原點,它包括窗口標題欄、菜單欄和工具欄等范圍。
客戶區(qū)坐標系以窗口客戶區(qū)左上角為原點,主要用于客戶區(qū)的繪圖輸出和窗口消息的處理。鼠標消息的坐標參數使用客戶區(qū)坐標,CDC類繪圖成員函數使用與客戶區(qū)坐標對應的邏輯坐標。
下面三種都是
顯示設備的物理坐標
,它們在屏幕上用真實的物理像素表示:
屏幕坐標 Screen?? coordinates:?? 原點(0,0)位于屏幕的左上角??
窗口坐標 Window?? coordinates:?? 原點(0,0)位于窗口的左上角(包括非客戶區(qū),如標題條)??
客戶區(qū)坐標 Client-window?? ? ? ? 原點(0,0)位于客戶窗口的左上角???
??
邏輯坐標
是GDI函數在屏幕上顯示數據所用的坐標,邏輯坐標除非與物理坐標相關聯(lián),否則沒有義.windows依靠映射模式解釋邏輯坐標.比如缺省的模式為MM_TEXT,該模式下,物理坐標與邏輯坐標是一對一的關系.
(2)坐標之間的相互轉換
編程時,有時需要根據當前的具體情況進行三種設備坐標之間或與邏輯坐標的相互轉換。
MFC提供了兩個函數CDC::DPtoLP()和CDC:: LPtoDP()用于設備坐標與邏輯坐標之間的相互轉換。
MFC提供了兩個函數CWnd::ScreenToClient()和CWnd::ClientToScreen()用于屏幕坐標與客戶區(qū)坐標的相互轉換。
GetWindowRect是取得窗口在屏幕坐標系下的RECT坐標(包括客戶區(qū)和非客戶區(qū)),這樣可以得到窗口的大小和相對屏幕左上角(0,0)的位置。
GetClientRect取得窗口客戶區(qū)(不包括非客戶區(qū))在客戶區(qū)坐標系下的RECT坐標,可以得到窗口的大小,而不能得到相對屏幕的位置,因為這個矩陣是在客戶區(qū)坐標系下(相對于窗口客戶區(qū)的左上角)的
。
???
? Windows繪圖是在邏輯平面上進行的,是以邏輯坐標作為參數,這個邏輯平面很大,坐標值可以是無限的,我們的窗口只能顯示一小部分,而我們?yōu)榱丝吹竭壿嬈矫娴钠渌糠郑覀兛梢砸苿釉O備平面或者移動邏輯平面,設備點(0,0)始終是客戶區(qū)的左上角,默認情況,邏輯坐標系和客戶區(qū)坐標系都是Y軸向下遞增,X軸向右遞增,兩者的原點是重合的。
紅色方框內,就是我們在設備能看到的內容,默認情況下,邏輯坐標系里-x,-y?的內容在設備上是看不到1?CRect?rect(-100,-100,100,100);
2?dc.Rectangle(rect)?;
3?dc.Ellipse(rect)?;
我們可以通過移動原點來顯示出(-x,-y)的內容
SetWindowOrg: 移動邏輯坐標的原點,即通知操作系統(tǒng),把邏輯點(x,y)映射成設備點(0,0)
SetViewportOrg: 移動設備坐標的原點,即通知操作系統(tǒng)把 設備點(x,y)映射成邏輯點(0,0)?1?CPaintDC?dc(this);
?2?
?3?CRect?rect;
?4?GetClientRect(&rect);//返回以設備單位表示的窗口尺寸(即像素)
?5?CPoint?point(rect.Width()/2,rect.Height()/2);
?6?
?7?dc.SetViewportOrg(point);
?8?
?9?CRect?rect2(-100,-100,100,100);
10?dc.Rectangle(rect2)?;
11?dc.Ellipse(rect2)?;

1?CPaintDC?dc(this);
2?CPoint?point(-100,-100);
3?
4?dc.SetWindowOrg(point);
5?
6?CRect?rect2(-100,-100,100,100);
7?dc.Rectangle(rect2)?;
8?dc.Ellipse(rect2)?;