天气与日历 切换到窄版

 找回密码
 立即注册
中国膜结构网
十大进口膜材评选 十大国产膜材评选 十大膜结构设计评选 十大膜结构公司评选
查看: 82|回复: 0

ObjectArx 使用消息钩子实现鼠标滚轮旋转实体

[复制链接]

该用户从未签到

主题

0

回帖

2912

积分

管理员

积分
2912
发表于 2024-6-22 09:46:18 | 显示全部楼层 |阅读模式
[code]实现方法:主要是程序注册一个消息函数:func,拦截鼠标滚轮触发的消息,需要注意的是,以写的方式处理实体时需要锁定文档。注册func的主要方法是:
BOOL acedRegisterFilterWinMsg(
const AcedFilterWinMsgFn pfn
);
AcedFilterWinMsgFn 这个类型 是一个函数指针,其实他是这样的:
typedef BOOL (* AcedFilterWinMsgFn)(MSG*);接受一个MSG *的参数,返回BOOL类型的函数。

这个MSG是个struct,参数内部是这样的:

typedef struct tagMSG {
    HWND        hwnd;
    UINT        message;
    WPARAM      wParam;
    LPARAM      lParam;
    DWORD       time;
    POINT       pt;
#ifdef _MAC
    DWORD       lPrivate;
#endif
} MSG
我们主要使用到的是message成员,和wParam成员。使用message成员过滤出鼠标滚轮滑动的消息,wParam的值来区分滚轮上和下的运动,然后我们就把实体的旋转写在这个里面。详细见代码:、

BOOL func(MSG *msg) {

    int zdFx = 0;

    if (msg->message == WM_MOUSEWHEEL) {

        zdFx = (short)HIWORD(msg->wParam);
        acutPrintf(L"
%d", zdFx);
        if (zdFx == 120) {

            AcDbEntity * pEnt = NULL;

            ErrorStatus es = acdbOpenObject(pEnt, oId, AcDb::kForWrite);
            if (es == Acad::eOk) {

                pEnt->transformBy(matx1);
                pEnt->close();
            }

        }
        else if (zdFx == -120) {

            AcDbEntity * pEnt = NULL;

            ErrorStatus es = acdbOpenObject(pEnt, oId, AcDb::kForWrite);

            if (es == Acad::eOk) {

                pEnt->transformBy(matx2);
                pEnt->close();
            }
        }
        return TRUE;
    }


    return FALSE;
}
这个func是个全局函数,这样方便我在注册func的类里面调用。因为注册了这个消息,cad默认的滚轮放大缩小的功能就会被屏蔽掉,需要使用解除注册的方法来取消对这个消息的监视。这个方法是:
BOOL acedRemoveFilterWinMsg(
const AcedFilterWinMsgFn pfn
);
我把注册和取消的方法封装到一个类里面,并且定义了一个BOOL类型的全局变量来避免重复注册和重复取消,见代码:


复制代码
#include "stdafx.h"
#include "RegMsg.h"

static bool isReged = FALSE;
extern BOOL func(MSG *msg);
RegMsg::RegMsg()
{
}


RegMsg::~RegMsg()
{
}

void RegMsg::reg()
{
    if (!isReged) {
        acutPrintf(L"
reging...
");
        if (!acedRegisterFilterWinMsg(func)) {
            acutPrintf(L"
reg  failed
");
        }
        else{
            acutPrintf(L"
reg success
");
            isReged = TRUE;
        }
    }
}

void RegMsg::unReg()
{
    if (isReged) {

        if (!acedRemoveFilterWinMsg(func)) {
            acutPrintf(L"
unreg  failed
");
        }
        else {
            acutPrintf(L"
unreg success
");
            isReged = FALSE;
        }
    }
}
复制代码
最后我需要做的就是,选择要选择的实体,把实体的ObjectId传入到func函数里,在func函数里进行旋转操作,我发现,必须在func函数里每滑动依次鼠标,就需要对实体进行依次开闭操作,如果,只是在处理函数里只旋转,而不关闭实体,cad里的实体是不会旋转的,到最后你什么时候关闭这个打开的实体,这个实体才会旋转到最后一次的操作上来。
下面是我在命令类的全局参数和定义的操作命令:


复制代码
#define PI 3.14159265358979323846

BOOL func(MSG *msg);

AcDbObjectId oId;
AcGeMatrix3d matx1;
AcGeMatrix3d matx2;
RegMsg * reg = NULL;
复制代码

复制代码
static void ECDMyGroupMyRegMsg() {

        acDocManager->lockDocument(acDocManager->curDocument());

        if (reg == NULL) {
            reg = new RegMsg();

            AcRxClass *cls = AcDbEntity::desc();

            AcDbEntity * pEnt = NULL;

            AcGePoint3d pickPoint;

            if (CSelectUtil::PromptSelectEntity(L"选择实体:", cls, pEnt, pickPoint, true)) {

                oId = pEnt->objectId();
                pEnt->close();
                matx1 = AcGeMatrix3d::rotation(1.0 / 18 * PI, AcGeVector3d::kZAxis, pickPoint);
                matx2 = AcGeMatrix3d::rotation(-1.0 / 18 * PI, AcGeVector3d::kZAxis, pickPoint);

                reg->reg();
            }
        }

    }
复制代码

复制代码
static void ECDMyGroupMyUnRegMsg() {

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

        if (reg != NULL) {

            reg->unReg();

            reg = NULL;

            delete reg;
        }
    }
复制代码[/code]

 

 

 

 

ObjectArx 使用消息钩子实现鼠标滚轮旋转实体
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|中国膜结构网|中国膜结构协会|进口膜材|国产膜材|ETFE|PVDF|PTFE|设计|施工|安装|车棚|看台|污水池|中国膜结构网_中国空间膜结构协会

GMT+8, 2024-11-1 09:33 , Processed in 0.124146 second(s), 23 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表