📄 atlframe.h
字号:
BEGIN_MSG_MAP(CFrameWindowImplBase)
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
#ifndef _WIN32_WCE
MESSAGE_HANDLER(WM_MENUSELECT, OnMenuSelect)
#endif // !_WIN32_WCE
MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
#ifndef _WIN32_WCE
NOTIFY_CODE_HANDLER(TTN_GETDISPINFOA, OnToolTipTextA)
NOTIFY_CODE_HANDLER(TTN_GETDISPINFOW, OnToolTipTextW)
#endif // !_WIN32_WCE
END_MSG_MAP()
LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
if(m_hWndClient != NULL) // view will paint itself instead
return 1;
bHandled = FALSE;
return 0;
}
#ifndef _WIN32_WCE
LRESULT OnMenuSelect(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
bHandled = FALSE;
if(m_hWndStatusBar == NULL)
return 1;
WORD wFlags = HIWORD(wParam);
if(wFlags == 0xFFFF && lParam == NULL) // menu closing
{
::SendMessage(m_hWndStatusBar, SB_SIMPLE, FALSE, 0L);
}
else
{
const int cchBuff = 256;
TCHAR szBuff[cchBuff];
szBuff[0] = 0;
if(!(wFlags & MF_POPUP))
{
WORD wID = LOWORD(wParam);
// check for special cases
if(wID >= 0xF000 && wID < 0xF1F0) // system menu IDs
wID = (WORD)(((wID - 0xF000) >> 4) + ATL_IDS_SCFIRST);
else if(wID >= ID_FILE_MRU_FIRST && wID <= ID_FILE_MRU_LAST) // MRU items
wID = ATL_IDS_MRU_FILE;
else if(wID >= ATL_IDM_FIRST_MDICHILD && wID <= ATL_IDM_LAST_MDICHILD) // MDI child windows
wID = ATL_IDS_MDICHILD;
int nRet = ::LoadString(ModuleHelper::GetResourceInstance(), wID, szBuff, cchBuff);
for(int i = 0; i < nRet; i++)
{
if(szBuff[i] == _T('\n'))
{
szBuff[i] = 0;
break;
}
}
}
::SendMessage(m_hWndStatusBar, SB_SIMPLE, TRUE, 0L);
::SendMessage(m_hWndStatusBar, SB_SETTEXT, (255 | SBT_NOBORDERS), (LPARAM)szBuff);
}
return 1;
}
#endif // !_WIN32_WCE
LRESULT OnSetFocus(UINT, WPARAM, LPARAM, BOOL& bHandled)
{
if(m_hWndClient != NULL)
::SetFocus(m_hWndClient);
bHandled = FALSE;
return 1;
}
LRESULT OnDestroy(UINT, WPARAM, LPARAM, BOOL& bHandled)
{
if((GetStyle() & (WS_CHILD | WS_POPUP)) == 0)
::PostQuitMessage(1);
bHandled = FALSE;
return 1;
}
#ifndef _WIN32_WCE
LRESULT OnToolTipTextA(int idCtrl, LPNMHDR pnmh, BOOL& /*bHandled*/)
{
LPNMTTDISPINFOA pDispInfo = (LPNMTTDISPINFOA)pnmh;
pDispInfo->szText[0] = 0;
if((idCtrl != 0) && !(pDispInfo->uFlags & TTF_IDISHWND))
{
const int cchBuff = 256;
char szBuff[cchBuff];
szBuff[0] = 0;
int nRet = ::LoadStringA(ModuleHelper::GetResourceInstance(), idCtrl, szBuff, cchBuff);
for(int i = 0; i < nRet; i++)
{
if(szBuff[i] == '\n')
{
SecureHelper::strncpyA_x(pDispInfo->szText, _countof(pDispInfo->szText), &szBuff[i + 1], _TRUNCATE);
break;
}
}
#if (_WIN32_IE >= 0x0300)
if(nRet > 0) // string was loaded, save it
pDispInfo->uFlags |= TTF_DI_SETITEM;
#endif // (_WIN32_IE >= 0x0300)
}
return 0;
}
LRESULT OnToolTipTextW(int idCtrl, LPNMHDR pnmh, BOOL& /*bHandled*/)
{
LPNMTTDISPINFOW pDispInfo = (LPNMTTDISPINFOW)pnmh;
pDispInfo->szText[0] = 0;
if((idCtrl != 0) && !(pDispInfo->uFlags & TTF_IDISHWND))
{
const int cchBuff = 256;
wchar_t szBuff[cchBuff];
szBuff[0] = 0;
int nRet = ::LoadStringW(ModuleHelper::GetResourceInstance(), idCtrl, szBuff, cchBuff);
for(int i = 0; i < nRet; i++)
{
if(szBuff[i] == L'\n')
{
SecureHelper::strncpyW_x(pDispInfo->szText, _countof(pDispInfo->szText), &szBuff[i + 1], _TRUNCATE);
break;
}
}
#if (_WIN32_IE >= 0x0300)
if(nRet > 0) // string was loaded, save it
pDispInfo->uFlags |= TTF_DI_SETITEM;
#endif // (_WIN32_IE >= 0x0300)
}
return 0;
}
#endif // !_WIN32_WCE
// Implementation - chevron menu support
#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
bool PrepareChevronMenu(_ChevronMenuInfo& cmi)
{
// get rebar and toolbar
REBARBANDINFO rbbi = { RunTimeHelper::SizeOf_REBARBANDINFO() };
rbbi.fMask = RBBIM_CHILD;
BOOL bRet = (BOOL)::SendMessage(cmi.lpnm->hdr.hwndFrom, RB_GETBANDINFO, cmi.lpnm->uBand, (LPARAM)&rbbi);
ATLASSERT(bRet);
// assume the band is a toolbar
ATL::CWindow wnd = rbbi.hwndChild;
int nCount = (int)wnd.SendMessage(TB_BUTTONCOUNT);
if(nCount <= 0) // probably not a toolbar
return false;
// check if it's a command bar
CMenuHandle menuCmdBar = (HMENU)wnd.SendMessage(CBRM_GETMENU);
cmi.bCmdBar = (menuCmdBar.m_hMenu != NULL);
// build a menu from hidden items
CMenuHandle menu;
bRet = menu.CreatePopupMenu();
ATLASSERT(bRet);
RECT rcClient = { 0 };
bRet = wnd.GetClientRect(&rcClient);
ATLASSERT(bRet);
for(int i = 0; i < nCount; i++)
{
TBBUTTON tbb = { 0 };
bRet = (BOOL)wnd.SendMessage(TB_GETBUTTON, i, (LPARAM)&tbb);
ATLASSERT(bRet);
// skip hidden buttons
if((tbb.fsState & TBSTATE_HIDDEN) != 0)
continue;
RECT rcButton = { 0 };
bRet = (BOOL)wnd.SendMessage(TB_GETITEMRECT, i, (LPARAM)&rcButton);
ATLASSERT(bRet);
bool bEnabled = ((tbb.fsState & TBSTATE_ENABLED) != 0);
if(rcButton.right > rcClient.right)
{
if(tbb.fsStyle & BTNS_SEP)
{
if(menu.GetMenuItemCount() > 0)
menu.AppendMenu(MF_SEPARATOR);
}
else if(cmi.bCmdBar)
{
const int cchBuff = 200;
TCHAR szBuff[cchBuff] = { 0 };
CMenuItemInfo mii;
mii.fMask = MIIM_TYPE | MIIM_SUBMENU;
mii.dwTypeData = szBuff;
mii.cch = cchBuff;
bRet = menuCmdBar.GetMenuItemInfo(i, TRUE, &mii);
ATLASSERT(bRet);
// Note: CmdBar currently supports only drop-down items
ATLASSERT(::IsMenu(mii.hSubMenu));
bRet = menu.AppendMenu(MF_STRING | MF_POPUP | (bEnabled ? MF_ENABLED : MF_GRAYED), (UINT_PTR)mii.hSubMenu, mii.dwTypeData);
ATLASSERT(bRet);
}
else
{
// get button's text
const int cchBuff = 200;
TCHAR szBuff[cchBuff] = { 0 };
LPTSTR lpstrText = szBuff;
TBBUTTONINFO tbbi = { 0 };
tbbi.cbSize = sizeof(TBBUTTONINFO);
tbbi.dwMask = TBIF_TEXT;
tbbi.pszText = szBuff;
tbbi.cchText = cchBuff;
if(wnd.SendMessage(TB_GETBUTTONINFO, tbb.idCommand, (LPARAM)&tbbi) == -1 || lstrlen(szBuff) == 0)
{
// no text for this button, try a resource string
lpstrText = _T("");
int nRet = ::LoadString(ModuleHelper::GetResourceInstance(), tbb.idCommand, szBuff, cchBuff);
for(int n = 0; n < nRet; n++)
{
if(szBuff[n] == _T('\n'))
{
lpstrText = &szBuff[n + 1];
break;
}
}
}
bRet = menu.AppendMenu(MF_STRING | (bEnabled ? MF_ENABLED : MF_GRAYED), tbb.idCommand, lpstrText);
ATLASSERT(bRet);
}
}
}
if(menu.GetMenuItemCount() == 0) // no hidden buttons after all
{
menu.DestroyMenu();
::MessageBeep((UINT)-1);
return false;
}
cmi.hMenu = menu;
return true;
}
void DisplayChevronMenu(_ChevronMenuInfo& cmi)
{
#ifndef TPM_VERPOSANIMATION
const UINT TPM_VERPOSANIMATION = 0x1000L; // Menu animation flag
#endif
// convert chevron rect to screen coordinates
ATL::CWindow wndFrom = cmi.lpnm->hdr.hwndFrom;
POINT pt = { cmi.lpnm->rc.left, cmi.lpnm->rc.bottom };
wndFrom.MapWindowPoints(NULL, &pt, 1);
RECT rc = cmi.lpnm->rc;
wndFrom.MapWindowPoints(NULL, &rc);
// set up flags and rect
UINT uMenuFlags = TPM_LEFTBUTTON | TPM_VERTICAL | TPM_LEFTALIGN | TPM_TOPALIGN | (!AtlIsOldWindows() ? TPM_VERPOSANIMATION : 0);
TPMPARAMS TPMParams = { 0 };
TPMParams.cbSize = sizeof(TPMPARAMS);
TPMParams.rcExclude = rc;
// check if this window has a command bar
HWND hWndCmdBar = (HWND)::SendMessage(m_hWnd, CBRM_GETCMDBAR, 0, 0L);
if(::IsWindow(hWndCmdBar))
{
CBRPOPUPMENU CBRPopupMenu = { sizeof(CBRPOPUPMENU), cmi.hMenu, uMenuFlags, pt.x, pt.y, &TPMParams };
::SendMessage(hWndCmdBar, CBRM_TRACKPOPUPMENU, 0, (LPARAM)&CBRPopupMenu);
}
else
{
CMenuHandle menu = cmi.hMenu;
menu.TrackPopupMenuEx(uMenuFlags, pt.x, pt.y, m_hWnd, &TPMParams);
}
}
void CleanupChevronMenu(_ChevronMenuInfo& cmi)
{
CMenuHandle menu = cmi.hMenu;
// if menu is from a command bar, detach submenus so they are not destroyed
if(cmi.bCmdBar)
{
for(int i = menu.GetMenuItemCount() - 1; i >=0; i--)
menu.RemoveMenu(i, MF_BYPOSITION);
}
// destroy menu
menu.DestroyMenu();
// convert chevron rect to screen coordinates
ATL::CWindow wndFrom = cmi.lpnm->hdr.hwndFrom;
RECT rc = cmi.lpnm->rc;
wndFrom.MapWindowPoints(NULL, &rc);
// eat next message if click is on the same button
MSG msg = { 0 };
if(::PeekMessage(&msg, m_hWnd, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_NOREMOVE) && ::PtInRect(&rc, msg.pt))
::PeekMessage(&msg, m_hWnd, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_REMOVE);
}
#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
};
template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CFrameWinTraits>
class ATL_NO_VTABLE CFrameWindowImpl : public CFrameWindowImplBase< TBase, TWinTraits >
{
public:
HWND Create(HWND hWndParent = NULL, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
DWORD dwStyle = 0, DWORD dwExStyle = 0,
HMENU hMenu = NULL, LPVOID lpCreateParam = NULL)
{
ATOM atom = T::GetWndClassInfo().Register(&m_pfnSuperWindowProc);
dwStyle = T::GetWndStyle(dwStyle);
dwExStyle = T::GetWndExStyle(dwExStyle);
if(rect.m_lpRect == NULL)
rect.m_lpRect = &TBase::rcDefault;
return CFrameWindowImplBase< TBase, TWinTraits >::Create(hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, hMenu, atom, lpCreateParam);
}
HWND CreateEx(HWND hWndParent = NULL, ATL::_U_RECT rect = NULL, DWORD dwStyle = 0, DWORD dwExStyle = 0, LPVOID lpCreateParam = NULL)
{
const int cchName = 256;
TCHAR szWindowName[cchName];
szWindowName[0] = 0;
#ifndef _WIN32_WCE
::LoadString(ModuleHelper::GetResourceInstance(), T::GetWndClassInfo().m_uCommonResourceID, szWindowName, cchName);
HMENU hMenu = ::LoadMenu(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID));
#else // CE specific
::LoadString(ModuleHelper::GetResourceInstance(), T::GetWndClassInfo().m_uCommonResourceID, szWindowName, cchName);
// This always needs to be NULL for Windows CE.
// Frame Window menus have to go onto the CommandBar.
// Use CreateSimpleCECommandBar
HMENU hMenu = NULL;
#endif // _WIN32_WCE
T* pT = static_cast<T*>(this);
HWND hWnd = pT->Create(hWndParent, rect, szWindowName, dwStyle, dwExStyle, hMenu, lpCreateParam);
if(hWnd != NULL)
m_hAccel = ::LoadAccelerators(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID));
return hWnd;
}
BOOL CreateSimpleToolBar(UINT nResourceID = 0, DWORD dwStyle = ATL_SIMPLE_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR)
{
if(nResourceID == 0)
nResourceID = T::GetWndClassInfo().m_uCommonResourceID;
#ifndef _WIN32_WCE
ATLASSERT(!::IsWindow(m_hWndToolBar));
m_hWndToolBar = T::CreateSimpleToolBarCtrl(m_hWnd, nResourceID, TRUE, dwStyle, nID);
return (m_hWndToolBar != NULL);
#else // CE specific
HWND hWnd= T::CreateSimpleToolBarCtrl(m_hWndCECommandBar, nResourceID, TRUE, dwStyle, nID);
return (hWnd != NULL);
#endif // _WIN32_WCE
}
#ifdef _WIN32_WCE
// CE specific variant that returns the handle of the toolbar
HWND CreateSimpleCEToolBar(UINT nResourceID = 0, DWORD dwStyle = ATL_SIMPLE_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR)
{
if(nResourceID == 0)
nResourceID = T::GetWndClassInfo().m_uCommonResourceID;
return T::CreateSimpleToolBarCtrl(m_hWndCECommandBar, nResourceID, TRUE, dwStyle, nID);
}
#endif // _WIN32_WCE
// message map and handlers
typedef CFrameWindowImplBase< TBase, TWinTraits > _baseClass;
BEGIN_MSG_MAP(CFrameWindowImpl)
MESSAGE_HANDLER(WM_SIZE, OnSize)
#ifndef _ATL_NO_REBAR_SUPPORT
#if (_WIN32_IE >= 0x0400)
NOTIFY_CODE_HANDLER(RBN_AUTOSIZE, OnReBarAutoSize)
#endif // (_WIN32_IE >= 0x0400)
#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
NOTIFY_CODE_HANDLER(RBN_CHEVRONPUSHED, OnChevronPushed)
#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
#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();
}
bHandled = FALSE;
return 1;
}
#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) && !defined(_WIN32_WCE)
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) && !defined(_WIN32_WCE)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -