实现在CAD中创建工具栏并添加菜单命令,如下图
参照文章:
主要实现路径是通过创建一个可停靠窗口,并在其中创建toolbutton并给button点击事件添加命令,将子菜单menu显示在button位置,如果需要更加顺滑的交互,需要重写一下menu的样式。
像文中所说,可以通过一个xml文件来控制控件,这样可以省略修改交互的步骤,
我这里只是做出了单纯横向布置的实现和button边框背景取消,还需要增加自适应修改的内容,让侧边顶部都可以实现。
代码逻辑也没有什么可以说的,直接将代码放到下面:
Dialog:
//-----------------------------------------------------------------------------
class CDockControlBarChildDlg : public CAcUiDialog {
DECLARE_DYNAMIC (CDockControlBarChildDlg)
public:
CDockControlBarChildDlg (CWnd *pParent =NULL, HINSTANCE hInstance =NULL) ;
enum { IDD = IDD_DOCKCONTROLBAR};
protected:
virtual void DoDataExchange (CDataExchange *pDX) ;
virtual BOOL OnCommand (WPARAM wParam, LPARAM lParam) ;
BOOL OnInitDialog() override;
protected:
afx_msg LRESULT OnAcadKeepFocus (WPARAM wParam, LPARAM lParam) ;
public:
afx_msg void OnSize (UINT nType, int cx, int cy) ;
protected:
DECLARE_MESSAGE_MAP()
public:
CDockMenuPickButton m_btn_1;
CDockMenuPickButton m_btn_3;
CDockMenuPickButton m_btn_4;
CDockMenuPickButton m_btn_5;
CDockMenuPickButton m_btn_6;
CDockMenuPickButton m_btn_7;
afx_msg void OnBnClickedButton7();
afx_msg void OnBnClickedButton6();
afx_msg void OnBnClickedButton3();
afx_msg void OnBnClickedButton4();
afx_msg void OnBnClickedButton5();
afx_msg void OnBnClickedButton1();
private:
CMenu m_menu_1;
CMenu m_menu_3;
CMenu m_menu_4;
CMenu m_menu_5;
CMenu m_menu_6;
CMenu m_menu_7;
} ;
IMPLEMENT_DYNAMIC (CDockControlBarChildDlg, CAcUiDialog)
BEGIN_MESSAGE_MAP(CDockControlBarChildDlg, CAcUiDialog)
//{{AFX_MSG_MAP(CDockControlBarChildDlg)
ON_MESSAGE(WM_ACAD_KEEPFOCUS, OnAcadKeepFocus) // Needed for modeless dialog.
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_BUTTON7, &CDockControlBarChildDlg::OnBnClickedButton7)
ON_BN_CLICKED(IDC_BUTTON6, &CDockControlBarChildDlg::OnBnClickedButton6)
ON_BN_CLICKED(IDC_BUTTON3, &CDockControlBarChildDlg::OnBnClickedButton3)
ON_BN_CLICKED(IDC_BUTTON4, &CDockControlBarChildDlg::OnBnClickedButton4)
ON_BN_CLICKED(IDC_BUTTON5, &CDockControlBarChildDlg::OnBnClickedButton5)
ON_BN_CLICKED(IDC_BUTTON1, &CDockControlBarChildDlg::OnBnClickedButton1)
END_MESSAGE_MAP()
//-----------------------------------------------------------------------------
CDockControlBarChildDlg::CDockControlBarChildDlg (CWnd *pParent /*=NULL*/, HINSTANCE hInstance /*=NULL*/) : CAcUiDialog (CDockControlBarChildDlg::IDD, pParent, hInstance) {
//{{AFX_DATA_INIT(CDockControlBarChildDlg)
//}}AFX_DATA_INIT
}
//-----------------------------------------------------------------------------
void CDockControlBarChildDlg::DoDataExchange (CDataExchange *pDX) {
CAcUiDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDockControlBarChildDlg)
//}}AFX_DATA_MAP
DDX_Control(pDX, IDC_BUTTON1, m_btn_1);//意见反馈
DDX_Control(pDX, IDC_BUTTON6, m_btn_6);//样图模板
DDX_Control(pDX, IDC_BUTTON3, m_btn_3);//文本模板
DDX_Control(pDX, IDC_BUTTON4, m_btn_4);//效率工具
DDX_Control(pDX, IDC_BUTTON5, m_btn_5);//绘制指导
DDX_Control(pDX, IDC_BUTTON7, m_btn_7);//制图模板
}
//-----------------------------------------------------------------------------
//- Needed for modeless dialogs to keep focus.
//- Return FALSE to not keep the focus, return TRUE to keep the focus
LRESULT CDockControlBarChildDlg::OnAcadKeepFocus (WPARAM wParam, LPARAM lParam) {
return (TRUE) ;
}
//-----------------------------------------------------------------------------
//- As this dialog is a child dialog we need to disable ok and cancel
BOOL CDockControlBarChildDlg::OnCommand (WPARAM wParam, LPARAM lParam) {
switch ( wParam ) {
case IDOK:
case IDCANCEL:
return (FALSE) ;
}
return (CAcUiDialog::OnCommand (wParam, lParam)) ;
}
BOOL CDockControlBarChildDlg::OnInitDialog()
{
CAcUiDialog::OnInitDialog();
//制图标准
m_menu_7.CreatePopupMenu();
m_menu_7.AppendMenu(MF_STRING, ID_32768, _T("标准图框"));
m_menu_7.AppendMenu(MF_STRING, ID_32769, _T("图层标准"));
m_menu_7.AppendMenu(MF_STRING, ID_32770, _T("制图标准"));
m_menu_7.AppendMenu(MF_STRING, ID_32771, _T("常用图块"));
//效率工具
m_menu_4.CreatePopupMenu();
m_menu_4.AppendMenu(MF_STRING, ID_32778, _T("数据速查"));
m_menu_4.AppendMenu(MF_STRING, ID_32779, _T("计算表格"));
m_menu_4.AppendMenu(MF_STRING, ID_327710, _T("绘图研发工具"));
文本模板
m_menu_3.CreatePopupMenu();
m_menu_3.AppendMenu(MF_STRING, ID_32774, _T("设计信息征询表"));
m_menu_3.AppendMenu(MF_STRING, ID_32775, _T("评审文本"));
m_menu_3.AppendMenu(MF_STRING, ID_32776, _T("汇报文本"));
m_menu_3.AppendMenu(MF_STRING, ID_32777, _T("施工图设计文件"));
样图模板
m_menu_6.CreatePopupMenu();
m_menu_6.AppendMenu(MF_STRING, ID_32772, _T("样图模板"));
m_menu_6.AppendMenu(MF_STRING, ID_327723, _T("深度样图"));
绘制指导
m_menu_5.CreatePopupMenu();
m_menu_5.AppendMenu(MF_STRING, ID_327711, _T("制图标准指导书"));
m_menu_5.AppendMenu(MF_STRING, ID_327712, _T("平面类绘制指导书"));
m_menu_5.AppendMenu(MF_STRING, ID_327713, _T("立剖面绘制指导书"));
m_menu_5.AppendMenu(MF_STRING, ID_327714, _T("放大图绘制指导书"));
m_menu_5.AppendMenu(MF_STRING, ID_327715, _T("专项绘制绘制指导书"));
意见反馈
m_menu_1.CreatePopupMenu();
m_menu_1.AppendMenu(MF_STRING, ID_327716, _T("意见反馈"));
/*m_menu_1 = (CMenu*)GetDlgItem(IDR_MENU1);
m_btn_1.SetMenu(m_menu_1);*/
return TRUE;
}
//-----------------------------------------------------------------------------
void CDockControlBarChildDlg::OnSize (UINT nType, int cx, int cy) {
CAcUiDialog::OnSize (nType, cx, cy) ;
//- Now update the dialog
MoveWindow (0, 0, cx, cy) ;
}
void CDockControlBarChildDlg::OnBnClickedButton7()
{
CRect rect;
m_btn_7.GetWindowRect(&rect);
CString str;
str.Format(_T("rect width : %d , rect length : %d"), rect.Width(), rect.Height());
m_menu_7.TrackPopupMenu(TPM_LEFTALIGN | TPM_TOPALIGN, rect.left, rect.bottom, this);
//m_menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_TOPALIGN, rect.left, rect.bottom, this);
}
void CDockControlBarChildDlg::OnBnClickedButton6()
{
// TODO: 在此添加控件通知处理程序代码
CRect rect;
m_btn_6.GetWindowRect(&rect);
CString str;
str.Format(_T("rect width : %d , rect length : %d"), rect.Width(), rect.Height());
m_menu_6.TrackPopupMenu(TPM_LEFTALIGN | TPM_TOPALIGN, rect.left, rect.bottom, this);
}
void CDockControlBarChildDlg::OnBnClickedButton3()
{
// TODO: 在此添加控件通知处理程序代码
CRect rect;
m_btn_3.GetWindowRect(&rect);
CString str;
str.Format(_T("rect width : %d , rect length : %d"), rect.Width(), rect.Height());
m_menu_3.TrackPopupMenu(TPM_LEFTALIGN | TPM_TOPALIGN, rect.left, rect.bottom, this);
}
void CDockControlBarChildDlg::OnBnClickedButton4()
{
// TODO: 在此添加控件通知处理程序代码
CRect rect;
m_btn_4.GetWindowRect(&rect);
CString str;
str.Format(_T("rect width : %d , rect length : %d"), rect.Width(), rect.Height());
m_menu_4.TrackPopupMenu(TPM_LEFTALIGN | TPM_TOPALIGN, rect.left, rect.bottom, this);
}
void CDockControlBarChildDlg::OnBnClickedButton5()
{
// TODO: 在此添加控件通知处理程序代码
CRect rect;
m_btn_5.GetWindowRect(&rect);
CString str;
str.Format(_T("rect width : %d , rect length : %d"), rect.Width(), rect.Height());
m_menu_5.TrackPopupMenu(TPM_LEFTALIGN | TPM_TOPALIGN, rect.left, rect.bottom, this);
}
void CDockControlBarChildDlg::OnBnClickedButton1()
{
//MessageBox(_T("Test Menu"));
// TODO: 在此添加控件通知处理程序代码
CRect rect;
m_btn_1.GetWindowRect(&rect);
/*CString str;
str.Format(_T("rect width : %d , rect length : %d"), rect.left, rect.bottom);
MessageBox(str);*/
BOOL addMenu = m_menu_1.TrackPopupMenu(TPM_LEFTALIGN | TPM_TOPALIGN, rect.left, rect.bottom, this);
if(!addMenu)
{
MessageBox(_T("Test Menu Failed"));
}
}
Button:
//-----------------------------------------------------------------------------
class CDockMenuPickButton : public CAcUiToolButton {
DECLARE_DYNAMIC (CDockMenuPickButton)
public:
CDockMenuPickButton () ;
virtual ~CDockMenuPickButton () ;
void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) override;
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnMouseHover(UINT nFlags, CPoint point);
afx_msg void OnMouseLeave();
protected:
DECLARE_MESSAGE_MAP()
private:
BOOL m_bTrackLeave;
} ;
#include "StdAfx.h"
#include "resource.h"
#include "DockMenuPickButton.h"
//-----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC (CDockMenuPickButton, CAcUiToolButton)
BEGIN_MESSAGE_MAP(CDockMenuPickButton, CAcUiToolButton)
END_MESSAGE_MAP()
CDC* hdc;
CRect hRect;
//-----------------------------------------------------------------------------
CDockMenuPickButton::CDockMenuPickButton () {
}
//-----------------------------------------------------------------------------
CDockMenuPickButton::~CDockMenuPickButton () {
}
void CDockMenuPickButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CDC dc;
dc.Attach(lpDrawItemStruct->hDC);
dc.SelectStockObject(NULL_BRUSH);
dc.Rectangle(&lpDrawItemStruct->rcItem);
hdc = &dc;
COLORREF local_bk = dc.GetBkColor();
CString str;
GetWindowText(str);
CRect rect = lpDrawItemStruct->rcItem;
hRect = rect;
GetClientRect(&rect);
//设置背景透明色
dc.SetBkMode(TRANSPARENT);
dc.SetPolyFillMode(TRANSPARENT);
::GetStockObject(NULL_BRUSH);
//设置画笔为空,无边框
if(lpDrawItemStruct->itemState & ODS_SELECTED )
{
//设置颜色为背景色,实现边框取消的效果
//dc.FillSolidRect(&rect,::GetBkColor(dc));
dc.FillSolidRect(&rect, RGB(190, 200, 255));
//如果悬停或者选中,需要显示仅显示边框
dc.Draw3dRect(&rect, GetSysColor(COLOR_3DDKSHADOW), GetSysColor(COLOR_3DDKSHADOW));
//设置文字
dc.DrawText(str, rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
dc.SetTextColor(RGB(255, 0, 0));
}
else if(lpDrawItemStruct->itemData & ODS_HOTLIGHT)
{
//设置颜色为背景色,实现边框取消的效果
dc.FillSolidRect(&rect, RGB(170,180,255));
//设置文字
dc.DrawText(str, rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
dc.SetTextColor(RGB(255, 0, 0));
}
else
{
//设置颜色为背景色,实现边框取消的效果
dc.FillSolidRect(&rect, ::GetBkColor(dc));
//设置文字
dc.DrawText(str, rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
dc.SetTextColor(RGB(255, 0, 0));
}
//CBrush* pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
//CBrush* pOldBrush = dc.SelectObject(pBrush);
//dc.SelectObject(pBrush);
//dc.SelectObject(pOldBrush);
}