// StaticMenuGrabber.cpp // // (c)1998-2025 Codejock Software, All Rights Reserved. // // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN // CONSENT OF CODEJOCK SOFTWARE. // // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A // SINGLE COMPUTER. // // CONTACT INFORMATION: // support@codejock.com // http://www.codejock.com // ///////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "commandbarsdesigner.h" #include "StaticMenuGrabber.h" #include "MainFrm.h" #ifdef _DEBUG # define new DEBUG_NEW # undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CStaticMenuGrabber CStaticMenuGrabber::CStaticMenuGrabber() { m_hCursor = AfxGetApp()->LoadCursor(IDC_GRABBER); m_bGrabbing = FALSE; m_pMenuBar = NULL; } CStaticMenuGrabber::~CStaticMenuGrabber() { } BEGIN_MESSAGE_MAP(CStaticMenuGrabber, CStatic) //{{AFX_MSG_MAP(CStaticMenuGrabber) ON_WM_PAINT() ON_WM_LBUTTONDOWN() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CStaticMenuGrabber message handlers void CStaticMenuGrabber::OnPaint() { CPaintDC dcPaint(this); // device context for painting CXTPBufferDC dc(dcPaint); CXTPClientRect rc(this); CMainFrame* pMainFrame = GetMainFrame(); dc.FillSolidRect(rc, pMainFrame->m_csPane.m_clrBack); // dc.FillSolidRect(rc, GetXtremeColor(COLOR_WINDOW)); // dc.Draw3dRect(rc, GetXtremeColor(COLOR_BTNSHADOW), GetXtremeColor(COLOR_BTNSHADOW)); dc.Draw3dRect(rc, pMainFrame->m_csPane.m_clrBorderDark, pMainFrame->m_csPane.m_clrBorderDark); CString str; GetWindowText(str); CXTPFontDC font(&dc, GetFont()); dc.SetBkMode(TRANSPARENT); // dc.SetTextColor(GetXtremeColor(COLOR_WINDOWTEXT)); dc.SetTextColor(pMainFrame->m_csPane.m_clrText); if (m_bGrabbing) { rc.left += XTP_DPI_X(5) + XTP_DPI_X(32) + XTP_DPI_X(5); dc.DrawText(_T("Now drag the mouse to select a menu"), rc, DT_VCENTER | DT_LEFT | DT_SINGLELINE); } else { ::DrawIconEx(dc, rc.left + XTP_DPI_X(5), rc.CenterPoint().y - XTP_DPI_X(32 / 2), m_hCursor, XTP_DPI_X(32), XTP_DPI_X(32), 0, 0, DI_NORMAL); rc.left += XTP_DPI_X(5) + XTP_DPI_X(32) + XTP_DPI_X(5); dc.DrawText(str, rc, DT_VCENTER | DT_LEFT | DT_SINGLELINE); } } struct XTP_MENUBARINFO { DWORD cbSize; RECT rcBar; // rect of bar, popup, item HMENU hMenu; // real menu handle of bar, popup HWND hwndMenu; // hwnd of item submenu if one BOOL fBarFocused : 1; // bar, popup has the focus BOOL fFocused : 1; // item has the focus }; #ifndef OBJID_MENU # define OBJID_MENU 0xFFFFFFFD #endif void CStaticMenuGrabber::HighlightWindow(HWND hwnd, BOOL fDraw) { #define DINV XTP_DPI_X(3) HDC hdc; RECT rcWindow; RECT rc; BOOL bBorderOn; bBorderOn = fDraw; if (hwnd == NULL || !IsWindow(hwnd)) return; typedef BOOL(WINAPI * PFNGETMENUBARINFO)(HWND hwnd, LONG idObject, LONG idItem, XTP_MENUBARINFO * pmbi); HINSTANCE hInst = ::GetModuleHandleA("USER32.DLL"); PFNGETMENUBARINFO pfnGetMenuBarInfo = (PFNGETMENUBARINFO)GetProcAddress(hInst, "GetMenuBarInfo"); if (!pfnGetMenuBarInfo) return; XTP_MENUBARINFO mbInfo = { sizeof(mbInfo) }; if (!(*pfnGetMenuBarInfo)(hwnd, OBJID_MENU, 0, &mbInfo)) return; hdc = ::GetWindowDC(hwnd); ::GetWindowRect(hwnd, &rcWindow); rc = mbInfo.rcBar; ::OffsetRect(&rc, -rcWindow.left, -rcWindow.top); if (!IsRectEmpty(&rc)) { PatBlt(hdc, rc.left, rc.top, rc.right - rc.left, DINV, DSTINVERT); PatBlt(hdc, rc.left, rc.bottom - DINV, DINV, -(rc.bottom - rc.top - 2 * DINV), DSTINVERT); PatBlt(hdc, rc.right - DINV, rc.top + DINV, DINV, rc.bottom - rc.top - 2 * DINV, DSTINVERT); PatBlt(hdc, rc.right, rc.bottom - DINV, -(rc.right - rc.left), DINV, DSTINVERT); } ::ReleaseDC(hwnd, hdc); } void CStaticMenuGrabber::ConvertMenu(HWND hWnd) { if (!m_pMenuBar) return; m_pMenuBar->GetControls()->RemoveAll(); HMENU hMenu = ::GetMenu(hWnd); if (!hMenu) return; m_pMenuBar->LoadMenu(CMenu::FromHandle(hMenu)); CXTPClientRect rc(m_pMenuBar->GetParent()); CSize sz = m_pMenuBar->CalcDockingLayout(rc.Width(), /*LM_HIDEWRAP|*/ LM_HORZDOCK | LM_HORZ | LM_COMMIT); m_pMenuBar->MoveWindow(0, 0, rc.Width(), sz.cy); m_pMenuBar->Invalidate(FALSE); } void CStaticMenuGrabber::OnLButtonDown(UINT /*nFlags*/, CPoint point) { m_bGrabbing = TRUE; Invalidate(FALSE); SetCapture(); ::SetCursor(m_hCursor); HWND hPrevSpyWnd = 0; BOOL bAccept = FALSE; for (;;) { MSG msg; VERIFY(::GetMessage(&msg, NULL, 0, 0)); if (msg.message == WM_LBUTTONUP) { bAccept = TRUE; break; } else if (msg.message == WM_KEYDOWN) { if (msg.wParam == VK_ESCAPE) break; } else if (msg.message == WM_MOUSEMOVE) { GetCursorPos(&point); HWND hWnd = ::WindowFromPoint(point); CRect rc; GetWindowRect(rc); if (rc.PtInRect(point)) hWnd = 0; HMENU hMenu = hWnd ? ::GetMenu(hWnd) : NULL; if (!hMenu) hWnd = NULL; if (hWnd != hPrevSpyWnd) { if (hPrevSpyWnd) HighlightWindow(hPrevSpyWnd, FALSE); if (hWnd) HighlightWindow(hWnd, TRUE); hPrevSpyWnd = hWnd; } // continue; } DispatchMessage(&msg); if (::GetCapture() != m_hWnd) break; } if (hPrevSpyWnd) { HighlightWindow(hPrevSpyWnd, FALSE); } ReleaseCapture(); if (bAccept && hPrevSpyWnd) { ConvertMenu(hPrevSpyWnd); } hPrevSpyWnd = 0; m_bGrabbing = FALSE; Invalidate(FALSE); }