WINDOWS 几种坐标系
2019獨角獸企業重金招聘Python工程師標準>>>
在窗口中繪圖
圖形設備接口(GDI)與設備描述表(DC)
圖形設備接口(GDI)
許多MS-DOS程序都直接往視頻存儲區或打印機端口輸送數據,
這種做法的不利之處在于需要對每種顯示卡或打印機類型提供相應的驅動程序。
Windows則提供了一抽象的接口,稱之為圖形設備接口(GDI)。
Windows己經提供了各種顯示卡及打印機的驅動程序,
這樣我們的程序就可以不必關心與系統相連的顯示卡及打印機的類型。
我們的程序可以通過調用GDI函數和硬件打交道,
而各種GDI函數會自動參考被稱為設備環境(CDC)的數據結構。
Windows會自動將設備環境結構映射到相應的物理設備,并且會提供正確的輸入輸出指令。
設備描述表(DC)
在Windows環境中,各程序的輸出必須限制在自己的窗口中。
GDI使用一種簡單的機制保證在窗口中畫圖的各程序遵循這個規則。
這種機制即為設備描述表(DC);
當Windows程序在屏幕、打印機或其它設備上畫圖時,
它并不是將像素直接輸出到設備上,而是將圖繪制到由設備描述表表示的邏輯意義上的"顯示平面"上去。
設備描述表是深寓于Windows中的一種數據結構,
它包含GDI需要的所有關于顯示平面情況的描述字段,包括相連的物理設備和各種各樣的狀態信息。
設備描述表對象
在使用MFC編制Windows程序時,設備描述表具有更加突出的作用。
除了可作為通往各種設備的橋梁之外,設備描述表對象還封裝了程序用來產生輸出的GDI函數。
在MFC中,你不用捕獲設備描述表句柄和調用GDI輸出函數,至少不必直接捕獲和調用,
而是通過創建一設備描述表對象并調用它的成員函數來畫圖。
設備描述表句柄
在平面上畫圖之前,Windows程序從GDI獲取設備描述表句柄,
并在每次調用完GDI輸出函數時將句柄返回給GDI。
在MFC應用程序中獲取設備描述表的一種方法是調用CWnd::GetDC,
它返回指向表示Windows設備描述表的CDC對象的指針。
在畫圖完畢,要用CWnd::ReleaseDC釋放指針(注:在OnPaint處理程序中,不用顯示調用這兩個函數)
CDC派生類
為了避免獲取和釋放設備描述表所帶來的麻煩,
MFC提供了一些CDC派生類,如CPaintDC,CClientDC,CWindowDC這些類被設計為可直接進行實例化。
各個類的構造函數和析構函數調用相應的函數捕獲和釋放設備描述表,
從而便得設備描述表的使用非常方便簡捷。
例如:
CPaintDC dc(this);
//Do some drawing
傳送給類構造函數的指針確定了設備描述表所屬的窗口。
設備描述表屬性
當使用CDC輸出函數在屏幕上畫圖時,
輸出的某些特性并沒有在函數調用過程中規定(采用系統默認的屬性畫圖),
但我們可以通過設備描述表自身獲得或得新設置屬性。
MFC提供了獲得和設置這些屬性的函數,我們可以用這些函數方便地改變畫圖時的默認屬性。
例如:
CDC::SetTextColor//設置文本顏色
CDC::GetTextColor//獲得文本顏色
CDC::SetBkColor//設置背景顏色
CDC::SetBkMode//設置背景模式
CDC::SetMapMode//設置映射模式
CDC::CDC::SetROP2//設置繪圖模式
CDC::MoveTo//當前位置
CDCL::SelectObject//當前畫筆,當前畫刷,當前字體
(如果想忽略背景色,可將背景設置為"Transparent",dc.SetBkMode(TRANSPARENT);)
SelectObject函數
最常用來定義設備描述表屬性的CDC函數是SelectObject。
例如:
CPen pen(PS_SOLID,2,RGB(0,192,0));
CPen* pOldPen = dc->SelectObject(&pen);//把新的CDC對象選入設備描述表,同時保存舊的CDC對象
dc->Ellipse(0,0,100,100);
dc.SelectObject(pOldPen);//
繪圖模式與SetROP2
GDI將像素點輸出到邏輯平面上時,它不只是簡單地輸出像素點顏色。
相反,它能過一系列的布爾運算將輸出像素點的顏色和目標位置上像素點的顏色合成一起。
它所使用的邏輯關系由設備描述表當前的繪圖模式確定。
使用CDC::SetROP2(Set Raster Operation To)可更改繪圖模式。
默認繪圖模式為R2_COPYPEN,它將將像素點復制到顯示平面上。
映射模式
默認映射模式
固定比例映射模式
可編程映射模式
簡單地說,映射模式是設備描述表的屬性,用于確定從邏輯坐標值到設備坐標值的轉換方式。
默認的映射模式
默認的映射模式使MM_TEXT,它使以象素為單位的。X軸向左為正,Y軸向下為正。默認的坐標原點在左上角。
固定比例映射模式
固定比例的映射模式有MM_LOMETRIC、MM_HIMETRIC、MM_LOENGLISH、MM_HIENGLISH、MM_TWIPS種。
它們默認的坐標原點都使在左上角。其區別在于每一個邏輯單位對應的物理大小不一樣。
所對用的邏輯單位分別為0.1毫米,0.01毫米,0.01英寸,0.001英寸,1/1440英寸(0.0007英寸)。
可變比例映射模式(可編程映射模式)
對于可變比例的映射模式用戶可以自己定義一個邏輯單位代表的大小,其大小可以任意。
也可以讓這個大小隨環境改變而改變。有MM_ISOTROPIC,MM_ANISOTROPIC這兩種映射模式。
其邏輯單位的大小等于視口范圍和窗口范圍的比值。
兩者的不同在于前者要求X軸和Y軸的度量單位必須相同,而后者沒有這樣的限制。
?
可編程映射模式
MM_ISOTROPIC和MM_ANISOTROPIC是由用戶決定從邏輯坐標值轉換成設備坐標值的方式,
即是由用戶決定一個邏輯單位等于多少個設備單位(cm,mm,m等),而不是由Windows決定。
所以被稱之為可編程映射模式;
MM_ISOTROPIC和MM_ANISOTROPIC映射模式最常用于根據窗口尺寸按比例自動調節畫圖的輸出大小的場合。
MM_ISOTROPIC和MM_ANISOTROPIC映射模式的區別
前者中X方向和Y方向具有同一個縮放比例因子,而后者兩個方向可以單獨縮放;
例子:
CRect rect;
GetClientRect(&rect);
dc.SetMapMode(MM_ISOTROPIC);
dc.SetWindowExt(500,500);//設置窗口范圍,將窗口的邏輯尺寸高為500單位×500單位
dc.SetViewportExt(rect.Width(),rect.Height());//設置視口范圍
dc.Ellipse(0,0,500,500);
注:窗口的尺寸以邏輯單位計算,視口的尺寸以設備單位或像素計算。
特別說明
MM_TEXT為默認映射模式,其原點在窗口的左上角,X軸的正向向右,Y軸的正向向下,
并且一個邏輯單位對應于設備坐標下的一個象素
其它映射模式則原點不變,只是Y軸會翻轉使正向朝上,并且邏輯單位被按比例轉換為實際距離大小,而不是像素數。
需要注意的是,使用公制映射模式(非默認映射模式)時,為使輸出可見,Y坐標必須為負值。
例如:
dc.Rectangle(0,0,200,100);//默認模式下畫圖
dc.SetMapMode(MM_LOENGLISH);//改變映射模式
dc.Rectangle(0,0,200,-100);//畫圖
傳送給CDC輸出函數的是邏輯坐標值。
設備坐標值是指窗口中相應的像素點位置。
?
Windows中的幾種坐標體系
1、屏幕坐標
屏幕坐標描述物理設備(顯示器、打印機等)的一種坐標體系,
坐標原點在屏幕的左上角,X軸向右為正,Y軸向下為正。度量單位是象素。
原點、坐標軸方向、度量單位都是不能夠改變的。
2、設備坐標(又稱物理坐標)
設備坐標是描述在屏幕和打印機顯示或打印的窗體的一種坐標體系。
默認的坐標原點是在其客戶區的左上角。X軸向右為正,Y軸向下為正。
度量單位為象素。原點和坐標軸方向可以改變,但是度量單位不可以改變。
3、邏輯坐標
邏輯坐標是在程序中控制顯示,打印使用的坐標體系。
該坐標系與定義的映射模式密切相關。默認的映射模式是MM_TEXT。
我們可以通過設置不同的映射模式來改變該坐標體系的默認行為。
注意:
首先,要記住兩點:
1。設備坐標的(0, 0)點始終是客戶區的左上角。?
2。我們在繪圖時指定的點全部都是邏輯坐標點。
坐標轉換
調用CDC::LPtoDP可以將邏輯坐標轉換為設備坐標;
高用CDC::DPtoLP可以將設備坐標轉換為邏輯坐標;
什么時候用什么坐標系
- 可以認為CDC的所有成員函數都以邏輯坐標作為參數
- 可以認為CWnd的所有成員函數都以設備坐標作為其參數
- 所有選中測試操作中都應該考慮設備坐標。區域的定義應采用設備坐標。
某些像CRect::PtInRect之類的函數只有在采用設備坐標參數時才會保證有正確的結果 - 將一些需要長期使用的值用邏輯坐標或物理坐標來保存。
如果用邏輯坐標來保存某點的坐標的話,那么只要用戶對窗口進行一下滾動,該點的坐標就不再有效了。 - 鼠標單擊事件下得到的坐標都是設備坐標!
移動原點
CDC::SetViewportOrg()移動視口的原點
CDC::SetWindwosOrg()移動窗口的原點
正常情況下,只能使用其中之一,同時使用兩個會搞提一團糟。
獲取設備信息
獲得系統分辨率
CClientDC dc(this);
int cx = dc.GetDeviceCaps(HORZRES);
int cy = dc.GetDeviceCaps(VERTRES);
用GDI繪圖
MFC的CDC類將相關的GDI函數封裝在類成員函數中。
在設備描述表對象中或通過指向設備描述表對象的指針可以方便地調用這些函數
畫線
dc.MoveTo(0,0);//設置當前位置
dc.LineTo(100,100);//指定一個線的終點位置
畫圓
dc.Ellipse(0,0,100,100);
CRect rect(0,0,100,100);
dc.Ellipse(rect);
畫矩形
dc.Rectangle(0,0,100,100);//畫一個帶直角的矩形
GDI畫筆和CPen類
Windows用當前選入設備描述表的畫筆繪制直線和曲線,
并給用Rectangle,Ellipse以及其他圖形生成函數畫出的圖形鑲畫邊框。
默認畫筆畫出的是一個像素點寬的黑色實線。
如果要改變畫線方式,則需創建一個GDI畫筆,并由CDC::SelectOjbect將它選設備描述表
MFC用類CPen表示GDI畫筆。
創建畫筆的方法
創建畫筆的最簡單的方法是構造一個CPen對象并把定義畫筆所用的參數都傳送給該對象
CPen pen(PS_SOLID,1,RGB(255,0,0));
創建畫筆的第二種方法是構造 一個漢有初始化的CPen對象并調用CPen::CreatePen:
CPen pen;
pen.CreatePen(PS_SOLID,1,RGB(255,0,0));
創建畫筆的第三種方法是構造一個沒有初始化的CPen對象,向LOGPEN結構中填充描述畫筆特性的參數
,然后調用CPen::CreatePenIndirect生成畫筆
CPen pen;
LOGPEN lp;
lp.lognStyle = PS_SOLID;//樣式
lp.lopnWidth.x = 1;//寬度
lp.lopnColor = RGB(255,0,0);//顏色
pen.CreatePenIndirect(&lp);
從以上的畫筆定義可以看出,定義畫筆需要三個特性:樣式,寬度和顏色。
畫筆的樣式說明請參見MSDN
GDI畫刷和CBrush類
在默認情況下,則Rectangle,Ellipse以及其它CDC函數畫出的封閉圖形填充著白色像素點。
通過創建GDI畫刷并在畫圖之前將它選入設備描述表,可以改變圖形的填充顏色。
MFC的CBrush類封裝了GDI畫刷。
畫刷有三種基本類型:單色、帶陰影和帶圖案。
單色畫刷填充的單色。
陰影線畫刷采用預先定義好的交叉線圖案填充圖形。
圖案畫刷用位圖來填充圖形。
創建單色畫刷的方法類似于創建畫筆,如下所示:
CBrush brush(RGB(255,0,0));
或
CBrush brush;
brush.CreateSolidBrush(RGB(255,0,0));
創建帶陰影線畫刷
CBrush brush(HS_DIAGCROSS,RGB(255,0,0));//陰影索引,COLORREF值
或
CBrush brush;
brush.CreateHatchBrush(HS_DIAGCROSS,RGB(255,0,0));
HS_DIAGCROSS是可供選擇的六種陰影線樣式之一,其它樣式請參見MSDN
注意:
在用陰影線畫刷填充時,除非用CDC::SetBkColor改變設備描述表的當前背景色,
或用CDC::SetBkMode把背景模式OPAQUE改成TRANSPARENT,禁止背景填充,
否則WIndows就以默認的背景鈀(白色)填充陰影色線間的空白處。
?
原文出處:http://blog.programfan.com/article.asp?id=19140
轉載于:https://my.oschina.net/iwuyang/blog/198618
總結
以上是生活随笔為你收集整理的WINDOWS 几种坐标系的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java mybatis实现mysql批
- 下一篇: 实现人脸识别“干货”