⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 classxp.cpp

📁 一个学生考试成绩管理的半成品
💻 CPP
字号:
////////////////////////////////////////////////////////////////////////////////////////////////////
// 说明: ClassXP.c 文件
// 更新: 2003-3-10
////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////
// 编译预处理
#if _WIN32_WINNT < 0x0400
#define _WIN32_WINNT 0x0400
#endif

//#include <Windows.h>
#include "ClassXP.h"
//#include <winuser.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;
    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_EDITBOX:
				if (lStyle & ES_READONLY)
					pCxp->dwState |= CXPS_READONLY;
				break;
			}
		// 重画窗口
			RedrawWindow(hWnd, NULL, NULL,
				 RDW_UPDATENOW|RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ERASENOW);
			return pCxp;
		}
	}
// 重画窗口
//	RedrawWindow(hWnd, NULL, NULL,
//				RDW_FRAME | RDW_INVALIDATE );
	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;
	char szTemp[MAX_PATH];
	static char s_szClass[][32] = 
	{
		"Button",					// 按钮类
		"Edit",						// 编辑框类
		"ComboBox",					// 组合框类
        "ListBox",                //NEW:列表框
		"ScrollBar",
		"Static",
		"#32770",
#ifdef CXP_DLLMODE
		"TButton",					// VCL TButton 类
		"ThunderCommandButton",		// Visual Basic Command Button 类
		"ThunderRT6CommandButton",	// Visual Basic Command Button 类
		"TCheckBox",
		"ThunderCheckBox",
		"ThunderRT6CheckBox",
		"TEdit",
		"TNumberEdit",
		"ThunderTextBox",
		"ThunderRT6TextBox",
		"TComboBox",
		"ThunderComboBox",
		"ThunderRT6ComboBox"
#endif // CXP_DLLMODE
	};

	// 查找判断匹配的类名称
	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;
	switch (lReturn)
	{
	case 0:
		lReturn = GetWindowLong(hWnd, GWL_STYLE);
		switch (lReturn & SS_TYPEMASK)
		{
		case BS_GROUPBOX:	// 组合框
			 lReturn = CXPT_GROUPBOX;
			break;
		default:	// 未知类型
			lReturn = CXPT_UNKNOWN;
		}
		break;

	case 1:			// 编辑框
		lReturn = CXPT_EDITBOX;
		break;
	
	case 2:			// 组合框
		if ((GetWindowLong(hWnd, GWL_STYLE) & 0x00000003) == CBS_SIMPLE)
			lReturn = CXPT_UNKNOWN;
		else
			lReturn = CXPT_COMBOBOX;
		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

	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 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);
	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]);

}
// 枚举窗口回调函数
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_EDITBOX:		// 编辑框
         return EditWindowProc(pCxp, uMsg,wParam, lParam);
	case CXPT_COMBOBOX:		// 组合框
         return ComboWindowProc(pCxp, uMsg,wParam, lParam);
	}
// 调用原来的回调函数
	lReturn = (LONG) CallWindowProc(pCxp->wpPrev, hWnd, uMsg, wParam, lParam);
	return lReturn;
}
#ifdef __cplusplus
}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -