📄 mtluser.h
字号:
#ifndef __MTLUSER_H__
#define __MTLUSER_H__
// MTL Version 0.03
// Copyright (C) 2000 MB<mb2@geocities.co.jp>
// All rights unreserved.
//
// This file is a part of Mb Template Library.
// The code and information is *NOT* provided "as-is" without
// warranty of any kind, either expressed or implied.
//
// Last updated: August 11, 2000
#pragma once
#ifndef __MTLMISC_H__
#error mtluser.h requires mtlmisc.h to be included first
#endif
#ifndef __MTLWIN_H__
#error mtluser.h requires mtlwin.h to be included first
#endif
#include <functional>
#include <zmouse.h>
namespace MTL
{
using WTL::CReBarCtrl;
////////////////////////////////////////////////////////////////////////////
// for ReBar Bands
inline BOOL MtlToggleBandVisible(CReBarCtrl rebar, UINT nID)
{
ATLASSERT(rebar.IsWindow());
int nIndex = rebar.IdToIndex(nID);
ATLASSERT(nIndex != -1);
CVersional<REBARBANDINFO> rbBand;
rbBand.fMask = RBBIM_STYLE;
MTLVERIFY(rebar.GetBandInfo(nIndex, &rbBand));
BOOL bNew = (rbBand.fStyle & RBBS_HIDDEN) ? TRUE : FALSE;
MTLVERIFY(rebar.ShowBand(nIndex, bNew));
return bNew;
}
inline BOOL MtlShowBand(CReBarCtrl rebar, UINT nID, BOOL bVisible = TRUE)
{
ATLASSERT(rebar.IsWindow());
int nIndex = rebar.IdToIndex(nID);
ATLASSERT(nIndex != -1);
CVersional<REBARBANDINFO> rbBand;
rbBand.fMask = RBBIM_STYLE;
MTLVERIFY(rebar.GetBandInfo(nIndex, &rbBand));
BOOL bOldVisible = (rbBand.fStyle & RBBS_HIDDEN) ? FALSE : TRUE;
if (bOldVisible != bVisible)
MTLVERIFY(rebar.ShowBand(nIndex, bVisible));
return TRUE;
}
inline BOOL MtlIsBandVisible(CReBarCtrl rebar, UINT nID)
{
ATLASSERT(rebar.IsWindow());
int nIndex = rebar.IdToIndex(nID);
ATLASSERT(nIndex != -1);
CVersional<REBARBANDINFO> rbBand;
rbBand.fMask = RBBIM_STYLE;
MTLVERIFY(rebar.GetBandInfo(nIndex, &rbBand));
return rbBand.fStyle & RBBS_HIDDEN ? FALSE : TRUE;
}
#define REFLECT_CHEVRONPUSHED_NOTIFICATION() \
{ \
if (uMsg == WM_NOTIFY && RBN_CHEVRONPUSHED == ((LPNMHDR)lParam)->code) \
{ \
bHandled = TRUE; \
LPNMREBARCHEVRON lpnm = (LPNMREBARCHEVRON)lParam; \
HWND hWndReBar = lpnm->hdr.hwndFrom; \
HWND hWndBand = MtlGetReBarBandHwnd(hWndReBar, lpnm->wID); \
if (hWndBand != NULL) \
lResult = ::SendMessage(hWndBand, OCM__BASE + uMsg, wParam, lParam); \
else \
bHandled = FALSE; \
if (bHandled) \
return TRUE; \
} \
}
inline HWND MtlGetReBarBandHwnd(CReBarCtrl rebar, UINT nID)
{
ATLASSERT(rebar.IsWindow());
int nIndex = rebar.IdToIndex(nID);
ATLASSERT(nIndex != -1);
CVersional<REBARBANDINFO> rbBand;
rbBand.fMask = RBBIM_CHILD;
MTLVERIFY(rebar.GetBandInfo(nIndex, &rbBand));
ATLASSERT(::IsWindow(rbBand.hwndChild));
return rbBand.hwndChild;
}
////////////////////////////////////////////////////////////////////////////
// UIEnable and UISetCheck, UISetRadio
class UIEnableFunction : public std::unary_function<int, BOOL>
{
public:
explicit UIEnableFunction(CUpdateUIBase* pUpdateUI, BOOL bEnable)
: _pUpdateUI(pUpdateUI), _bEnable(bEnable) { }
result_type operator()(argument_type arg)
{
return _pUpdateUI->UIEnable(arg, _bEnable);
}
private:
CUpdateUIBase* _pUpdateUI;
BOOL _bEnable;
};
class UISetCheckFunction : public std::unary_function<int, BOOL>
{
public:
explicit UISetCheckFunction(CUpdateUIBase* pUpdateUI, int nCheck)
: _pUpdateUI(pUpdateUI), _nCheck(nCheck) { }
result_type operator()(argument_type arg)
{
return _pUpdateUI->UISetCheck(arg, _nCheck);
}
private:
CUpdateUIBase* _pUpdateUI;
int _nCheck;
};
class UISetRadioFunction : public std::unary_function<int, BOOL>
{
public:
explicit UISetRadioFunction(CUpdateUIBase* pUpdateUI, BOOL bRadio)
: _pUpdateUI(pUpdateUI), _bRadio(bRadio) { }
result_type operator()(argument_type arg)
{
return _pUpdateUI->UISetRadio(arg, _bRadio);
}
private:
CUpdateUIBase* _pUpdateUI;
BOOL _bRadio;
};
////////////////////////////////////////////////////////////////////////////
// for standard application commands
template <class T>
class CAppCommandHandler
{
public:
BEGIN_MSG_MAP(CAppCommandHandler)
COMMAND_ID_HANDLER(ID_APP_EXIT, OnAppExit)
COMMAND_ID_HANDLER(ID_APP_ABOUT, OnAppAbout)
END_MSG_MAP()
LRESULT OnAppAbout(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
T* pT = static_cast<T*>(this);
CAboutDlg dlg;
dlg.DoModal();
return 0;
}
LRESULT OnAppExit(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
T* pT = static_cast<T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));
pT->PostMessage(WM_CLOSE);
return 0;
}
};
////////////////////////////////////////////////////////////////////////////
// for Window Menu command
struct _Mtl_Function_CloseAll
{
void operator()(HWND hWnd)
{
::SendMessage(hWnd, WM_CLOSE, 0, 0);
}
};
struct _Mtl_Function_CloseAllExcept
{
HWND _hWndExcept;
_Mtl_Function_CloseAllExcept(HWND hWndExcept) : _hWndExcept(hWndExcept) { }
void operator()(HWND hWnd)
{
if (hWnd != _hWndExcept)
::SendMessage(hWnd, WM_CLOSE, 0, 0);
}
};
struct _Mtl_Function_CloseAllExcept2
{
HWND _hWndExcept, _hWndExcept2;
_Mtl_Function_CloseAllExcept2(HWND hWndExcept, HWND hWndExcept2)
: _hWndExcept(hWndExcept), _hWndExcept2(hWndExcept2) { }
void operator()(HWND hWnd)
{
if (hWnd != _hWndExcept && hWnd != _hWndExcept2)
::SendMessage(hWnd, WM_CLOSE, 0, 0);
}
};
inline void MtlCloseAllMDIChildren(HWND hWndMDIClient)
{
HWND hWndActive =(HWND)::SendMessage(hWndMDIClient, WM_MDIGETACTIVE, 0, (LPARAM)NULL);
MtlForEachMDIChild(hWndMDIClient, _Mtl_Function_CloseAllExcept(hWndActive));
::SendMessage(hWndActive, WM_CLOSE, 0, 0);
}
inline void MtlCloseAllMDIChildrenExcept(HWND hWndMDIClient, HWND hWndExcept)
{
HWND hWndActive =(HWND)::SendMessage(hWndMDIClient, WM_MDIGETACTIVE, 0, (LPARAM)NULL);
if (hWndActive == hWndExcept) {
MtlForEachMDIChild(hWndMDIClient, _Mtl_Function_CloseAllExcept(hWndExcept));
}
else {
MtlForEachMDIChild(hWndMDIClient, _Mtl_Function_CloseAllExcept2(hWndActive, hWndExcept));
::SendMessage(hWndActive, WM_CLOSE, 0, 0);
}
}
inline void MtlCompactMDIWindowMenuDocumentList(CMenuHandle menuWindow, int nWindowMenuItemCount, int nMaxTextLength)
{
int nLen = nMaxTextLength + 5;// add a little
LPTSTR lpszText = (LPTSTR)_alloca((nLen+1)*sizeof(TCHAR));
int i = nWindowMenuItemCount + 1;// add a separator
for (; i < menuWindow.GetMenuItemCount(); ++i) {
CMenuItemInfo mii;
mii.fMask = MIIM_TYPE;
mii.cch = nLen;
mii.dwTypeData = lpszText;
::GetMenuItemInfo(menuWindow, i, TRUE, &mii);
CString strMenuItem(mii.dwTypeData);
int nHeaderLen = strMenuItem.Left(1) == _T("&") ? 3 : 0;
CString strHeader = strMenuItem.Left(nHeaderLen);
strMenuItem = MtlCompactString(strMenuItem.Right(strMenuItem.GetLength() - nHeaderLen), nMaxTextLength);
strMenuItem = strHeader + strMenuItem;
mii.dwTypeData = (LPTSTR)(LPCTSTR)strMenuItem;
::SetMenuItemInfo(menuWindow, i, TRUE, &mii);
}
}
template <class T>
class CWindowMenuCommandHandler
{
public:
// Message map and handlers
BEGIN_MSG_MAP(CWindowMenuCommandHandler)
COMMAND_ID_HANDLER(ID_WINDOW_CASCADE, OnWindowCascade)
COMMAND_ID_HANDLER(ID_WINDOW_TILE_HORZ, OnWindowTileHorz)
COMMAND_ID_HANDLER(ID_WINDOW_TILE_VERT, OnWindowTileVert)
COMMAND_ID_HANDLER(ID_WINDOW_ARRANGE, OnWindowArrangeIcons)
COMMAND_ID_HANDLER(ID_WINDOW_CLOSE_ALL, OnWindowCloseAll)
// COMMAND_ID_HANDLER(ID_WINDOW_CLOSE_EXCEPT, OnWindowCloseExcept)
COMMAND_ID_HANDLER(ID_WINDOW_RESTORE, OnWindowRestore)
COMMAND_ID_HANDLER(ID_WINDOW_MOVE, OnWindowMove)
COMMAND_ID_HANDLER(ID_WINDOW_SIZE, OnWindowSize)
COMMAND_ID_HANDLER(ID_WINDOW_MINIMIZE, OnWindowMinimize)
COMMAND_ID_HANDLER(ID_WINDOW_MAXIMIZE, OnWindowMaximize)
END_MSG_MAP()
LRESULT OnWindowCascade(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
T* pT = static_cast<T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));
pT->MDICascade();
return 0;
}
LRESULT OnWindowTileHorz(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
T* pT = static_cast<T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));
pT->MDITile();
return 0;
}
LRESULT OnWindowTileVert(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
T* pT = static_cast<T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));
pT->MDITile(MDITILE_VERTICAL);
return 0;
}
LRESULT OnWindowArrangeIcons(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
T* pT = static_cast<T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));
pT->MDIIconArrange();
return 0;
}
LRESULT OnWindowCloseAll(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
T* pT = static_cast<T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));
ATLASSERT(::IsWindow(pT->m_hWndMDIClient));
CWaitCursor cur;
CLockRedrawMDIClient lock(pT->m_hWndMDIClient);
MtlCloseAllMDIChildren(pT->m_hWndMDIClient);
return 0;
}
LRESULT OnWindowCloseExcept(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
T* pT = static_cast<T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));
ATLASSERT(::IsWindow(pT->m_hWndMDIClient));
CWaitCursor cur;
CLockRedrawMDIClient lock(pT->m_hWndMDIClient);
MtlCloseAllMDIChildrenExcept(pT->m_hWndMDIClient, pT->MDIGetActive());
return 0;
}
LRESULT OnWindowRestore(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
_SendSysCommand(SC_RESTORE);
return 0;
}
LRESULT OnWindowMove(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
_SendSysCommand(SC_MOVE);
return 0;
}
LRESULT OnWindowSize(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
_SendSysCommand(SC_SIZE);
return 0;
}
LRESULT OnWindowMinimize(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
_SendSysCommand(SC_MINIMIZE);
return 0;
}
LRESULT OnWindowMaximize(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
_SendSysCommand(SC_MAXIMIZE);
return 0;
}
protected:
void _SendSysCommand(int wID)
{
T* pT = static_cast<T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));
ATLASSERT(::IsWindow(pT->m_hWndMDIClient));
BOOL bMaximized = FALSE;
CWindow wnd = pT->MDIGetActive(&bMaximized);
if (wnd.m_hWnd == NULL)
return;
if (wID == SC_MAXIMIZE && bMaximized)
return;
wnd.SendMessage(WM_SYSCOMMAND, (WPARAM)wID);
}
};
////////////////////////////////////////////////////////////////////////////
// Fixing CMDIChildWindowImpl
// WTL sucks, it support only english menu.
template <class T, int __nWindowMenuPos = 2, class TBase = CMDIWindow, class TWinTraits = CMDIChildWinTraits>
class ATL_NO_VTABLE CMDIChildWindowImplFixed : public CMDIChildWindowImpl<T, TBase, TWinTraits>
{
public:
// Declarations
typedef CMDIChildWindowImpl<T, TBase, TWinTraits> baseClass;
// Overrides
static DWORD GetWndStyle(DWORD dwStyle)
{// created invisibly
return TWinTraits::GetWndStyle(dwStyle) & ~(WS_VISIBLE | WS_CLIPCHILDREN/* makes drawing slower*/ | WS_CLIPSIBLINGS);
}
// Message map and handlers
BEGIN_MSG_MAP(CMDIChildWindowImplFixed)
MSG_WM_MDIACTIVATE(OnMDIActivate)
CHAIN_MSG_MAP(baseClass)
END_MSG_MAP()
void OnMDIActivate(HWND hwndChildDeact, HWND hwndChildAct)
{
if(hwndChildAct == m_hWnd && m_hMenu != NULL)
_SetMDIFrameMenuFixed();
else if(hwndChildAct == NULL)
::SendMessage(GetMDIFrame(), WM_MDISETMENU, 0, 0);
// don't allow CMDIChildWindowImpl to handle this one
DefWindowProc();
}
// Methods
void ActivateFrame(int nCmdShow = -1)
{// cf.MFC6::CMDIChildWnd::ActivateFrame
// determine default show command
if (nCmdShow == -1) {
// get maximized state of previously active child
BOOL bMaximized = FALSE;
HWND hWndActive = MDIGetActive(&bMaximized);
// convert show command based on current style
DWORD dwStyle = GetStyle();
if (bMaximized || !hWndActive || (dwStyle & WS_MAXIMIZE))
nCmdShow = SW_SHOWMAXIMIZED;
else if (dwStyle & WS_MINIMIZE)
nCmdShow = SW_SHOWMINIMIZED;
}
// translate default nCmdShow (-1)
if (nCmdShow == -1) {
if (!IsWindowVisible())
nCmdShow = SW_SHOWNORMAL;
else if (IsIconic())
nCmdShow = SW_RESTORE;
}
// bring to top before showing <-important
BringToTop(nCmdShow);
if (nCmdShow != -1) {
// show the window as specified
ShowWindow(nCmdShow);
// and finally, bring to top after showing
BringToTop(nCmdShow);
}
// strangely, MDIRefreshMenu in CMDIWindowFixed::SetMDIFrameMenuFixed ignored
MDIRefreshMenu();// refresh the Window menu
ATLTRACE2(atlTraceUser, 4, _T("CChildFrame::ActivateFrame - activated!\n"));
}
void BringToTop(int nCmdShow)
{// cf.MFC6::CFrameWnd::BringToTop
// place the window on top except for certain nCmdShow
if (nCmdShow != SW_HIDE &&
nCmdShow != SW_MINIMIZE && nCmdShow != SW_SHOWMINNOACTIVE &&
nCmdShow != SW_SHOWNA && nCmdShow != SW_SHOWNOACTIVATE) {
// if no last active popup, it will return m_hWnd
HWND hWndLastPop = ::GetLastActivePopup(m_hWnd);
::BringWindowToTop(hWndLastPop);
}
}
// Implementation
private:
HMENU _GetStandardWindowMenuFixed(HMENU hMenu)
{
int nCount = ::GetMenuItemCount(hMenu);
if(nCount == -1)
return NULL;
int nLen = ::GetMenuString(hMenu, nCount - __nWindowMenuPos, NULL, 0, MF_BYPOSITION);
if(nLen == 0)
return NULL;
LPTSTR lpszText = (LPTSTR)_alloca((nLen + 1) * sizeof(TCHAR));
if(::GetMenuString(hMenu, nCount - __nWindowMenuPos, lpszText, nLen + 1, MF_BYPOSITION) != nLen)
return NULL;
// if(lstrcmp(lpszText, m_lpszWindowMenu))
// return NULL;
return ::GetSubMenu(hMenu, nCount - __nWindowMenuPos);
}
void _SetMDIFrameMenuFixed()
{
ATLTRACE2(atlTraceUser, 4, _T("CMDIWindowFixed::SetMDIFrameMenuFixed\n"));
HMENU hWindowMenu = _GetStandardWindowMenuFixed(m_hMenu);
MDISetMenu(m_hMenu, hWindowMenu);
MDIRefreshMenu();
::DrawMenuBar(GetMDIFrame());
}
};
////////////////////////////////////////////////////////////////////////////
// Customizable tool bar handler
template <class T>
class CCustomizableToolBarHandler
{
public:
// Constructor
CCustomizableToolBarHandler()
: m_nResourceID(0),
m_nItems(0), m_pTBBtn(NULL),
m_pUpdateUI(NULL) { }
// Overridable
void OnTbnCustHelp(HWND hWndToolBar)
{
// you can override to deal with HELP.
}
// Operations
void InitCustomizableToolBarHandler(HWND hWndToolBar, UINT nResourceID, CUpdateUIBase* pUpdateUI)
{
ATLASSERT(::IsWindow(hWndToolBar));
m_toolbar = hWndToolBar;
m_nResourceID = nResourceID;
m_pUpdateUI = pUpdateUI;
m_toolbar.ModifyStyle(0, CCS_ADJUSTABLE);
}
void InitCustomizableToolBarHandler(HWND hWndToolBar, int* __firstID, int* __lastID, CUpdateUIBase* pUpdateUI)
{
if (__firstID == __lastID)
return;
for (; __firstID < __lastID; ++__firstID) {
m_arrCmdID.Add(*__firstID);
}
m_toolbar = hWndToolBar;
m_pUpdateUI = pUpdateUI;
m_toolbar.ModifyStyle(0, CCS_ADJUSTABLE);
}
protected:
// Message map and handlers
BEGIN_MSG_MAP(CCustomizableToolbarHandler)
NOTIFY_HANDLER_EX(m_toolbar.GetDlgCtrlID(), TBN_BEGINADJUST, OnTbnBeginAdjust)
NOTIFY_HANDLER_EX(m_toolbar.GetDlgCtrlID(), TBN_ENDADJUST, OnTbnEndAdjust)
NOTIFY_HANDLER_EX(m_toolbar.GetDlgCtrlID(), TBN_QUERYINSERT, OnTbnQueryInsert)
NOTIFY_HANDLER_EX(m_toolbar.GetDlgCtrlID(), TBN_QUERYDELETE, OnTbnQueryDelete)
NOTIFY_HANDLER_EX(m_toolbar.GetDlgCtrlID(), TBN_GETBUTTONINFO, OnTbnGetButtonInfo)
NOTIFY_HANDLER_EX(m_toolbar.GetDlgCtrlID(), TBN_TOOLBARCHANGE, OnTbnToolBarChange)
NOTIFY_HANDLER_EX(m_toolbar.GetDlgCtrlID(), TBN_RESET, OnTbnReset)
NOTIFY_HANDLER_EX(m_toolbar.GetDlgCtrlID(), TBN_CUSTHELP, OnTbnCustHelp)
// NOTIFY_HANDLER_EX(m_toolbar.GetDlgCtrlID(), TBN_BEGINDRAG, OnTbnBeginDrag)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -