记录一个问题
对于现在这个代码有几个问题1.实际上我对着立方体右键并不会实现修改的功能而是BricsCAD本身的右键选中功能只有我在命令行输入EditCube然后左键选中立方体才能调出对话框进行修改我本意是要实现右键调出对话框进行修改。 2.我希望右键修改应该进行判断如果我用插件创建了不同的图形比如立方体、圆柱我希望我右键立方体的时候调用出立方体的对话框右键圆柱的时候调用出圆柱的对话框也就是加个选择功能而且对于我直接画出的图形而不是用插件生成的图形我希望右键的时候是BricsCAD自身的右键功能#include StdAfx.h #include Box.h #include resource.h #include windows.h #include tchar.h // 全局变量保存插件自身模块句柄用于获取对话框资源插件的身份证号 static HMODULE g_hPluginModule NULL; // 新增定义XData的注册应用名唯一标识 #define CUBE_XDATA_APP _T(CUBE_PLUGIN_XDATA) // 定义XData的标签码1001应用名1040双精度浮点数 const int XDATA_APP_CODE 1001; // 应用名标签 const int XDATA_LENGTH 1040; // 长度标签 const int XDATA_WIDTH 1040; // 宽度标签 const int XDATA_HEIGHT 1040; // 高度标签 // 全局结构体存储立方体参数 typedef struct { double dLength; // 长度 double dWidth; // 宽度 double dHeight; // 高度 BOOL bDialogActive; // 对话框是否激活 HWND hDialog; // 对话框句柄 AcDbObjectId editCubeId; // 待修改的立方体ID区分新建/修改 } CubeParamStruct; // 全局变量初始化默认参数100×100×100 static CubeParamStruct g_CubeParam { 100.0, 100.0, 100.0, FALSE, NULL, AcDbObjectId::kNull }; // 修正适配AcDbObjectId的XData写入函数 void WriteCubeXData(AcDbObjectId objId, double length, double width, double height) { if (objId.isNull()) return; // 1. 创建XData数据列表 resbuf* pXData acutBuildList( XDATA_APP_CODE, CUBE_XDATA_APP, XDATA_LENGTH, length, XDATA_WIDTH, width, XDATA_HEIGHT, height, RTNONE ); // 2. 直接打开实体写权限替代事务 AcDbEntity* pEnt NULL; if (acdbOpenObject(pEnt, objId, AcDb::kForWrite) ! Acad::eOk) // 打开实体 { acutRelRb(pXData); // 释放内存 acutPrintf(_T(\n* 无法打开实体写入XData)); return; } // 3. 写入XData pEnt-setXData(pXData); // 4. 必须关闭实体核心避免锁死 pEnt-close(); acutRelRb(pXData); // 释放XData内存 } // 修正从实体ID读取XData的函数 bool ReadCubeXData(AcDbObjectId objId, double length, double width, double height) { if (objId.isNull()) return false; // 1. 打开实体读权限 AcDbEntity* pEntity NULL; if (acdbOpenObject(pEntity, objId, AcDb::kForRead) ! Acad::eOk) { acutPrintf(_T(\n* 无法打开实体读取XData)); return false; } // 2. 正确调用xData()传入应用名直接返回resbuf* resbuf* pXData pEntity-xData(CUBE_XDATA_APP); if (pXData NULL) { pEntity-close(); return false; } // 3. 解析XData跳过应用名标签 resbuf* pRb pXData-rbnext; // 跳过第一个应用名标签1001 length 100.0; width 100.0; height 100.0; int count 0; while (pRb ! NULL pRb-restype ! RTNONE count 3) { if (pRb-restype 1040) // 1040是双精度浮点数标签 { if (count 0) length pRb-resval.rreal; else if (count 1) width pRb-resval.rreal; else if (count 2) height pRb-resval.rreal; count; } pRb pRb-rbnext; } // 4. 清理资源 acutRelRb(pXData); // 释放XData内存 pEntity-close(); // 关闭实体 return (count 3); } // 对话框过程函数非模态 INT_PTR CALLBACK CubeDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) //对话框句柄、消息类型、消息的附加细节如控件ID和通知码 { switch (uMsg) //判断消息类型 { // 对话框初始化 case WM_INITDIALOG: { g_CubeParam.hDialog hDlg; g_CubeParam.bDialogActive TRUE; // 初始化编辑框显示默认值 TCHAR szValue[64]; _stprintf_s(szValue, _T(%.2f), g_CubeParam.dLength); //以下三处显示的均为默认值100.00 SetDlgItemText(hDlg, IDC_EDIT_LENGTH, szValue); _stprintf_s(szValue, _T(%.2f), g_CubeParam.dWidth); SetDlgItemText(hDlg, IDC_EDIT_WIDTH, szValue); _stprintf_s(szValue, _T(%.2f), g_CubeParam.dHeight); SetDlgItemText(hDlg, IDC_EDIT_HEIGHT, szValue); return TRUE; } // 按钮点击消息处理 case WM_COMMAND: { switch (LOWORD(wParam)) { // 确定按钮创建立方体 case IDOK: { TCHAR szBuffer[64]; //读取编辑框数据 GetDlgItemText(hDlg, IDC_EDIT_LENGTH, szBuffer, 64); g_CubeParam.dLength _tstof(szBuffer); GetDlgItemText(hDlg, IDC_EDIT_WIDTH, szBuffer, 64); g_CubeParam.dWidth _tstof(szBuffer); GetDlgItemText(hDlg, IDC_EDIT_HEIGHT, szBuffer, 64); g_CubeParam.dHeight _tstof(szBuffer); //合法性校验 if (g_CubeParam.dLength 0.001 || g_CubeParam.dWidth 0.001 || g_CubeParam.dHeight 0.001) { MessageBox(hDlg, _T(长宽高必须大于0.001), _T(错误), MB_OK | MB_ICONERROR); return TRUE; } // 判断是「新建」还是「修改」立方体 if (g_CubeParam.editCubeId.isNull()) { // 新建立方体 try { AcDbObjectId cubeId Box::createBoxSolid( g_CubeParam.dLength, g_CubeParam.dWidth, g_CubeParam.dHeight, AcGeVector3d(100, 100, 100), 1 ); if (!cubeId.isNull()) { WriteCubeXData(cubeId, g_CubeParam.dLength, g_CubeParam.dWidth, g_CubeParam.dHeight); acutPrintf(_T(\n* 立方体创建成功尺寸%.2f×%.2f×%.2f), g_CubeParam.dLength, g_CubeParam.dWidth, g_CubeParam.dHeight); } else { MessageBox(hDlg, _T(创建立方体失败), _T(错误), MB_OK | MB_ICONERROR); } } catch (...) { MessageBox(hDlg, _T(创建立方体失败), _T(错误), MB_OK | MB_ICONERROR); } } else { // 无事务版删除旧立方体核心修改 AcDbEntity* pOldCube NULL; if (acdbOpenObject(pOldCube, g_CubeParam.editCubeId, AcDb::kForWrite) Acad::eOk) { pOldCube-erase(); // 删除实体 pOldCube-close(); // 关闭实体 } else { acutPrintf(_T(\n* 删除旧立方体失败)); } // 创建新立方体 AcDbObjectId newCubeId Box::createBoxSolid( g_CubeParam.dLength, g_CubeParam.dWidth, g_CubeParam.dHeight, AcGeVector3d(100, 100, 100), 1 ); if (!newCubeId.isNull()) { WriteCubeXData(newCubeId, g_CubeParam.dLength, g_CubeParam.dWidth, g_CubeParam.dHeight); acutPrintf(_T(\n* 立方体尺寸修改成功新尺寸%.2f×%.2f×%.2f), g_CubeParam.dLength, g_CubeParam.dWidth, g_CubeParam.dHeight); } else { acutPrintf(_T(\n* 创建新立方体失败)); } // 重置待修改ID g_CubeParam.editCubeId AcDbObjectId::kNull; } // 关闭对话框 DestroyWindow(hDlg); g_CubeParam.bDialogActive FALSE; g_CubeParam.hDialog NULL; return TRUE; } // 取消按钮关闭对话框 case IDCANCEL: { DestroyWindow(hDlg); g_CubeParam.bDialogActive FALSE; g_CubeParam.hDialog NULL; return TRUE; } } break; } // 对话框关闭消息 case WM_CLOSE: DestroyWindow(hDlg); g_CubeParam.bDialogActive FALSE; g_CubeParam.hDialog NULL; return TRUE; case WM_DESTROY: g_CubeParam.bDialogActive FALSE; g_CubeParam.hDialog NULL; return TRUE; } return FALSE; } // 插件核心类继承 AcRxArxApp 基类BRX 模板规范 class CubePlugin : public AcRxArxApp { public: // 构造函数调用父类构造初始化插件基础信息 CubePlugin() : AcRxArxApp() {} // 服务器组件注册空实现满足 BRX 框架要求无复杂组件需注册 virtual void RegisterServerComponents() { } // 插件加载时触发初始化配置 打印提示信息 virtual AcRx::AppRetCode On_kInitAppMsg(void* pAppData) { // 调用父类默认初始化完成底层绑定 AcRx::AppRetCode result AcRxArxApp::On_kInitAppMsg(pAppData); // 配置插件支持多文档 允许运行时卸载 acrxRegisterAppMDIAware(pAppData); acrxUnlockApplication(pAppData); // 注册所有命令 acedRegCmds-addCommand(_T(CUBE_PLUGIN_CMD), _T(BCreateCube), _T(BCreateCube), ACRX_CMD_TRANSPARENT, CubePluginBCreateCube); acedRegCmds-addCommand(_T(CUBE_PLUGIN_CMD), _T(CubeDlg), _T(CubeDlg), ACRX_CMD_TRANSPARENT, CubePluginCubeDlg); acedRegCmds-addCommand(_T(CUBE_PLUGIN_CMD), _T(EditCube), _T(EditCube), ACRX_CMD_TRANSPARENT, CubePluginEditCube); // 打印加载成功提示新增注册右键菜单BricsCAD专用 acedMenuCmd(_T(^C^C-_menuitem POP1.1 \修改立方体尺寸\ ^C^CEditCube)); acutPrintf(_T(\n* 立方体 DLL 插件加载成功)); acutPrintf(_T(\n* 可用命令BCreateCube、CubeDlg、EditCube右键立方体调用)); return result; } // 插件卸载时触发清理命令 关闭对话框 virtual AcRx::AppRetCode On_kUnloadAppMsg(void* pAppData) { // 清理已打开的对话框 if (g_CubeParam.bDialogActive g_CubeParam.hDialog IsWindow(g_CubeParam.hDialog)) //如果对话框还开着 { DestroyWindow(g_CubeParam.hDialog); //销毁对话框 } g_CubeParam.bDialogActive FALSE; g_CubeParam.hDialog NULL; //更改全局变量信息 // 调用父类默认卸载逻辑 return AcRxArxApp::On_kUnloadAppMsg(pAppData); } // 其他生命周期方法空实现保证类的完整性满足 BRX 框架要求 virtual AcRx::AppRetCode On_kLoadDwgMsg(void* pAppData) { return AcRxArxApp::On_kLoadDwgMsg(pAppData); } virtual AcRx::AppRetCode On_kUnloadDwgMsg(void* pAppData) { return AcRxArxApp::On_kUnloadDwgMsg(pAppData); } // BRX 命令1快速创建默认立方体静态成员函数符合 BRX 命令规范 static void CubePluginBCreateCube(void) { double length 100.0, width 100.0, height 100.0; // 创建立方体返回AcDbObjectId AcDbObjectId cubeId Box::createBoxSolid(length, width, height, AcGeVector3d(100, 100, 100), 1); //红色 // 给立方体写入XData保存尺寸 if (!cubeId.isNull()) { WriteCubeXData(cubeId, length, width, height); acutPrintf(_T(\n* 默认立方体创建成功尺寸100×100×100)); } else { acutPrintf(_T(\n* 立方体创建失败)); } } // BRX 命令2打开参数对话框静态成员函数符合 BRX 命令规范 static void CubePluginCubeDlg(void) { // 若对话框已打开直接激活调用到最前方 if (g_CubeParam.hDialog IsWindow(g_CubeParam.hDialog) g_CubeParam.bDialogActive) { SetForegroundWindow(g_CubeParam.hDialog); ShowWindow(g_CubeParam.hDialog, SW_SHOW); return; } // 获取BricsCAD主窗口句柄对话框主要依附在主窗口上 HWND hWndAcad adsw_acadMainWnd(); if (hWndAcad NULL) { hWndAcad GetDesktopWindow(); //兜底没有主窗口就用桌面 } // 创建对话框非模态 HWND hDlg CreateDialogParam( g_hPluginModule, //插件的身份证号 MAKEINTRESOURCE(IDD_DIALOG_CUBE_PARAM), //对话框的ID,和resource.h里面的对应 hWndAcad, //父窗口BricsCAD主窗口 CubeDlgProc, //上面的对话框过程函数相当于对话框的大脑进行处理 0 ); if (hDlg NULL) //创建失败提示错误 { acutPrintf(_T(\n* 错误无法创建对话框错误代码%d), GetLastError()); return; } // 显示对话框 ShowWindow(hDlg, SW_SHOW); //刷新对话框 UpdateWindow(hDlg); // 更新全局变量 g_CubeParam.hDialog hDlg; //记录对话框ID g_CubeParam.bDialogActive TRUE; //标记对话框已打开 } // BRX 命令3修改立方体尺寸命令核心右键功能适配AcDbObjectId static void CubePluginEditCube(void) { // 1. 选择立方体 ads_name ename; ads_point pt; if (acedEntSel(_T(\n请选择要修改的立方体), ename, pt) ! RTNORM) { acutPrintf(_T(\n* 未选择任何实体)); return; } // 2. 转换为实体ID AcDbObjectId cubeId; acdbGetObjectId(cubeId, ename); if (cubeId.isNull()) { acutPrintf(_T(\n* 选中的实体无效)); return; } // 3. 读取当前尺寸无事务 double length 100.0, width 100.0, height 100.0; if (!ReadCubeXData(cubeId, length, width, height)) { acutPrintf(_T(\n* 该实体无尺寸数据使用默认值100×100×100)); } // 4. 赋值并打开对话框 g_CubeParam.dLength length; g_CubeParam.dWidth width; g_CubeParam.dHeight height; g_CubeParam.editCubeId cubeId; // 标记为修改 HWND hWndAcad adsw_acadMainWnd(); if (hWndAcad NULL) hWndAcad GetDesktopWindow(); HWND hDlg CreateDialogParam( g_hPluginModule, MAKEINTRESOURCE(IDD_DIALOG_CUBE_PARAM), hWndAcad, CubeDlgProc, 0 ); if (hDlg NULL) { acutPrintf(_T(\n* 错误无法创建对话框错误代码%d), GetLastError()); return; } ShowWindow(hDlg, SW_SHOW); UpdateWindow(hDlg); g_CubeParam.hDialog hDlg; g_CubeParam.bDialogActive TRUE; } }; // 关键入口宏告诉 BRX 框架核心插件类无法省略 IMPLEMENT_ARX_ENTRYPOINT(CubePlugin) // DLL 入口函数保存插件模块句柄系统自动调用 BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: // 插件加载时保存自身模块句柄把插件的身份证号存到全局变量里 g_hPluginModule hModule; break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } // 命令1自动注册 BCreateCube遵循 BRX 模板自动注册宏规范 ACED_ARXCOMMAND_ENTRY_AUTO(CubePlugin, CubePlugin, BCreateCube, BCreateCube, ACRX_CMD_TRANSPARENT, NULL) // 命令2自动注册 CubeDlg遵循 BRX 模板自动注册宏规范 ACED_ARXCOMMAND_ENTRY_AUTO(CubePlugin, CubePlugin, CubeDlg, CubeDlg, ACRX_CMD_TRANSPARENT, NULL) // 命令3自动注册 EditCube遵循 BRX 模板自动注册宏规范 ACED_ARXCOMMAND_ENTRY_AUTO(CubePlugin, CubePlugin, EditCube, EditCube, ACRX_CMD_TRANSPARENT, NULL)豆包给的修改代码#include StdAfx.h #include Box.h #include Cylinder.h // 新增圆柱类头文件需你补充实现 #include resource.h #include windows.h #include tchar.h // 全局变量保存插件自身模块句柄 static HMODULE g_hPluginModule NULL; // 新增图形类型枚举 XData标识 // 图形类型枚举 enum ShapeType { SHAPE_UNKNOWN 0, SHAPE_CUBE 1, SHAPE_CYLINDER 2 }; // XData注册应用名唯一标识 #define PLUGIN_XDATA_APP _T(SHAPE_PLUGIN_XDATA) // XData标签码 const int XDATA_APP_CODE 1001; // 应用名标签 const int XDATA_SHAPE_TYPE 1070; // 图形类型整数 const int XDATA_LENGTH 1040; // 长度/直径 const int XDATA_WIDTH 1040; // 宽度 const int XDATA_HEIGHT 1040; // 高度/高度 // 全局结构体存储图形参数 typedef struct { // 通用参数 ShapeType shapeType; // 图形类型 BOOL bDialogActive; // 对话框是否激活 HWND hDialog; // 对话框句柄 AcDbObjectId editShapeId; // 待修改的图形ID // 立方体参数 double dCubeLength; double dCubeWidth; double dCubeHeight; // 圆柱参数 double dCylRadius; double dCylHeight; } ShapeParamStruct; // 全局参数初始化 static ShapeParamStruct g_ShapeParam { SHAPE_UNKNOWN, FALSE, NULL, AcDbObjectId::kNull, 100.0, 100.0, 100.0, // 立方体默认值 50.0, 100.0 // 圆柱默认值 }; // XData读写函数支持多图形类型 // 写入图形XData通用支持立方体/圆柱 void WriteShapeXData(AcDbObjectId objId, ShapeType type, double p1, double p2, double p3) { if (objId.isNull()) return; // 创建XData列表包含图形类型尺寸 resbuf* pXData acutBuildList( XDATA_APP_CODE, PLUGIN_XDATA_APP, XDATA_SHAPE_TYPE, (int)type, // 图形类型标识 XDATA_LENGTH, p1, XDATA_WIDTH, p2, XDATA_HEIGHT, p3, RTNONE ); // 打开实体写入XData AcDbEntity* pEnt NULL; if (acdbOpenObject(pEnt, objId, AcDb::kForWrite) ! Acad::eOk) { acutRelRb(pXData); acutPrintf(_T(\n* 无法打开实体写入XData)); return; } pEnt-setXData(pXData); pEnt-close(); acutRelRb(pXData); } // 读取图形XData返回图形类型输出尺寸 ShapeType ReadShapeXData(AcDbObjectId objId, double p1, double p2, double p3) { if (objId.isNull()) return SHAPE_UNKNOWN; // 打开实体读取XData AcDbEntity* pEntity NULL; if (acdbOpenObject(pEntity, objId, AcDb::kForRead) ! Acad::eOk) { acutPrintf(_T(\n* 无法打开实体读取XData)); return SHAPE_UNKNOWN; } resbuf* pXData pEntity-xData(PLUGIN_XDATA_APP); if (pXData NULL) { pEntity-close(); return SHAPE_UNKNOWN; } // 解析XData先读类型再读尺寸 ShapeType type SHAPE_UNKNOWN; resbuf* pRb pXData-rbnext; // 跳过应用名标签 int count 0; p1 p2 p3 0.0; while (pRb ! NULL pRb-restype ! RTNONE) { if (pRb-restype XDATA_SHAPE_TYPE) { type (ShapeType)pRb-resval.rint; // 读取图形类型 } else if (pRb-restype 1040) { if (count 0) p1 pRb-resval.rreal; else if (count 1) p2 pRb-resval.rreal; else if (count 2) p3 pRb-resval.rreal; count; } pRb pRb-rbnext; } // 清理资源 acutRelRb(pXData); pEntity-close(); return (count 3) ? type : SHAPE_UNKNOWN; } // 实体类型判断函数核心区分插件/原生图形 // 判断实体是否为插件创建的图形返回类型原生图形返回UNKNOWN ShapeType getPluginShapeType(ads_name ename) { if (ename NULL) return SHAPE_UNKNOWN; // 1. 转换为ObjectId AcDbObjectId objId; if (acdbGetObjectId(objId, ename) ! Acad::eOk) return SHAPE_UNKNOWN; // 2. 读取XData判断类型无插件XData原生图形 double p1, p2, p3; return ReadShapeXData(objId, p1, p2, p3); } // 对话框过程函数立方体 INT_PTR CALLBACK CubeDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_INITDIALOG: g_ShapeParam.hDialog hDlg; g_ShapeParam.bDialogActive TRUE; // 初始化立方体尺寸显示 TCHAR szValue[64]; _stprintf_s(szValue, _T(%.2f), g_ShapeParam.dCubeLength); SetDlgItemText(hDlg, IDC_EDIT_LENGTH, szValue); _stprintf_s(szValue, _T(%.2f), g_ShapeParam.dCubeWidth); SetDlgItemText(hDlg, IDC_EDIT_WIDTH, szValue); _stprintf_s(szValue, _T(%.2f), g_ShapeParam.dCubeHeight); SetDlgItemText(hDlg, IDC_EDIT_HEIGHT, szValue); return TRUE; case WM_COMMAND: if (LOWORD(wParam) IDOK) { // 读取立方体尺寸 TCHAR szBuffer[64]; GetDlgItemText(hDlg, IDC_EDIT_LENGTH, szBuffer, 64); g_ShapeParam.dCubeLength _tstof(szBuffer); GetDlgItemText(hDlg, IDC_EDIT_WIDTH, szBuffer, 64); g_ShapeParam.dCubeWidth _tstof(szBuffer); GetDlgItemText(hDlg, IDC_EDIT_HEIGHT, szBuffer, 64); g_ShapeParam.dCubeHeight _tstof(szBuffer); // 合法性校验 if (g_ShapeParam.dCubeLength 0.001 || g_ShapeParam.dCubeWidth 0.001 || g_ShapeParam.dCubeHeight 0.001) { MessageBox(hDlg, _T(长宽高必须大于0.001), _T(错误), MB_OK | MB_ICONERROR); return TRUE; } // 删除旧立方体 AcDbEntity* pOldShape NULL; if (acdbOpenObject(pOldShape, g_ShapeParam.editShapeId, AcDb::kForWrite) Acad::eOk) { pOldShape-erase(); pOldShape-close(); } // 创建新立方体 AcDbObjectId newCubeId Box::createBoxSolid( g_ShapeParam.dCubeLength, g_ShapeParam.dCubeWidth, g_ShapeParam.dCubeHeight, AcGeVector3d(100, 100, 100), 1 ); if (!newCubeId.isNull()) { WriteShapeXData(newCubeId, SHAPE_CUBE, g_ShapeParam.dCubeLength, g_ShapeParam.dCubeWidth, g_ShapeParam.dCubeHeight); acutPrintf(_T(\n* 立方体修改成功尺寸%.2f×%.2f×%.2f), g_ShapeParam.dCubeLength, g_ShapeParam.dCubeWidth, g_ShapeParam.dCubeHeight); } // 关闭对话框 DestroyWindow(hDlg); g_ShapeParam.bDialogActive FALSE; g_ShapeParam.hDialog NULL; g_ShapeParam.editShapeId AcDbObjectId::kNull; return TRUE; } else if (LOWORD(wParam) IDCANCEL) { DestroyWindow(hDlg); g_ShapeParam.bDialogActive FALSE; g_ShapeParam.hDialog NULL; return TRUE; } break; case WM_CLOSE: case WM_DESTROY: DestroyWindow(hDlg); g_ShapeParam.bDialogActive FALSE; g_ShapeParam.hDialog NULL; return TRUE; } return FALSE; } // 对话框过程函数圆柱 INT_PTR CALLBACK CylinderDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_INITDIALOG: g_ShapeParam.hDialog hDlg; g_ShapeParam.bDialogActive TRUE; // 初始化圆柱尺寸显示 TCHAR szValue[64]; _stprintf_s(szValue, _T(%.2f), g_ShapeParam.dCylRadius); SetDlgItemText(hDlg, IDC_EDIT_RADIUS, szValue); _stprintf_s(szValue, _T(%.2f), g_ShapeParam.dCylHeight); SetDlgItemText(hDlg, IDC_EDIT_CYL_HEIGHT, szValue); return TRUE; case WM_COMMAND: if (LOWORD(wParam) IDOK) { // 读取圆柱尺寸 TCHAR szBuffer[64]; GetDlgItemText(hDlg, IDC_EDIT_RADIUS, szBuffer, 64); g_ShapeParam.dCylRadius _tstof(szBuffer); GetDlgItemText(hDlg, IDC_EDIT_CYL_HEIGHT, szBuffer, 64); g_ShapeParam.dCylHeight _tstof(szBuffer); // 合法性校验 if (g_ShapeParam.dCylRadius 0.001 || g_ShapeParam.dCylHeight 0.001) { MessageBox(hDlg, _T(半径和高度必须大于0.001), _T(错误), MB_OK | MB_ICONERROR); return TRUE; } // 删除旧圆柱 AcDbEntity* pOldShape NULL; if (acdbOpenObject(pOldShape, g_ShapeParam.editShapeId, AcDb::kForWrite) Acad::eOk) { pOldShape-erase(); pOldShape-close(); } // 创建新圆柱需你补充Cylinder::createCylinderSolid实现 AcDbObjectId newCylId Cylinder::createCylinderSolid( g_ShapeParam.dCylRadius, g_ShapeParam.dCylHeight, AcGeVector3d(200, 200, 100), 2 // 蓝色区分立方体 ); if (!newCylId.isNull()) { WriteShapeXData(newCylId, SHAPE_CYLINDER, g_ShapeParam.dCylRadius, 0.0, g_ShapeParam.dCylHeight); acutPrintf(_T(\n* 圆柱修改成功半径%.2f高度%.2f), g_ShapeParam.dCylRadius, g_ShapeParam.dCylHeight); } // 关闭对话框 DestroyWindow(hDlg); g_ShapeParam.bDialogActive FALSE; g_ShapeParam.hDialog NULL; g_ShapeParam.editShapeId AcDbObjectId::kNull; return TRUE; } else if (LOWORD(wParam) IDCANCEL) { DestroyWindow(hDlg); g_ShapeParam.bDialogActive FALSE; g_ShapeParam.hDialog NULL; return TRUE; } break; case WM_CLOSE: case WM_DESTROY: DestroyWindow(hDlg); g_ShapeParam.bDialogActive FALSE; g_ShapeParam.hDialog NULL; return TRUE; } return FALSE; } // 右键触发核心函数区分图形类型 static void ShapeRightClickHandler(void) { // 1. 获取当前选中的实体兼容旧版SDK ads_name ename; ads_point pt; if (acedEntSel(_T(\n请选择要修改的图形), ename, pt) ! RTNORM) return; // 2. 判断是否为插件创建的图形 ShapeType type getPluginShapeType(ename); if (type SHAPE_UNKNOWN) { // 原生图形执行CAD默认右键功能 acedMenuCmd(_T(^C^C-_shortcutmenu)); return; } // 3. 转换为ObjectId AcDbObjectId shapeId; acdbGetObjectId(shapeId, ename); if (shapeId.isNull()) return; // 4. 读取尺寸并打开对应对话框 double p1, p2, p3; ReadShapeXData(shapeId, p1, p2, p3); g_ShapeParam.editShapeId shapeId; HWND hWndAcad adsw_acadMainWnd(); if (hWndAcad NULL) hWndAcad GetDesktopWindow(); // 立方体 → 打开立方体对话框 if (type SHAPE_CUBE) { g_ShapeParam.dCubeLength p1; g_ShapeParam.dCubeWidth p2; g_ShapeParam.dCubeHeight p3; HWND hDlg CreateDialogParam( g_hPluginModule, MAKEINTRESOURCE(IDD_DIALOG_CUBE_PARAM), hWndAcad, CubeDlgProc, 0 ); if (hDlg ! NULL) { ShowWindow(hDlg, SW_SHOW); UpdateWindow(hDlg); g_ShapeParam.hDialog hDlg; g_ShapeParam.bDialogActive TRUE; } } // 圆柱 → 打开圆柱对话框 else if (type SHAPE_CYLINDER) { g_ShapeParam.dCylRadius p1; g_ShapeParam.dCylHeight p3; HWND hDlg CreateDialogParam( g_hPluginModule, MAKEINTRESOURCE(IDD_DIALOG_CYL_PARAM), // 圆柱对话框ID hWndAcad, CylinderDlgProc, 0 ); if (hDlg ! NULL) { ShowWindow(hDlg, SW_SHOW); UpdateWindow(hDlg); g_ShapeParam.hDialog hDlg; g_ShapeParam.bDialogActive TRUE; } } } // 插件核心类 class ShapePlugin : public AcRxArxApp { public: ShapePlugin() : AcRxArxApp() {} virtual void RegisterServerComponents() {} // 插件加载注册命令 绑定右键 virtual AcRx::AppRetCode On_kInitAppMsg(void* pAppData) { AcRx::AppRetCode result AcRxArxApp::On_kInitAppMsg(pAppData); acrxRegisterAppMDIAware(pAppData); acrxUnlockApplication(pAppData); // 注册命令 acedRegCmds-addCommand(_T(SHAPE_PLUGIN_CMD), _T(BCreateCube), _T(BCreateCube), ACRX_CMD_TRANSPARENT, CreateCube); acedRegCmds-addCommand(_T(SHAPE_PLUGIN_CMD), _T(BCreateCyl), _T(BCreateCyl), ACRX_CMD_TRANSPARENT, CreateCylinder); acedRegCmds-addCommand(_T(SHAPE_PLUGIN_CMD), _T(EditShape), _T(EditShape), ACRX_CMD_TRANSPARENT, ShapeRightClickHandler); // 核心绑定右键触发绕过CAD默认选中 acedDefun(_T(SHAPE_RIGHTCLICK), ACRX_CMD_TRANSPARENT); acedRegCmds-addCommand( _T(SHAPE_PLUGIN_CMD), _T(SHAPE_RIGHTCLICK), _T(SHAPE_RIGHTCLICK), ACRX_CMD_TRANSPARENT, ShapeRightClickHandler ); // 绑定到实体右键菜单POP513是BricsCAD实体右键菜单标准ID acedMenuCmd(_T(^C^C-_bind POP513.1 SHAPE_RIGHTCLICK)); acutPrintf(_T(\n* 图形插件加载成功)); acutPrintf(_T(\n* 命令BCreateCube创建立方体、BCreateCyl创建圆柱)); acutPrintf(_T(\n* 右键插件图形可修改尺寸原生图形保留默认右键)); return result; } // 插件卸载清理对话框 virtual AcRx::AppRetCode On_kUnloadAppMsg(void* pAppData) { if (g_ShapeParam.bDialogActive g_ShapeParam.hDialog IsWindow(g_ShapeParam.hDialog)) DestroyWindow(g_ShapeParam.hDialog); g_ShapeParam.bDialogActive FALSE; g_ShapeParam.hDialog NULL; return AcRxArxApp::On_kUnloadAppMsg(pAppData); } // 其他生命周期函数 virtual AcRx::AppRetCode On_kLoadDwgMsg(void* pAppData) { return AcRxArxApp::On_kLoadDwgMsg(pAppData); } virtual AcRx::AppRetCode On_kUnloadDwgMsg(void* pAppData) { return AcRxArxApp::On_kUnloadDwgMsg(pAppData); } // 创建立方体命令 static void CreateCube(void) { AcDbObjectId cubeId Box::createBoxSolid(100.0, 100.0, 100.0, AcGeVector3d(100, 100, 100), 1); if (!cubeId.isNull()) { WriteShapeXData(cubeId, SHAPE_CUBE, 100.0, 100.0, 100.0); acutPrintf(_T(\n* 立方体创建成功右键可修改尺寸)); } } // 创建圆柱命令 static void CreateCylinder(void) { // 需你补充Cylinder::createCylinderSolid实现 AcDbObjectId cylId Cylinder::createCylinderSolid(50.0, 100.0, AcGeVector3d(200, 200, 100), 2); if (!cylId.isNull()) { WriteShapeXData(cylId, SHAPE_CYLINDER, 50.0, 0.0, 100.0); acutPrintf(_T(\n* 圆柱创建成功右键可修改尺寸)); } } }; // 框架必备代码 IMPLEMENT_ARX_ENTRYPOINT(ShapePlugin) BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: g_hPluginModule hModule; break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } // 命令注册宏 ACED_ARXCOMMAND_ENTRY_AUTO(ShapePlugin, ShapePlugin, BCreateCube, BCreateCube, ACRX_CMD_TRANSPARENT, NULL) ACED_ARXCOMMAND_ENTRY_AUTO(ShapePlugin, ShapePlugin, BCreateCyl, BCreateCyl, ACRX_CMD_TRANSPARENT, NULL) ACED_ARXCOMMAND_ENTRY_AUTO(ShapePlugin, ShapePlugin, EditShape, EditShape, ACRX_CMD_TRANSPARENT, NULL)

