您的位置:首页 > 其它

Windows图形设备接口和绘图

2015-05-21 22:45 211 查看
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_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课件
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: