📄 skinmenumgr.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 + -