#include "StdAfx.h" #include "KTMenuCtrlBar.h" #include "KTMenuPage.h" #include #include "tools.h" #include "initools.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif namespace { void getMenuFiles(LPCTSTR pszDir, LPCTSTR pszIni, std::vector> &mm) { if (!pszDir || !pszIni) return; TCHAR szMenu[MAX_PATH]; TCHAR szName[MAX_PATH]; CString sDir(pszDir); DWORD dwRes = ::GetPrivateProfileString(_T("Product"), _T("StartType"), _T("0"), szMenu, MAX_PATH, pszIni); CString sType(szMenu); if (sType == _T("0")) { IniTools::getSectionContent(pszIni, _T("MENUS"), mm); CString sSys(FilePath::GetSysDir()); for (size_t i = 0; i < mm.size(); ++i) { std::pair &s(mm[i]); s.first = sSys + _T("\\") + s.first + _T(".mnu"); } } else { if (::GetPrivateProfileString(_T("Product"), _T("StartMenu"), _T(""), szMenu, MAX_PATH, pszIni) > 0 && ::GetPrivateProfileString(_T("Product"), _T("StartMenuName"), _T(""), szName, MAX_PATH, pszIni) > 0 ) mm.push_back(std::make_pair(sDir + szMenu, szName)); } } } KTMenuCtrlBar * KTMenuCtrlBar::m_pMySelft = NULL; IMPLEMENT_DYNAMIC(KTMenuCtrlBar, CAdUiPaletteSet); KTMenuCtrlBar::KTMenuCtrlBar() { // 解决AutoCAD2009以后屏幕菜单拖动限制最小尺寸问题 --wyg20090522 m_pMySelft = this; m_hDockBar = NULL; m_pfnOldProc = NULL; m_bTracking = FALSE; } KTMenuCtrlBar::~KTMenuCtrlBar() { // 解决AutoCAD2009以后屏幕菜单拖动限制最小尺寸问题 --wyg20090522 if (IsWindow(m_hDockBar)) UnsubclassDockBar(); m_pMySelft = NULL; } BEGIN_MESSAGE_MAP(KTMenuCtrlBar, CAdUiPaletteSet) ON_WM_CREATE() ON_WM_CONTEXTMENU() ON_WM_TIMER() ON_WM_DESTROY() END_MESSAGE_MAP() BOOL KTMenuCtrlBar::CreateMenuBar(LPCTSTR pszTitle) { CMDIFrameWnd* pFrame = acedGetAcadFrame(); ASSERT(NULL != pFrame); if (!Create(pszTitle, WS_CHILD | WS_VISIBLE | CBRS_SIZE_DYNAMIC | CBRS_RIGHT, CRect(0, 0, 160, 100), pFrame)) { acutPrintf(_T("\n创建系统主菜单失败!")); return FALSE; } EnableDocking(CBRS_ALIGN_LEFT|CBRS_ALIGN_RIGHT); RestoreControlBar(AFX_IDW_DOCKBAR_RIGHT); std::vector> mm; getMenuFiles(FilePath::GetSysDir(), FilePath::GetSysDir() + _T("\\product.ini"), mm); if (mm.empty()) return FALSE; std::vector>::const_iterator it(mm.begin()); for (int nIndex = 0; it != mm.end(); ++it, ++nIndex) { KTMenuPage *pPage = new KTMenuPage; pPage->Create(WS_CHILD | WS_VISIBLE,it->second, this,NULL);//PS_EDIT_NAME if (pPage->CreateMenuBar(it->first, it->second, nIndex)) { AddPalette(pPage); } else { pPage->DestroyWindow(); delete pPage; } } if (this->GetPaletteCount() > 0) { SetActivePalette(0); } SetTimer(1024,600000,NULL); return TRUE; } void KTMenuCtrlBar::GetMinimumSize (CSize &size) { //- Call the default implementation by default CAdUiPaletteSet::GetMinimumSize (size) ; } //----------------------------------------------------------------------------- void KTMenuCtrlBar::GetMaximumSize (CSize &size) { //- Call the default implementation by default CAdUiPaletteSet::GetMaximumSize (size) ; } void KTMenuCtrlBar::OnTimer(UINT_PTR nIDEvent) { CAdUiPaletteSet::OnTimer(nIDEvent); } int KTMenuCtrlBar::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CAdUiPaletteSet::OnCreate(lpCreateStruct) == -1) return -1; CWnd* pWnd = GetDlgItem(idCloseBtn); ASSERT(NULL != pWnd); pWnd->EnableWindow(FALSE); // {B1C0135A-434A-4a60-8983-47BD73AD5D04} static GUID cMenuBar = { 0xb1c0135b, 0x434a, 0x4a60, { 0x89, 0x83, 0x47, 0xbd, 0x73, 0xad, 0x5d, 0x4 } }; SetToolID(&cMenuBar); return 0; } bool KTMenuCtrlBar::OnClosing() { return (IDYES != MessageBox(_T("屏幕菜单窗口即将关闭,执行“GP”命令即可重新打开。\n\n是否要关闭屏幕菜单窗口?"), _T("屏幕菜单"), MB_YESNO | MB_ICONQUESTION)); } void KTMenuCtrlBar::GetFloatingMinSize(long *plMinWidth, long *plMinHeight) { *plMinWidth = 40; *plMinHeight = 100; } void KTMenuCtrlBar::SizeChanged(CRect *lpRect, BOOL bFloating, int flags) { CAdUiPaletteSet::SizeChanged(lpRect, bFloating, flags); CRect rc(lpRect); rc.DeflateRect(6, 6); CString sKey; CAdUiPalette* pPage = NULL; for (int i = 0;i < GetPaletteCount();i++) { pPage = GetPalette(i); if (pPage != NULL) { pPage->MoveWindow(rc); } } } void KTMenuCtrlBar::OnContextMenu(CWnd* pWnd, CPoint point) { CAdUiPalette* pPage = NULL; for (int i = 0;i < GetPaletteCount();i++) { pPage = GetPalette(i); if (pPage == pWnd) { ((KTMenuPage*)pPage)->OnContextMenu(pWnd,point); break; } } } // 解决AutoCAD2009以后屏幕菜单拖动限制最小尺寸问题 --wyg20090522 #define AS_DOCK_CONTROLBAR(pBar) ((CControlBar*)((DWORD_PTR(pBar) <= 0xffff) ? NULL : (pBar))) CSize KTMenuCtrlBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz) { int iMajor = acdbHostApplicationServices()->releaseMajorVersion(); int iMinor = acdbHostApplicationServices()->releaseMinorVersion(); //if (iMajor >= 17 && iMinor >= 2) // 仅AutoCAD2009以后 if ((iMajor >= 17 && iMinor >= 2)|| (iMajor > 17)) // 仅AutoCAD2009以后 { BOOL bFloat = IsFloating(); if (bFloat) { UnsubclassDockBar(); } else { int iPos; CDockBar* pDockBar = DYNAMIC_DOWNCAST(CDockBar, GetParent()); if (NULL != pDockBar && ((iPos = pDockBar->FindBar(this)) > 0 && NULL != AS_DOCK_CONTROLBAR(pDockBar->m_arrBars[iPos - 1]) && AS_DOCK_CONTROLBAR(pDockBar->m_arrBars[iPos - 1])->IsVisible() || NULL != AS_DOCK_CONTROLBAR(pDockBar->m_arrBars[iPos + 1]) && AS_DOCK_CONTROLBAR(pDockBar->m_arrBars[iPos + 1])->IsVisible())) { UnsubclassDockBar(); } else { SubclassDockBar(pDockBar->GetSafeHwnd()); } } } return CAdUiPaletteSet::CalcFixedLayout(bStretch, bHorz); } BOOL KTMenuCtrlBar::SubclassDockBar(HWND hWnd) { if (NULL == hWnd) return FALSE; if (m_hDockBar == hWnd) return TRUE; UnsubclassDockBar(); m_hDockBar = hWnd; #ifdef _WIN64 m_pfnOldProc = (WNDPROC)SetWindowLongPtr(m_hDockBar, GWLP_WNDPROC, (LPARAM)&KTMenuCtrlBar::DockBarProc); #else m_pfnOldProc = (WNDPROC)SetWindowLong(m_hDockBar, GWLP_WNDPROC, (LPARAM)&KTMenuCtrlBar::DockBarProc); #endif ASSERT(NULL != m_pfnOldProc); return TRUE; } void KTMenuCtrlBar::UnsubclassDockBar() { if (NULL == m_hDockBar || NULL == m_pfnOldProc) return; #ifdef _WIN64 VERIFY(SetWindowLongPtr(m_hDockBar, GWLP_WNDPROC, (LPARAM)m_pfnOldProc) == (LPARAM)&KTMenuCtrlBar::DockBarProc); #else VERIFY(SetWindowLong(m_hDockBar, GWLP_WNDPROC, (LPARAM)m_pfnOldProc) == (LPARAM)&KTMenuCtrlBar::DockBarProc); #endif m_hDockBar = NULL; m_pfnOldProc = NULL; } UINT KTMenuCtrlBar::OnTrackHitTest(CPoint pt) { CRect rc; UINT nHit = OnGetTrackRect(::GetDlgCtrlID(m_hDockBar), rc); return (rc.PtInRect(pt) ? nHit : HTNOWHERE); } UINT KTMenuCtrlBar::OnGetTrackRect(UINT nDockOrHit, CRect& rc) { CRect rc1; GetWindowRect(&rc1); CWnd::FromHandle(m_hDockBar)->ScreenToClient(&rc1); CRect rc2; ::GetClientRect(m_hDockBar, &rc2); CSize szBorder; szBorder.cx = GetSystemMetrics(SM_CXFRAME); szBorder.cy = GetSystemMetrics(SM_CYFRAME); switch (nDockOrHit) { case HTLEFT: case AFX_IDW_DOCKBAR_RIGHT: rc.SetRect(rc1.left - szBorder.cx, rc2.top, rc1.left, rc2.bottom); return HTLEFT; case HTRIGHT: case AFX_IDW_DOCKBAR_LEFT: rc.SetRect(rc1.right, rc2.top, rc1.right + szBorder.cx, rc2.bottom); return HTRIGHT; case HTTOP: case AFX_IDW_DOCKBAR_BOTTOM: rc.SetRect(rc2.left, rc1.top - szBorder.cy, rc2.right, rc1.top); return HTTOP; case HTBOTTOM: case AFX_IDW_DOCKBAR_TOP: rc.SetRect(rc2.left, rc1.bottom, rc2.right, rc1.bottom + szBorder.cy); return HTBOTTOM; default: ASSERT(FALSE); return HTNOWHERE; } } void KTMenuCtrlBar::OnStartTracking(UINT nHit) { m_bTracking = TRUE; ::SetCapture(m_hDockBar); ::RedrawWindow(m_hDockBar, NULL, NULL, RDW_ALLCHILDREN | RDW_UPDATENOW); OnGetTrackRect(nHit, m_rcTracking); OnTrackPaint(); } void KTMenuCtrlBar::OnTrackUpdate(CPoint pt) { UINT nDock = ::GetDlgCtrlID(m_hDockBar); BOOL bHorz = (AFX_IDW_DOCKBAR_TOP == nDock || AFX_IDW_DOCKBAR_BOTTOM == nDock); CSize szOff = pt - m_rcTracking.CenterPoint(); ((bHorz) ? szOff.cx : szOff.cy) = 0; CSize szLimit; GetFloatingMinSize(&szLimit.cx, &szLimit.cy); CRect rc; GetWindowRect(&rc); CWnd::FromHandle(m_hDockBar)->ScreenToClient(&rc); switch (nDock) { case AFX_IDW_DOCKBAR_LEFT: if ((m_rcTracking.left + szOff.cx) - rc.left < szLimit.cx) return; break; case AFX_IDW_DOCKBAR_RIGHT: if (rc.right - (m_rcTracking.right + szOff.cx) < szLimit.cx) return; break; case AFX_IDW_DOCKBAR_TOP: if ((m_rcTracking.top + szOff.cy) - rc.top < szLimit.cy) return; break; case AFX_IDW_DOCKBAR_BOTTOM: if (rc.bottom - (m_rcTracking.bottom + szOff.cy) < szLimit.cy) return; break; } OnTrackPaint(); m_rcTracking.OffsetRect(szOff); OnTrackPaint(); } void KTMenuCtrlBar::OnStopTracking() { m_bTracking = FALSE; ::ReleaseCapture(); OnTrackPaint(); CRect rc; UINT nDock = ::GetDlgCtrlID(m_hDockBar); UINT nHit = OnGetTrackRect(nDock, rc); CSize szOff = m_rcTracking.CenterPoint() - rc.CenterPoint(); GetWindowRect(&rc); switch (nHit) { case HTLEFT: rc.left += szOff.cx; break; case HTRIGHT: rc.right += szOff.cx; break; case HTTOP: rc.top += szOff.cy; break; case HTBOTTOM: rc.bottom += szOff.cy; break; } DockControlBar(nDock, rc); m_pDockSite->DelayRecalcLayout(); } void KTMenuCtrlBar::OnTrackPaint() { CWnd* pWnd = CWnd::GetDesktopWindow(); CDC *pDC = pWnd->GetDCEx(NULL, DCX_WINDOW | DCX_CACHE | DCX_LOCKWINDOWUPDATE); CBrush* pBrush = CDC::GetHalftoneBrush(); CBrush* pBrushOld = pDC->SelectObject(pBrush); CRect rc(m_rcTracking); CWnd::FromHandle(m_hDockBar)->ClientToScreen(&rc); pDC->PatBlt(rc.left, rc.top, rc.Width(), rc.Height(), PATINVERT); pDC->SelectObject(pBrushOld); pWnd->ReleaseDC(pDC); } LRESULT KTMenuCtrlBar::OnDockBarProc(HWND hWnd, UINT nMessage, WPARAM wParam, LPARAM lParam) { ASSERT(NULL != m_pfnOldProc && m_hDockBar == hWnd); switch (nMessage) { case WM_LBUTTONDOWN: if (!m_bTracking) { CPoint pt(lParam); UINT nHit = OnTrackHitTest(pt); if ((HTLEFT | HTRIGHT) & nHit) { OnStartTracking(nHit); return 0l; } } break; case WM_MOUSEMOVE: if (m_bTracking) { CPoint pt(lParam); OnTrackUpdate(pt); return 0l; } break; case WM_LBUTTONUP: case WM_RBUTTONDOWN: if (m_bTracking) { OnStopTracking(); return 0l; } break; case WM_CAPTURECHANGED: if (m_bTracking && ((HWND)lParam != hWnd)) { OnStopTracking(); } break; } return CallWindowProc(m_pfnOldProc, hWnd, nMessage, wParam, lParam); } LRESULT CALLBACK KTMenuCtrlBar::DockBarProc(HWND hWnd, UINT nMessage, WPARAM wParam, LPARAM lParam) { ASSERT(NULL != m_pMySelft); return m_pMySelft->OnDockBarProc(hWnd, nMessage, wParam, lParam); } void KTMenuCtrlBar::OnDestroy() { CAdUiPalette* pPage = NULL; while(GetPaletteCount() > 0) { pPage = GetPalette(0); RemovePalette(pPage); delete pPage; } CAdUiPaletteSet::OnDestroy(); }