📄 atlframe.h
字号:
}
#endif //_DEBUG
ATLASSERT(::IsWindow(hWndBand)); // must be already created
// Get number of buttons on the toolbar
int nBtnCount = (int)::SendMessage(hWndBand, TB_BUTTONCOUNT, 0, 0L);
// Set band info structure
REBARBANDINFO rbBand;
rbBand.cbSize = sizeof(REBARBANDINFO);
#if (_WIN32_IE >= 0x0400)
rbBand.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_STYLE | RBBIM_ID | RBBIM_SIZE | RBBIM_IDEALSIZE;
#else
rbBand.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_STYLE | RBBIM_ID | RBBIM_SIZE;
#endif //!(_WIN32_IE >= 0x0400)
if(lpstrTitle != NULL)
rbBand.fMask |= RBBIM_TEXT;
rbBand.fStyle = RBBS_CHILDEDGE;
#if (_WIN32_IE >= 0x0500)
if(nBtnCount > 0) // add chevron style for toolbar with buttons
rbBand.fStyle |= RBBS_USECHEVRON;
#endif //(_WIN32_IE >= 0x0500)
if(bNewRow)
rbBand.fStyle |= RBBS_BREAK;
rbBand.lpText = lpstrTitle;
rbBand.hwndChild = hWndBand;
if(nID == 0) // calc band ID
nID = ATL_IDW_BAND_FIRST + (int)::SendMessage(hWndReBar, RB_GETBANDCOUNT, 0, 0L);
rbBand.wID = nID;
// Calculate the size of the band
BOOL bRet;
RECT rcTmp;
if(nBtnCount > 0)
{
bRet = (BOOL)::SendMessage(hWndBand, TB_GETITEMRECT, nBtnCount - 1, (LPARAM)&rcTmp);
ATLASSERT(bRet);
rbBand.cx = (cxWidth != 0) ? cxWidth : rcTmp.right;
rbBand.cyMinChild = rcTmp.bottom - rcTmp.top;
if(bFullWidthAlways)
{
rbBand.cxMinChild = rbBand.cx;
}
else if(lpstrTitle == 0)
{
bRet = (BOOL)::SendMessage(hWndBand, TB_GETITEMRECT, 0, (LPARAM)&rcTmp);
ATLASSERT(bRet);
rbBand.cxMinChild = rcTmp.right;
}
else
{
rbBand.cxMinChild = 0;
}
}
else // no buttons, either not a toolbar or really has no buttons
{
bRet = ::GetWindowRect(hWndBand, &rcTmp);
ATLASSERT(bRet);
rbBand.cx = (cxWidth != 0) ? cxWidth : (rcTmp.right - rcTmp.left);
rbBand.cxMinChild = bFullWidthAlways ? rbBand.cx : 0;
rbBand.cyMinChild = rcTmp.bottom - rcTmp.top;
}
#if (_WIN32_IE >= 0x0400)
rbBand.cxIdeal = rbBand.cx;
#endif //(_WIN32_IE >= 0x0400)
// Add the band
LRESULT lRes = ::SendMessage(hWndReBar, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbBand);
if(lRes == 0)
{
ATLTRACE2(atlTraceUI, 0, _T("Failed to add a band to the rebar.\n"));
return FALSE;
}
#if (_WIN32_IE >= 0x0501)
DWORD dwExStyle = (DWORD)::SendMessage(hWndBand, TB_GETEXTENDEDSTYLE, 0, 0L);
::SendMessage(hWndBand, TB_SETEXTENDEDSTYLE, 0, dwExStyle | TBSTYLE_EX_HIDECLIPPEDBUTTONS);
#endif //(_WIN32_IE >= 0x0501)
return TRUE;
}
BOOL AddSimpleReBarBand(HWND hWndBand, LPTSTR lpstrTitle = NULL, BOOL bNewRow = FALSE, int cxWidth = 0, BOOL bFullWidthAlways = FALSE)
{
ATLASSERT(::IsWindow(m_hWndToolBar)); // must be an existing rebar
ATLASSERT(::IsWindow(hWndBand)); // must be created
return AddSimpleReBarBandCtrl(m_hWndToolBar, hWndBand, 0, lpstrTitle, bNewRow, cxWidth, bFullWidthAlways);
}
#if (_WIN32_IE >= 0x0400)
void SizeSimpleReBarBands()
{
ATLASSERT(::IsWindow(m_hWndToolBar)); // must be an existing rebar
int nCount = (int)::SendMessage(m_hWndToolBar, RB_GETBANDCOUNT, 0, 0L);
for(int i = 0; i < nCount; i++)
{
REBARBANDINFO rbBand;
rbBand.cbSize = sizeof(REBARBANDINFO);
rbBand.fMask = RBBIM_SIZE;
BOOL bRet = (BOOL)::SendMessage(m_hWndToolBar, RB_GETBANDINFO, i, (LPARAM)&rbBand);
ATLASSERT(bRet);
RECT rect = { 0, 0, 0, 0 };
::SendMessage(m_hWndToolBar, RB_GETBANDBORDERS, i, (LPARAM)&rect);
rbBand.cx += rect.left + rect.right;
bRet = (BOOL)::SendMessage(m_hWndToolBar, RB_SETBANDINFO, i, (LPARAM)&rbBand);
ATLASSERT(bRet);
}
}
#endif //(_WIN32_IE >= 0x0400)
BOOL CreateSimpleStatusBar(LPCTSTR lpstrText, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | SBARS_SIZEGRIP, UINT nID = ATL_IDW_STATUS_BAR)
{
ATLASSERT(!::IsWindow(m_hWndStatusBar));
m_hWndStatusBar = ::CreateStatusWindow(dwStyle, lpstrText, m_hWnd, nID);
return (m_hWndStatusBar != NULL);
}
BOOL CreateSimpleStatusBar(UINT nTextID = ATL_IDS_IDLEMESSAGE, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | SBARS_SIZEGRIP, UINT nID = ATL_IDW_STATUS_BAR)
{
TCHAR szText[128]; // max text lentgth is 127 for status bars
szText[0] = 0;
::LoadString(_Module.GetResourceInstance(), nTextID, szText, 128);
return CreateSimpleStatusBar(szText, dwStyle, nID);
}
void UpdateLayout(BOOL bResizeBars = TRUE)
{
RECT rect;
GetClientRect(&rect);
// position bars and offset their dimensions
UpdateBarsPosition(rect, bResizeBars);
// resize client window
if(m_hWndClient != NULL)
::SetWindowPos(m_hWndClient, NULL, rect.left, rect.top,
rect.right - rect.left, rect.bottom - rect.top,
SWP_NOZORDER | SWP_NOACTIVATE);
}
void UpdateBarsPosition(RECT& rect, BOOL bResizeBars = TRUE)
{
// resize toolbar
if(m_hWndToolBar != NULL && ((DWORD)::GetWindowLong(m_hWndToolBar, GWL_STYLE) & WS_VISIBLE))
{
if(bResizeBars)
::SendMessage(m_hWndToolBar, WM_SIZE, 0, 0);
RECT rectTB;
::GetWindowRect(m_hWndToolBar, &rectTB);
rect.top += rectTB.bottom - rectTB.top;
}
// resize status bar
if(m_hWndStatusBar != NULL && ((DWORD)::GetWindowLong(m_hWndStatusBar, GWL_STYLE) & WS_VISIBLE))
{
if(bResizeBars)
::SendMessage(m_hWndStatusBar, WM_SIZE, 0, 0);
RECT rectSB;
::GetWindowRect(m_hWndStatusBar, &rectSB);
rect.bottom -= rectSB.bottom - rectSB.top;
}
}
BOOL PreTranslateMessage(MSG* pMsg)
{
if(m_hAccel != NULL && ::TranslateAccelerator(m_hWnd, m_hAccel, pMsg))
return TRUE;
return FALSE;
}
typedef CFrameWindowImplBase< TBase, TWinTraits > thisClass;
BEGIN_MSG_MAP(thisClass)
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
MESSAGE_HANDLER(WM_MENUSELECT, OnMenuSelect)
MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
NOTIFY_CODE_HANDLER(TTN_GETDISPINFOA, OnToolTipTextA)
NOTIFY_CODE_HANDLER(TTN_GETDISPINFOW, OnToolTipTextW)
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;
}
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
{
TCHAR szBuff[256];
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) // MDI child windows
wID = ATL_IDS_MDICHILD;
int nRet = ::LoadString(_Module.GetResourceInstance(), wID, szBuff, 256);
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;
}
LRESULT OnSetFocus(UINT, WPARAM, LPARAM, BOOL& bHandled)
{
if(m_hWndClient != NULL && ::IsWindowVisible(m_hWndClient))
::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;
}
LRESULT OnToolTipTextA(int idCtrl, LPNMHDR pnmh, BOOL& /*bHandled*/)
{
LPNMTTDISPINFOA pDispInfo = (LPNMTTDISPINFOA)pnmh;
pDispInfo->szText[0] = 0;
if((idCtrl != 0) && !(pDispInfo->uFlags & TTF_IDISHWND))
{
char szBuff[256];
szBuff[0] = 0;
int nRet = ::LoadStringA(_Module.GetResourceInstance(), idCtrl, szBuff, 256);
for(int i = 0; i < nRet; i++)
{
if(szBuff[i] == '\n')
{
lstrcpynA(pDispInfo->szText, &szBuff[i + 1], sizeof(pDispInfo->szText) / sizeof(pDispInfo->szText[0]));
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))
{
wchar_t szBuff[256];
szBuff[0] = 0;
int nRet = ::LoadStringW(_Module.GetResourceInstance(), idCtrl, szBuff, 256);
for(int i = 0; i < nRet; i++)
{
if(szBuff[i] == L'\n')
{
lstrcpynW(pDispInfo->szText, &szBuff[i + 1], sizeof(pDispInfo->szText) / sizeof(pDispInfo->szText[0]));
break;
}
}
#if (_WIN32_IE >= 0x0300)
if(nRet > 0) // string was loaded, save it
pDispInfo->uFlags |= TTF_DI_SETITEM;
#endif //(_WIN32_IE >= 0x0300)
}
return 0;
}
// Implementation - chevron menu support
#if (_WIN32_IE >= 0x0500)
bool PrepareChevronMenu(_ChevronMenuInfo& cmi)
{
// get rebar and toolbar
REBARBANDINFO rbbi;
rbbi.cbSize = 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
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;
bRet = wnd.GetClientRect(&rcClient);
ATLASSERT(bRet);
for(int i = 0; i < nCount; i++)
{
TBBUTTON tbb;
bRet = (BOOL)wnd.SendMessage(TB_GETBUTTON, i, (LPARAM)&tbb);
ATLASSERT(bRet);
// skip hidden buttons
if((tbb.fsState & TBSTATE_HIDDEN) != 0)
continue;
RECT rcButton;
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)
{
TCHAR szBuff[100];
CMenuItemInfo mii;
mii.fMask = MIIM_TYPE | MIIM_SUBMENU;
mii.dwTypeData = szBuff;
mii.cch = sizeof(szBuff) / sizeof(TCHAR);
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
TCHAR szBuff[100];
LPTSTR lpstrText = szBuff;
TBBUTTONINFO tbbi;
tbbi.cbSize = sizeof(TBBUTTONINFO);
tbbi.dwMask = TBIF_TEXT;
tbbi.pszText = szBuff;
tbbi.cchText = sizeof(szBuff) / sizeof(TCHAR);
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(_Module.GetResourceInstance(), tbb.idCommand, szBuff, sizeof(szBuff) / sizeof(TCHAR));
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
CWindow wndFrom = cmi.lpnm->hdr.hwndFrom;
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;
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, rc.left, rc.bottom, &TPMParams };
::SendMessage(hWndCmdBar, CBRM_TRACKPOPUPMENU, 0, (LPARAM)&CBRPopupMenu);
}
else
{
::TrackPopupMenuEx(cmi.hMenu, uMenuFlags, rc.left, rc.bottom, 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();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -