Win32开拓入门(7) 多边形窗口
副标题#e#
凡是环境下,窗口都是一个矩形,不外,挪用下面这个函数,可以自界说窗口的形状。
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,理论常识筹备好了,下面就趁暖和打铁,实战一下吧。
接下来我们要做出 这个容貌的窗口。
#p#副标题#e#
由于这个形状是牢靠的,只需要配置一次即可,所以,我不规划在处理惩罚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); //建设赤色的pen HPEN 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); // 删除HPEN DeleteObject(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); //建设赤色的pen HPEN 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); // 删除HPEN DeleteObject(pen); EndPaint(hwnd, &ps); } return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, msg, wParam, lParam); }
关于画图方面的东东,后头会专门先容,这里重点是说一下SetWindowRgn函数。