#include "stdafx.h" #include "CXMLCMainBar.h" //-------------------------------------------------------------------------------- // = Copyright // Copyright(c) 2009 2010 lifuyin // All rights reserved // = Author(S) // Ligend@163.com // = Version // Version1.0 // = Date // 2010 1-30 // = Modify Date // //-------------------------------------------------------------------------------- #include "stdafx.h" #include "resource.h" #include "CXMLCMainBar.h" #include "XMLCDlg.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[] = __FILE__; #define new DEBUG_NEW #endif #if ARX > 16 CXMLCMainBar *CXMLCMainBar::m_pMySelft = NULL; #endif IMPLEMENT_DYNAMIC(CXMLCMainBar, CAdUiPaletteSet); CXMLCMainBar::CXMLCMainBar() { m_pwndXMLCMainDlg = NULL; // 解决AutoCAD2009以后屏幕菜单拖动限制最小尺寸问题 --wyg20090522 #if ARX > 16 m_pMySelft = this; m_hDockBar = NULL; m_pfnOldProc = NULL; m_bTracking = FALSE; #endif // ARX > } CXMLCMainBar::~CXMLCMainBar() { // 解决AutoCAD2009以后屏幕菜单拖动限制最小尺寸问题 --wyg20090522 #if ARX > 16 if (IsWindow(m_hDockBar)) UnsubclassDockBar(); m_pMySelft = NULL; #endif // ARX > 16 } BEGIN_MESSAGE_MAP(CXMLCMainBar, CAdUiPaletteSet) //{{AFX_MSG_MAP(CXMLCMainBar) ON_WM_CREATE() ON_WM_CONTEXTMENU() ON_WM_DESTROY() //}}AFX_MSG_MAP END_MESSAGE_MAP() int CXMLCMainBar::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CAdUiPaletteSet::OnCreate(lpCreateStruct) == -1) return -1; if (m_pwndXMLCMainDlg == NULL) { m_pwndXMLCMainDlg = new CXMLCDlg(this); m_pwndXMLCMainDlg->Create(CXMLCDlg::IDD, this); } m_pwndXMLCMainDlg->ShowWindow(SW_SHOW); return 0; } bool CXMLCMainBar::OnClosing() { CAdUiDockControlBar::OnClosing(); acedGetAcadFrame()->ShowControlBar(this, FALSE, FALSE); acedGetAcadFrame()->RecalcLayout(); return false; } void CXMLCMainBar::SizeChanged(CRect *lpRect, BOOL bFloating, int flags) { CRect rect = *lpRect; rect.top += 4; //GetClientRect(&rect); if (m_pwndXMLCMainDlg != NULL && ::IsWindow(m_pwndXMLCMainDlg->m_hWnd)) { m_pwndXMLCMainDlg->SetWindowPos(NULL, rect.left, rect.top, rect.Width(), rect.Height(), SWP_NOZORDER | SWP_NOACTIVATE); } } void CXMLCMainBar::OnContextMenu(CWnd *pWnd, CPoint point) { } void CXMLCMainBar::OnDestroy() { if (m_pwndXMLCMainDlg != NULL) { m_pwndXMLCMainDlg->DestroyWindow(); m_pwndXMLCMainDlg = NULL; } CAdUiPaletteSet::OnDestroy(); } // 解决AutoCAD2009以后屏幕菜单拖动限制最小尺寸问题 --wyg20090522 #if ARX > 16 #define AS_DOCK_CONTROLBAR(pBar) ((CControlBar*)((DWORD_PTR(pBar) <= 0xffff) ? NULL : (pBar))) CSize CXMLCMainBar::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 CXMLCMainBar::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, (LONG_PTR)&CXMLCMainBar::DockBarProc); #else m_pfnOldProc = (WNDPROC)SetWindowLong(m_hDockBar, GWLP_WNDPROC, (LONG)&CXMLCMainBar::DockBarProc); #endif ASSERT(NULL != m_pfnOldProc); return TRUE; } void CXMLCMainBar::UnsubclassDockBar() { if (NULL == m_hDockBar || NULL == m_pfnOldProc) return; #ifdef _WIN64 VERIFY(SetWindowLongPtr(m_hDockBar, GWLP_WNDPROC, (LONG_PTR)m_pfnOldProc) == (LONG_PTR)&CXMLCMainBar::DockBarProc); #else VERIFY(SetWindowLong(m_hDockBar, GWLP_WNDPROC, (LONG)m_pfnOldProc) == (LONG)&CXMLCMainBar::DockBarProc); #endif m_hDockBar = NULL; m_pfnOldProc = NULL; } UINT CXMLCMainBar::OnTrackHitTest(CPoint pt) { CRect rc; UINT nHit = OnGetTrackRect(::GetDlgCtrlID(m_hDockBar), rc); return (rc.PtInRect(pt) ? nHit : HTNOWHERE); } UINT CXMLCMainBar::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 CXMLCMainBar::OnStartTracking(UINT nHit) { m_bTracking = TRUE; ::SetCapture(m_hDockBar); ::RedrawWindow(m_hDockBar, NULL, NULL, RDW_ALLCHILDREN | RDW_UPDATENOW); OnGetTrackRect(nHit, m_rcTracking); OnTrackPaint(); } void CXMLCMainBar::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 CXMLCMainBar::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 CXMLCMainBar::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 CXMLCMainBar::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 CXMLCMainBar::DockBarProc(HWND hWnd, UINT nMessage, WPARAM wParam, LPARAM lParam) { ASSERT(NULL != m_pMySelft); return m_pMySelft->OnDockBarProc(hWnd, nMessage, wParam, lParam); } #endif // ARX > 16