写1个acedGrRead+ acedSSget 配合,实现鼠标悬浮不点击状态选中图元
本来想在Jig 中使用,但是jIG过程ssget 返回5003, 大佬有别的方法也可以教我一下#include <stdarx.h>
#include <memory>
// 全局变量记录上次选中的图元
static ads_name g_oldAdsEnt = { 0, 0 };
static AcDbObjectId g_objidOld = AcDbObjectId::kNull;
// 比较两个ads_name是否相同
bool CompareAdsEnt(const ads_name& left, const ads_name& right) {
return (left == right) && (left == right);
}
// 检查ads_name是否有效
bool IsValidAdsName(const ads_name& name) {
return name != 0 || name != 0;
}
bool SelectEntity(const AcGePoint3d& pt, ads_name& ss, AcDbObjectId& objid, AcDbEntity*& pEnt) {
// 释放之前的选择集
if (IsValidAdsName(ss)) {
acedSSFree(ss);
ss = ss = 0;
}
// 尝试选择图元
if (acedSSGet(nullptr, &pt, nullptr, nullptr, ss) != RTNORM) {
return false;
}
// 检查选择集有效性
int len = 0;
if (acedSSLength(ss, &len) != RTNORM || len == 0) {
return false;
}
// 获取第一个图元
ads_name ent;
if (acedSSName(ss, 0, ent) != RTNORM) {
return false;
}
// 比较是否与上次选中的图元相同
if (CompareAdsEnt(ent, g_oldAdsEnt) && pEnt != nullptr) {
return true;
}
// 获取对象ID
if (acdbGetObjectId(objid, ent) != Acad::eOk) {
return false;
}
// 关闭之前打开的图元
if (pEnt != nullptr) {
pEnt->close();
pEnt = nullptr;
}
// 打开新图元
if (acdbOpenObject(pEnt, objid, AcDb::kForRead) == Acad::eOk) {
// 更新记录
g_oldAdsEnt = ent;
g_oldAdsEnt = ent;
g_objidOld = objid;
acutPrintf(L"\n选中新图元(颜色: %d)", pEnt->colorIndex());
return true;
}
return false;
}
void monitorInput() {
ads_name ss = { 0 };
AcDbObjectId objid = AcDbObjectId::kNull;
AcDbEntity* pEnt = nullptr;
const int trackFlags = 8 | 4 | 2 | 1; // 启用所有输入类型
std::unique_ptr<resbuf> result(new resbuf);
AcGePoint3d lastPoint, dragPt;
std::wstring inputBuffer;
acutPrintf(L"\n开始监控输入(按ESC退出)...");
while (true) {
int inputType = 2;// 设定鼠标选图元样式
int status = acedGrRead(trackFlags, &inputType, result.get());
if (status == RTCAN) {
acutPrintf(L"\n用户取消操作");
break;
}
switch (inputType) {
case 2: // 键盘输入
if (result->resval.rint >= 32 && result->resval.rint <= 126) {
wchar_t ch = static_cast<wchar_t>(result->resval.rint);
inputBuffer += ch;
if (inputBuffer.find(L"abc") != std::wstring::npos) {
acutPrintf(L"\n检测到关键字'abc'");
inputBuffer.clear();
}
}
break;
case 3: // 鼠标点击
lastPoint.set(result->resval.rpoint);
acutPrintf(L"\n点击坐标: (%.2f, %.2f)", lastPoint.x, lastPoint.y);
break;
case 5: // 鼠标拖拽
dragPt.set(result->resval.rpoint);
if (!lastPoint.isEqualTo(dragPt)) {
SelectEntity(dragPt, ss, objid, pEnt);
}
break;
}
}
// 清理资源
if (pEnt != nullptr) {
pEnt->close();
}
if (IsValidAdsName(ss)) {
acedSSFree(ss);
}
acutPrintf(L"\n监控结束");
}
本帖最后由 你有种再说一遍 于 2026-1-4 22:04 编辑
悬浮不点击图元从而选中,这个功能应该用四叉树做,
判断当前鼠标点位于四叉树哪个最小节点,获取节点内的图元,
节点中每个 图元.包围盒.Contains(pt) 即可,这样就不需要调用选择集.
你可以用鼠标钩子+键盘钩子.
钩子的鼠标点高频写入一个静态变量中,然后使用的时候要从屏幕坐标转图纸WCS坐标.
而且也不需要jig,用jig目的是basepoint+当前鼠标点构成的向量,
然后不断修改和刷新多个图元,
不必为了展示技术而加入不必要的东西,除非你有其它逻辑需要.
这样下来你就没有用到任何的cad提供的交互API,完全绕过交互报错.
页:
[1]