在ObjectARX中使用MFC-可停靠窗体

(1)使用的ObjectARX创建一个新工程

 

 添加对话框:

 添加“绘制直线”按钮:

(3)设置对话框的“可见”为真

 

(4)为对话框添加ObjectARX MFC类

 

(5)创建可停靠窗体的类

当现在基类的时候,会弹出下图警告对话框,提示说:输入一个资源ID,然后系统会自动创建一个子对话框。当我输入一个ID时,程序会出错,这里不要填入ID。

 (6)为了能够早测试,我们先做的是将可停靠窗体在AutoCAD的中显示出来;

简单起见,不注册命令,直接在应用程序加载的时候显示这个窗体;

在acrxEntryPoint.cpp文件中添加一个全局变量

(7)在应用程序被加载后初始化的消息处理函数中,显示可停靠的窗体:

这时候编译程序,发现出错:

 第一个错误修改:从LPCSTR改成LPCTSTR

给大家贴上这一段代码:


		//显示可停靠的窗体
		CAcModuleResourceOverride resOverride;
		if (g_pDlgBar == NULL)
		{
			g_pDlgBar = new CMyDockControlBar();
			g_pDlgBar->Create(acedGetAcadFrame(), (LPCSTR)_T("DockerBar"));
			g_pDlgBar->SetWindowText(_T("MyControlBar"));// changes the text of the specified window's title bar (if it has one). 
			g_pDlgBar->EnableDocking(CBRS_ALIGN_ANY);//CBRS_ALIGN_ANY   Allows docking on any side of the client area. 

		}

		acedGetAcadFrame()->FloatControlBar(g_pDlgBar, CPoint(100, 100), CBRS_ALIGN_TOP); //初始位置//CBRS_ALIGN_TOP   Orients the control bar vertically.
		acedGetAcadFrame()->ShowControlBar(g_pDlgBar, TRUE, TRUE);//void ShowControlBar( CControlBar* pBar, BOOL bShow, BOOL bDelay );

第二个错误修改:将创建()函数有保护改为公

 编译,发现还有一个错误,按提示修改:

(8)在应用程序卸载的消息处理函数中,手工销毁这个窗体:

在acrxEntryPoint.cpp中,


	virtual AcRx::AppRetCode On_kUnloadAppMsg (void *pkt) {
		// TODO: Add your code here

		// You *must* call On_kUnloadAppMsg here
		AcRx::AppRetCode retCode =AcRxArxApp::On_kUnloadAppMsg (pkt) ;

		// TODO: Unload dependencies here
		
		//手动销毁可停靠窗体
		if (g_pDlgBar != NULL)
		{
			g_pDlgBar->DestroyWindow();
			delete g_pDlgBar;
			g_pDlgBar = NULL;
		}

		return (retCode) ;
	}

 (9)编译程序,在CAD中加载应用程序,显示如下图的窗口,但是没有任何控件,这是因为我们还没有将窗体嵌入进去

 (10)在CMyDockControlBar类中,添加一个私有的成员变量用于表示要其嵌入的子窗体

	CChildDlg* m_childDlg;

 同时添加头文件:

#include "ChildDlg.h"

(11)在对画框的构造函数中对这个成员变量进行初始化:在MyDockControlBar.cpp中

CMyDockControlBar::CMyDockControlBar() : CAcUiDockControlBar()
{
	m_childDlg = NULL;
}

(12)在MyDockControlBar.cpp中的OnCreate中()函数中添加显示子窗体的代码:

int CMyDockControlBar::OnCreate (LPCREATESTRUCT lpCreateStruct) {
	if ( CAcUiDockControlBar::OnCreate (lpCreateStruct) == -1 )
		return (-1) ;

	//显示子窗体
	CAcModuleResourceOverride resourceOverride;
	m_childDlg = new CChildDlg;
	m_childDlg->Create(IDD_DIALOG, this);
	m_childDlg->ShowWindow(SW_SHOW);//SW_SHOW:Activates the window and displays it in its current size and position. 
	m_childDlg->MoveWindow(0, 0, 160, 160, TRUE);//TRUE:Specifies whether the window is to be repainted. 


	return (0) ;
}

 (13)在MyDockControlBar.cpp中的SizeChanged将()函数中处理子窗体大小与可停靠窗体的匹配:

void CMyDockControlBar::SizeChanged (CRect *lpRect, BOOL bFloating, int flags) {
	
	CAcModuleResourceOverride resourceOverride;
	if (m_childDlg != NULL)
	{
		m_childDlg->SetWindowPos(this, lpRect->left, lpRect->top,
			lpRect->Width(), lpRect->Height(), SWP_NOZORDER);//SWP_NOZORDER:Retains the current Z order
	}

}

(14)再次编译运行程序,CAD弹出如图的结果:

(15)为对画框中的【绘制直线】按钮添加单击事件

 

为OnBnClickedLine()函数添加代码:


void CChildDlg::OnBnClickedLine()
{
	// TODO: 在此添加控件通知处理程序代码

	//类似于非模态对话框,需要锁定和解锁文档
	acDocManager->lockDocument(acDocManager->curDocument());

	//在内存上创建一个新的AcDbLine对象
	AcGePoint3d ptStart(0, 0, 0);
	AcGePoint3d ptEnd(560, 500, 0);
	AcDbLine *pLine = new AcDbLine(ptStart, ptEnd);

	//获得指向块表的指针
	AcDbBlockTable *pBlockTable;
	acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable, AcDb::kForRead);

	//获得指向特定的块表记录(模型空间)的指针
	AcDbBlockTableRecord *pBlockTableRecord;
	pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord,
		AcDb::kForWrite);

	//将AcDbLine类的对象添加到块表记录中
	AcDbObjectId lineId;
	pBlockTableRecord->appendAcDbEntity(lineId, pLine);
	pLine->setColorIndex(1); //设置直线为红色

							 //关闭图形数据库的各种对象
	pBlockTable->close();
	pBlockTableRecord->close();
	pLine->close();

	acDocManager->unlockDocument(acDocManager->curDocument());

}

效果:

满满的幸福感有没有!

项目源代码下载链接:在ObjectARX中使用MFC-可停靠窗体

最后,附上流程图:

猜你喜欢

转载自blog.csdn.net/qq_40416052/article/details/81771799
今日推荐