www.gusucode.com > 一个支持各种交叉等形状工业控制管道控件 > 一个支持各种交叉等形状工业控制管道控件/testPipe2/PipeCtrl.cpp

    /***********************************************************************
* Copyright (c) 2007 * All rights reserved.* 
* ATTRIBUTE:        一种管道的控件,用于面板管道信息显示,模拟现场环境等
* FILE NAME:		PipeCtrl.cpp
* FILE ID:			PIPECTRL-CPP
* ABSTRACT:			工业组态控制系统控制处理专用 
* CURRENT VERSION:	V1.0
* AUTHOR:			戚高
* CONTECT:			successq_g@163.com	
* BUILD DATA:		09/12/2007
* COMPLETION DATE:	09/12/2007
* PRE-VERSION:		NONE
* PRE-AUTHOR:		NONE
* PRE-COMPLETION DATE:	
* NOTE:	            未经授权请不要作为商业用途,或者如果您要作为商业
                    用途,请联系作者
***********************************************************************/
#include "stdafx.h"
#include "PipeCtrl.h"

//-----------------------------------------------------
CPipeCtrl::CPipeCtrl()
{
	m_nShadowBeginColor = RGB( 150, 150, 150);
	m_nShadowEndColor = RGB( 20, 20, 20); 

	m_nWidth = 30;

	m_enumFace = PF_HORIZONTAL;

	m_nBackColor[0] = RGB( 0, 0, 0);
	m_nBackColor[1] = RGB( 75, 75, 75);
	m_nBackColor[2] = RGB( 128, 128, 128);
	m_nBackColor[3] = RGB( 192, 192, 192);
	m_nBackColor[4] = RGB( 220, 220, 220);
	m_nBackColor[5] = RGB( 255, 255, 255);
}

CPipeCtrl::~CPipeCtrl()
{
	
}


BEGIN_MESSAGE_MAP(CPipeCtrl, CStatic)
	//{{AFX_MSG_MAP(CPipeCtrl)
	ON_WM_PAINT()
	ON_WM_ERASEBKGND()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

void CPipeCtrl::PreSubclassWindow() 
{
	CStatic::PreSubclassWindow();

	SetBackTransparent(this);
}

void CPipeCtrl::SetPipeWidth(const int nWidth)
{
	CRect rect;
	GetClientRect(&rect);
	
	if (rect.Width() < nWidth)
	{
		m_nWidth = rect.Width();
	}
	else
	{
		m_nWidth = nWidth;
	}

	Invalidate();
}

void CPipeCtrl::SetItemFace(const PIPEFACE enumFace)
{
	m_enumFace = enumFace;
	Invalidate();
}

void CPipeCtrl::OnPaint() 
{
	CPaintDC dc(this);
	
	RECT rcClient;
	GetClientRect(&rcClient);

	switch (m_enumFace)
	{
	case PF_HORIZONTAL:
		DrawHorizontal(&dc, rcClient);
		break;

	case PF_VERTICAL:
		DrawVertical(&dc, rcClient);
		break;

	case PF_CORNER_LEFT_TOP:
		DrawCornerLeftTop(&dc, rcClient);
		break;

	case PF_CORNER_RIGHT_TOP:
		DrawCornerRightTop(&dc, rcClient);
		break;

	case PF_CORNER_RIGHT_BOTTOM:
		DrawCornerRightBottom(&dc, rcClient);
		break;

	case PF_CORNER_LEFT_BOTTOM:
		DrawCornerLeftBottom(&dc, rcClient);
		break;

	case PF_CROSS_CENTER:
		DrawCrossCenter(&dc, rcClient);
		break;

	case PF_CROSS_TOP:
		DrawCrossTop(&dc, rcClient);
		break;

	case PF_CROSS_RIGHT:
		DrawCrossRight(&dc, rcClient);
		break;

	case PF_CROSS_BOTTOM:
		DrawCrossBottom(&dc, rcClient);
		break;

	case PF_CROSS_LEFT:
		DrawCrossLeft(&dc, rcClient);
		break;
	}
}

