从这个公式可以看到 逻辑点 (xWinOrg,yWinOrg)映射到 (xViewOrg,yViewOrg)从而证明了窗口原点永远跟视口原点匹配映射。
示例代码:
#include <Windows.h> #include<stdio.h> #pragma comment(lib, "winmm.lib") LRESULT CALLBACK WndProc( HWND hwnd, // handle to window UINT uMsg, // message identifier WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ); int WINAPI WinMain( HINSTANCE hInstance, // handle to current instance HINSTANCE hPrevInstance, // handle to previous instance LPSTR lpCmdLine, // command line int nCmdShow // show state ) { static TCHAR szAppName[]=TEXT("HelloWin"); HWND hwnd; MSG msg; WNDCLASS wndcls; wndcls.cbClsExtra=0; wndcls.cbWndExtra=0; wndcls.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); wndcls.hCursor=LoadCursor(NULL,IDC_ARROW); wndcls.hIcon=LoadIcon(NULL,IDI_APPLICATION); wndcls.hInstance=hInstance; wndcls.lpfnWndProc=WndProc; wndcls.lpszClassName=szAppName; wndcls.lpszMenuName=NULL; wndcls.style=CS_HREDRAW | CS_VREDRAW; if(!RegisterClass(&wndcls)) { MessageBox(NULL,TEXT("error"),szAppName,MB_OKCANCEL); return 0; } hwnd=CreateWindow(szAppName,TEXT("the hello program!"),WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL); ShowWindow(hwnd,SW_SHOWNORMAL); UpdateWindow(hwnd); while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return 0; } LRESULT CALLBACK WndProc( HWND hwnd, // handle to window UINT uMsg, // message identifier WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ) { HDC hdc; PAINTSTRUCT ps; RECT rect; POINT pt1,pt2; switch(uMsg) { case WM_PAINT: hdc = GetDC(hwnd); GetClientRect(hwnd,&rect); SetViewportOrgEx(hdc,rect.right/2,rect.bottom/2,NULL); SetWindowOrgEx(hdc,-rect.right/2,-rect.bottom/2,NULL); Rectangle(hdc,0,0,-100,-100); GetViewportOrgEx(hdc,&pt1); GetWindowOrgEx(hdc,&pt2); ReleaseDC(hwnd,hdc); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd,uMsg,wParam,lParam); }可以调试程序观测程序运行时候点pt1,pt2对应的值。通过对比就很容易发现问题,拨开迷雾见晴天。