#include "StdAfx.h" #include "cmdPalette.h" #include "cmdgroupwnd.h" namespace { CString GetArxDir() { TCHAR szPath[MAX_PATH]; ::GetModuleFileName(_hdllInstance, szPath, MAX_PATH); CString sPath(szPath); sPath = sPath.Left(sPath.ReverseFind(_T('\\'))); return sPath; } CString GetSysDir() { CString arx = GetArxDir(); CString sys = arx.Left(arx.ReverseFind(_T('\\'))); return sys + _T("\\sys"); } void getFilesInFolder(LPCTSTR sPath, LPCTSTR filter, std::vector& vs, bool bOnlyName) { if (!sPath) return; CString filename(_T("")); CFileFind finder; BOOL isNotEmpty = finder.FindFile(CString(sPath) + _T("\\") + filter); while (isNotEmpty) { isNotEmpty = finder.FindNextFile(); filename = bOnlyName ? finder.GetFileTitle() : finder.GetFilePath(); if (!(finder.IsDirectory())) { vs.push_back(filename); } else { if (!(finder.IsDots() || finder.IsHidden() || finder.IsSystem() || finder.IsTemporary() || finder.IsReadOnly())) { getFilesInFolder(filename + _T("\\"), filter, vs, bOnlyName); } } } } } IMPLEMENT_DYNAMIC(CmdPaletteSet, CAdUiPaletteSet) BEGIN_MESSAGE_MAP(CmdPaletteSet, CAdUiPaletteSet) ON_WM_CREATE() ON_WM_DESTROY() END_MESSAGE_MAP() CmdPaletteSet * CmdPaletteSet::m_pMySelft = NULL; CmdPaletteSet::CmdPaletteSet() { m_pMySelft = this; m_hDockBar = NULL; m_pfnOldProc = NULL; m_bTracking = FALSE; } CmdPaletteSet::~CmdPaletteSet() { if (IsWindow(m_hDockBar)) UnsubclassDockBar(); m_pMySelft = NULL; } bool CmdPaletteSet::CreatePaletteSet(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); CString sSys = GetSysDir(); CString sfilter(_T("*.mnu")); std::vector files(0); getFilesInFolder(sSys, sfilter, files, true); DWORD dwRes(0); TCHAR szPaletteName[MAX_PATH]; int idx(0); for (size_t i = 0; i < files.size(); ++i) { dwRes = ::GetPrivateProfileString(_T("Product") , files[i] , _T("") , szPaletteName , MAX_PATH , sSys + _T("\\product.ini")); if (dwRes <= 0) continue; CmdPalette *pPage = new CmdPalette; pPage->Create(WS_CHILD | WS_VISIBLE, szPaletteName, this, NULL); if (pPage->CreatePalette(sSys + _T("\\") + files[i], szPaletteName, idx)) { idx++; AddPalette(pPage); } else { pPage->DestroyWindow(); delete pPage; } } if (this->GetPaletteCount() > 0) { SetActivePalette(0); } SetTimer(1024, 600000, NULL); return true; } int CmdPaletteSet::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 = { 0xb1c0135a, 0x434a, 0x4a60, { 0x89, 0x83, 0x47, 0xbd, 0x73, 0xad, 0x5d, 0x4 } }; SetToolID(&cMenuBar); return 0; } void CmdPaletteSet::OnDestroy() { CAdUiPalette* pPage = NULL; while (GetPaletteCount() > 0) { pPage = GetPalette(0); RemovePalette(pPage); delete pPage; } CAdUiPaletteSet::OnDestroy(); } bool CmdPaletteSet::OnClosing() { return (IDYES != MessageBox(_T("屏幕菜单窗口即将关闭,执行“GP”命令即可重新打开。\n\n是否要关闭屏幕菜单窗口?"), _T("屏幕菜单"), MB_YESNO | MB_ICONQUESTION)); } void CmdPaletteSet::GetFloatingMinSize(long * plMinWidth, long * plMinHeight) { *plMinWidth = 40; *plMinHeight = 100; } void CmdPaletteSet::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) { ((CmdPalette*)pPage)->MoveWindow(rc); } } } void CmdPaletteSet::GetMinimumSize(CSize & size) { CAdUiPaletteSet::GetMinimumSize (size) ; } void CmdPaletteSet::GetMaximumSize(CSize & size) { CAdUiPaletteSet::GetMaximumSize (size) ; } #define AS_DOCK_CONTROLBAR(pBar) ((CControlBar*)((DWORD_PTR(pBar) <= 0xffff) ? NULL : (pBar))) CSize CmdPaletteSet::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 CmdPaletteSet::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)&CmdPaletteSet::DockBarProc); #else m_pfnOldProc = (WNDPROC)SetWindowLong(m_hDockBar, GWLP_WNDPROC, (LPARAM)&CmdPaletteSet::DockBarProc); #endif ASSERT(NULL != m_pfnOldProc); return TRUE; } void CmdPaletteSet::UnsubclassDockBar() { if (NULL == m_hDockBar || NULL == m_pfnOldProc) return; #ifdef _WIN64 VERIFY(SetWindowLongPtr(m_hDockBar, GWLP_WNDPROC, (LPARAM)m_pfnOldProc) == (LPARAM)&CmdPaletteSet::DockBarProc); #else VERIFY(SetWindowLong(m_hDockBar, GWLP_WNDPROC, (LPARAM)m_pfnOldProc) == (LPARAM)&CmdPaletteSet::DockBarProc); #endif m_hDockBar = NULL; m_pfnOldProc = NULL; } UINT CmdPaletteSet::OnTrackHitTest(CPoint pt) { CRect rc; UINT nHit = OnGetTrackRect(::GetDlgCtrlID(m_hDockBar), rc); return (rc.PtInRect(pt) ? nHit : HTNOWHERE); } UINT CmdPaletteSet::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 CmdPaletteSet::OnStartTracking(UINT nHit) { m_bTracking = TRUE; ::SetCapture(m_hDockBar); ::RedrawWindow(m_hDockBar, NULL, NULL, RDW_ALLCHILDREN | RDW_UPDATENOW); OnGetTrackRect(nHit, m_rcTracking); OnTrackPaint(); } void CmdPaletteSet::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 CmdPaletteSet::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 CmdPaletteSet::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 CmdPaletteSet::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 CmdPaletteSet::DockBarProc(HWND hWnd, UINT nMessage, WPARAM wParam, LPARAM lParam) { ASSERT(NULL != m_pMySelft); return m_pMySelft->OnDockBarProc(hWnd, nMessage, wParam, lParam); } /////////////////////////////////////////////////////////////////////////////////////////////////// IMPLEMENT_DYNAMIC(CmdPalette, CAdUiPalette) BEGIN_MESSAGE_MAP(CmdPalette, CAdUiPalette) ON_WM_DESTROY() ON_WM_MOUSEWHEEL() ON_WM_PAINT() END_MESSAGE_MAP() inline CmdPalette::CmdPalette(): m_grpWndPtrs(0) {} inline CmdPalette::~CmdPalette() { for (size_t i = 0; i < m_grpWndPtrs.size(); ++i) { CWnd *p(m_grpWndPtrs[i]); if (p) { delete p; p = NULL; } } m_grpWndPtrs.clear(); } bool CmdPalette::CreatePalette(LPCTSTR pszMenuFile, LPCTSTR pszTitle, int nIndex) { // 根据传入的菜单文件解析出 cmdGroupWnd // test CRect rc; GetClientRect(rc); CmdGroupWnd *pWnd(NULL); int h(int(rc.Height() * .1) - 2); CSize sz(rc.Width() - 2, h); for (size_t i = 0; i < 1; ++i) { pWnd = new CmdGroupWnd(_T("a"), CmdGroupWnd::eList , CmdGroupWnd::eLight); if (pWnd) { if (pWnd->Create(CRect(CPoint(1, i * (h) + 1), sz), this)) { pWnd->ShowWindow(SW_SHOW); m_grpWndPtrs.push_back(pWnd); } else { delete pWnd; pWnd = NULL; } } } return !m_grpWndPtrs.empty(); } BOOL CmdPalette::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) { for (size_t i = 0; i < m_grpWndPtrs.size(); ++i) { CWnd *p(m_grpWndPtrs[i]); //if (p) p->OnMouseWheel(nFlags, zDelta, pt); } return TRUE; } void CmdPalette::MoveWindow(LPCRECT lpRect, BOOL bRepaint) { CAdUiPalette::MoveWindow(lpRect, bRepaint); CRect rc, rc2(lpRect); for (size_t i = 0; i < m_grpWndPtrs.size(); ++i) { CmdGroupWnd *p(m_grpWndPtrs[i]); p->GetWindowRect(rc); ScreenToClient(rc); rc.left = 1; // CAdUiPalette的宽要比lpRect的宽多12像素 rc.right = rc.left + (rc2.Width() + 12) - 2; p->MoveWindow(rc); p->Invalidate(); } } void CmdPalette::OnSetActive() { } void CmdPalette::OnDestroy() { for (size_t i = 0; i < m_grpWndPtrs.size(); ++i) { CWnd *p(m_grpWndPtrs[i]); if (p) p->DestroyWindow(); } CAdUiPalette::OnDestroy(); } void CmdPalette::OnPaint() { CPaintDC dc(this); CRect rc; GetClientRect(rc); dc.FillSolidRect(rc, RGB(240, 240, 240)); } void CmdPalette::GetFloatingMinSize(long * pnMinWidth, long * pnMinHeight) { *pnMinWidth = 74; *pnMinHeight = 200; }