Windows图形设备接口和绘图

来源:互联网 发布:linux的dd命令详解 编辑:程序博客网 时间:2024/06/01 20:38

1.画刷和画笔的应用:

新建一个空的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_ISOTROPICInvalidateRect(hWnd, NULL, 1);//刷新用户区break;case WM_RBUTTONDOWN://单击鼠标右键消息nMode = MM_ANISOTROPIC;//更改显示模式为MM_ANISOTROPICInvalidateRect(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.1415926long 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"映射模式" ,//lpszClassNameL"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课件

0 0
原创粉丝点击