#include <Windows.h>
#include <tchar.h>
BOOLEAN InitWindowClass(HINSTANCE hInstance, int nCmdShow);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
MSG msg;
if(!InitWindowClass(hInstance, nCmdShow)){
MessageBox(NULL, L"Failed to Create Windows", L"InFo", NULL);
return 1;
}
while(GetMessage(&msg, NULL, 0, 0)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
BOOLEAN InitWindowClass(HINSTANCE hInstance, int nCmdShow){
WNDCLASSEX wcex;
HWND hWnd;
TCHAR szWindowsClass[] = L"窗口示例";
TCHAR szTitle[] = L"映射模式及填充示例图";
wcex.cbClsExtra = 0;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.cbWndExtra = 0;
wcex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wcex.hInstance = hInstance;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
wcex.lpfnWndProc = WndProc;
wcex.lpszClassName = szWindowsClass;
wcex.lpszMenuName = NULL;
wcex.style = 0;
if(!RegisterClassEx(&wcex)){
return FALSE;
}
hWnd = CreateWindow(szWindowsClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
if(!hWnd){
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){
HDC hDC; // 标识设备环境句柄
PAINTSTRUCT PtStr; // 标识无效区域结构
HBRUSH hBrush;
HPEN hPen;
static int dispMode = -1; // 按键计数器
LPCTSTR str; // Unicode 字符串
switch(message){
case WM_LBUTTONDOWN:
InvalidateRect(hWnd, NULL, TRUE); // 向指定窗体更新区域添加一个矩形,然后窗口客户区域的这一部分将被重新绘制
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_PAINT:
hDC = BeginPaint(hWnd, &PtStr); // 获取设备环境
dispMode = (dispMode + 1) % 6;
switch(dispMode){
case 0:
str = _T("映射方式 MM_TEXT: 缺省的映射方式");
SetMapMode(hDC, MM_TEXT); // 设置映射模式
TextOut(hDC, 0, 0, str, _tcsclen(str));
break;
case 1:
str = _T("映射方式 MM_ISOTROPIC: 窗口坐标为 20 * 20,映射为视口尺寸为 10 * 10, 图形缩小1倍");
SetMapMode(hDC, MM_ISOTROPIC);
SetWindowExtEx(hDC, 20, 20, NULL); // 窗口区域定义
SetViewportExtEx(hDC, 10, 10, NULL); // 视口区域定义
TextOut(hDC, 0, 0, str, _tcsclen(str));
break;
case 2:
str = _T("映射方式 MM_ISOTROPIC: 窗口坐标为 10 * 10,映射为视口尺寸为 20 * 20, 图形放大1倍");
SetMapMode(hDC, MM_ISOTROPIC);
SetWindowExtEx(hDC, 10, 10, NULL);
SetViewportExtEx(hDC, 20, 20, NULL);
TextOut(hDC, 0, 0, str, _tcsclen(str));
break;
case 3:
str = _T("映射方式 MM_ANISOTROPIC: 窗口坐标为 10 * 10,映射为视口尺寸为 20 * 10, 图形横向放大1倍,纵向不变");
SetMapMode(hDC, MM_ANISOTROPIC);
SetWindowExtEx(hDC, 10, 10, NULL);
SetViewportExtEx(hDC, 20, 10, NULL);
TextOut(hDC, 0, 0, str, _tcsclen(str));
break;
case 4:
str = _T("映射方式 MM_ANISOTROPIC: 窗口坐标为 10 * 10,映射为视口尺寸为 20 * 5, 图形横向放大1倍,纵向缩小1倍");
SetMapMode(hDC, MM_ANISOTROPIC);
SetWindowExtEx(hDC, 10, 10, NULL);
SetViewportExtEx(hDC, 20, 5, NULL);
TextOut(hDC, 0, 0, str, _tcsclen(str));
break;
case 5:
str = _T("映射方式 MM_ISOTROPIC: 窗口坐标为 10 * 10,映射为视口尺寸为 20 * 5, 图形为了保持原纵横比,系统会调整映射比例");
SetMapMode(hDC, MM_ISOTROPIC);
SetWindowExtEx(hDC, 10, 10, NULL);
SetViewportExtEx(hDC, 20, 5, NULL);
TextOut(hDC, 0, 0, str, _tcsclen(str));
break;
}
hPen = (HPEN)GetStockObject(BLACK_BRUSH); // 获取系统画笔、画刷
hBrush = (HBRUSH)GetStockObject(DKGRAY_BRUSH);
SelectObject(hDC, hBrush); // 将画笔、画刷选入设备环境
SelectObject(hDC, hPen);
RoundRect(hDC, 50, 120, 100, 200, 15, 15); // 圆角矩形
hBrush = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
SelectObject(hDC, hBrush);
Ellipse(hDC, 150, 50, 200, 150); // 椭圆形
hBrush = (HBRUSH)GetStockObject(HOLLOW_BRUSH);
SelectObject(hDC, hBrush);
Pie(hDC, 250, 50, 300, 100, 250, 50, 300, 50); // 饼形
EndPaint(hWnd, &PtStr); // 结束绘图
DeleteObject(hPen); // 删除画笔、画刷
DeleteObject(hBrush);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}Windows绘图—六种映射方式
最新推荐文章于 2025-03-21 13:58:05 发布
本文通过一个Windows应用程序示例,详细介绍了MM_TEXT、MM_ISOTROPIC和MM_ANISOTROPIC三种映射模式及其效果,包括不同比例的窗口到视口的映射,以及在保持纵横比条件下的映射调整。同时,文章还展示了使用基本图形函数如RoundRect、Ellipse和Pie进行绘图的操作。
1132

被折叠的 条评论
为什么被折叠?



