Windows图形设备接口和绘图
2015-05-21 22:45
211 查看
1.画刷和画笔的应用:
新建一个空的Win32项目,手动添加一个源文件Source.cpp,键入以下代码:
执行结果如图:
2.设置映像模式
映像模式定义了将逻辑单位转化为设备的度量单位以及设备的x方向和y方向。缺省的模式为TEXT绘图模式。
执行结果:
按下左键:
按下鼠标右键:
3.实现一个圆沿着正玄曲线移动的试验,并且每四分之一周期颜色发生变化。
运行结果:
4.字符消息的响应,以及不同的映射模式下的图形显示
下图为原始状态、按下A/a键、按下B/b键、按下C/c键后的效果
清华大学MOOC课件
新建一个空的Win32项目,手动添加一个源文件Source.cpp,键入以下代码:
#include<Windows.h> #include<stdlib.h> #include<string.h> long WINAPI WndProc(HWND hWnd, UINT iMessage, UINT wParam, LONG lParam); BOOL InitWindowsClass(HINSTANCE hInstance); BOOL InitWindows(HINSTANCE hInstance, int nCmdShow); //主函数 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow) { MSG Message; if (!InitWindowsClass(hInstance))return FALSE; //窗口类初始化或者叫注册 if (!InitWindows(hInstance, nCmdShow))return FALSE; //初始化窗口 while (GetMessage(&Message, 0, 0, 0)) //消息循环 { TranslateMessage(&Message); DispatchMessage(&Message); } return Message.wParam; } long WINAPI WndProc(HWND hWnd, UINT iMessage, UINT wParam, LONG lParam) { HDC hDC; //定义设备环境句柄 HBRUSH hBrush; //定义画刷句柄 HPEN hPen; //定义画笔句柄 PAINTSTRUCT PtStr; //定义指向包含绘图信息的结构体变量 //定义一个POINT数组,包括6个点 POINT points[6] = { { 100, 212 }, { 70, 227 }, { 70, 250 }, { 130, 250 }, { 130, 227 }, { 100, 212 } }; switch (iMessage) //消息处理 { case WM_PAINT: //处理绘图消息 hDC = BeginPaint(hWnd, &PtStr); hPen = (HPEN)GetStockObject(NULL_BRUSH); //获取系统定义的空画笔 SelectObject(hDC, hPen); //选择画笔 hBrush = (HBRUSH)GetStockObject(BLACK_BRUSH); //获取系统定义的画刷 SelectObject(hDC, hBrush); //选择画刷 LineTo(hDC, 50, 50); //画线 DeleteObject(hPen); //删除画笔 hPen = CreatePen(PS_SOLID, 2, RGB(255, 0, 0)); //创建画笔 SelectObject(hDC, hPen); //选择画笔 //画一个三角形 LineTo(hDC, 150, 50); LineTo(hDC, 100, 137); LineTo(hDC, 50, 50); Polyline(hDC, points, 6); //画一个五边形 Arc(hDC, 63, 137, 138, 212, 100, 137, 100, 137); //画一个圆 Pie(hDC, 213, 137, 288, 212, 240, 137, 260, 137); //画一个圆饼 Rectangle(hDC, 213, 212, 287, 250); //画一个长方形 RoundRect(hDC, 213, 100, 287, 137, 20, 20); //画一个圆角长方形 DeleteObject(hPen); //删除画笔 DeleteObject(hBrush); //删除画刷 EndPaint(hWnd, &PtStr); //结束绘图 return 0; case WM_DESTROY: //结束应用程序 PostQuitMessage(0); return 0; default://其他消息处理程序 return(DefWindowProc(hWnd, iMessage, wParam, lParam)); } } //初始化窗口 BOOL InitWindows(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; hWnd = CreateWindow(L"WinFill", L"填充示例", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if(!hWnd) return FALSE; ShowWindow(hWnd, nCmdShow); //显示窗口 UpdateWindow(hWnd); return TRUE; } BOOL InitWindowsClass(HINSTANCE hInstance) { WNDCLASS WndClass; WndClass.cbClsExtra = 0; WndClass.cbWndExtra = 0; WndClass.hbrBackground = (HBRUSH)(GetStockObject(WHITE_BRUSH)); //窗口背景:白色 WndClass.hCursor = LoadCursor(NULL, IDC_ARROW); WndClass.hIcon = LoadIcon(NULL, L"END"); WndClass.hInstance = hInstance; WndClass.lpfnWndProc = WndProc; //消息处理函数 WndClass.lpszClassName = L"WinFill"; WndClass.lpszMenuName = NULL; WndClass.style = CS_HREDRAW | CS_VREDRAW; return RegisterClass(&WndClass); }
执行结果如图:
2.设置映像模式
映像模式定义了将逻辑单位转化为设备的度量单位以及设备的x方向和y方向。缺省的模式为TEXT绘图模式。
#include<Windows.h> #include<stdlib.h> #include<string.h> #include<stdio.h> LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, UINT wParam, LONG lParam); BOOL InitWindowsClass(HINSTANCE hInstance); BOOL InitWindows(HINSTANCE hInstance, int nCmdShow); int nMode; //记录映射模式 //主函数 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow) { MSG Message; if (!InitWindowsClass(hInstance))return FALSE; //窗口类初始化或者叫注册 if (!InitWindows(hInstance, nCmdShow))return FALSE; //初始化窗口 while (GetMessage(&Message, 0, 0, 0)) //消息循环 { TranslateMessage(&Message); DispatchMessage(&Message); } return Message.wParam; } LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, UINT wParam, LONG lParam) { HDC hDC; //定义设备环境句柄 HBRUSH hB1,hB2; //定义画刷句柄 PAINTSTRUCT ps; //定义指向包含绘图信息的结构体变量 switch (iMessage) //消息处理 { case WM_LBUTTONDOWN: //鼠标左键单击消息 nMode = MM_ISOTROPIC; //更改映射模式为MM_ISOTROPIC InvalidateRect(hWnd, NULL, 1); //刷新用户区 break; case WM_RBUTTONDOWN: //单击鼠标右键消息 nMode = MM_ANISOTROPIC; //更改显示模式为MM_ANISOTROPIC InvalidateRect(hWnd, NULL, 1); //刷新用户区 break; case WM_DESTROY: //结束应用程序 PostQuitMessage(0); return 0; case WM_PAINT: hDC = BeginPaint(hWnd, &ps); //取得设备环境句柄 SetMapMode(hDC, nMode); //设置映射模式 SetWindowExtEx(hDC, 150, 150, NULL); //设置窗口区域 SetViewportExtEx(hDC, 150, 100, NULL); //设置视口区域 SetViewportOrgEx(hDC, 150, 60, NULL); //设置视口原点 hB1 = (HBRUSH)GetStockObject(WHITE_BRUSH); //定义白色画刷 hB2 = (HBRUSH)GetStockObject(BLACK_BRUSH); //定义黑色画刷 SelectObject(hDC, hB1); //将黑白刷选入设备环境 RoundRect(hDC, 0, 0, 150, 150, 30, 30); //绘制圆角矩形并填充 SelectObject(hDC, hB2); //更改当前画刷为黑色画刷 Ellipse(hDC, 0, 10, 150, 140); //绘制椭圆并填充 EndPaint(hWnd, &ps); //释放设备环境句柄 DeleteObject(hB1); //删除画刷句柄 DeleteObject(hB2); break; default://其他消息处理程序 return(DefWindowProc(hWnd, iMessage, wParam, lParam)); } } //初始化窗口 BOOL InitWindows(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; hWnd = CreateWindow(L"映射模式", L"My_Map_Mode", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if(!hWnd) return FALSE; ShowWindow(hWnd, nCmdShow); //显示窗口 UpdateWindow(hWnd); return TRUE; } BOOL InitWindowsClass(HINSTANCE hInstance) { WNDCLASS WndClass; WndClass.cbClsExtra = 0; WndClass.cbWndExtra = 0; WndClass.hbrBackground = (HBRUSH)(GetStockObject(WHITE_BRUSH)); //窗口背景:白色 WndClass.hCursor = LoadCursor(NULL, IDC_ARROW); WndClass.hIcon = LoadIcon(NULL, L"END"); WndClass.hInstance = hInstance; WndClass.lpfnWndProc = WndProc; //消息处理函数 WndClass.lpszClassName = L"映射模式"; WndClass.lpszMenuName = NULL; WndClass.style = CS_HREDRAW | CS_VREDRAW; return RegisterClass(&WndClass); }
执行结果:
按下左键:
按下鼠标右键:
3.实现一个圆沿着正玄曲线移动的试验,并且每四分之一周期颜色发生变化。
#include<Windows.h> #include<stdlib.h> #include<string.h> #include<stdio.h> #include<cmath> #define Pi 3.1415926 long WINAPI WndProc(HWND hWnd, UINT iMessage, UINT wParam, LONG lParam); //消息处理函数声明. double dfTheta = 0, dfRange = 100.0; //正弦曲线的角度变量. long i = 0, j = 0; long lCentreX = 0, lCentreY = 0, lRadious = (long)(0.2*dfRange);//定义圆心坐标和圆坐标. POINT lpSin[100]; //定义正弦曲线的点坐标. //主函数 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow) { MSG Message; //定义消息变量. HWND hWnd; //定义窗口句柄. WNDCLASS WndClass; //定义窗口类. 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 = L"SIN"; //窗口类名称. WndClass.lpszMenuName = NULL; //无窗口菜单. WndClass.style = 0; //窗口类型为缺省类型. if (!RegisterClass(&WndClass)) //注册窗口. { MessageBeep(0); return FALSE; } hWnd = CreateWindow(L"SIN", //窗口类名. L"4_6", //标题名. WS_OVERLAPPEDWINDOW, //带标题栏,最大和最小按钮的窗口. CW_USEDEFAULT, //窗口左上角坐标. 0, CW_USEDEFAULT, //采用缺省的宽度和高度. 0, NULL, //无父窗口. NULL, //无主菜单. hInstance, //当前实例句柄. NULL); //不要此参数. ShowWindow(hWnd, nCmdShow); //显示窗口. UpdateWindow(hWnd); //更新并绘制用户区. for (int j = 0; j<100; j++) //生成正弦曲线的点坐标. { lpSin[j].x = (long)(j * 2 * Pi / 100 * 60); lpSin[j].y = (long)(dfRange*sin(j * 2 * Pi / 100)); } while (GetMessage(&Message, 0, 0, 0)) { TranslateMessage(&Message); //消息循环. DispatchMessage(&Message); } return Message.wParam; } long WINAPI WndProc(HWND hWnd, UINT iMessage, UINT wParam, LONG lParam) //消息处理函数. { HDC hDC; //定义设备环境句柄. HBRUSH hBrush; //定义画刷句柄 HPEN hPen; //定义画笔句柄 PAINTSTRUCT PtStr; //定义包含绘图信息的结构体变量 switch (iMessage) { case WM_PAINT: //处理绘图消息. hDC = BeginPaint(hWnd, &PtStr); //获得设备环境指针. SetWindowOrgEx(hDC, -100, -100, NULL); //设置原点坐标为(-100,-100). hPen = CreatePen(PS_DASH, 1, RGB(255, 0, 0)); //创新画笔. SelectObject(hDC, hPen); //选入画笔. Polyline(hDC, lpSin, 100); //绘制正弦曲线. if (i <= 25) //第一个1/4周期. { hPen = CreatePen(PS_DASH, 1, RGB(255, 0, 0));//创新红笔. hBrush = CreateHatchBrush(HS_BDIAGONAL, RGB(255, 0, 0));//创新红画刷. lRadious = (long)(dfRange*0.2 + i % 25 * dfRange*0.4 / 25);//计算半径. } else if (i <= 50)//第二个1/4周期. { hPen = CreatePen(PS_DASH, 1, RGB(0, 255, 0));//创新绿笔. hBrush = CreateHatchBrush(HS_DIAGCROSS, RGB(0, 255, 0));//创新绿刷. lRadious = (long)(dfRange*0.2 + i % 25 * dfRange*0.4 / 25);//计算半径. } else if (i <= 75)//第三个周期. { hPen = CreatePen(PS_DASH, 1, RGB(0, 0, 255));//创新蓝笔 hBrush = CreateHatchBrush(HS_CROSS, RGB(0, 0, 255));//创新蓝刷. lRadious = (long)(dfRange*0.2 + i % 25 * dfRange*0.4 / 25);//计算半径. } else//第四个周期. { hPen = CreatePen(PS_DASH, 1, RGB(255, 255, 0));//创新黄笔 hBrush = CreateHatchBrush(HS_VERTICAL, RGB(255, 255, 0));//创新黄刷. lRadious = (long)(dfRange*0.2 + i % 25 * dfRange*0.4 / 25);//计算半径. } SelectObject(hDC, hBrush); //选入画刷. SelectObject(hDC, hPen); //选入画笔. lCentreX = lpSin[i].x; //圆心x坐标. lCentreY = lpSin[i].y; //圆心y坐标. Ellipse(hDC, lCentreX - lRadious, lCentreY - lRadious,lCentreX + lRadious, lCentreY + lRadious); //画圆,当椭圆的长短轴相等时为圆 i++; DeleteObject(hPen); //删除画笔. DeleteObject(hBrush); //删除画刷. EndPaint(hWnd, &PtStr); //删除设备环境指针. Sleep(100); //停0.1秒. if (i<100) InvalidateRect(hWnd, NULL, 1); //刷新用户区. return 0; case WM_DESTROY: //关闭窗口. PostQuitMessage(0); return 0; default: return(DefWindowProc(hWnd, iMessage, wParam, lParam)); } }
运行结果:
4.字符消息的响应,以及不同的映射模式下的图形显示
#include <windows.h> #include <string.h> #include <stdlib.h> #include <stdio.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int nMode = MM_TEXT; //初始绘图模式 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR lpszCmdLine, int nCmdShow) { HWND hwnd; MSG Msg; WNDCLASS wndclass; //char lpszClassName[] ="映射模式"; //char lpszTitle[] = "My_Map_Mode"; wndclass.style = 0; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = L"映射模式"; if (!RegisterClass(&wndclass)) { MessageBeep(0); return FALSE; } hwnd = CreateWindow(L"映射模式" ,//lpszClassName L"My_Map_Mode",//lpszTitle, 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; //消息循环结束时将信息返回系统 } //窗口函数 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam ) { HDC hdc; PAINTSTRUCT ps; HPEN hPen; switch (message){ case WM_CHAR: //字符消息 if (wParam == 'a' || wParam == 'A') nMode = MM_ISOTROPIC; else if (wParam == 'b' || wParam == 'B') nMode = MM_ANISOTROPIC; else if (wParam == 'c' || wParam == 'C') nMode = MM_LOMETRIC; else ; InvalidateRect(hwnd, NULL, 1); //刷新用户区 break; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); //取得设备环境句柄 SetMapMode(hdc, nMode); //设置映射模式 SetWindowExtEx(hdc, 15, 15, NULL); //设置窗口区域 SetViewportExtEx(hdc, 15, 10, NULL); //设置视口区域 SetViewportOrgEx(hdc, 120, 120, NULL); //设置视口原点 hPen = CreatePen(PS_SOLID, 2, RGB(255, 0, 0)); //创建红色画笔 SelectObject(hdc, hPen); //将画笔选入设备环境 //画坐标系,原点在视口原点 LineTo(hdc, 200, 0); LineTo(hdc, 195, -5); MoveToEx(hdc, 200, 0, NULL); LineTo(hdc, 195, 5); MoveToEx(hdc, 0, 0, NULL); LineTo(hdc, 0, 200); LineTo(hdc, -5, 195); MoveToEx(hdc, 0, 200, NULL); LineTo(hdc, 5, 195); DeleteObject(hPen); //删除画笔 EndPaint(hwnd, &ps); //释放设备环境句柄 break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, message, wParam, lParam); } return 0; }
下图为原始状态、按下A/a键、按下B/b键、按下C/c键后的效果
清华大学MOOC课件
相关文章推荐
- Windows 中绘图以及Windows 的图形设备接口(GDI )
- Windows图形设备接口及Windows绘图
- 从Delphi转向VC系列学习二:Windows的图形设备接口及Windows绘图
- Windows图形设备接口(GDI)及Windows绘图
- Windows图形设备接口(GDI)及Windows绘图
- WindowsAPI学习笔记二 - 图形设备接口及windows绘图
- Windows的图形设备接口与Windows绘图
- Windows的图形设备接口(GDI)
- MFC----图形设备接口1
- GDI 图形设备接口
- Win32 API 图形设备接口
- Windows图形设备接口类概述
- VC++绘图:windows图形环境
- windows程序设计之绘图基础之设备的尺寸
- WINDOW API基本屏幕绘图(GDI Graphics Device Interface 图像设备接口)
- GDI(Graphics Device Interface), 图形设备接口
- Graphics Device Interface:图形设备接口
- windows程序设计之绘图基础之设备的尺寸
- 图形设备接口
- 图形设备接口 GDI