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

📄 xpdialog.cpp

📁 xp风格的对话框
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//////////////////////////////////////////////////////////////////////
// XPDialog.cpp: implementation of the CXPDialog class.
//
//作者:北斗龙
//EMail:xhjbeidoulong01@163.com
//Ver:	1.2
//日期:10-6
//申明:你可以随意使用和修改此代码,但请保留作者名字;

#include "stdafx.h"
#include "XPDialog.h"
#pragma comment(lib, "Msimg32.lib")		//为API:GradientFill所用

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//WndColor[0]窗体颜色最深点, WndColor[1]为窗体的本色,WndColor[2]为最亮点的颜色,WndColor[3]为国次亮点颜色, WndColor[4]为国次次亮点颜色
const COLORREF WndColor[]={ RGB(0,32,175), RGB(0,81,229), RGB(144,175,249), RGB(43,144,255), RGB(13,134,255)};
const COLORREF WndColorUnAct[]={ RGB(79,83,188), RGB(104,141,224), RGB(132,159,234), RGB(152,178,232), RGB(129,167,232) };

const COLORREF MinMaxBTColor[]={ RGB(132,159,234), RGB(104,141,224) };
const COLORREF MinMaxBTColorAct[]={ RGB(144,175,249), RGB(0,81,229) };
const COLORREF MinMaxBTColorMsOn[]={ RGB(132,159,234), RGB(13,134,255) };

const COLORREF ExitBTColor[]={ RGB(180,155,185), RGB(175,102,115) };
const COLORREF ExitBTColorAct[]={ RGB(240,169,151), RGB(228,61,5) };
const COLORREF ExitBTColorMsOn[]={ RGB(240,169,151), RGB(238,101,35) };

//////////////////////////////////////////////////////////
// Construction/Destruction
CXPDialog *CXPDialog::s_pThis=NULL;

CXPDialog::CXPDialog()
{
	//防止定义多个对象,因为不同对象共用s_pThis,产生不良后果
	ASSERT(s_pThis==NULL);

	s_pThis=this;
	m_phead=NULL;
	m_hPrevHookXP=NULL;
}

CXPDialog::~CXPDialog()
{
	SCLASSXP *p=m_phead;
	while(p!=NULL)
		p=this->DeleteCXPDialog(p->hWnd);
}

//设置或取消XP风格
BOOL CXPDialog::SetDialogXP(HWND hWnd, BOOL bsetXP)
{
	BOOL bReturn;
	if ( hWnd == NULL )//设置整个线程窗体
	{
		// 如果是取消当前进程中的所有窗口
		if ((bsetXP == FALSE) && (m_hPrevHookXP != NULL))
		{
			// 取消所有ClassXP 风格
			SCLASSXP *p=m_phead;
			while(p!=NULL)
				p=this->DeleteCXPDialog(p->hWnd);

			// 取消窗口消息 HOOK
			bReturn=UnhookWindowsHookEx(m_hPrevHookXP);
			m_hPrevHookXP = NULL;
		}
		// 如果是设置当前进程中的所有窗口
		else if ((bsetXP == TRUE) && (m_hPrevHookXP == NULL))
		{
			// 枚举当前线程中已存在的窗口
			CUIntArray gethWnd;
			EnumThreadWindows(GetCurrentThreadId(), EnumWndProcXP, (LONG)&gethWnd);
			//将所有窗体设为xp风格
			int j=gethWnd.GetSize();
			for ( int i=0; i<j; i++ )
				this->CreateCXPDialog((HWND)gethWnd[i]);

			// 安装窗口消息 HOOK
			m_hPrevHookXP = SetWindowsHookEx(WH_CALLWNDPROC, HookProcXP, 0, GetCurrentThreadId());
			bReturn = (BOOL) m_hPrevHookXP;
		}
	}
	else	//设定指定窗体
	{
		if ( bsetXP )
			bReturn=(BOOL)CreateCXPDialog(hWnd);
		else
			bReturn=(BOOL)DeleteCXPDialog(hWnd);
	}
	return bReturn;
}

//判定指定窗口是否XP化
BOOL CXPDialog::IsDialogXP(HWND hWnd)
{
	ASSERT( hWnd!=NULL );
	return (BOOL)this->Find(hWnd);
}


// 枚举窗口回调函数
CALLBACK CXPDialog::EnumWndProcXP(HWND hWnd, LPARAM lParam)
{
	CUIntArray *pGethWnd=(CUIntArray *)lParam;
	char szTmp[MAX_PATH];
	GetClassName(hWnd, szTmp, MAX_PATH);
	// 如果是对话框类将XP化
	if ( ::strcmp(szTmp, "#32770")==0 )
		pGethWnd->Add((UINT) hWnd);
	return TRUE;
}



// 窗口消息 HOOK 回调函数
LRESULT CALLBACK CXPDialog::HookProcXP(int iCode, WPARAM wParam, LPARAM lParam)
{
	// 设置新建的窗口为 ClassXP 风格
	if ((((CWPSTRUCT *) lParam)->message == WM_CREATE) && (iCode >= 0))
	{
		// 查找判断是否为对话框类
		char szTmp[MAX_PATH];
		GetClassName(((CWPSTRUCT *) lParam)->hwnd, szTmp, MAX_PATH);
		if ( ::strcmp(szTmp, "#32770")==0 )
			s_pThis->CreateCXPDialog(((CWPSTRUCT *) lParam)->hwnd);
	}

	return CallNextHookEx(s_pThis->m_hPrevHookXP, iCode, wParam, lParam);
}


