📄 cmdbar.h
字号:
// Ramon Smits (mailto:ramons@infosupport.co)
// Cool WTL menu with Gradient Sidebar (http://www.codetools.com/wtl/sidebarmenu.asp)
#ifndef _CmdBar_d1d0a48a_662a_4619_9da7_d547a97e0acc
#define _CmdBar_d1d0a48a_662a_4619_9da7_d547a97e0acc
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
template <class T, class TBase = CCommandBarCtrlBase, class TWinTraits = CControlWinTraits>
class ATL_NO_VTABLE RamonSmit_CCommandBarCtrlImpl : public CWindowImpl< T, TBase, TWinTraits>
{
public:
DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName())
// Declarations
struct _MenuItemData // menu item data
{
DWORD dwMagic;
LPTSTR lpstrText;
UINT fType;
UINT fState;
int iButton;
_MenuItemData() { dwMagic = 0x1313; }
bool IsCmdBarMenuItem() { return (dwMagic == 0x1313); }
};
struct _ToolBarData // toolbar resource data
{
WORD wVersion;
WORD wWidth;
WORD wHeight;
WORD wItemCount;
//WORD aItems[wItemCount]
WORD* items()
{ return (WORD*)(this+1); }
};
// Constants
enum _CmdBarDrawConstants
{
s_kcxGap = 1,
s_kcxTextMargin = 2,
s_kcxButtonMargin = 3,
s_kcyButtonMargin = 3
};
enum { _nMaxMenuItemTextLength = 100 };
// Data members
HMENU m_hMenu;
HIMAGELIST m_hImageList;
CSimpleValArray<WORD> m_arrCommand;
CContainedWindow m_wndParent;
CContainedWindow m_wndMDIClient;
bool m_bMenuActive;
bool m_bAttachedMenu;
bool m_bImagesVisible;
bool m_bPopupItem;
bool m_bContextMenu;
bool m_bEscapePressed;
int m_nPopBtn;
int m_nNextPopBtn;
SIZE m_szBitmap;
SIZE m_szButton;
COLORREF m_clrMask;
CFont m_fontMenu;
bool m_bSkipMsg;
UINT m_uSysKey;
HWND m_hWndFocus; // Alternate focus mode
DWORD m_dwExtendedStyle; // Command Bar specific extended styles
// Constructor/destructor
RamonSmit_CCommandBarCtrlImpl() :
m_hMenu(NULL),
m_hImageList(NULL),
m_wndParent(this, 1),
m_bMenuActive(false),
m_bAttachedMenu(false),
m_nPopBtn(-1),
m_nNextPopBtn(-1),
m_bPopupItem(false),
m_bImagesVisible(true),
m_wndMDIClient(this, 2),
m_bSkipMsg(false),
m_uSysKey(0),
m_hWndFocus(NULL),
m_bContextMenu(false),
m_bEscapePressed(false),
m_clrMask(RGB(192, 192, 192)),
m_dwExtendedStyle(CBR_EX_TRANSPARENT | CBR_EX_SHAREMENU)
{
m_szBitmap.cx = 16;
m_szBitmap.cy = 15;
m_szButton.cx = m_szBitmap.cx + s_kcxButtonMargin;
m_szButton.cy = m_szBitmap.cy + s_kcyButtonMargin;
}
~RamonSmit_CCommandBarCtrlImpl()
{
if(m_wndParent.IsWindow())
/*scary!*/ m_wndParent.UnsubclassWindow();
if(m_wndMDIClient.IsWindow())
/*scary!*/ m_wndMDIClient.UnsubclassWindow();
if(m_hMenu != NULL && (m_dwExtendedStyle & CBR_EX_SHAREMENU) == 0)
::DestroyMenu(m_hMenu);
if(m_hImageList != NULL)
::ImageList_Destroy(m_hImageList);
}
// Attributes
DWORD GetCommandBarExtendedStyle() const
{
return m_dwExtendedStyle;
}
DWORD SetCommandBarExtendedStyle(DWORD dwExtendedStyle)
{
DWORD dwPrevStyle = m_dwExtendedStyle;
m_dwExtendedStyle = dwExtendedStyle;
return dwPrevStyle;
}
CMenuHandle GetMenu() const
{
ATLASSERT(::IsWindow(m_hWnd));
return m_hMenu;
}
COLORREF GetImageMaskColor() const
{
ATLASSERT(::IsWindow(m_hWnd));
return m_clrMask;
}
COLORREF SetImageMaskColor(COLORREF clrMask)
{
ATLASSERT(::IsWindow(m_hWnd));
COLORREF clrOld = m_clrMask;
m_clrMask = clrMask;
return clrOld;
}
bool GetImagesVisible() const
{
ATLASSERT(::IsWindow(m_hWnd));
return m_bImagesVisible;
}
bool SetImagesVisible(bool bVisible)
{
ATLASSERT(::IsWindow(m_hWnd));
bool bOld = m_bImagesVisible;
m_bImagesVisible = bVisible;
return bOld;
}
void GetImageSize(SIZE& size) const
{
ATLASSERT(::IsWindow(m_hWnd));
size = m_szBitmap;
}
bool SetImageSize(SIZE& size)
{
ATLASSERT(::IsWindow(m_hWnd));
if(m_hImageList != NULL)
{
if(::ImageList_GetImageCount(m_hImageList) == 0) // empty
{
::ImageList_Destroy(m_hImageList);
m_hImageList = NULL;
}
else
{
return false; // can't set, image list exists
}
}
if(size.cx == 0 || size.cy == 0)
return false;
m_szBitmap = size;
m_szButton.cx = m_szBitmap.cx + s_kcxButtonMargin;
m_szButton.cy = m_szBitmap.cy + s_kcyButtonMargin;
return true;
}
HWND GetCmdBar() const
{
ATLASSERT(::IsWindow(m_hWnd));
return (HWND)::SendMessage(m_hWnd, CBRM_GETCMDBAR, 0, 0L);
}
// Methods
BOOL AttachToWindow(HWND hWnd)
{
ATLASSERT(m_hWnd == NULL);
ATLASSERT(::IsWindow(hWnd));
BOOL bRet = SubclassWindow(hWnd);
if(bRet)
{
m_bAttachedMenu = true;
GetSystemSettings();
}
return bRet;
}
BOOL LoadMenu(_U_STRINGorID menu)
{
ATLASSERT(::IsWindow(m_hWnd));
if(m_bAttachedMenu) // doesn't work in this mode
return FALSE;
if(menu.m_lpstr == NULL)
return FALSE;
HMENU hMenu = ::LoadMenu(_Module.GetResourceInstance(), menu.m_lpstr);
if(hMenu == NULL)
return FALSE;
return AttachMenu(hMenu);
}
BOOL AttachMenu(HMENU hMenu)
{
ATLASSERT(::IsWindow(m_hWnd));
ATLASSERT(::IsMenu(hMenu));
if(hMenu != NULL && !::IsMenu(hMenu))
return FALSE;
// destroy old menu, if needed, and set new one
if(m_hMenu != NULL && (m_dwExtendedStyle & CBR_EX_SHAREMENU) == 0)
::DestroyMenu(m_hMenu);
m_hMenu = hMenu;
if(m_bAttachedMenu) // Nothing else in this mode
return TRUE;
// Build buttons according to menu
SetRedraw(FALSE);
// Clear all
BOOL bRet;
int nCount = GetButtonCount();
for(int i = 0; i < nCount; i++)
{
bRet = DeleteButton(0);
ATLASSERT(bRet);
}
// Add buttons for each menu item
if(m_hMenu != NULL)
{
int nItems = ::GetMenuItemCount(m_hMenu);
TCHAR szString[_nMaxMenuItemTextLength];
for(int i = 0; i < nItems; i++)
{
CMenuItemInfo mii;
mii.fMask = MIIM_ID | MIIM_TYPE;
mii.fType = MFT_STRING;
mii.dwTypeData = szString;
mii.cch = _nMaxMenuItemTextLength;
bRet = ::GetMenuItemInfo(m_hMenu, i, TRUE, &mii);
ATLASSERT(bRet);
// If we have more than the buffer, we assume we have bitmaps bits
if(lstrlen(szString) > _nMaxMenuItemTextLength - 1)
{
mii.fType = MFT_BITMAP;
::SetMenuItemInfo(m_hMenu, i, TRUE, &mii);
szString[0] = 0;
}
// NOTE: Command Bar currently supports only menu items
// that are enabled and have a drop-down menu
TBBUTTON btn;
btn.iBitmap = 0;
btn.idCommand = i;
btn.fsState = TBSTATE_ENABLED;
btn.fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE | TBSTYLE_DROPDOWN;
btn.dwData = 0;
btn.iString = 0;
bRet = InsertButton(-1, &btn);
ATLASSERT(bRet);
TBBUTTONINFO bi;
memset(&bi, 0, sizeof(bi));
bi.cbSize = sizeof(TBBUTTONINFO);
bi.dwMask = TBIF_TEXT;
bi.pszText = szString;
bRet = SetButtonInfo(i, &bi);
ATLASSERT(bRet);
}
}
SetRedraw(TRUE);
Invalidate();
UpdateWindow();
return TRUE;
}
BOOL LoadImages(_U_STRINGorID image)
{
ATLASSERT(::IsWindow(m_hWnd));
HINSTANCE hInstance = _Module.GetResourceInstance();
HRSRC hRsrc = ::FindResource(hInstance, image.m_lpstr, (LPTSTR)RT_TOOLBAR);
if(hRsrc == NULL)
return FALSE;
HGLOBAL hGlobal = ::LoadResource(hInstance, hRsrc);
if(hGlobal == NULL)
return FALSE;
_ToolBarData* pData = (_ToolBarData*)::LockResource(hGlobal);
if(pData == NULL)
return FALSE;
ATLASSERT(pData->wVersion == 1);
WORD* pItems = pData->items();
int nItems = pData->wItemCount;
// Add bitmap to our image list (create it if it doesn't exist)
if(m_hImageList == NULL)
{
m_hImageList = ::ImageList_Create(pData->wWidth, pData->wHeight, ILC_COLOR | ILC_MASK, pData->wItemCount, 1);
ATLASSERT(m_hImageList != NULL);
if(m_hImageList == NULL)
return FALSE;
}
CBitmap bmp;
bmp.LoadBitmap(image.m_lpstr);
ATLASSERT(bmp.m_hBitmap != NULL);
if(bmp.m_hBitmap == NULL)
return FALSE;
if(::ImageList_AddMasked(m_hImageList, bmp, m_clrMask) == -1)
return FALSE;
// Fill the array with command IDs
for(int i = 0; i < nItems; i++)
{
if(pItems[i] != 0)
m_arrCommand.Add(pItems[i]);
}
ATLASSERT(::ImageList_GetImageCount(m_hImageList) == m_arrCommand.GetSize());
if(::ImageList_GetImageCount(m_hImageList) != m_arrCommand.GetSize())
return FALSE;
// Set some internal stuff
m_szBitmap.cx = pData->wWidth;
m_szBitmap.cy = pData->wHeight;
m_szButton.cx = m_szBitmap.cx + 2 * s_kcxButtonMargin;
m_szButton.cy = m_szBitmap.cy + 2 * s_kcyButtonMargin;
return TRUE;
}
BOOL AddBitmap(_U_STRINGorID bitmap, int nCommandID)
{
ATLASSERT(::IsWindow(m_hWnd));
CBitmap bmp;
bmp.LoadBitmap(bitmap.m_lpstr);
if(bmp.m_hBitmap == NULL)
return FALSE;
return AddBitmap(bmp, nCommandID);
}
BOOL AddBitmap(HBITMAP hBitmap, UINT nCommandID)
{
// Create image list if it doesn't exist
if(m_hImageList == NULL)
{
m_hImageList = ::ImageList_Create(m_szBitmap.cx, m_szBitmap.cy, ILC_COLOR | ILC_MASK, 1, 1);
if(m_hImageList == NULL)
return FALSE;
}
// check bitmap size
CBitmapHandle bmp = hBitmap;
SIZE size = { 0, 0 };
bmp.GetSize(size);
if(size.cx != m_szBitmap.cx || size.cy != m_szBitmap.cy)
{
ATLASSERT(FALSE); // must match size!
return FALSE;
}
// add bitmap
int nRet = ::ImageList_AddMasked(m_hImageList, hBitmap, m_clrMask);
if(nRet == -1)
return FALSE;
BOOL bRet = m_arrCommand.Add((WORD)nCommandID);
ATLASSERT(::ImageList_GetImageCount(m_hImageList) == m_arrCommand.GetSize());
return bRet;
}
BOOL AddIcon(HICON hIcon, UINT nCommandID)
{
// create image list if it doesn't exist
if(m_hImageList == NULL)
{
m_hImageList = ::ImageList_Create(m_szBitmap.cx, m_szBitmap.cy, ILC_COLOR | ILC_MASK, 1, 1);
if(m_hImageList == NULL)
return FALSE;
}
int nRet = ::ImageList_AddIcon(m_hImageList, hIcon);
if(nRet == -1)
return FALSE;
BOOL bRet = m_arrCommand.Add((WORD)nCommandID);
ATLASSERT(::ImageList_GetImageCount(m_hImageList) == m_arrCommand.GetSize());
return bRet;
}
BOOL ReplaceBitmap(_U_STRINGorID bitmap, int nCommandID)
{
ATLASSERT(::IsWindow(m_hWnd));
CBitmap bmp;
bmp.LoadBitmap(bitmap.m_lpstr);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -