1. 程式人生 > >win32座標系統的轉換

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比較簡單,就不舉例了。

如有用語不當之處,敬請各位大佬指正,指點。