📄 atlframe.h
字号:
}
virtual WNDPROC GetWindowProc()
{
return MDIFrameWindowProc;
}
static LRESULT CALLBACK MDIFrameWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
CMDIFrameWindowImpl< T, TBase, TWinTraits >* pThis = (CMDIFrameWindowImpl< T, TBase, TWinTraits >*)hWnd;
// set a ptr to this message and save the old value
#if (_ATL_VER >= 0x0700)
ATL::_ATL_MSG msg(pThis->m_hWnd, uMsg, wParam, lParam);
const ATL::_ATL_MSG* pOldMsg = pThis->m_pCurrentMsg;
#else // !(_ATL_VER >= 0x0700)
MSG msg = { pThis->m_hWnd, uMsg, wParam, lParam, 0, { 0, 0 } };
const MSG* pOldMsg = pThis->m_pCurrentMsg;
#endif // !(_ATL_VER >= 0x0700)
pThis->m_pCurrentMsg = &msg;
// pass to the message map to process
LRESULT lRes = 0;
BOOL bRet = pThis->ProcessWindowMessage(pThis->m_hWnd, uMsg, wParam, lParam, lRes, 0);
// restore saved value for the current message
ATLASSERT(pThis->m_pCurrentMsg == &msg);
pThis->m_pCurrentMsg = pOldMsg;
// do the default processing if message was not handled
if(!bRet)
{
if(uMsg != WM_NCDESTROY)
lRes = pThis->DefWindowProc(uMsg, wParam, lParam);
else
{
// unsubclass, if needed
LONG_PTR pfnWndProc = ::GetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC);
lRes = pThis->DefWindowProc(uMsg, wParam, lParam);
if(pThis->m_pfnSuperWindowProc != ::DefWindowProc && ::GetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC) == pfnWndProc)
::SetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC, (LONG_PTR)pThis->m_pfnSuperWindowProc);
#if (_ATL_VER >= 0x0700)
// mark window as destryed
pThis->m_dwState |= WINSTATE_DESTROYED;
#else // !(_ATL_VER >= 0x0700)
// clear out window handle
HWND hWnd = pThis->m_hWnd;
pThis->m_hWnd = NULL;
// clean up after window is destroyed
pThis->OnFinalMessage(hWnd);
#endif // !(_ATL_VER >= 0x0700)
}
}
#if (_ATL_VER >= 0x0700)
if(pThis->m_dwState & WINSTATE_DESTROYED && pThis->m_pCurrentMsg == NULL)
{
// clear out window handle
HWND hWnd = pThis->m_hWnd;
pThis->m_hWnd = NULL;
pThis->m_dwState &= ~WINSTATE_DESTROYED;
// clean up after window is destroyed
pThis->OnFinalMessage(hWnd);
}
#endif // (_ATL_VER >= 0x0700)
return lRes;
}
// Overriden to call DefWindowProc which uses DefFrameProc
LRESULT DefWindowProc()
{
const MSG* pMsg = m_pCurrentMsg;
LRESULT lRes = 0;
if (pMsg != NULL)
lRes = DefWindowProc(pMsg->message, pMsg->wParam, pMsg->lParam);
return lRes;
}
LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
return ::DefFrameProc(m_hWnd, m_hWndMDIClient, uMsg, wParam, lParam);
}
BOOL PreTranslateMessage(MSG* pMsg)
{
if(CFrameWindowImplBase<TBase, TWinTraits>::PreTranslateMessage(pMsg))
return TRUE;
return ::TranslateMDISysAccel(m_hWndMDIClient, pMsg);
}
HWND CreateMDIClient(HMENU hWindowMenu = NULL, UINT nID = ATL_IDW_CLIENT, UINT nFirstChildID = ATL_IDM_FIRST_MDICHILD)
{
DWORD dwStyle = WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | MDIS_ALLCHILDSTYLES;
DWORD dwExStyle = WS_EX_CLIENTEDGE;
CLIENTCREATESTRUCT ccs = { 0 };
ccs.hWindowMenu = hWindowMenu;
ccs.idFirstChild = nFirstChildID;
if((GetStyle() & (WS_HSCROLL | WS_VSCROLL)) != 0)
{
// parent MDI frame's scroll styles move to the MDICLIENT
dwStyle |= (GetStyle() & (WS_HSCROLL | WS_VSCROLL));
// fast way to turn off the scrollbar bits (without a resize)
ModifyStyle(WS_HSCROLL | WS_VSCROLL, 0, SWP_NOREDRAW | SWP_FRAMECHANGED);
}
// Create MDICLIENT window
#if (_ATL_VER >= 0x0700)
m_hWndClient = ::CreateWindowEx(dwExStyle, _T("MDIClient"), NULL,
dwStyle, 0, 0, 1, 1, m_hWnd, (HMENU)LongToHandle(nID),
ATL::_AtlBaseModule.GetModuleInstance(), (LPVOID)&ccs);
#else // !(_ATL_VER >= 0x0700)
m_hWndClient = ::CreateWindowEx(dwExStyle, _T("MDIClient"), NULL,
dwStyle, 0, 0, 1, 1, m_hWnd, (HMENU)LongToHandle(nID),
_Module.GetModuleInstance(), (LPVOID)&ccs);
#endif // !(_ATL_VER >= 0x0700)
if (m_hWndClient == NULL)
{
ATLTRACE2(atlTraceUI, 0, _T("MDI Frame failed to create MDICLIENT.\n"));
return NULL;
}
// Move it to the top of z-order
::BringWindowToTop(m_hWndClient);
// set as MDI client window
m_hWndMDIClient = m_hWndClient;
// update to proper size
T* pT = static_cast<T*>(this);
pT->UpdateLayout();
return m_hWndClient;
}
typedef CFrameWindowImplBase<TBase, TWinTraits > _baseClass;
BEGIN_MSG_MAP(CMDIFrameWindowImpl)
MESSAGE_HANDLER(WM_SIZE, OnSize)
MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
MESSAGE_HANDLER(WM_MDISETMENU, OnMDISetMenu)
#ifndef _ATL_NO_REBAR_SUPPORT
#if (_WIN32_IE >= 0x0400)
NOTIFY_CODE_HANDLER(RBN_AUTOSIZE, OnReBarAutoSize)
#endif // (_WIN32_IE >= 0x0400)
#if (_WIN32_IE >= 0x0500)
NOTIFY_CODE_HANDLER(RBN_CHEVRONPUSHED, OnChevronPushed)
#endif // (_WIN32_IE >= 0x0500)
#endif // !_ATL_NO_REBAR_SUPPORT
CHAIN_MSG_MAP(_baseClass)
END_MSG_MAP()
LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
if(wParam != SIZE_MINIMIZED)
{
T* pT = static_cast<T*>(this);
pT->UpdateLayout();
}
// message must be handled, otherwise DefFrameProc would resize the client again
return 0;
}
LRESULT OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
// don't allow CFrameWindowImplBase to handle this one
return DefWindowProc(uMsg, wParam, lParam);
}
LRESULT OnMDISetMenu(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
SetMDIFrameMenu();
return 0;
}
#ifndef _ATL_NO_REBAR_SUPPORT
#if (_WIN32_IE >= 0x0400)
LRESULT OnReBarAutoSize(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
{
T* pT = static_cast<T*>(this);
pT->UpdateLayout(FALSE);
return 0;
}
#endif // (_WIN32_IE >= 0x0400)
#if (_WIN32_IE >= 0x0500)
LRESULT OnChevronPushed(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled)
{
T* pT = static_cast<T*>(this);
_ChevronMenuInfo cmi = { NULL, (LPNMREBARCHEVRON)pnmh, false };
if(!pT->PrepareChevronMenu(cmi))
{
bHandled = FALSE;
return 1;
}
// display a popup menu with hidden items
pT->DisplayChevronMenu(cmi);
// cleanup
pT->CleanupChevronMenu(cmi);
return 0;
}
#endif // (_WIN32_IE >= 0x0500)
#endif // !_ATL_NO_REBAR_SUPPORT
};
#endif // !_WIN32_WCE
///////////////////////////////////////////////////////////////////////////////
// CMDIChildWindowImpl
#ifndef _WIN32_WCE
template <class T, class TBase = CMDIWindow, class TWinTraits = ATL::CMDIChildWinTraits>
class ATL_NO_VTABLE CMDIChildWindowImpl : public CFrameWindowImplBase<TBase, TWinTraits >
{
public:
HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
DWORD dwStyle = 0, DWORD dwExStyle = 0,
UINT nMenuID = 0, LPVOID lpCreateParam = NULL)
{
ATOM atom = T::GetWndClassInfo().Register(&m_pfnSuperWindowProc);
if(nMenuID != 0)
#if (_ATL_VER >= 0x0700)
m_hMenu = ::LoadMenu(ATL::_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(nMenuID));
#else // !(_ATL_VER >= 0x0700)
m_hMenu = ::LoadMenu(_Module.GetResourceInstance(), MAKEINTRESOURCE(nMenuID));
#endif // !(_ATL_VER >= 0x0700)
dwStyle = T::GetWndStyle(dwStyle);
dwExStyle = T::GetWndExStyle(dwExStyle);
dwExStyle |= WS_EX_MDICHILD; // force this one
m_pfnSuperWindowProc = ::DefMDIChildProc;
m_hWndMDIClient = hWndParent;
ATLASSERT(::IsWindow(m_hWndMDIClient));
if(rect.m_lpRect == NULL)
rect.m_lpRect = &TBase::rcDefault;
// If the currently active MDI child is maximized, we want to create this one maximized too
ATL::CWindow wndParent = hWndParent;
BOOL bMaximized = FALSE;
wndParent.SendMessage(WM_MDIGETACTIVE, 0, (LPARAM)&bMaximized);
if(bMaximized)
wndParent.SetRedraw(FALSE);
HWND hWnd = CFrameWindowImplBase<TBase, TWinTraits >::Create(hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, (UINT)0U, atom, lpCreateParam);
if(bMaximized)
{
// Maximize and redraw everything
if(hWnd != NULL)
MDIMaximize(hWnd);
wndParent.SetRedraw(TRUE);
wndParent.RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN);
::SetFocus(GetMDIFrame()); // focus will be set back to this window
}
else if(hWnd != NULL && ::IsWindowVisible(m_hWnd) && !::IsChild(hWnd, ::GetFocus()))
{
::SetFocus(hWnd);
}
return hWnd;
}
HWND CreateEx(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR lpcstrWindowName = NULL, DWORD dwStyle = 0, DWORD dwExStyle = 0, LPVOID lpCreateParam = NULL)
{
const int cchName = 256;
TCHAR szWindowName[cchName];
szWindowName[0] = 0;
if(lpcstrWindowName == NULL)
{
#if (_ATL_VER >= 0x0700)
::LoadString(ATL::_AtlBaseModule.GetResourceInstance(), T::GetWndClassInfo().m_uCommonResourceID, szWindowName, cchName);
#else // !(_ATL_VER >= 0x0700)
::LoadString(_Module.GetResourceInstance(), T::GetWndClassInfo().m_uCommonResourceID, szWindowName, cchName);
#endif // !(_ATL_VER >= 0x0700)
lpcstrWindowName = szWindowName;
}
T* pT = static_cast<T*>(this);
HWND hWnd = pT->Create(hWndParent, rect, lpcstrWindowName, dwStyle, dwExStyle, T::GetWndClassInfo().m_uCommonResourceID, lpCreateParam);
if(hWnd != NULL)
#if (_ATL_VER >= 0x0700)
m_hAccel = ::LoadAccelerators(ATL::_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID));
#else // !(_ATL_VER >= 0x0700)
m_hAccel = ::LoadAccelerators(_Module.GetResourceInstance(), MAKEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID));
#endif // !(_ATL_VER >= 0x0700)
return hWnd;
}
BOOL CreateSimpleToolBar(UINT nResourceID = 0, DWORD dwStyle = ATL_SIMPLE_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR)
{
ATLASSERT(!::IsWindow(m_hWndToolBar));
if(nResourceID == 0)
nResourceID = T::GetWndClassInfo().m_uCommonResourceID;
m_hWndToolBar = T::CreateSimpleToolBarCtrl(m_hWnd, nResourceID, TRUE, dwStyle, nID);
return (m_hWndToolBar != NULL);
}
BOOL UpdateClientEdge(LPRECT lpRect = NULL)
{
// only adjust for active MDI child window
HWND hWndChild = MDIGetActive();
if(hWndChild != NULL && hWndChild != m_hWnd)
return FALSE;
// need to adjust the client edge style as max/restore happens
DWORD dwStyle = ::GetWindowLong(m_hWndMDIClient, GWL_EXSTYLE);
DWORD dwNewStyle = dwStyle;
if(hWndChild != NULL && ((GetExStyle() & WS_EX_CLIENTEDGE) == 0) && ((GetStyle() & WS_MAXIMIZE) != 0))
dwNewStyle &= ~(WS_EX_CLIENTEDGE);
else
dwNewStyle |= WS_EX_CLIENTEDGE;
if(dwStyle != dwNewStyle)
{
// SetWindowPos will not move invalid bits
::RedrawWindow(m_hWndMDIClient, NULL, NULL,
RDW_INVALIDATE | RDW_ALLCHILDREN);
// remove/add WS_EX_CLIENTEDGE to MDI client area
::SetWindowLong(m_hWndMDIClient, GWL_EXSTYLE, dwNewStyle);
::SetWindowPos(m_hWndMDIClient, NULL, 0, 0, 0, 0,
SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE |
SWP_NOZORDER | SWP_NOCOPYBITS);
// return new client area
if (lpRect != NULL)
::GetClientRect(m_hWndMDIClient, lpRect);
return TRUE;
}
return FALSE;
}
typedef CFrameWindowImplBase<TBase, TWinTraits > _baseClass;
BEGIN_MSG_MAP(CMDIChildWindowImpl)
MESSAGE_HANDLER(WM_SIZE, OnSize)
MESSAGE_HANDLER(WM_WINDOWPOSCHANGED, OnWindowPosChanged)
MESSAGE_HANDLER(WM_MOUSEACTIVATE, OnMouseActivate)
MESSAGE_HANDLER(WM_MENUSELECT, OnMenuSelect)
MESSAGE_HANDLER(WM_MDIACTIVATE, OnMDIActivate)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
#ifndef _ATL_NO_REBAR_SUPPORT
#if (_WIN32_IE >= 0x0400)
NOTIFY_CODE_HANDLER(RBN_AUTOSIZE, OnReBarAutoSize)
#endif // (_WIN32_IE >= 0x0400)
#if (_WIN32_IE >= 0x0500)
NOTIFY_CODE_HANDLER(RBN_CHEVRONPUSHED, OnChevronPushed)
#endif // (_WIN32_IE >= 0x0500)
#endif // !_ATL_NO_REBAR_SUPPORT
CHAIN_MSG_MAP(_baseClass)
END_MSG_MAP()
LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
DefWindowProc(uMsg, wParam, lParam); // needed for MDI children
if(wParam != SIZE_MINIMIZED)
{
T* pT = static_cast<T*>(this);
pT->UpdateLayout();
}
return 0;
}
LRESULT OnWindowPosChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
{
// update MDI client edge and adjust MDI child rect
LPWINDOWPOS lpWndPos = (LPWINDOWPOS)lParam;
if(!(lpWndPos->flags & SWP_NOSIZE))
{
RECT rectClient;
if(UpdateClientEdge(&rectClient) && ((GetStyle() & WS_MAXIMIZE) != 0))
{
::AdjustWindowRectEx(&rectClient, GetStyle(), FALSE, GetExStyle());
lpWndPos->x = rectClient.left;
lpWndPos->y = rectClient.top;
lpWndPos->cx = rectClient.right - rectClient.left;
lpWndPos->cy = rectClient.bottom - rectClient.top;
}
}
bHandled = FALSE;
return 1;
}
LRESULT OnMouseActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
LRESULT lRes = DefWindowProc(uMsg, wParam, lParam);
// Activate this MDI window if needed
if(lRes == MA_ACTIVATE || lRes == MA_ACTIVA
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -