Files
envi-code/SourceCode/Code2026/EarthWormMain/KTMenuCtrlBar.cpp
T
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

473 lines
11 KiB
C++

#include "StdAfx.h"
#include "KTMenuCtrlBar.h"
#include "KTMenuPage.h"
#include <string>
#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<std::pair<CString, CString>> &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<CString, CString> &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<std::pair<CString, CString>> mm;
getMenuFiles(FilePath::GetSysDir(), FilePath::GetSysDir() + _T("\\product.ini"), mm);
if (mm.empty()) return FALSE;
std::vector<std::pair<CString, CString>>::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();
}