572 lines
12 KiB
C++
572 lines
12 KiB
C++
#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<CString>& 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<CString> 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;
|
|
}
|