測試結果:
實現方法:主要是程序注冊一個消息函數: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"\n%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"\n reging...\n"); if (!acedRegisterFilterWinMsg(func)) { acutPrintf(L"\n reg failed\n"); } else{ acutPrintf(L"\n reg success\n"); isReged = TRUE; } } } void RegMsg::unReg() { if (isReged) { if (!acedRemoveFilterWinMsg(func)) { acutPrintf(L"\n unreg failed\n"); } else { acutPrintf(L"\n unreg success\n"); 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; } }