您的位置:首页 > 其它

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

2013-01-20 16:05 405 查看
通常情况下,窗口都是一个矩形,不过,调用下面这个函数,可以自定义窗口的形状。

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,理论知识准备好了,下面就趁温暖打铁,实战一下吧。

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





由于这个形状是固定的,只需要设置一次即可,所以,我不打算在处理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函数。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: