今天来学习用windows应用程序编程的窗口绘图功能
首先是主函数,还是四部曲:窗口类注册,窗口生成,显示窗口,消息循环
// 主程序
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
MSG Message;
HWND hWnd;
WNDCLASS WndClass;
//1-定义窗口类
WndClass.cbClsExtra=0;
WndClass.cbWndExtra=0;
WndClass.hbrBackground=(HBRUSH)(GetStockObject(WHITE_BRUSH));
WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
WndClass.hIcon=LoadIcon(NULL,"END");
WndClass.hInstance=hInstance;
WndClass.lpfnWndProc=WndProc;
WndClass.lpszClassName="WinFill";
WndClass.lpszMenuName=NULL;
WndClass.style=CS_HREDRAW|CS_VREDRAW;
RegisterClass(&WndClass);
//2-生成窗口
hWnd=CreateWindow("WinFill","填充示例",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,0,CW_USEDEFAULT,0,NULL,NULL,hInstance,NULL);
//3-显示窗口
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
//4-消息循环
while(GetMessage(&Message,0,0,0))
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
return Message.wParam;
}
这些程序段其实都可以写成子函数形式,比如InitWindowClass之类的,其实也可以直接放在WinMain函数里,更直观。写完主程序,还需要调用的窗口函数,这里就是用来处理消息的,当消息为WM_PAINT时,就执行绘图操作,具体代码如下:
// 窗口函数
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);
SetMapMode(hDC,MM_ANISOTROPIC); //设置映射模式
hPen=(HPEN)GetStockObject(BLACK_PEN); //设置画笔为系统预定定义的黑色画笔
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); //结束绘图
return 0;
case WM_DESTROY: //结束应用程序
PostQuitMessage(0);
return 0;
default: //其他消息处理程序
return(DefWindowProc(hWnd,iMessage,wParam,lParam)) ;
}
}
这段代码比较长,其实就是处理消息内容,其他的和Hello World里的一致,就是遇到WM_PAINT消息时,执行绘图操作。整体程序就一个文件,如下所示:
#include<windows.h>
// 窗口函数
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);
SetMapMode(hDC,MM_ANISOTROPIC); //设置映射模式
hPen=(HPEN)GetStockObject(BLACK_PEN); //设置画笔为系统预定定义的黑色画笔
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); //结束绘图
return 0;
case WM_DESTROY: //结束应用程序
PostQuitMessage(0);
return 0;
default: //其他消息处理程序
return(DefWindowProc(hWnd,iMessage,wParam,lParam)) ;
}
}
// 主程序
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
MSG Message;
HWND hWnd;
WNDCLASS WndClass;
//1-定义窗口类
WndClass.cbClsExtra=0;
WndClass.cbWndExtra=0;
WndClass.hbrBackground=(HBRUSH)(GetStockObject(WHITE_BRUSH));
WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
WndClass.hIcon=LoadIcon(NULL,"END");
WndClass.hInstance=hInstance;
WndClass.lpfnWndProc=WndProc;
WndClass.lpszClassName="WinFill";
WndClass.lpszMenuName=NULL;
WndClass.style=CS_HREDRAW|CS_VREDRAW;
RegisterClass(&WndClass);
//2-生成窗口
hWnd=CreateWindow("WinFill","填充示例",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,0,CW_USEDEFAULT,0,NULL,NULL,hInstance,NULL);
//3-显示窗口
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
//4-消息循环
while(GetMessage(&Message,0,0,0))
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
return Message.wParam;
}
直接编译这个文件,就可以出来绘图后的窗体效果了。

这里,需要重点关注一下绘图过程:
hDC=BeginPaint(hWnd,&PtStr);
SetMapMode(hDC,MM_ANISOTROPIC); //设置映射模式
hPen=(HPEN)GetStockObject(BLACK_PEN); //设置画笔为系统预定定义的黑色画笔
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); //结束绘图
(1) hDC=BeginPaint(hWnd,&PtStr);
?这个主要是用来获取设备环境,也就是说通过句柄hWnd来传入设备参数。注意,使用这种方式绘图,最后要通过EndPaint来释放。
(2)SetMapMode(hDC,MM_ANISOTROPIC); ??? ?//设置映射模式
映射关系大致就是说对屏幕坐标系做出规定。
(3)hPen=(HPEN)GetStockObject(BLACK_PEN);?? ??? ??? ?//设置画笔为系统预定定义的黑色画笔
画笔用于画线,画刷用于填充区域。
(3)hBrush=(HBRUSH)GetStockObject(DKGRAY_BRUSH);?? ?//采用系统预定义的深灰色画刷
(4)SelectObject(hDC,hBrush); ??? ??? ??? ?//选择画刷 ?? ??? ?SelectObject(hDC,hPen); ? ??? ??? ??? ?//选择画笔
将画笔 画刷选入设备环境。画完以后,要删除对应的画笔,画刷。(好像也可以不删除)
(5)?? ??? ?RoundRect(hDC,50,120,100,200,15,15);//圆角矩形
绘制圆角矩形,参数意义为:左上角x 左上角y 长度dx 长度dy 角度宽度ax 角度宽度ay。
因为画笔和画刷都选用了,所以填充出有深灰色的圆角矩形:

(6)hBrush=(HBRUSH)GetStockObject(LTGRAY_BRUSH);?? ?//采用系统预定义的淡灰色画刷
将画刷改为灰色,就画出来第二个图形。
(7)?? ??? ?SelectObject(hDC,hBrush); ??? ??? ??? ?//选择画刷 ?? ??? ?Ellipse(hDC,150,50,200,150); ?? ??? ?//椭圆
绘制椭圆,参数为左上角x 左上角y 右下角x 右下角y
(8)?? ??? ?hBrush=(HBRUSH)GetStockObject(HOLLOW_BRUSH);?? ?//采用系统预定义的虚画刷
我怀疑这个就是不填充色。
(9)?? ??? ?SelectObject(hDC,hBrush); ??? ??? ??? ?//选择画刷 ?? ??? ?Pie(hDC,250,50,300,100,250,50,300,50); ??? ??? ?//饼形
画饼。参数为:左上角x 左上角y 右下角x 右下角y 起始点半径确定点坐标,终止点半径确定点坐标
这个可能不太好理解,看图就好了:

主要是把从哪开始,到哪结束定好就行了。
(10)?? ?EndPaint(hWnd,&PtStr); ??? ??? ??? ?//结束绘图
这就完成了我们画图的hello world。
?
?
|