//用渐变的方法进行填充,不过这里效果不明显,慎重采用这个方法
void CPipeCtrl::DrawGradient(HDC pDC, const RECT &rectClient,
							 COLORREF nShadowBeginColor, 
							 COLORREF nShadowEndColor)
{   
	RECT rectFill;		//显示区域   
	float fStep;		//每一步的幅宽   
	HBRUSH hBrush;		//显示的颜色画刷   
    
	int nRed = 0, nGreen = 0, nBlue = 0;   
	float fRefStep = 0.0f, fGreenStep =0.0f, fBlueStep = 0.0f;   
    
	//得到不同颜色并相减,返回颜色之间的最大差值   
	nRed = (GetRValue(nShadowEndColor) - GetRValue(nShadowBeginColor));   
	nGreen = (GetGValue(nShadowEndColor) - GetGValue(nShadowBeginColor));   
	nBlue = (GetBValue(nShadowEndColor) - GetBValue(nShadowBeginColor));   
    
	//使进程条显示的总数   等于最大的颜色差值   
	int nSteps = max(abs(nRed), max(abs(nGreen), abs(nBlue)));   
    
	//确定每一颜色填充多大的矩形区域   
	//以下两种计算步长方式均成立,视个人喜好而定    
	fStep = (float)m_nWidth / (float)(nSteps * 2);   
	//设置每一颜色填充的步数   
	fRefStep = nRed / (float)nSteps;   
	fGreenStep = nGreen / (float)nSteps;   
	fBlueStep = nBlue / (float)nSteps;   
    
	nRed = GetRValue(nShadowBeginColor);   
	nGreen = GetGValue(nShadowBeginColor);   
	nBlue = GetBValue(nShadowBeginColor);  
	
	//绘制颜色渐变的进程条   
	for (int nOnBand=0; nOnBand<nSteps; nOnBand++)   
	{   
		//本质为使用一个一个的小RECT填充客户区,而每次填充使用不同的颜色(BRUSH),从而达到渐变的效果   
		SetRect(&rectFill, 0, (int)(nOnBand * fStep) + rectClient.top, 
				rectClient.right + 1, (int)((nOnBand + 1) * fStep) + rectClient.top);
		
		hBrush = CreateSolidBrush(RGB(nRed + fRefStep * nOnBand,   
								  nGreen + fGreenStep * nOnBand,   
								  nBlue + fBlueStep * nOnBand)); 
		
		HBRUSH oldBrush = (HBRUSH)::SelectObject(pDC, hBrush); 
		FillRect(pDC, &rectFill , hBrush); 
		
		::SelectObject(pDC, oldBrush);   
		DeleteObject(hBrush);   
	}   
}   

void CPipeCtrl::DrawHorizontal(CDC *pDC, RECT &rectClient)
{
	RECT rcSect;
	CBrush pBackBrush, *pOldBrush;
	int nSectWidth = m_nWidth / SECTCOUNT;

	for (int i=0; i<SECTCOUNT; i++)
	{ 
		pBackBrush.CreateSolidBrush(GetSectColor(i));
		pOldBrush = (CBrush *)pDC->SelectObject(&pBackBrush);			
		SetRect(&rcSect, rectClient.left, rectClient.top + i * nSectWidth,
				rectClient.right, rectClient.top + (i + 1) * nSectWidth);
		pDC->FillRect(&rcSect, &pBackBrush);

		pDC->SelectObject(pOldBrush);
		pBackBrush.DeleteObject();
	}
}

void CPipeCtrl::DrawVertical(CDC *pDC, RECT &rectClient)
{
	RECT rcSect;
	CBrush pBackBrush, *pOldBrush;
	int nSectWidth = m_nWidth / SECTCOUNT;

	for (int i=0; i<SECTCOUNT; i++)
	{ 
		pBackBrush.CreateSolidBrush(GetSectColor(i));
		pOldBrush = (CBrush *)pDC->SelectObject(&pBackBrush);			
		SetRect(&rcSect, rectClient.left + i * nSectWidth, rectClient.top,
				rectClient.left + (i + 1) * nSectWidth, rectClient.bottom);
		pDC->FillRect(&rcSect, &pBackBrush);

		pDC->SelectObject(pOldBrush);
		pBackBrush.DeleteObject();
	}
}

