调用 SetMapMode 函数可以设置映射模式:
int SetMapMode( HDC hdc, // 设备环境句柄 int fnMapMode // 要设置的映射模式 );
同样,调用 GetMapMode 函数可以获取映射模式:
int GetMapMode( HDC hdc // 设备环境句柄 );
注:
设备坐标指视口坐标,逻辑坐标指窗口坐标
在 MM_TEXT 映射模式下,逻辑坐标与设备坐标重合,更改映射模式后,逻辑坐标对设备坐标的映射方法将发生改变。
xView = (xWin - xWinOrg) * (xViewExt / xWinExt) + xViewOrg
yView = (yWin - yWinOrg) * (yViewExt / yWinExt) + yViewOrg
当第一次指定各同向性 (MM_ISOTROPIC) 和各异向性 (MM_ANISOTROPIC) 的映射模式时, 和 MM_LOMETRIC 映射模式有相同的效果
调用 SetViewPortExtEx 函数可以设置视口 (设备坐标) 区域的大小 (仅在各同向性 (MM_ISOTROPIC) 和各异向性 (MM_ANISOTROPIC) 的映射模式中起作用)
调用 SetWindowExtEx 函数可以设置窗口 (逻辑坐标)区域的大小 (仅在各同向性 (MM_ISOTROPIC) 和各异向性 (MM_ANISOTROPIC) 的映射模式中起作用)
(SetWindowExtEx 和 SetViewPortExtEx 函数,必须先后都调用,SetWindowExtEx 最好在 SetViewPortExtEx 前调用,这两个函数的本质是设置一种从逻辑坐标到设备坐标的缩放比例,实际上最终要转换到用以下两个公式来换算逻辑坐标位置映射到的设备坐标位置)
xView = (xWin - xWinOrg) * (xViewExt / xWinExt) + xViewOrg
yView = (yWin - yWinOrg) * (yViewExt / yWinExt) + yViewOrg
MM_ISOTROPIC 会将横纵坐标的缩放比例保持一致(以比例较小的为标准),故当逻辑区域大小改变的时候,图形不会发生拉伸现象,会保持横纵缩放比例一致。
MM_ANISOTROPIC 不会将横纵坐标缩放比例保持一致,故当逻辑区域大小改变的时候,图形将可能会发生拉伸现象。
#include <strsafe.h>
#include <windows.h>
void Show(HWND hwnd, HDC hdc, int xText, int yText, int iMapMode, LPCTSTR szMapMode) {
TCHAR szBuffer[60];
size_t ccLength;
RECT rcClient;
SaveDC(hdc);
SetMapMode(hdc, iMapMode);
GetClientRect(hwnd, &rcClient);
DPtoLP(hdc, (LPPOINT)&rcClient, 2);
RestoreDC(hdc, -1);
StringCchPrintf(szBuffer, sizeof(szBuffer) / sizeof(TCHAR), TEXT("%-20s %7d %7d %7d %7d"), szMapMode, rcClient.left, rcClient.right, rcClient.top, rcClient.bottom);
StringCchLength(szBuffer, sizeof(szBuffer) / sizeof(TCHAR), &ccLength);
TextOut(hdc, xText, yText, szBuffer, ccLength);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
HDC hdc;
static int cxChar, cyChar;
PAINTSTRUCT ps;
TEXTMETRIC tm;
static TCHAR szHeading[] = TEXT("Mapping Mode Left Right Top Bottom");
static TCHAR szUndLine[] = TEXT("------------ ---- ----- --- ------");
size_t ccLength;
switch (message) {
case WM_CREATE:
hdc = GetDC(hwnd);
SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
GetTextMetrics(hdc, &tm);
cxChar = tm.tmAveCharWidth;
cyChar = tm.tmHeight + tm.tmExternalLeading;
ReleaseDC(hwnd, hdc);
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
SetMapMode(hdc, MM_ANISOTROPIC);
SetWindowExtEx(hdc, 1, 1, NULL);
SetViewportExtEx(hdc, cxChar, cyChar, NULL);
StringCchLength(szHeading, sizeof(szHeading) / sizeof(TCHAR), &ccLength);
TextOut(hdc, 1, 1, szHeading, ccLength);
StringCchLength(szUndLine, sizeof(szUndLine) / sizeof(TCHAR), &ccLength);
TextOut(hdc, 1, 2, szUndLine, ccLength);
Show(hwnd, hdc, 1, 3, MM_TEXT, TEXT("TEXT (pixels)"));
Show(hwnd, hdc, 1, 4, MM_LOMETRIC, TEXT("LOMETRIC (.1 mm)"));
Show(hwnd, hdc, 1, 5, MM_HIMETRIC, TEXT("HIMETRIC (.01 mm)"));
Show(hwnd, hdc, 1, 6, MM_LOENGLISH, TEXT("LOENGLISH (.01 in)"));
Show(hwnd, hdc, 1, 7, MM_HIENGLISH, TEXT("HIENGLISH (.001 in)"));
Show(hwnd, hdc, 1, 8, MM_TWIPS, TEXT("TWIPS (1 / 1440 in)"));
EndPaint(hwnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
LPCTSTR lpszClassName = TEXT("WHATSIZE");
LPCTSTR lpszWindowName = TEXT("WHATSIZE Program");
WNDCLASS wndclass;
HWND hwnd;
MSG msg;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hInstance = hInstance;
wndclass.lpfnWndProc = WndProc;
wndclass.lpszClassName = lpszClassName;
wndclass.lpszMenuName = NULL;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
if (!RegisterClass(&wndclass)) {
MessageBox(NULL, TEXT("window class registering failed!"), TEXT("Error"), MB_ICONERROR);
return 0;
}
hwnd = CreateWindow(
lpszClassName,
lpszWindowName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL
);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
🖊️ 本文由 Alone Café 创作,如果您觉得本文让您有所收获,请随意赞赏 🥺
⚖️ 本文以 CC BY-NC-SA 4.0,即《署名-非商业性使用-相同方式共享 4.0 国际许可协议》进行许可
👨⚖️ 本站所发表的文章除注明转载或出处外,均为本站作者原创或翻译,转载前请务必署名并遵守上述协议
🔗 原文链接:https://alone.cafe/2018/06/gdiying-she-mo-shi
📅 最后更新:2018年06月05日 Tuesday 01:13
Update your browser to view this website correctly. Update my browser now