首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

跟小弟我一起玩Win32开发(7):多边形窗口

2013-01-25 
跟我一起玩Win32开发(7):多边形窗口通常情况下,窗口都是一个矩形,不过,调用下面这个函数,可以自定义窗口的

跟我一起玩Win32开发(7):多边形窗口

通常情况下,窗口都是一个矩形,不过,调用下面这个函数,可以自定义窗口的形状。

int SetWindowRgn(    __in  HWND hWnd,    __in  HRGN hRgn,    __in  BOOL bRedraw  );


第一个参数是窗口的句柄,第二个参数也是一个句柄——HRGN,一个多边形的区域,可以用CreatePolygonRgn函数来创建。第三个参数指定函数调用成功后是否重画窗口,如果窗口还没有显示,就不必了,如果窗口已经显示,可以考虑设为TRUE。

我们创建用于显示窗口形状的区域句柄HRGN可以不显示用DeleteObject函数删除,因为MSDN上面有这么一句话:In particular, do not delete this region handle. The system deletes the region handle when it no longer needed.

 

OK,理论知识准备好了,下面就趁温暖打铁,实战一下吧。

接下来我们要做出这个模样的窗口。

跟小弟我一起玩Win32开发(7):多边形窗口

 

由于这个形状是固定的,只需要设置一次即可,所以,我不打算在处理WM_PAINT消息的时候来设置多边形区域,改为在CreateWindow成功后就设置,设置之后再ShowWindow。

WNDCLASS wc = {};wc.lpszClassName = L"MyApp";wc.hbrBackground = CreateSolidBrush(RGB(254, 239, 180));wc.lpfnWndProc = WindowProc;wc.hInstance = hThisApp;wc.style = CS_HREDRAW | CS_VREDRAW;wc.hCursor = LoadCursor(hThisApp, IDC_ARROW);RegisterClass(&wc);HWND hwnd = CreateWindow(L"MyApp",L"我的应用",WS_POPUP,300,140,400,400,NULL,NULL,hThisApp,NULL);if(hwnd == NULL)return -1;POINT pts[5] = {{ 200, 0}, { 0, 160 },{ 120, 400 },{ 285, 400 },{ 400, 160 }};HRGN rgn = CreatePolygonRgn(pts, 5, WINDING);SetWindowRgn(hwnd, rgn, FALSE);//DeleteObject(rgn);ShowWindow(hwnd,nShow);    //UpdateWindow(hwnd);


为了去掉标题栏和边框,我在CreateWindow的时候,使用WS_POPUP。

不过,这窗口好像有点单调,于是,我想着能画些什么东西在上面,故也处理了WM_PAINT消息。

case WM_PAINT:{PAINTSTRUCT ps;BeginPaint(hwnd, &ps);//创建红色的penHPEN pen= CreatePen(PS_DASHDOTDOT, 1, RGB(255,0,0));//把pen选择到设备上下文auto orgObj = SelectObject(ps.hdc, pen);//第一部分POINT lnpts1[5] = {{200,50}, {180,360}, {220, 360}, {60,120}, {340,120}};BYTE bts1[5] =  {PT_MOVETO, PT_LINETO, PT_LINETO,  PT_MOVETO, PT_LINETO };PolyDraw(ps.hdc,lnpts1,bts1,5);// 第二部分POINT lnpts2[2] = { {200,50}, {220,360} };BYTE bts2[2] = { PT_MOVETO, PT_LINETO};PolyDraw(ps.hdc, lnpts2, bts2, 2);// 第三部分POINT lnpts3[2] = {{180,360}, {60,120}};BYTE bts3[2] = {PT_MOVETO, PT_LINETO};PolyDraw(ps.hdc, lnpts3, bts3, 2);// 第四部分POINT lnpts4[2] = {{220,360}, {340,120}};BYTE bts4[2] = {PT_MOVETO, PT_LINETO};PolyDraw(ps.hdc, lnpts4, bts4, 2);SelectObject(ps.hdc, orgObj);// 删除HPENDeleteObject(pen);EndPaint(hwnd, &ps);}return 0;


画些线条上面,让窗口可视区域看上去不那么单调。

 

下面是完整的代码清单。

#include <Windows.h>LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);int WINAPI WinMain(HINSTANCE hThisApp,HINSTANCE hPrevApp,LPSTR cmdlint,int nShow){WNDCLASS wc = {};wc.lpszClassName = L"MyApp";wc.hbrBackground = CreateSolidBrush(RGB(254, 239, 180));wc.lpfnWndProc = WindowProc;wc.hInstance = hThisApp;wc.style = CS_HREDRAW | CS_VREDRAW;wc.hCursor = LoadCursor(hThisApp, IDC_ARROW);RegisterClass(&wc);HWND hwnd = CreateWindow(L"MyApp",L"我的应用",WS_POPUP,300,140,400,400,NULL,NULL,hThisApp,NULL);if(hwnd == NULL)return -1;POINT pts[5] = {{ 200, 0}, { 0, 160 },{ 120, 400 },{ 285, 400 },{ 400, 160 }};HRGN rgn = CreatePolygonRgn(pts, 5, WINDING);SetWindowRgn(hwnd, rgn, FALSE);//DeleteObject(rgn);ShowWindow(hwnd,nShow);    //UpdateWindow(hwnd);// 消息循环MSG msg;while(GetMessage(&msg, NULL, 0, 0)){TranslateMessage(&msg);DispatchMessage(&msg);}return 0;}LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){switch(msg){case WM_PAINT:{PAINTSTRUCT ps;BeginPaint(hwnd, &ps);//创建红色的penHPEN pen= CreatePen(PS_DASHDOTDOT, 1, RGB(255,0,0));//把pen选择到设备上下文auto orgObj = SelectObject(ps.hdc, pen);//第一部分POINT lnpts1[5] = {{200,50}, {180,360}, {220, 360}, {60,120}, {340,120}};BYTE bts1[5] =  {PT_MOVETO, PT_LINETO, PT_LINETO,  PT_MOVETO, PT_LINETO };PolyDraw(ps.hdc,lnpts1,bts1,5);// 第二部分POINT lnpts2[2] = { {200,50}, {220,360} };BYTE bts2[2] = { PT_MOVETO, PT_LINETO};PolyDraw(ps.hdc, lnpts2, bts2, 2);// 第三部分POINT lnpts3[2] = {{180,360}, {60,120}};BYTE bts3[2] = {PT_MOVETO, PT_LINETO};PolyDraw(ps.hdc, lnpts3, bts3, 2);// 第四部分POINT lnpts4[2] = {{220,360}, {340,120}};BYTE bts4[2] = {PT_MOVETO, PT_LINETO};PolyDraw(ps.hdc, lnpts4, bts4, 2);SelectObject(ps.hdc, orgObj);// 删除HPENDeleteObject(pen);EndPaint(hwnd, &ps);}return 0;case WM_DESTROY:PostQuitMessage(0);return 0;}return DefWindowProc(hwnd, msg, wParam, lParam);}

 

关于绘图方面的东东,后面会专门介绍,这里重点是说一下SetWindowRgn函数。

2楼liuyar昨天 15:27
楼主坚持!
1楼zhoujielunzhimi昨天 13:45
支持!!!

热点排行