void CPipeCtrl::DrawCornerLeftTop(CDC *pDC, RECT &rectClient)
{
	RECT rcSect;
	CBrush pBackBrush, *pOldBrush;
	int nSectWidth = m_nWidth / SECTCOUNT;

	for (int i=0; i<SECTCOUNT; i++)
	{ 		
		pBackBrush.CreateSolidBrush(GetSectColor(i));
		pOldBrush = (CBrush *)pDC->SelectObject(&pBackBrush);			
		//绘制横向
		SetRect(&rcSect, rectClient.left + i * nSectWidth, rectClient.top + i * nSectWidth,
				rectClient.right, rectClient.top + (i + 1) * nSectWidth);
		pDC->FillRect(&rcSect, &pBackBrush);
		//绘制竖向
		SetRect(&rcSect, rectClient.left + i * nSectWidth, rectClient.top + i * nSectWidth,
				rectClient.left + (i + 1) * nSectWidth, rectClient.bottom);
		pDC->FillRect(&rcSect, &pBackBrush);

		pDC->SelectObject(pOldBrush);
		pBackBrush.DeleteObject(); 		
	}
}

void CPipeCtrl::DrawCornerRightBottom(CDC *pDC, RECT &rectClient)
{
	RECT rcSect;
	CBrush pBackBrush, *pOldBrush;
	int nSectWidth = m_nWidth / SECTCOUNT;

	for (int i=0; i<SECTCOUNT; i++)
	{ 		
		pBackBrush.CreateSolidBrush(GetSectColor(i));
		pOldBrush = (CBrush *)pDC->SelectObject(&pBackBrush);			
		//绘制横向
		SetRect(&rcSect, rectClient.left, rectClient.bottom - (SECTCOUNT - i) * nSectWidth,
				rectClient.right - (SECTCOUNT - i) * nSectWidth, rectClient.bottom - (SECTCOUNT - i - 1) * nSectWidth);
		pDC->FillRect(&rcSect, &pBackBrush);
		//绘制竖向
		SetRect(&rcSect, rectClient.right - (SECTCOUNT - i) * nSectWidth, rectClient.top,
				rectClient.right - (SECTCOUNT - i - 1) * nSectWidth, rectClient.bottom - (SECTCOUNT - i - 1) * nSectWidth);
		pDC->FillRect(&rcSect, &pBackBrush);

		pDC->SelectObject(pOldBrush);
		pBackBrush.DeleteObject(); 		
	}
}

void CPipeCtrl::DrawCornerRightTop(CDC *pDC, RECT &rectClient)
{
	RECT rcSect;
	CBrush pBackBrush, *pOldBrush;
	int nSectWidth = m_nWidth / SECTCOUNT;

	for (int i=0; i<SECTCOUNT; i++)
	{ 		
		pBackBrush.CreateSolidBrush(GetSectColor(i));
		pOldBrush = (CBrush *)pDC->SelectObject(&pBackBrush);			
		//绘制横向
		SetRect(&rcSect, rectClient.left, rectClient.top + i * nSectWidth,
				rectClient.right - i * nSectWidth, rectClient.top + (i + 1) * nSectWidth);
		pDC->FillRect(&rcSect, &pBackBrush);
		//绘制竖向
		SetRect(&rcSect, rectClient.right - (SECTCOUNT -i) * nSectWidth, rectClient.top + (SECTCOUNT - i) * nSectWidth,
				rectClient.right - (SECTCOUNT - i - 1) * nSectWidth, rectClient.bottom);
		pDC->FillRect(&rcSect, &pBackBrush);

		pDC->SelectObject(pOldBrush);
		pBackBrush.DeleteObject(); 		
	}
}

void CPipeCtrl::DrawCornerLeftBottom(CDC *pDC, RECT &rectClient)
{
	RECT rcSect;
	CBrush pBackBrush, *pOldBrush;
	int nSectWidth = m_nWidth / SECTCOUNT;

	for (int i=0; i<SECTCOUNT; i++)
	{ 		
		pBackBrush.CreateSolidBrush(GetSectColor(i));
		pOldBrush = (CBrush *)pDC->SelectObject(&pBackBrush);			
		//绘制横向
		SetRect(&rcSect, rectClient.left + (SECTCOUNT - i) * nSectWidth, rectClient.bottom - (SECTCOUNT - i) * nSectWidth,
				rectClient.right, rectClient.bottom);
		pDC->FillRect(&rcSect, &pBackBrush);
		//绘制竖向
		SetRect(&rcSect, rectClient.left + i * nSectWidth, rectClient.top,
				rectClient.left + (i + 1) * nSectWidth, rectClient.bottom - i * nSectWidth);
		pDC->FillRect(&rcSect, &pBackBrush);

		pDC->SelectObject(pOldBrush);
		pBackBrush.DeleteObject(); 		
	}
}