//对窗体子类化
//返回创建的节点
SCLASSXP *CXPDialog::CreateCXPDialog(HWND hWnd)
{
	ASSERT(hWnd!=NULL);
	SCLASSXP *p;
	if( (p=Find(hWnd))!=NULL )//己被XP化则
		return p;

	p=m_phead;
	if ( p == NULL )
	{
		m_phead=new SCLASSXP;
		p=m_phead;
	}
	else
	{
		SCLASSXP *ptmp=m_phead->pNext;
		while( ptmp!=NULL )
		{
			p=ptmp;
			ptmp=ptmp->pNext;
		}
		p->pNext=new SCLASSXP;
		p=p->pNext;
	}

	p->hWnd=hWnd;
	p->wpPrev = (WNDPROC)::SetWindowLong(hWnd,GWL_WNDPROC,(LONG)DialogProcXP);//窗口子类化
	p->pNext=NULL;

	this->SetRoundWindow(hWnd, TRUE, TRUE);

	return p;
}

//取消窗体子类化
//返回它的下一个节点,为NULL则无下个节点
SCLASSXP * CXPDialog::DeleteCXPDialog(HWND hWnd)
{
	ASSERT(hWnd!=NULL);

	SCLASSXP *pPre,*p;
	
	pPre=p=m_phead;
	for ( ; p!=NULL; p=p->pNext )
	{
		//找到对应窗体
		if ( p->hWnd == hWnd )
		{
			if ( p == m_phead )
				m_phead=p->pNext;
			
			pPre->pNext=p->pNext;
			pPre=pPre->pNext;

			SetWindowLong(hWnd, GWL_WNDPROC, (LONG)p->wpPrev);
			delete p;

			//取消窗体圆角
			SetRoundWindow(hWnd, FALSE, FALSE);
			// 重画窗口
			::RedrawWindow(hWnd, NULL, NULL,
				RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ERASENOW | RDW_UPDATENOW);
			break;
		}
		 pPre=p;
	}
	return pPre;
}

//在连表中找到指定节点
SCLASSXP *CXPDialog::Find(HWND hWnd)
{
	SCLASSXP *pPre=m_phead;
	while( pPre!=NULL)
	{
		if ( pPre->hWnd == hWnd )
			break;
		else
			pPre=pPre->pNext;
	}
	return pPre;
}

//画标题栏线程
UINT CXPDialog::Thread(PVOID P)
{
	s_pThis->DrawDialog((HWND)P);
	return 1;
}

//窗体的过程函数
LRESULT CXPDialog::DialogProcXP(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	WNDPROC oldProc=s_pThis->Find(hWnd)->wpPrev;
	LONG lReturn;

	switch( uMsg )
	{
	case WM_NCLBUTTONDOWN:
		if ( s_pThis->OnNcLButtonDown(hWnd, wParam, lParam) )
			return true;
		break;

	case WM_NCACTIVATE:
		{
			SCLASSXP *p;
			p=s_pThis->Find(hWnd);
			p->bNcActive=wParam;
		}
	case WM_ACTIVATE:
	case WM_NCPAINT:
		lReturn=oldProc(hWnd, uMsg, wParam, lParam);
		s_pThis->DrawDialog(hWnd);
		return lReturn;

	case WM_SIZE:
		s_pThis->SetRoundWindow(hWnd, TRUE, TRUE);
		break;

	case WM_HELP:
	case WM_NCMOUSEMOVE:
	case WM_INITMENU:
		s_pThis->DrawDialog(hWnd);
		break;

	case WM_DESTROY:
		s_pThis->DeleteCXPDialog(hWnd);
	default:
		break;
	}
	
	return oldProc(hWnd, uMsg, wParam, lParam);
}


//返回TRUE,表示无需默认处理,
BOOL CXPDialog::OnNcLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
	UINT windowStyle=GetWindowLong(hWnd, GWL_STYLE);

	if ( HTCLOSE == wParam )
	{
		::SendMessage(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0);
		return TRUE;
	}

	if ( HTMAXBUTTON==wParam ) 
	{
		if ( windowStyle & WS_MAXIMIZEBOX )
		{
			if ( ::IsZoomed(hWnd) )
				wParam=SC_RESTORE;
			else
				wParam=SC_MAXIMIZE;
			::SendMessage(hWnd, WM_SYSCOMMAND, wParam, 0);
		}
		return TRUE;
	}

	if ( HTMINBUTTON==wParam )
	{
		if ( windowStyle & WS_MINIMIZEBOX )
		{
			if ( ::IsIconic(hWnd) )
				wParam=SC_RESTORE;
			else
				wParam=SC_MINIMIZE;
			 ::SendMessage(hWnd, WM_SYSCOMMAND, wParam, 0);
		}
		return TRUE;
	}

	if ( HTHELP == wParam )
	{
		::SendMessage(hWnd, WM_SYSCOMMAND, SC_CONTEXTHELP, 0);
	}
	
	::AfxBeginThread(Thread, hWnd);//启动线程维护标题
	return false;
}


//画对话框的非客户区
//hWnd,对应的窗体句柄
void CXPDialog::DrawDialog(HWND hWnd)
{
    HDC hdc;		//窗体的环境设备句柄
	HDC hMemdc;		//兼容环境设备句柄
	HBITMAP	hBmp;	//作图用的位图句柄
	CRect wndrt;	//窗体的屏幕位置
	CRect rt;
	UINT windowStyle, windowExStyle;
	int captionHi;	//标题的高度
	int frame;		//边框的宽度

⌨️ 快捷键说明

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