win32座標系統的轉換
- First,code…
//my_header.h
#ifndef __MY_HEADER_
#define __MY_HEADER_
#include<windows.h>
#include<strsafe.h>
#include<tchar.h>
#define WIDTH 800
#define HEIGHT 600
#endif
//main.cpp #include"my_header.h" HWND hwnd = NULL; TCHAR szClassName[32] = TEXT("my_class"); LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam); bool RegisterMyClass(HWND hwnd, HINSTANCE hInstance, int nShow); int WINAPI wWinMain(HINSTANCE hinstance, HINSTANCE prehInstance, LPTSTR cmdLine, int nShow) { MSG msg; if (!RegisterMyClass(hwnd, hinstance, nShow)) return 0; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } bool RegisterMyClass(HWND hwnd, HINSTANCE hInstance, int nShow) { WNDCLASS wndclass = { sizeof(wndclass) }; wndclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); wndclass.hCursor = LoadCursor(hInstance, IDC_ARROW); wndclass.hIcon = LoadIcon(hInstance, IDI_APPLICATION); wndclass.hInstance = hInstance; wndclass.lpfnWndProc = WndProc; wndclass.lpszClassName = szClassName; wndclass.lpszMenuName = NULL; wndclass.style = CS_VREDRAW | CS_HREDRAW; if (!RegisterClass(&wndclass)) { MessageBox(NULL, TEXT("call RegisterClass false..."), TEXT("msg"), MB_OK); return false; } hwnd = CreateWindow(szClassName, TEXT("Supper App"), WS_OVERLAPPEDWINDOW, 300,200, WIDTH, HEIGHT, NULL, NULL, hInstance, NULL); if (NULL == hwnd) { MessageBox(NULL, TEXT("call CreateWindow false..."), TEXT("msg"), MB_OK); return 0; } ShowWindow(hwnd, nShow); UpdateWindow(hwnd); return true; } LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { static int iClientWidth, iClientHeight; static TEXTMETRIC tm; switch (message) { case WM_CREATE: break; case WM_PAINT: { static PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); //TextOut(ps.hdc, 200, 200, TEXT("千古風流人物"), 6); POINT point; GetWindowOrgEx(hdc, &point); GetViewportOrgEx(hdc, &point); SetMapMode(hdc, MM_LOMETRIC); //DPtoLP(hdc, (LPPOINT)&ps.rcPaint, 2); //SetViewportOrgEx(hdc,200,200,NULL); //SetWindowOrgEx(hdc, (ps.rcPaint.left - ps.rcPaint.right) / 2, (ps.rcPaint.top - ps.rcPaint.bottom) / 2, NULL); //SetViewportOrgEx(hdc, 200, 200, NULL); SetWindowOrgEx(hdc, -200,200, NULL); Ellipse(hdc, -100, -100, 100, 100); MoveToEx(hdc, -200, 0, NULL); LineTo(hdc, 200, 0); MoveToEx(hdc, 0, -200, NULL); LineTo(hdc, 0, 200); MoveToEx(hdc, 0, 0, NULL); LineTo(hdc, 100, 100); EndPaint(hwnd, &ps); } break; case WM_SIZE: { iClientWidth = LOWORD(lparam); iClientHeight = HIWORD(lparam); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, message, wparam, lparam); } return 0; }
//上面是我的為win32的基本專案模板,我就不註釋了,simple
然後分別測試: //SetViewportOrgEx(hdc, 200, 200, NULL); SetWindowOrgEx(hdc, -200,200, NULL);
兩次呼叫都是相似的功能,重置兩個座標系統(視窗和視口)的中座標原點。 座標系1 --> 座標系2
視口和視窗,簡單的說:顯示的地方(裝置),視窗:程式設計師編碼的地方。
SetViewportOrgEx備註:
The SetViewportOrgEx function specifies which device point maps to the window origin (0,0). SetViewportOrgEx函式指定哪個裝置點對映到視窗原點(0,0)。
函式與SetMapMode無關,SetMapMode設定的是視窗對映模式而不是視口。
SetViewportOrg在座標系1中選取一個點設定成座標系2的原點
SetWindowOrgEx:
函式行為與SetMapMode有關。
SetWindowOrgEx是將座標系1中的遠點轉化為座標系2中的座標。
關於Option:
所謂的各向異性在物理化學中的含義我就不班門弄斧了,這裡的各向異性其實就是指的X和Y軸方向的 邏輯1代表的含義是否相同。 no pic say jb. 在上圖中:Y軸的邏輯1 表示的是1億元, X軸的邏輯1表示的是1年
在windows視窗中,MM_TEXT模式下,你CreateWindow一個視窗,Width = 1200, Height = 800;那800什麼? 1200什麼?釐米?毫米?英寸?畫素? 1200畫素,800米?
MM_ISOTROPIC: 各向異性。
MM_ANISOTROPIC: 各向同性。
SetWindowExtEx和SetViewportExtEx來設定視窗邏輯單位到視口裝置單位的對映。
一般而言,視口具有固定的正方向和裝置單位: X軸:–> Y軸: 向下。 裝置單位:畫素
視口和視窗理解為兩個座標系,視口是引數相對固定的。 我們需要將視窗的座標系對映到視口上,即兩個座標系的對映。
座標系對映引數: 原點: SetWindowOrgEx,SetViewportOrgEx
座標軸方向和比例變換: SetWindowExtEx,SetViewportExtEx
而只有MM_ISOTROPIC和MM_ISOTROPIC兩種模式可以進行相對自由的對映,其他的模式只能變化對映的原點座標。
/--------------SetWindowExtEx,SetViewportExtEx比較簡單,就不舉例了。
如有用語不當之處,敬請各位大佬指正,指點。