void CPipeCtrl::DrawCrossCenter(CDC *pDC, RECT &rectClient)
{
	RECT rcSect;
	CBrush pBackBrush, *pOldBrush;
	int nSectWidth = m_nWidth / SECTCOUNT;
	int xCenter = rectClient.left + (rectClient.right - rectClient.left) / 2;
	int yCenter = rectClient.top + (rectClient.bottom - rectClient.top) / 2;
	int xLeft = xCenter - SECTCOUNT * nSectWidth / 2;
	int yTop = yCenter - SECTCOUNT * nSectWidth / 2;

	//绘制横向
	for (int i=0; i<SECTCOUNT; i++)
	{ 
		pBackBrush.CreateSolidBrush(GetSectColor(i));
		pOldBrush = (CBrush *)pDC->SelectObject(&pBackBrush);		
		SetRect(&rcSect, rectClient.left, yTop + i * nSectWidth,
				rectClient.right, yTop + (i + 1) * nSectWidth);
		pDC->FillRect(&rcSect, &pBackBrush); 		
		
		pDC->SelectObject(pOldBrush);
		pBackBrush.DeleteObject(); 		
	}	

	//绘制竖向 
	for (i=0; i<=SECTCOUNT / 2; i++)
	{
		pBackBrush.CreateSolidBrush(GetSectColor(i));
		pOldBrush = (CBrush *)pDC->SelectObject(&pBackBrush);
		//上左
		SetRect(&rcSect, xLeft + i * nSectWidth, rectClient.top,
				xLeft + (i + 1) * nSectWidth, yTop + i * nSectWidth);
		pDC->FillRect(&rcSect, &pBackBrush); 	
		//上右
		SetRect(&rcSect, xLeft + (SECTCOUNT - i -1) * nSectWidth, rectClient.top,
				xLeft + (SECTCOUNT - i) * nSectWidth, yTop + i * nSectWidth);
		pDC->FillRect(&rcSect, &pBackBrush); 
		//下左
		SetRect(&rcSect, xLeft + i * nSectWidth, yTop + (SECTCOUNT - i) * nSectWidth,
				xLeft + (i + 1) * nSectWidth, rectClient.bottom);
		pDC->FillRect(&rcSect, &pBackBrush); 	
		//下右
		SetRect(&rcSect, xLeft + (SECTCOUNT - i -1) * nSectWidth, yTop + (SECTCOUNT - i) * nSectWidth,
				xLeft + (SECTCOUNT - i) * nSectWidth, rectClient.bottom);
		pDC->FillRect(&rcSect, &pBackBrush); 
		
		pDC->SelectObject(pOldBrush);
		pBackBrush.DeleteObject(); 	
	}
}

void CPipeCtrl::DrawCrossTop(CDC *pDC, RECT &rectClient)
{
	RECT rcSect;
	CBrush pBackBrush, *pOldBrush;
	int nSectWidth = m_nWidth / SECTCOUNT;
	int xCenter = rectClient.left + (rectClient.right - rectClient.left) / 2;	

	//绘制横向
	for (int i=0; i<SECTCOUNT; i++)
	{ 
		pBackBrush.CreateSolidBrush(GetSectColor(i));
		pOldBrush = (CBrush *)pDC->SelectObject(&pBackBrush);		
		SetRect(&rcSect, rectClient.left, rectClient.top + i * nSectWidth,
				rectClient.right, rectClient.top + (i + 1) * nSectWidth);
		pDC->FillRect(&rcSect, &pBackBrush); 		
		
		pDC->SelectObject(pOldBrush);
		pBackBrush.DeleteObject(); 		
	}	

	//绘制竖向 
	int xLeft = xCenter - SECTCOUNT * nSectWidth / 2;
	for (i=0; i<=SECTCOUNT / 2; i++)
	{
		pBackBrush.CreateSolidBrush(GetSectColor(i));
		pOldBrush = (CBrush *)pDC->SelectObject(&pBackBrush);
		//下左
		SetRect(&rcSect, xLeft + i * nSectWidth, rectClient.top + (SECTCOUNT - i) * nSectWidth,
				xLeft + (i + 1) * nSectWidth, rectClient.bottom);
		pDC->FillRect(&rcSect, &pBackBrush); 	
		//下右
		SetRect(&rcSect, xLeft + (SECTCOUNT - i - 1) * nSectWidth, rectClient.top + (SECTCOUNT - i) * nSectWidth,
				xLeft + (SECTCOUNT - i) * nSectWidth, rectClient.bottom);
		pDC->FillRect(&rcSect, &pBackBrush); 
		
		pDC->SelectObject(pOldBrush);
		pBackBrush.DeleteObject(); 	
	}
}