相关新闻

小白也能懂的视觉推理入门:用Glyph镜像轻松实现多模态应用

小白也能懂的视觉推理入门:用Glyph镜像轻松实现多模态应用

小白也能懂的视觉推理入门:用Glyph镜像轻松实现多模态应用 1. 什么是视觉推理?别被名字吓到,它其实很接地气 你有没有遇到过这些场景: 看到一张复杂的电路图,想快速理解各模块功能,但密密麻麻的符号让人…

2026/7/8 14:07:53 阅读更多 →
2026必备!专科生毕业论文AI论文平台TOP9测评

2026必备!专科生毕业论文AI论文平台TOP9测评

2026必备!专科生毕业论文AI论文平台TOP9测评 2026专科生毕业论文AI平台测评:选对工具,事半功倍 随着人工智能技术的快速发展,越来越多的专科生开始借助AI论文平台来提升毕业论文的撰写效率与质量。然而,面对市场上种…

2026/7/3 19:13:21 阅读更多 →
手把手教你用Glyph镜像搭建长文本理解系统

手把手教你用Glyph镜像搭建长文本理解系统

手把手教你用Glyph镜像搭建长文本理解系统 1. 为什么你需要一个长文本理解系统? 你有没有遇到过这些情况: 看一份50页的PDF技术白皮书,想快速定位“模型量化策略”相关段落,但ChatGPT每次只能处理前3页;客服团队每天…

