Files
envi-code/SourceCode/Code2026/EarthWormMain/cmdPalette.cpp
T
2026-09-28 15:28:50 +08:00

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;
}