void CPipeCtrl::DrawCrossRight(CDC *pDC, RECT &rectClient)
{
	RECT rcSect;
	CBrush pBackBrush, *pOldBrush;
	int nSectWidth = m_nWidth / SECTCOUNT;
	int yCenter = rectClient.top + (rectClient.bottom - rectClient.top) / 2;	

	//绘制竖向
	for (int i=0; i<SECTCOUNT; i++)
	{ 
		pBackBrush.CreateSolidBrush(GetSectColor(i));
		pOldBrush = (CBrush *)pDC->SelectObject(&pBackBrush);		
		SetRect(&rcSect, rectClient.right - (SECTCOUNT - i) * nSectWidth, rectClient.top,
				rectClient.right - (SECTCOUNT - i - 1) * nSectWidth, rectClient.bottom);
		pDC->FillRect(&rcSect, &pBackBrush); 		
		
		pDC->SelectObject(pOldBrush);
		pBackBrush.DeleteObject(); 		
	}	

	//绘制横向
	int yTop = yCenter - SECTCOUNT * nSectWidth / 2;
	for (i=0; i<=SECTCOUNT / 2; i++)
	{
		pBackBrush.CreateSolidBrush(GetSectColor(i));
		pOldBrush = (CBrush *)pDC->SelectObject(&pBackBrush);
		//上
		SetRect(&rcSect, rectClient.left, yTop + i * nSectWidth,
				rectClient.right - (SECTCOUNT - i) * nSectWidth, yTop + (SECTCOUNT - i - 1) * nSectWidth);
		pDC->FillRect(&rcSect, &pBackBrush); 	
		//下
		SetRect(&rcSect, rectClient.left, yTop + (SECTCOUNT - i) * nSectWidth,
				rectClient.right - (SECTCOUNT - i) * nSectWidth, yTop + (SECTCOUNT - i - 1) * nSectWidth);
		pDC->FillRect(&rcSect, &pBackBrush); 
		
		pDC->SelectObject(pOldBrush);
		pBackBrush.DeleteObject(); 	
	}
}

void CPipeCtrl::DrawCrossBottom(CDC *pDC, RECT &rectClient)
{
	RECT rcSect;
	CBrush pBackBrush, *pOldBrush;
	int nSectWidth = m_nWidth / SECTCOUNT;
	int xCenter = rectClient.left + (rectClient.right - rectClient.left) / 2;	

	//绘制横向
	for (int i=0; i<SECTCOUNT; i++)
	{ 
		pBackBrush.CreateSolidBrush(GetSectColor(i));
		pOldBrush = (CBrush *)pDC->SelectObject(&pBackBrush);		
		SetRect(&rcSect, rectClient.left, rectClient.bottom - (i + 1) * nSectWidth,
				rectClient.right, rectClient.bottom - i * nSectWidth);
		pDC->FillRect(&rcSect, &pBackBrush); 		
		
		pDC->SelectObject(pOldBrush);
		pBackBrush.DeleteObject(); 		
	}	

	//绘制竖向 
	int xLeft = xCenter - SECTCOUNT * nSectWidth / 2;
	for (i=0; i<=SECTCOUNT / 2; i++)
	{
		pBackBrush.CreateSolidBrush(GetSectColor(i));
		pOldBrush = (CBrush *)pDC->SelectObject(&pBackBrush);
		//下左
		SetRect(&rcSect, xLeft + i * nSectWidth, rectClient.top,
				xLeft + (i + 1) * nSectWidth, rectClient.bottom - (SECTCOUNT - i) * nSectWidth);
		pDC->FillRect(&rcSect, &pBackBrush); 	
		//下右
		SetRect(&rcSect, xLeft + (SECTCOUNT - i - 1) * nSectWidth, rectClient.top,
				xLeft + (SECTCOUNT - i) * nSectWidth, rectClient.bottom - (SECTCOUNT - i) * nSectWidth);
		pDC->FillRect(&rcSect, &pBackBrush); 
		
		pDC->SelectObject(pOldBrush);
		pBackBrush.DeleteObject(); 	
	}
}

