📄 menubar.cpp.svn-base
字号:
if (m_nCurIndex == 0 || m_nCurIndex == 1 || hMenu == m_hWindowMenu) {
LTRACE2(_T(" it's container menu, send to frame\n"));
return NULL;
}
}
else {
LTRACE2(_T(" it's container menu, send to frame\n"));
if (m_nCurIndex == 0) {
return NULL;
}
}
LTRACE2(_T(" it's server menu, send to server\n"));
return pOleWnd->GetSafeHwnd();
}
break;
case WM_COMMAND:
bSend = FALSE;
if (m_bMDIApp) {
LTRACE2(_T(" this is MDI\n"));
if (_nPrevIndexForCmd == 0 || _nPrevIndexForCmd == 1 || _bWindowMenuSendCmd) {
LTRACE2(_T(" it's container menu, send to frame\n"));
return NULL;
}
}
else {
if (_nPrevIndexForCmd == 0) {
LTRACE2(_T(" it's container menu, send to frame\n"));
return NULL;
}
}
LTRACE2(_T(" it's server menu, send to server\n"));
return pOleWnd->GetSafeHwnd();
}
return NULL;// send to frame
}
//******************************************************************
CWnd* CMenuBar::GetCmdSentOleWnd()
{
// *****fixed by VORGA, thanks!*****
CWnd* pWnd = AfxGetMainWnd();
if (pWnd == NULL || !pWnd->IsFrameWnd())
return NULL;
CFrameWnd* pFrame = NULL;
if (m_bMDIApp) {
CMDIFrameWnd *pMDIFrame = STATIC_DOWNCAST(CMDIFrameWnd, pWnd);
if (pMDIFrame == NULL)
return NULL;
pFrame = pMDIFrame->GetActiveFrame();
}
else {
pFrame = STATIC_DOWNCAST(CFrameWnd, pWnd);
}
if (pFrame == NULL)
return NULL;
CDocument* pDoc = pFrame->GetActiveDocument();
if (pDoc != NULL && pDoc->IsKindOf(RUNTIME_CLASS(COleDocument))) {
COleDocument* pOleDoc = STATIC_DOWNCAST(COleDocument, pDoc);
ASSERT_VALID(pOleDoc);
COleClientItem* pClientItem = pOleDoc->GetInPlaceActiveItem(pFrame);
CWnd* pWnd = (pClientItem == NULL) ? NULL : pClientItem->GetInPlaceWindow();
if (pWnd != NULL) {
return pWnd;
}
}
return NULL;
}
//******************************************************************
/////////////////////////////////////////////////////////////////////////////
// CMDIClientHook
CMDIClientHook::CMDIClientHook()
{
m_pMenuBar = NULL;
}
//******************************************************************
BOOL CMDIClientHook::Install(CMenuBar* pMenuBar, HWND hWndToHook)
{
ASSERT_VALID(pMenuBar);
ASSERT(m_pMenuBar == NULL);
m_pMenuBar = pMenuBar;
return HookWindow(hWndToHook);
}
//******************************************************************
CMDIClientHook::~CMDIClientHook()
{
}
//******************************************************************
LRESULT CMDIClientHook::WindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam)
{
ASSERT_VALID(m_pMenuBar);
switch (nMsg) {
case WM_MDISETMENU: // only sent to MDI client window
// Setting new frame/window menu: bypass MDI. wParam is new menu.
if (wParam) {
//LTRACE(_T("CMenuBar::WM_MDISETMENU 0x%04x\n"), wParam);
m_pMenuBar->OnSetMenu((HMENU)wParam, (HMENU)lParam);
}
return 0;
case WM_MDIREFRESHMENU: // only sent to MDI client window
// Normally, would call DrawMenuBar, but I have the menu, so eat it.
//LTRACE(_T("CMenuBar::WM_MDIREFRESHMENU\n"));
return 0;
}
return CSubclassWnd::WindowProc(nMsg, wParam, lParam);
}
//******************************************************************
/////////////////////////////////////////////////////////////////////////////
// CMainFrameHook
CMainFrameHook::CMainFrameHook()
{
m_pMenuBar = NULL;
}
//******************************************************************
BOOL CMainFrameHook::Install(CMenuBar* pMenuBar, HWND hWndToHook)
{
ASSERT_VALID(pMenuBar);
ASSERT(m_pMenuBar == NULL);
m_pMenuBar = pMenuBar;
return HookWindow(hWndToHook);
}
//******************************************************************
CMainFrameHook::~CMainFrameHook()
{
}
//******************************************************************
LRESULT CMainFrameHook::WindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam)
{
ASSERT_VALID(m_pMenuBar);
// be care for other windows(MainFrame) hooking
// possible called when already this wnd destroyed (WM_NCACTIVATE is)
if (!::IsWindow(m_pMenuBar->m_hWnd)) {
return CSubclassWnd::WindowProc(nMsg, wParam, lParam);
}
BOOL bSend = FALSE;
if (HWND hWndServer = m_pMenuBar->OleMenuDescriptor(bSend, nMsg, wParam, lParam)) {
// OLE wnd will handle message
if (bSend)
return ::SendMessage(hWndServer, nMsg, wParam, lParam);
else
return ::PostMessage(hWndServer, nMsg, wParam, lParam);
}
switch (nMsg) {
case WM_MENUSELECT:
m_pMenuBar->OnMenuSelect((HMENU)lParam, (UINT)LOWORD(wParam));
break;
case WM_INITMENUPOPUP:
if (!HIWORD(lParam) && (HMENU)wParam == m_pMenuBar->m_hWindowMenu)
m_pMenuBar->OnInitMenuPopup(CMenu::FromHandle((HMENU)wParam),
LOWORD(lParam), (BOOL)HIWORD(lParam));
break;
case WM_NCACTIVATE:
m_pMenuBar->OnFrameNcActivate((BOOL)wParam);
break;
case WM_SYSCOLORCHANGE:
case WM_SETTINGCHANGE:
LTRACE(_T("CMenuBar::WM_SETTINGCHANGE\n"));
// It's enough to reinitialize common resources once.
m_pMenuBar->OnSettingChange(wParam, lParam);
break;
}
if (nMsg == CMenuBar::WM_GETMENU)
return (LRESULT)m_pMenuBar->m_hMenu;
return CSubclassWnd::WindowProc(nMsg, wParam, lParam);
}
//******************************************************************
//////////////////////////////////////////////////////////////////////
// CMenuItem interface
CMenuItem::CMenuItem()
{
m_fsStyle = 0;
m_fsState = 0;
m_rcItem.SetRectEmpty();
m_sizeHorz = CSize(0, 0);
m_cAccessKey = 0;
}
//******************************************************************
void CMenuItem::ModifyState(BYTE fsRemove, BYTE fsAdd)
{
m_fsState = (m_fsState & ~fsRemove) | fsAdd;
}
//******************************************************************
CSize CMenuItem::GetHorizontalSize() const
{
if (m_fsState & MISTATE_HIDDEN)
return CSize(0, 0);
else
return m_sizeHorz;
}
//******************************************************************
//////////////////////////////////////////////////////////////////////
// CMenuButton class
CMenuButton::CMenuButton(HMENU hMenu, int nIndex)
{
ASSERT(::IsMenu(hMenu));
ASSERT(nIndex >= 0);
m_fsStyle |= (MISTYLE_TRACKABLE | MISTYLE_WRAPPABLE);
InitButtonStringAndSubMenuHandle(hMenu, nIndex);
InitHorizontalButtonSize();
InitAccessKeyAndVerticalLinePoint();
}
//******************************************************************
void CMenuButton::InitButtonStringAndSubMenuHandle(HMENU hMenu, int nIndex)
{
// get menu button Text
TCHAR szText[256];
MENUITEMINFO info; ::memset(&info, 0, sizeof(MENUITEMINFO));
info.cbSize = sizeof(MENUITEMINFO);
info.fMask = MIIM_ID | MIIM_TYPE;
info.dwTypeData = szText;
info.cch = sizeof(szText);
::GetMenuItemInfo(hMenu, nIndex, TRUE, &info);
m_strBtn = CString(szText);
m_hSubMenu = ::GetSubMenu(hMenu, nIndex);
if (!m_hSubMenu) {
m_nID = ::GetMenuItemID(hMenu, nIndex);
ASSERT(m_nID != -1);
}
else {
m_nID = -1;
}
}
//******************************************************************
void CMenuButton::InitHorizontalButtonSize()
{
// get menu button Text size
ASSERT(m_strBtn.IsEmpty() == FALSE);
m_sizeHorz.cx = (_CalcTextWidth(m_strBtn) + CXTEXTMARGIN*2)+5;
m_sizeHorz.cy = (_cyHorzFont + _cyTextMargin*2)+1;
}
//******************************************************************
void CMenuButton::InitAccessKeyAndVerticalLinePoint()
{
int nIndex = m_strBtn.Find('&');
if (nIndex + 1 == m_strBtn.GetLength()) {
TRACE(_T("warning : & is bad position, access key is invalid.\n"));
m_cAccessKey = 0;
m_ptLineFrom = m_ptLineTo = CPoint(0, 0);
return;
}
m_cAccessKey = m_strBtn[nIndex + 1];// -1 + 1 = 0; it's ok
if (nIndex == -1) {
m_ptLineFrom = m_ptLineTo = CPoint(0, 0);
}
else if (nIndex == 0) {
m_ptLineFrom = CPoint(_cyTextMargin, CXTEXTMARGIN);
m_ptLineTo = CPoint(_cyTextMargin, CXTEXTMARGIN + _CalcTextWidth(m_strBtn.Left(nIndex+2)));
}
else {
m_ptLineFrom = CPoint(_cyTextMargin, CXTEXTMARGIN + _CalcTextWidth(m_strBtn.Left(nIndex)));
m_ptLineTo = CPoint(_cyTextMargin, CXTEXTMARGIN + _CalcTextWidth(m_strBtn.Left(nIndex+2)));
}
}
//******************************************************************
void CMenuButton::Layout(CPoint point, BOOL bHorz)
{
if (bHorz)
m_fsState |= MISTATE_HORZ;
else
m_fsState &= ~MISTATE_HORZ;
if (m_fsState & MISTATE_HIDDEN) {
m_rcItem.SetRectEmpty();
return;
}
if (bHorz) {
m_rcItem = CRect(point, m_sizeHorz);
}
else {
m_rcItem = CRect(point, CSize(m_sizeHorz.cy, m_sizeHorz.cx));
}
}
//******************************************************************
void CMenuButton::Update(CDC* pDC)
{
if (m_fsState & MISTATE_HIDDEN)
return;
// clean background
COLORREF clr = ::GetSysColor(COLOR_BTNFACE);
pDC->FillSolidRect(m_rcItem, clr);
if (m_fsState & MISTATE_HOT){
DrawHot(pDC);
}
else if (m_fsState & MISTATE_PRESSED){
DrawPressed(pDC);
}
else {
DrawNone(pDC);
}
}
//*********************************************************
void CMenuButton::TrackPopup(CWnd* pBar, CWnd* pWndSentCmd)
{
LTRACE(_T("CMenuButton::TrackPopup\n"));
ASSERT_VALID(pBar);
ASSERT(!(m_fsState & MISTATE_HIDDEN));
pMenuBar = STATIC_DOWNCAST(CMenuBar, pBar);
ASSERT_VALID(pMenuBar);
// "! menu" (no sub menu)
if (!m_hSubMenu) {
ASSERT(m_nID != -1);
pWndSentCmd->SendMessage(WM_COMMAND, (WPARAM)m_nID, (LPARAM)pBar->GetSafeHwnd());
return;
}
CRect rcItem(m_rcItem); pMenuBar->ClientToScreen(rcItem);
UINT fuFlags; TPMPARAMS tpm;
CPoint pt = _ComputeMenuTrackPoint(rcItem, pMenuBar->GetBarStyle(), fuFlags, tpm);
if (m_hSubMenu == pMenuBar->m_hWindowMenu)
_bWindowMenuSendCmd = TRUE;
else
_bWindowMenuSendCmd = FALSE;
if (pMenuBar->GetBarStyle() & CBRS_ORIENT_HORZ)
{
pt.x+=1; pt.y-=2;
}
else
{
pt.x-=2; pt.y+=2;
}
::TrackPopupMenuEx(m_hSubMenu, fuFlags,
pt.x, pt.y, pWndSentCmd->GetSafeHwnd(), &tpm);
}
//******************************************************************
void CMenuButton::DrawHorzText(CDC* pDC, CPoint ptOffset)
{
COLORREF clr = (m_fsState & MISTATE_INACTIVE) ?
::GetSysColor(COLOR_GRAYTEXT) : ::GetSysColor(COLOR_MENUTEXT);
pDC->SetTextColor(clr);
CRect rcBtn = m_rcItem;
pDC->SetBkMode(TRANSPARENT);
CFont* pOldFont = pDC->SelectObject(&_fontHorzMenu);
// I know precise text size, but better to leave this job to Windows
// *****fixed by andi, thanks!*****
pDC->DrawText(m_strBtn, rcBtn + ptOffset,
DT_SINGLELINE | DT_CENTER | DT_VCENTER);
pDC->SelectObject(pOldFont);
gbintHorz=0;
rcMenu=rcBtn;
rcMenu.right-=4;
}
//******************************************************************
void CMenuButton::DrawVertText(CDC* pDC, CPoint ptOffset)
{
COLORREF clr = (m_fsState & MISTATE_INACTIVE) ?
::GetSysColor(COLOR_GRAYTEXT) : ::GetSysColor(COLOR_MENUTEXT);
pDC->SetTextColor(clr);
CRect rcBtn = m_rcItem;
int nLength = m_strBtn.GetLength();
int nIndex = m_strBtn.Find('&');
CString strBtn = m_strBtn.Left(nIndex) + m_strBtn.Right(nLength - (nIndex+1));
// fixed for WinNT. *****fixed by Simon, thanks!*****
int iGraphicsMode = ::GetGraphicsMode(pDC->m_hDC);
::SetGraphicsMode(pDC->m_hDC, GM_ADVANCED);
pDC->SetBkMode(TRANSPARENT);
CFont* pOldFont = pDC->SelectObject(&_fontVertMenu);
// I know precise text size
CRect rcString = CRect(
CPoint(rcBtn.right - _cyTextMargin, rcBtn.top + CXTEXTMARGIN), m_sizeHorz);
pDC->DrawText(strBtn, rcString + ptOffset,
DT_SINGLELINE | DT_NOCLIP | DT_NOPREFIX);// don't forget DT_NOCLIP
gbintHorz=1;
rcMenu=rcBtn;
rcMenu.bottom-=3;
pDC->SelectObject(pOldFont);
// CDC::DrawText is poor, so we have to draw vertical line by ourselves
CPen pen(PS_SOLID, 0, clr);
CPen* pOldPen = pDC->SelectObject(&pen);
pDC->MoveTo(rcBtn.TopLeft() + m_ptLineFrom + ptOffset);
pDC->LineTo(rcBtn.TopLeft() + m_ptLineTo + ptOffset);
pDC->SelectObject(pOldPen);
::SetGraphicsMode( pDC->m_hDC, iGraphicsMode );
}
//******************************************************************
void CMenuButton::DrawButton(CDC* pDC,WORD wState)
{
/* ASSERT(m_strBtn.IsEmpty() == FALSE);
m_sizeHorz.cx = (_CalcTextWidth(m_strBtn) + CXTEXTMARGIN*2)+5;
m_sizeHorz.cy = (_cyHorzFont + _cyTextMargin*2)+1;
*/
CBrush cblu;
CRect rcBtn =m_rcItem;
if (dSt & CBRS_ORIENT_HORZ )
rcBtn.right-=4;
else
rcBtn.bottom-=2;
if (wState & BDR_RAISEDINNER)
pDC->Draw3dRect(rcBtn,m_dw.GetRGBCaptionXP(),m_dw.GetRGBCaptionXP());
else
{
if (dSt & CBRS_ORIENT_HORZ )
rcBtn.bottom+=1;
else
rcBtn.bottom-=1;
pDC->Draw3dRect(rcBtn,GuiDrawLayer::GetRGBColorShadow(),GuiDrawLayer::GetRGBColorShadow());
if (dSt & CBRS_ORIENT_HORZ )
rcBtn.bottom-=1;
else
rcBtn.bottom+=1;
CPen pen(PS_SOLID, 0, GuiDrawLayer::GetRGBColorFace());
CPen* pOldPen = pDC->SelectObject(&pen);
pDC->MoveTo(rcBtn.left, rcBtn.bottom);
pDC->LineTo(rcBtn.right, rcBtn.bottom);
COLORREF ColA = GetSysColor(COLOR_WINDOW);
COLORREF ColB = GuiDrawLayer::GetRGBColorFace();
CRect rect = rcBtn;
int X,Y;
X=Y=0;
int winH = rect.Height();
int winW = rect.Width();
if (dSt & CBRS_ORIENT_HORZ )
{
rect.right+=4;
// Simulate a shadow on righ
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -