////////////////////////////////////////////////////////////////////////////////////////////////////
// ˵��: ClassXP.c �ļ�
// ����: 2003-3-10
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
// ����Ԥ����
#if _WIN32_WINNT < 0x0400
#define _WIN32_WINNT 0x0400
#endif
#include "ClassXP.h"
#include <CommCtrl.H>

#pragma warning(disable: 4311)
#pragma warning(disable: 4312)
#pragma comment(lib, "Msimg32.lib")

// ��������
#ifdef CXP_DLLMODE
#pragma comment(linker, "/EXPORT:ClassXP=_ClassXP@8")
#endif // CXP_DLLMODE

// ǿ��ʹ�� C ���Է�ʽ����
#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus

////////////////////////////////////////////////////////////////////////////////////////////////////
// ȫ�ֱ���

HHOOK g_hPrevHookXP = NULL;		// ������Ϣ HOOK ���
PCLASSXP g_pClassXP = NULL;		// ���ڵ� CLASSXP �ṹָ��
COLORREF g_crDialogbkColor = 0x00FFFFFF;  // ���ڱ�����ɫ

#ifdef CXP_DLLMODE
HINSTANCE g_hModuleXP = NULL;	// ��̬���ӿ�ģ����
#endif // CXP_DLLMODE
////////////////////////////////////////////////////////////////////////////////////////////////////
#ifdef CXP_DLLMODE
////////////////////////////////////////////////////////////////////////////////////////////////////
// ��̬���ӿ�������
BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, LPVOID pvReserved)
{
    if (dwReason == DLL_PROCESS_ATTACH)
	{
		g_hModuleXP = hModule;
		DisableThreadLibraryCalls(hModule);
	}
	return TRUE;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
#endif // CXP_DLLMODE
////////////////////////////////////////////////////////////////////////////////////////////////////
// ���û�ȡ�����ڵ� ClassXP ���
BOOL WINAPI ClassXP(HWND hWnd, BOOL bEnable)
{
	BOOL bReturn;

	bReturn = FALSE;

	// �����Ӱ�쵱ǰ�����е����д���
	if (hWnd == NULL)
	{
		// �����ȡ����ǰ�����е����д���
		if ((bEnable == FALSE) && (g_hPrevHookXP != NULL))
		{
			// ö�ٵ�ǰ�̵߳Ĵ��ڲ�ȡ�� ClassXP ���
			EnumThreadWindows(GetCurrentThreadId(), EnumWndProcXP, FALSE);

			// ȡ��������Ϣ HOOK
			bReturn = UnhookWindowsHookEx(g_hPrevHookXP);
			g_hPrevHookXP = NULL;
		}
		// ��������õ�ǰ�����е����д���
		else if ((bEnable == TRUE) && (g_hPrevHookXP == NULL))
		{
			// ö�ٵ�ǰ�߳����Ѵ��ڵĴ��ڲ�����Ϊ ClassXP ���
			EnumThreadWindows(GetCurrentThreadId(), EnumWndProcXP, TRUE);

			// ��װ������Ϣ HOOK
			g_hPrevHookXP = SetWindowsHookEx(WH_CALLWNDPROC, HookProcXP, 0, GetCurrentThreadId());
			bReturn = (BOOL) g_hPrevHookXP;
		}
	}
	else
	{
		// �����ȡ��ָ�����ڵ� ClassXP ���
		if (bEnable == FALSE)
			bReturn = (BOOL) DeleteClassXP(hWnd);
		// ���������ָ�����ڵ� ClassXP ���
		else
			bReturn = (BOOL) CreateClassXP(hWnd);			
	}
	return bReturn;
}
////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////
// ��������ʼ�� CLASSXP ���ݽṹ�����໯����
// ������� NULL����ʾû�д��������򷵻��´����ڵ��ָ�룬ͬʱ g_pClassXP ָ���´����Ľڵ�
PCLASSXP WINAPI CreateClassXP(HWND hWnd)
{
	LONG lStyle;
	DWORD dwType;
	PCLASSXP pCxp, pEditCxp;
    DWORD pID = NULL;
	HICON hIcon;
	HINSTANCE hInst;

	// �Ƿ��Ѿ��� ClassXP ���
	if (GetClassXP(hWnd) == NULL)
	{
		// ��ȡ�������ͣ�������ж��Ƿ�������Ϊ ClassXP ���
		dwType = GetWindowTypeXP(hWnd);
//		if (dwType >= CXPT_PUSHBUTTON) && (dwType <= CXPT_DIALOG))
		if (dwType != CXPT_UNKNOWN)
		{
			lStyle = GetWindowLong(hWnd, GWL_STYLE);

			// ����洢�ռ䣬����һ���ڵ�
			pCxp = (PCLASSXP) HeapAlloc(GetProcessHeap(), 0, sizeof(CLASSXP));
			pCxp->pNext = g_pClassXP;
			g_pClassXP = pCxp;

			// ���໯���ڲ���ʼ�� CLASSXP ���ݽṹ
			pCxp->hWnd = hWnd;
			pCxp->dwType = dwType;
			pCxp->dwState = (lStyle & WS_DISABLED) ? CXPS_DISABLED : 0;
			if (hWnd == GetFocus())
				pCxp->dwState |= CXPS_FOCUS;
			pCxp->wpPrev = (WNDPROC) SetWindowLong(hWnd, GWL_WNDPROC, (LONG) WindowProcXP);

			// ���������ͷֱ� CLASSXP ���ݽṹ
			switch (dwType)
			{
	//case CXPT_STATEBOX:
			case CXPT_PUSHBUTTON:
			case CXPT_CHECKBOX:
			case CXPT_RADIOBOX:
		//ase CXPT_GROUPBOX:
				if ((lStyle & SS_TYPEMASK) == BS_DEFPUSHBUTTON)
					pCxp->dwState |= CXPS_DEFAULT;
				lStyle = (LONG) SendMessage(hWnd, BM_GETCHECK, 0, 0);
				if (lStyle == BST_CHECKED)
					pCxp->dwState |= CXPS_CHECKED;
				else if (lStyle == BST_INDETERMINATE)
					pCxp->dwState |= CXPS_INDETERMINATE;
				if (dwType == CXPT_PUSHBUTTON)//װ���밴ťID����ͬ��ͼ��ID
				{
                   pID =GetDlgCtrlID(pCxp->hWnd);
                   hInst = (HINSTANCE)GetWindowLong(pCxp->hWnd, GWL_HINSTANCE);
                   hIcon = (HICON)LoadIcon(hInst, MAKEINTRESOURCE(pID));
                   if (!hIcon) break;
                   SendMessage(pCxp->hWnd, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM)hIcon);
				}
				break;
        //  case CXPT_LISTBOX:
		//pCxp->pData  = (void *) HeapAlloc(GetProcessHeap(), 0, sizeof(SCROLLXP));
		// break;
			case CXPT_EDITBOX:
				if (lStyle & ES_READONLY)
					pCxp->dwState |= CXPS_READONLY;
				break;
			case CXPT_DIALOG: //����DIALOG��չ����
				pCxp->pData  = (void *) HeapAlloc(GetProcessHeap(), 0, sizeof(DIALOGXP));
				pCxp->hRgn = NULL;
				break;
			case CXPT_SCROLLBOX: //����SCROLL��չ����
				pCxp->pData  = (void *) HeapAlloc(GetProcessHeap(), 0, sizeof(SCROLLXP));
				break;
			case CXPT_SPINBOX:
				if (lStyle & UDS_HORZ)
					pCxp->dwState |= CXPS_HORIZON;
				if (GetWindowTypeXP((HWND) SendMessage(hWnd, UDM_GETBUDDY, 0, 0)) == CXPT_EDITBOX)
				{
					pEditCxp = GetClassXP((HWND) SendMessage(hWnd, UDM_GETBUDDY, 0, 0));
					if (pEditCxp)
					{
						if (lStyle & UDS_ALIGNLEFT)
						{
							pCxp->dwState |= CXPU_ALIGNLEFT;
							pEditCxp->dwState |= CXPE_LEFTSPIN;
						}
						else if (lStyle & UDS_ALIGNRIGHT)
						{
							pCxp->dwState |= CXPU_ALIGNRIGHT;
							pEditCxp->dwState |= CXPE_RIGHTSPIN;
						}
					}
				}
				break;
			}
		// �ػ�����
			RedrawWindow(hWnd, NULL, NULL,
				 RDW_UPDATENOW|RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ERASENOW);
			return pCxp;
		}
	}
	return NULL;
}
////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////
// ȡ���������໯�����ٴ��ڵ� CLASSXP ���ݽṹ
// �������ֵ��Ϊ NULL ��ʾ�ɹ�ɾ��������ֵΪָ����һ���ڵ�ָ�룻
// ������� NULL �� g_pClassXP Ϊ NULL����ȫ���ڵ㱻ɾ����
// �����ʾû���ҵ��ýڵ㡣
// ��л: ��л dREAMtHEATER �Ľ��˺���!
PCLASSXP WINAPI DeleteClassXP(HWND hWnd)
{
	PCLASSXP pDel;
	PCLASSXP pCxp;
	// ��ȡ��ɾ���Ľڵ�ָ��
	pDel = GetClassXP(hWnd);
	if (pDel != NULL)
	{
		// �����ɾ���Ľڵ���� g_pClassXP �ڵ�
		if (pDel == g_pClassXP)
			pCxp = g_pClassXP = pDel->pNext;
		else
		{
			// ѭ�����Ҵ�ɾ���ڵ����һ���ڵ�
			for (pCxp = g_pClassXP; pCxp != NULL; pCxp = pCxp->pNext)
			{
				// ����ҵ�
				if (pCxp->pNext == pDel)
				{
					// ʹ����������ɾ���Ľڵ�
					pCxp->pNext = pDel->pNext;
					break;
				}
			}
		}

		// ȡ���������໯���ػ�����
		  SetWindowLong(hWnd, GWL_WNDPROC, (LONG) pDel->wpPrev);

  
		//��������
		if (pDel->pData) 
			HeapFree(GetProcessHeap(), 0, pDel->pData);
		//��������
		if (pDel->hRgn) DeleteObject(pDel->hRgn);
		// ɾ�����ڴ�
		HeapFree(GetProcessHeap(), 0, pDel);

		// �ػ�����
		RedrawWindow(hWnd, NULL, NULL,
			RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ERASENOW | RDW_UPDATENOW);
		return pCxp;
	}
	return NULL;
}
////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////
// ��ȡ���ڵ� CLASSXP ���ݽṹ
// ������� NULL����ʾû���ҵ������򷵻ؽڵ��ָ��
PCLASSXP WINAPI GetClassXP(HWND hWnd)
{
	PCLASSXP pCxp;

	for (pCxp = g_pClassXP; pCxp != NULL; pCxp = pCxp->pNext)
	{
		if (pCxp->hWnd == hWnd)
			return pCxp;
	}
	return FALSE;
}
////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////
// ��ȡ��������
DWORD WINAPI GetWindowTypeXP(HWND hWnd)
{
	DWORD lReturn, dwStyle;
	char szTemp[MAX_PATH];
	static char s_szClass[][32] = 
	{
		"Button",					// ��ť��
		"Edit",						// �༭����
		"ComboBox",					// ��Ͽ���
        "ListBox",                //NEW�����
		"ScrollBar",
		"Static",
		"#32770",
	    "msctls_hotkey32",			// �ȼ�
		"SysIPAddress32",			// IP ��ַ
		"SysListView32",			// �б��鿴
		"SysTreeView32",			// ���β鿴
		"SysDateTimePick32",		// ����/ʱ��ѡ��
		"msctls_updown32",			// ��ת
		"SysMonthCal32",			// ����
		"SysTabControl32",			// TAB �ؼ�
		"msctls_progress32",		// ������
		"msctls_trackbar32",		// ׷����
	};

	// �����ж�ƥ���������
	GetClassName(hWnd, szTemp, sizeof(szTemp));
	for (lReturn = 0; lReturn < (sizeof(s_szClass) / sizeof(s_szClass[0])); lReturn++)
		if (lstrcmpi(szTemp, s_szClass[lReturn]) == 0)
			break;
/*
    if ((GetWindowLong(hWnd, GWL_STYLE) && SS_TYPEMASK) == BS_OWNERDRAW)
		return CXPT_UNKNOWN; //�Ի水ť
*/
 	dwStyle = GetWindowLong(hWnd, GWL_STYLE);
	switch (lReturn)
	{
	case 0:
		//lReturn = GetWindowLong(hWnd, GWL_STYLE);
		switch (dwStyle & SS_TYPEMASK)
		{
		case BS_OWNERDRAW:          //�Ի水ť
			lReturn = CXPT_UNKNOWN;
			break;
		case BS_DEFPUSHBUTTON:		// Ĭ�ϰ�ť
		case BS_PUSHBUTTON:			// ��ͨ��ť
			lReturn = CXPT_PUSHBUTTON;
			break;

		case BS_CHECKBOX:			// ��ѡ��
		case BS_AUTOCHECKBOX:		// �Զ���ѡ��
		case BS_3STATE:				// ��״̬��ѡ��
		case BS_AUTO3STATE:			// �Զ���״̬��ѡ��
			if (dwStyle & BS_PUSHLIKE)
				lReturn = CXPT_PUSHBUTTON;
			else
				lReturn = CXPT_CHECKBOX;
			break;

		case BS_RADIOBUTTON:		// ��ѡ��
		case BS_AUTORADIOBUTTON:	// �Զ���ѡ��
			if (dwStyle & BS_PUSHLIKE)
				lReturn = CXPT_PUSHBUTTON;
			else
				lReturn = CXPT_RADIOBOX;
			break;
		case BS_GROUPBOX:	// ����
			 lReturn = CXPT_GROUPBOX;
			break;
		default:	// δ֪����
			lReturn = CXPT_UNKNOWN;
		}
		break;

	
	case 2:			// ��Ͽ�
	case 11:
	case 13:
		if ((dwStyle & 0x00000003) == CBS_SIMPLE)
			lReturn = CXPT_UNKNOWN;
		else
			lReturn = CXPT_COMBOBOX;
		break;
    case 3:       //���
		lReturn = CXPT_LISTBOX;
		break;
	case 4:
		lReturn = CXPT_SCROLLBOX;
//			lReturn = CXPT_UNKNOWN;
		break;
	case 5:
//       if((lReturn & SS_BITMAP) && !(lReturn & SS_ICON)) //BMPͼ�󲻴���
       if((dwStyle & SS_BITMAP)) //BMPͼ�󲻴���
		   return CXPT_UNKNOWN;
	    lReturn = CXPT_STATEBOX;
		break;
	case 6:
	    lReturn = CXPT_DIALOG;
		break;
	case 12:
		 lReturn = CXPT_SPINBOX;
		 break;
	case 1:			// �༭��
	case 7:
	case 8:
	case 9:
	case 10:
		if (dwStyle & WS_BORDER)
			lReturn = CXPT_EDITBOX;
		else
		{
			dwStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
			if ((dwStyle & WS_EX_CLIENTEDGE) || (dwStyle & WS_EX_STATICEDGE))
				lReturn = CXPT_EDITBOX;
			else
				lReturn = CXPT_UNKNOWN;
		}
		break;
/*
#ifdef CXP_DLLMODE
	// VB �� VCL �Ŀؼ���ֻ���ڶ�̬���ӿⷽʽ�²��п��ܳ����������
	case 7:
	case 8:
	case 9:
		lReturn = CXPT_PUSHBUTTON;
		break;

	case 10:
	case 11:
	case 12:
		lReturn = CXPT_CHECKBOX;
		break;

	case 13:
	case 14:
	case 15:
	case 16:
		lReturn = CXPT_EDITBOX;
		break;

	case 17:
	case 18:
	case 19:
		lReturn = CXPT_COMBOBOX;
		break;

#endif // CXP_DLLMODE
*/
	default:		// δ֪����
		lReturn = CXPT_UNKNOWN;
	}

	return lReturn;
}
////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////
// ��ȡ���ڵ��ڴ�����豸����
HDC WINAPI GetMemDCXP(LPMEMDCXP pMdcxp)
{
	RECT Rect;

	GetWindowRect(pMdcxp->hWnd, &Rect);
	// ���������ڴ�����豸����������Ϊ͸��ģʽ
	pMdcxp->hDC = GetWindowDC(pMdcxp->hWnd);
	pMdcxp->hMemDC = CreateCompatibleDC(pMdcxp->hDC);;
    SetBkMode(pMdcxp->hMemDC, TRANSPARENT);

	// �Ƿ��Ѿ�ָ����λͼ���
	if (pMdcxp->hBitmap)
	{
		// ѡ��λͼ����
		SelectObject(pMdcxp->hMemDC, pMdcxp->hBitmap);
	}
	else
	{
		// ������ѡ��λͼ����
		pMdcxp->hBitmap = (HBITMAP) SelectObject(pMdcxp->hMemDC,
			CreateCompatibleBitmap(pMdcxp->hDC, Rect.right - Rect.left, Rect.bottom - Rect.top));
	}

	// ���Ҫ��������
	if (pMdcxp->bTransfer == TRUE)
	{
		BitBlt(pMdcxp->hMemDC, 0 , 0,
			Rect.right - Rect.left, Rect.bottom - Rect.top, pMdcxp->hDC, 0 , 0, SRCCOPY);
	}

	return pMdcxp->hMemDC;
}
////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////
// ��ȡ���ڵ��ڴ�����豸����
VOID WINAPI ReleaseMemDCXP(LPMEMDCXP pMdcxp)
{
	RECT Rect;

	// ���Ҫ��������
	if (pMdcxp->bTransfer == TRUE)
	{
		GetWindowRect(pMdcxp->hWnd, &Rect);
		BitBlt(pMdcxp->hDC, 0 , 0,
			Rect.right - Rect.left, Rect.bottom - Rect.top, pMdcxp->hMemDC, 0 ,0, SRCCOPY);
	}

	if (pMdcxp->hBitmap)
		DeleteObject(SelectObject(pMdcxp->hMemDC, pMdcxp->hBitmap));
	DeleteDC(pMdcxp->hMemDC);
	ReleaseDC(pMdcxp->hWnd, pMdcxp->hDC);
}
////////////////////////////////////////////////////////////////////////////////////////////////////


//ƽ����ͼ
//void CXPDialog::GradientFill(HDC hdc, const CRect &rt, COLORREF crColor[], int fillType)
VOID WINAPI GradientRectXP2(HDC hdc, const RECT &rt,COLORREF crColor[], int fillType)
{
	TRIVERTEX        vert[4] ;
	GRADIENT_RECT    gRect;
	vert[0].x      = rt.left;
	vert[0].y      = rt.top;
	vert[0].Red    = (GetRValue(crColor[0]))<<8;
	vert[0].Green  = (GetGValue(crColor[0]))<<8;
	vert[0].Blue   = (GetBValue(crColor[0]))<<8;
	vert[0].Alpha  = 0x0000;
	vert[1].Red    = (GetRValue(crColor[1]))<<8;
	vert[1].Green  = (GetGValue(crColor[1]))<<8;
	vert[1].Blue   = (GetBValue(crColor[1]))<<8;
	vert[1].Alpha  = 0x0000;
	if ( fillType != GRADIENT_FILL_TRIANGLE )
	{
		vert[1].x      = rt.right;
		vert[1].y      = rt.bottom; 
		gRect.UpperLeft  = 0;
		gRect.LowerRight = 1;
		::GradientFill(hdc,vert,2,&gRect,1,fillType);
		return ;
	}
	
	vert[1].x      = rt.right;
	vert[1].y      = rt.top;
	vert[2].x      = rt.left;
	vert[2].y      = rt.bottom;
	vert[2].Red    = (GetRValue(crColor[2]))<<8;
	vert[2].Green  = (GetGValue(crColor[2]))<<8;
	vert[2].Blue   = (GetBValue(crColor[2]))<<8;
	vert[2].Alpha  = 0x0000;
	vert[3].x      = rt.right;
	vert[3].y      = rt.bottom; 
	vert[3].Red    = (GetRValue(crColor[3]))<<8;
	vert[3].Green  = (GetGValue(crColor[3]))<<8;
	vert[3].Blue   = (GetBValue(crColor[3]))<<8;
	vert[3].Alpha  = 0x0000;
	GRADIENT_TRIANGLE GTrg;
	GTrg.Vertex1=0;
	GTrg.Vertex2=1;
	GTrg.Vertex3=2;
	::GradientFill(hdc,vert,4,&GTrg,1,fillType);
	GTrg.Vertex1=1;
	GTrg.Vertex2=2;
	GTrg.Vertex3=3;
	::GradientFill(hdc,vert,4,&GTrg,1,fillType);
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// ���ƽ������
VOID WINAPI GradientRectXP(HDC hDC, LPRECT pRect,COLORREF crColor[4])
{
	int i;
	TRIVERTEX Tve[4]; 
	GRADIENT_RECT GRect;
	GRADIENT_TRIANGLE GTrg;

	for (i = 0; i < 4; i++)
	{
		Tve[i].Red = ((COLOR16) GetRValue(crColor[i])) << 8;
		Tve[i].Green = ((COLOR16) GetGValue(crColor[i])) << 8;
		Tve[i].Blue = ((COLOR16) GetBValue(crColor[i])) << 8;
		Tve[i].Alpha = ((COLOR16) (crColor[i] >> 24)) << 8;
	}

	Tve[0].x = pRect->left;
	Tve[0].y = pRect->top;
	Tve[1].x = pRect->right;
	Tve[1].y = pRect->top;
	Tve[2].x = pRect->left;
	Tve[2].y = pRect->bottom;
	Tve[3].x = pRect->right;
	Tve[3].y = pRect->bottom;

	if ((crColor[0] == crColor[2]) &&
		(crColor[1] == crColor[3]))
		i = GRADIENT_FILL_RECT_H;
	if ((crColor[0] == crColor[1]) &&
		(crColor[2] == crColor[3]))
		i = GRADIENT_FILL_RECT_V;
	else
		i = GRADIENT_FILL_TRIANGLE;

	if (i == GRADIENT_FILL_TRIANGLE)
	{
		GTrg.Vertex1 = 0;
		GTrg.Vertex2 = 1;
		GTrg.Vertex3 = 2;
	}
	else
	{
		GRect.UpperLeft = 0;
		GRect.LowerRight = 3;
	}
	GradientFill(hDC, Tve, 4,
		((i == GRADIENT_FILL_TRIANGLE) ? ((PVOID) &GTrg) : ((PVOID) &GRect)), 1, i);

	if (i == GRADIENT_FILL_TRIANGLE)
	{
		GTrg.Vertex1 = 3;
		GradientFill(hDC,Tve, 4, &GTrg, 1, GRADIENT_FILL_TRIANGLE);
	}
}
////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////
// ���ƽ������
/*
VOID WINAPI DrawDropGripXP(HDC hDC, LPRECT pRect, COLORREF crColor[4], DWORD crBack)
{
	HANDLE hHandle; 
	RECT Rect;
	Rect.left = pRect->left ;
	Rect.top = pRect->top;
	Rect.right = pRect->right ;
	Rect.bottom= pRect->bottom;
	static COLORREF s_crGradientXP[][4] =
	{
		{0x00F7F7F7, 0x00EFF3F7, 0x00EFF3F7, 0x00EFF3F7},
		{0x00DEC3BD, 0x00DEB6AD, 0x00FFE3DE, 0x00F7E3DE},
		{0x00EFDBCE, 0x00EFCFC6, 0x00E7CFC6, 0x00E7CBBD},
		{0x00FFEFE7, 0x00FFE7DE, 0x00FFE3DE, 0x00F7E3DE},
	};
	// �������
	hHandle = (HANDLE) CreateSolidBrush(0x00FFFFFF);
	FrameRect(hDC, &Rect, (HBRUSH) hHandle);
//	DeleteObject((HGDIOBJ) hHandle);

	// �����ڿ�
//	InflateRect(&Rect, -1, -1);
//	Rect.left = Rect.right - GetSystemMetrics(SM_CYVTHUMB);
	FrameRect(hDC, &Rect, (HBRUSH) hHandle);

	// �����������
	GradientRectXP(hDC, pRect, crColor);

	// �����������ս�����
	SetPixel(hDC, Rect.left, Rect.top, s_crGradientXP[0][0]);
	SetPixel(hDC, Rect.right - 1, Rect.top, s_crGradientXP[0][1]);
	SetPixel(hDC, Rect.left, Rect.bottom - 1, s_crGradientXP[0][2]);
	SetPixel(hDC, Rect.right - 1, Rect.bottom - 1, s_crGradientXP[0][3]);		

	// ���������ڿ�
//	InflateRect(&Rect, -1, -1);
//	GradientRectXP(Mdcxp.hMemDC, &Rect, s_crGradientXP[i + 8]);
//	DeleteObject(SelectObject(hDC, (HGDIOBJ) hHandle));

}
*/
////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////
// ö�ٴ��ڻص�����
BOOL CALLBACK EnumWndProcXP(HWND hWnd, LPARAM lParam)
{
	// �����ȡ��ָ�����ڵ� ClassXP ���
	if (lParam == FALSE)
		DeleteClassXP(hWnd);
	// ���������ָ�����ڵ� ClassXP ���
	else
		CreateClassXP(hWnd);	

	// ö���Ӵ���
	EnumChildWindows(hWnd, EnumWndProcXP, lParam);
	return TRUE;
}
////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////
// ������Ϣ HOOK �ص�����
LRESULT CALLBACK HookProcXP(int iCode, WPARAM wParam, LPARAM lParam)
{
	// �����½��Ĵ���Ϊ ClassXP ���
	if ((((CWPSTRUCT *) lParam)->message == WM_CREATE) && (iCode >= 0))
		CreateClassXP(((CWPSTRUCT *) lParam)->hwnd);

	return CallNextHookEx(g_hPrevHookXP, iCode, wParam, lParam);
}
////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////
// �������໯�ص�����
LRESULT CALLBACK WindowProcXP(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	LONG lReturn;
	PCLASSXP pCxp;
	pCxp = GetClassXP(hWnd);
	switch (pCxp->dwType)
	{
	case CXPT_PUSHBUTTON:	// ��ť
	case CXPT_CHECKBOX:		// ��ѡ��
	case CXPT_RADIOBOX:		// ��ѡ��
//	case CXPT_GROUPBOX:		// ��Ͽ�
//	case CXPT_STATEBOX:		// ˵����
         return ButtonWindowProc(pCxp, uMsg,wParam, lParam);
	case CXPT_EDITBOX:		// �༭��
         return EditWindowProc(pCxp, uMsg,wParam, lParam);
	case CXPT_COMBOBOX:		// ��Ͽ�
         return ComboWindowProc(pCxp, uMsg,wParam, lParam);
/*	case CXPT_LISTBOX:		// ���
         return ListWindowProc(pCxp, uMsg,wParam, lParam);
	case CXPT_SCROLLBOX:	// ������
         return ScrollWindowProc(pCxp, uMsg,wParam, lParam);
	case CXPT_DIALOG:		// ��������
         return DlgWindowProc(pCxp, uMsg,wParam, lParam);
	case CXPT_SPINBOX:		// ��ת��
         return SpinWindowProc(pCxp, uMsg,wParam, lParam);*/
	}
// ����ԭ���Ļص�����
	lReturn = (LONG) CallWindowProc(pCxp->wpPrev, hWnd, uMsg, wParam, lParam);
	return lReturn;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
#ifdef __cplusplus
}
#endif // __cplusplus
////////////////////////////////////////////////////////////////////////////////////////////////////