void CPipeCtrl::DrawCrossLeft(CDC *pDC, RECT &rectClient)
{
	RECT rcSect;
	CBrush pBackBrush, *pOldBrush;
	int nSectWidth = m_nWidth / SECTCOUNT;
	int yCenter = rectClient.top + (rectClient.bottom - rectClient.top) / 2;	

	//绘制竖向
	for (int i=0; i<SECTCOUNT; i++)
	{ 
		pBackBrush.CreateSolidBrush(GetSectColor(i));
		pOldBrush = (CBrush *)pDC->SelectObject(&pBackBrush);		
		SetRect(&rcSect, rectClient.left + (SECTCOUNT - i) * nSectWidth, rectClient.top,
				rectClient.left + (SECTCOUNT - i + 1) * nSectWidth, rectClient.bottom);
		pDC->FillRect(&rcSect, &pBackBrush); 		
		
		pDC->SelectObject(pOldBrush);
		pBackBrush.DeleteObject(); 		
	}	

	//绘制横向
	int yTop = yCenter - SECTCOUNT * nSectWidth / 2;
	for (i=0; i<=SECTCOUNT / 2; i++)
	{
		pBackBrush.CreateSolidBrush(GetSectColor(i));
		pOldBrush = (CBrush *)pDC->SelectObject(&pBackBrush);
		//上
		SetRect(&rcSect, rectClient.left + (SECTCOUNT - i) * nSectWidth, yTop + i * nSectWidth,
				rectClient.right, yTop + (SECTCOUNT - i - 1) * nSectWidth);
		pDC->FillRect(&rcSect, &pBackBrush); 	
		//下
		SetRect(&rcSect, rectClient.left + (SECTCOUNT - i) * nSectWidth, yTop + (SECTCOUNT - i) * nSectWidth,
				rectClient.right, yTop + (SECTCOUNT - i - 1) * nSectWidth);
		pDC->FillRect(&rcSect, &pBackBrush); 
		
		pDC->SelectObject(pOldBrush);
		pBackBrush.DeleteObject(); 	
	}
}

COLORREF & CPipeCtrl::GetSectColor(const int nSect)
{
	int nPos = 0;

	switch (nSect)
	{
	case 0:
	case SECTCOUNT - 1: 
		nPos = 0;
		break;

	case 1:
	case SECTCOUNT - 2:
		nPos = 1;
		break;

	case 2:
	case SECTCOUNT - 3:
		nPos = 2;
		break;

	case 3:
	case SECTCOUNT - 4:
		nPos = 3;
		break;

	case 4:
	case SECTCOUNT - 5:
		nPos = 4;
		break;

	case 5:
		nPos = 5;
		break;
	}

	return m_nBackColor[nPos];
}

BOOL CPipeCtrl::OnEraseBkgnd(CDC* pDC) 
{
	return TRUE;
}

BOOL CALLBACK CPipeCtrl::EnumChildFunc(HWND hwnd, LPARAM lParam)
{
	CRgn *pRgn = (CRgn *)lParam;
	RECT rcChild;
	CRgn rgnChild, rgnCopy;

	::GetWindowRect(hwnd, &rcChild);   
	rgnCopy.CreateRectRgn(0, 0, 1, 1);
	rgnCopy.CopyRgn(pRgn);
	rgnChild.CreateRectRgn(rcChild.left, rcChild.top, rcChild.right, rcChild.bottom);

	pRgn->CombineRgn(&rgnCopy, &rgnChild, RGN_OR);

	return TRUE;

}

int CPipeCtrl::SetBackTransparent(CWnd *pWnd, bool bClientOnly)
{
	CRgn rgn;
	if (bClientOnly)
	{
		CRgn rgnWindow, rgnClient;
		RECT rcWindow, rcClient;

		pWnd->GetWindowRect(&rcWindow);
		pWnd->GetClientRect(&rcClient);
		pWnd->ClientToScreen(&rcClient);

		rgnWindow.CreateRectRgn(rcWindow.left, rcWindow.top, rcWindow.right, rcWindow.bottom);
		rgnClient.CreateRectRgn(rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);
		rgn.CreateRectRgn(0, 0, 1, 1);
		rgn.CombineRgn(&rgnWindow, &rgnClient, RGN_DIFF);
	}
	else
	{
		rgn.CreateRectRgn(0, 0, 0, 0);
	}

	::EnumChildWindows(pWnd->GetSafeHwnd(), (WNDENUMPROC)EnumChildFunc, (LPARAM)(LPVOID)&rgn);   
	return pWnd->SetWindowRgn(rgn, TRUE);
}