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

📄 skinmenumgr.cpp

📁 WMI接口测试Demo程序
💻 CPP
字号:
// SkinMenuMgr.cpp: implementation of the CSkinMenuMgr class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"

#include "SkinMenuMgr.h"
#include "skinmenu.h"
#include "wclassdefines.h"
#include "skinbase.h"

#ifndef NO_SKIN_INI
#include "skininifile.h"
#endif

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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CSkinMenuMgr::CSkinMenuMgr()
{
	m_dwMenuStyle = SKMS_SIDEBAR;
	m_nSidebarWidth = 10;
	m_pCurSkinMenu = NULL;
	m_hCurContextWnd = NULL;
	m_hCurMenu = NULL;
}

CSkinMenuMgr::~CSkinMenuMgr()
{
	// cleanup any remaining windows
	ASSERT (!m_mapMenus.GetCount());

	if (m_mapMenus.GetCount() != 0)
	{
		HWND hwnd;
		CSkinMenu* pSkin;
		POSITION pos = m_mapMenus.GetStartPosition();

		while (pos)
		{
			m_mapMenus.GetNextAssoc(pos, hwnd, pSkin);

			if (pSkin)
				delete pSkin;
		}

		m_mapMenus.RemoveAll();
	}

	m_skGlobals.Reset();
}

/////////////////////////////////////////////////////////////////////////////////
// static methods start

BOOL CSkinMenuMgr::Initialize(DWORD dwMenuStyle, int nSBWidth, BOOL bNotXP)
{
	if (bNotXP && CSkinBase::GetOS() >= SBOS_XP)
	{
		return FALSE;
	}

	// only initialize once
	VERIFY(GetInstance().InitHooks(HM_CALLWNDPROC | HM_CBT));

	GetInstance().m_dwMenuStyle = dwMenuStyle;
	GetInstance().m_nSidebarWidth = nSBWidth;

	return TRUE;
}

#ifndef NO_SKIN_INI
void CSkinMenuMgr::UnloadSkin()
{
	GetInstance().m_skGlobals.UnloadSkin();
}

BOOL CSkinMenuMgr::LoadSkin(const CSkinIniGlobalsFile* pIniFile)
{
	if (!pIniFile)
		return FALSE;

	GetInstance().m_skGlobals.LoadSkin(pIniFile);

	return TRUE;
}
#endif

void CSkinMenuMgr::SetColor(int nColor, COLORREF color)
{
	int nOS = CSkinBase::GetOS();

	if (nOS == SBOS_95 || nOS == SBOS_NT4)
		return;

	GetInstance().m_skGlobals.SetColor(nColor, color);
}

COLORREF CSkinMenuMgr::GetColor(int nColor)
{
	return GetInstance().m_skGlobals.GetColor(nColor);
}

void CSkinMenuMgr::ClearColors()
{
	GetInstance().m_skGlobals.Reset();
}

// static methods end
///////////////////////////////////////////////////////////////////////////////////

//#define NO_SKINNING

void CSkinMenuMgr::OnCallWndProc(const MSG& msg)
{   
	static BOOL bSkinning = FALSE; // initialized first time only but persistent

	if (!bSkinning)
	{
		bSkinning = TRUE;

#ifndef NO_SKINNING

		// skin/unskin menus at each and every opportunity 
		switch (msg.message)
		{
		case WM_CREATE:
			if (CSkinMenu::IsMenuWnd(msg.hwnd))
			{
				BOOL bRes = Skin(msg.hwnd);
			}
			break;
			
		case WM_WINDOWPOSCHANGING: 
			if (CSkinMenu::IsMenuWnd(msg.hwnd) && msg.lParam)
			{
				WINDOWPOS* pWPos = (WINDOWPOS*)msg.lParam;

				if (pWPos->flags & SWP_SHOWWINDOW)
				{
					BOOL bRes = Skin(msg.hwnd);
				}
				else if (pWPos->flags & SWP_HIDEWINDOW)
				{
					BOOL bRes = Unskin(msg.hwnd);
				}
			}
			break;


		case 0x1e2:
			if (CSkinMenu::IsMenuWnd(msg.hwnd) && msg.wParam)
			{
				BOOL bRes = Skin(msg.hwnd);

				if (!bRes)
					TRACE("Skin failed on 0x1e2");
			}
			break;
			
		case WM_SHOWWINDOW: 
			if (CSkinMenu::IsMenuWnd(msg.hwnd))
			{
				if (msg.wParam)
				{
					BOOL bRes = Skin(msg.hwnd);
				}
				else // if (!msg.wParam)
				{
					BOOL bRes = Unskin(msg.hwnd);
				}
			}
			break;

		case WM_DESTROY:
		case WM_NCDESTROY:
			if (CSkinMenu::IsMenuWnd(msg.hwnd))
			{
				BOOL bRes = Unskin(msg.hwnd);
			}
			break;

			// grab the menu handle at each and every opportunity
			//
			// notes:
			//
			// 1. menu bars generate a WM_INITMENUPOPUP prior to showing their menus
			//
			// 2. edit windows do not generate WM_INITMENUPOPUP prior to showing
			//    their context menu so the best we can do is grab their window handle
			//
			// 3. other controls display their context menus prior to generating
			//    a WM_INITMENUPOPUP

		case WM_CONTEXTMENU: // means a menu may be about to appear
			{
				TRACEMSG("OnCallWndProc", &msg);
				m_pCurSkinMenu = NULL;
				m_hCurContextWnd = msg.hwnd;

				TRACE ("WM_CONTEXTMENU sent to window of type '%s'\n", CWinClasses::GetClass(msg.hwnd));
			}
			break;

		case WM_INITMENUPOPUP:
			TRACEMSG("OnCallWndProc", &msg);

			if (m_pCurSkinMenu && !m_pCurSkinMenu->GetMenu())
			{
				m_pCurSkinMenu->SetContextWnd(NULL);
				m_pCurSkinMenu->SetMenu((HMENU)msg.wParam, GetParentSkinMenu((HMENU)msg.wParam));

				m_hCurMenu = NULL;
				m_pCurSkinMenu = NULL;
				m_hCurContextWnd = NULL;
			}
			else // save for menu skinning
				m_hCurMenu = (HMENU)msg.wParam;
		}
#endif

		if (msg.message != WM_NCHITTEST)
			TRACEMSG("OnCallWndProc", &msg, WC_MENU);

		bSkinning = FALSE;
	}
}

BOOL CSkinMenuMgr::OnCbt(int nCode, WPARAM wParam, LPARAM lParam)
{   
	if (nCode == HCBT_SYSCOMMAND)
	{
		switch (wParam)
		{
		case SC_MOUSEMENU:
			if (lParam)
			{
				int xPos = GET_X_LPARAM(lParam);
				int yPos = GET_Y_LPARAM(lParam);

				HWND hwnd = WindowFromPoint(CPoint(xPos, yPos));

				if (hwnd && (GetWindowLong(hwnd, GWL_STYLE) & WS_SYSMENU))
				{
					// convert to window coords
					CRect rWindow;
					GetWindowRect(hwnd, rWindow);

					CPoint ptScreen(xPos, yPos);

					xPos -= rWindow.left;
					yPos -= rWindow.top;

					if (xPos > 0 && xPos < 16 && yPos > 0 && yPos < 16)
					{
						CSkinBase::DoSysMenu(CWnd::FromHandle(hwnd), ptScreen, NULL, TRUE);
						return TRUE; // handled
					}
				}
			}
			break;
		}
	}

	return FALSE;
}

CSkinMenu* CSkinMenuMgr::GetSkinMenu(HWND hWnd)
{
	CSkinMenu* pSkin = NULL;
	
	m_mapMenus.Lookup(hWnd, pSkin);
	return pSkin;
}

BOOL CSkinMenuMgr::Unskin(HWND hWnd)
{
	m_pCurSkinMenu = NULL;
	m_hCurContextWnd = NULL;
	m_hCurMenu = NULL;

	ASSERT (CSkinMenu::IsMenuWnd(hWnd));

	CSkinMenu* pSkinMenu = GetSkinMenu(hWnd);
	
	if (!pSkinMenu)
		return TRUE; // already done
	
	TRACE ("menu unskinned (%08X)\n", (UINT)hWnd);
	m_mapMenus.RemoveKey(hWnd);

	pSkinMenu->DetachWindow();
	delete pSkinMenu;

	return TRUE;
}

BOOL CSkinMenuMgr::Skin(HWND hWnd)
{
	ASSERT (CSkinMenu::IsMenuWnd(hWnd));

	CSkinMenu* pSkinMenu = GetSkinMenu(hWnd);
	
	if (pSkinMenu)
		return TRUE; // already done

	pSkinMenu = new CSkinMenu(&m_skGlobals, m_dwMenuStyle, m_nSidebarWidth);
	
	if (pSkinMenu && pSkinMenu->AttachWindow(hWnd))
	{
		TRACE ("menu skinned (%08X)\n", (UINT)hWnd);

		m_pCurSkinMenu = pSkinMenu;
		m_pCurSkinMenu->SetContextWnd(m_hCurContextWnd);
		m_pCurSkinMenu->SetMenu(m_hCurMenu, GetParentSkinMenu(m_hCurMenu));

		m_mapMenus[hWnd] = pSkinMenu;

		return TRUE;
	}
	
	// else
	delete pSkinMenu;
	return FALSE;
}

CSkinMenu* CSkinMenuMgr::GetParentSkinMenu(HMENU hMenu)
{
	if (!hMenu)
		return NULL;

	// search the map if CSkinMenus looking for a menu
	// having this menu as a popup
	HWND hwnd;
	CSkinMenu* pSkin;
	POSITION pos = m_mapMenus.GetStartPosition();

	while (pos)
	{
		m_mapMenus.GetNextAssoc(pos, hwnd, pSkin);

		const HMENU hOther = pSkin->GetMenu();

		if (hOther && hOther != hMenu)
		{
			// iterate the items looking for submenus
			int nMenu = GetMenuItemCount(hOther);

			while (nMenu--)
			{
				if (GetSubMenu(hOther, nMenu) == hMenu) // submenu
					return pSkin;
			}
		}
	}
	
	return NULL;
}

⌨️ 快捷键说明

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