2026/7/3 19:13:22 阅读更多 →

最新新闻

STM32与ADS8665构建高精度信号采集系统设计

STM32与ADS8665构建高精度信号采集系统设计

1. 项目概述:高精度信号转换系统设计在工业测量和精密仪器领域,16位ADC的应用正变得越来越普遍。这次我选用TI的ADS8665与ST的STM32L162ZE搭建了一套信号采集系统,实测下来采样速率可达500kSPS,INL(积分非线性度&#…

2026/7/8 20:04:45 阅读更多 →
企业全员营销短视频统一管理技术方案解析:架构、痛点与矩阵通系统解构

企业全员营销短视频统一管理技术方案解析:架构、痛点与矩阵通系统解构

当企业启动全员营销,涉及销售团队、经销商及门店员工(KOS)大规模参与短视频发布时,管理核心聚焦于账号资产确权、任务执行闭环、跨平台数据归一化及线索归因四个技术维度。本文基于公开资料与行业通用实践,对全员营销管…

2026/7/8 19:58:40 阅读更多 →
WebLogic T3协议漏洞CVE-2018-2628:3种临时缓解方案与官方补丁对比

WebLogic T3协议漏洞CVE-2018-2628:3种临时缓解方案与官方补丁对比

WebLogic T3协议漏洞CVE-2018-2628:3种临时缓解方案与官方补丁对比 当WebLogic服务器的控制台端口(默认7001)暴露在互联网时,T3协议服务会默认开启。这个看似高效的Java RMI通信协议,却因反序列化机制缺陷成为攻击者的…

2026/7/8 19:52:33 阅读更多 →
RunAsSpc vs CPAU vs 组策略:3种AD域软件提权方案对比与安全风险分析

RunAsSpc vs CPAU vs 组策略:3种AD域软件提权方案对比与安全风险分析

RunAsSpc vs CPAU vs 组策略:3种AD域软件提权方案对比与安全风险分析在企业AD域环境中,IT管理员经常面临一个两难选择:既需要限制普通用户的管理员权限以保障系统安全,又不得不应对某些业务软件必须使用管理员权限运行的现实需求。…

2026/7/8 19:52:33 阅读更多 →
国家中小学智慧教育平台电子课本下载终极指南:三步完成教材获取的完整解决方案

国家中小学智慧教育平台电子课本下载终极指南:三步完成教材获取的完整解决方案

国家中小学智慧教育平台电子课本下载终极指南:三步完成教材获取的完整解决方案 【免费下载链接】tchMaterial-parser 国家中小学智慧教育平台 电子课本下载工具,帮助您从智慧教育平台中获取电子课本的 PDF 文件网址并进行下载,让您更方便地获…

2026/7/8 19:50:33 阅读更多 →
JSP/Servlet 机票系统性能优化:3 个关键点将查询响应时间降低 40%

JSP/Servlet 机票系统性能优化:3 个关键点将查询响应时间降低 40%

JSP/Servlet 机票系统性能优化:3 个关键点将查询响应时间降低 40% 在开发机票预订系统时,性能往往是决定用户体验的关键因素。当用户搜索航班时,系统响应速度直接影响转化率——每增加1秒的延迟可能导致7%的用户流失。本文将聚焦三个核心优化…

2026/7/8 19:50:33 阅读更多 →

日新闻

3大核心能力重塑《明日方舟》游戏体验:MAA自动化助手的革命性突破

3大核心能力重塑《明日方舟》游戏体验:MAA自动化助手的革命性突破

3大核心能力重塑《明日方舟》游戏体验:MAA自动化助手的革命性突破 【免费下载链接】MaaAssistantArknights 《明日方舟》小助手,全日常一键长草!| A one-click tool for the daily tasks of Arknights, supporting all clients. 项目地址: …

2026/7/8 0:00:48 阅读更多 →
MyBatis 批量操作深度优化——从 N+1 到批处理的全路径

MyBatis 批量操作深度优化——从 N+1 到批处理的全路径

MyBatis 批量操作深度优化——从 N1 到批处理的全路径 一、从"功能正确"到"性能可接受"——MyBatis 批量操作的三段式进化 MyBatis 在日常增删改查场景中几乎是无感的——实体映射直观、SQL 控制灵活。但当数据量从千级上升到十万级、百万级,许…

2026/7/8 0:00:48 阅读更多 →
工业负载控制方案:TPD2015FN与PIC18F45K22应用解析

工业负载控制方案:TPD2015FN与PIC18F45K22应用解析

1. 工业负载控制方案概述在工业自动化、电机驱动和照明控制等高需求场景中,可靠地控制电感和电阻负载是核心挑战之一。TPD2015FN作为东芝的8通道高端智能功率开关IC,配合PIC18F45K22微控制器,能够构建一套稳定、高效的负载控制系统。这套组合…

2026/7/8 0:02:48 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/8 16:14:06 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/7 12:34:47 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/8 16:59:55 阅读更多 →

月新闻