ObjectARX非模态窗口设置CAD获得焦点、设置非模态对话框获得焦点

作者: admin 分类: C++,CAD,ObjectARX 发布时间: 2020-03-04 21:19

获取无事件的鼠标(光标)位置   梁晓东

AutoCAD API提供了AcEdInputPointManager.Inputpointmonitor,它可以监视用户的任何输入,包括鼠标。API还允许您监视Windows消息。有时您可能只需要在没有任何事件的情况下获取当前鼠标位置。下面是代码演示。实际上,它只是获取当前光标位置并将其转换为AutoCAD坐标。它还考虑了UCS。

Get mouse (cursor) position without event

By Xiaodong Liang

AutoCAD API provides AcEdInputPointManager.Inputpointmonitor which can monitor any input of the user, including mouse. API also allows you to monitor Windows message. Sometimes you may just need to get the current mouse position without any event. The following is code demo. Actually, it just get the current cursor position and convert it to AutoCAD coordinate. It also takes UCS into consideration.

static void getMousePosition(void)
{     
    //get cursor position by Windows API
     POINT CursorPos;
     GetCursorPos(&CursorPos);
     acedGetAcadDwgView()->ScreenToClient(&CursorPos);
     //Returns the viewport number based on
     // Windows client coordinates.
     int vpNum = acedGetWinNum(CursorPos.x, CursorPos.y);
     //Converts coordinates from AutoCAD 
     // drawing window
     //to current active viewport's coordinates 
     acedDwgPoint acPt, newPt;
     acedCoordFromPixelToWorld(vpNum, 
                               CursorPos, 
                               acPt);  
     double worldPoint[3];
     acedCoordFromPixelToWorld(vpNum,
                                CPoint(CursorPos.x,
                                CursorPos.y) ,
                                worldPoint);
     acutPrintf( 
         L"\nModel Position (no UCS): [%f, %f, %f]\n",
                    worldPoint[0],
                    worldPoint[1],
                    worldPoint[2]);
     //Take UCS translation in consideration    
     AcGeMatrix3d mat;
     acedGetCurrentUCS(mat);
     AcGePoint3d ptUcs(worldPoint[0],
                     worldPoint[1],
                     worldPoint[2]);
     ptUcs.transformBy(mat.inverse());
     resbuf wcs;
     wcs.restype = RTSHORT;
     wcs.resval.rint = 0;
     resbuf dcs;
     dcs.restype = RTSHORT;
     dcs.resval.rint = 2;
     //translate the WCS coordinate to UCS
     double result[3];
     acedTrans(asDblArray(ptUcs),
                &wcs,
                &dcs,
                0,
                result);
     acutPrintf( 
       L"\nModel Position (with UCS): [%f, %f, %f]\n",
         result[0], result[1], result[2]);
}
Posted at 06:34 PM in AutoCAD, ObjectARX, Xiaodong Liang | Permalink

几个ARX取CAD窗口句柄的函数 

CWinApp* acedGetAcadWinApp()
返回指向AutoCAD应用程序类实例的指针


CDocument* acedGetAcadDoc()
返回指向AutoCAD文件类实例的指针


CView* acedGetAcadDwgView()
返回指向视图类的指针(AutoCAD的绘图区)


CMDIFrameWnd* acedGetAcadFrame()
返回一个多文档(MDI)程序主框架类实例的指针


CWnd* acedGetAcadDockCmdLine()
返回指向AutoCAD命令窗口实例的指针


CWnd* acedGetAcadTextCmdLine()
返回指向AutoCAD文本窗口实例的指针


HINSTANCE acedGetAcadResourceInstance()
返回AutoCAD使用的资源句柄


int acedSetStatusBarProgressMeter(
const char* pszLabel,
int nMinPos,
int nMaxPos);
在AutoCAD主程序窗口的状态条上生成一个进度条,
返回值为0,表示函数调用成功
返回值为-1,表示函数调用失败


int acedSetStatusBarProgressMeterPos(int nPos)
设置当前的进度
nPos>=0,则nPos为当前进度值
nPos<0, 则将当前进度值与nPos相加


void acedRestoreStatusBar()
恢复进度条的原始状态,既进度条消失,不返回任何值
CWinApp* acedGetAcadWinApp()
返回指向AutoCAD应用程序类实例的指针


CDocument* acedGetAcadDoc()
返回指向AutoCAD文件类实例的指针


CView* acedGetAcadDwgView()
返回指向视图类的指针(AutoCAD的绘图区)


CMDIFrameWnd* acedGetAcadFrame()
返回一个多文档(MDI)程序主框架类实例的指针


CWnd* acedGetAcadDockCmdLine()
返回指向AutoCAD命令窗口实例的指针


CWnd* acedGetAcadTextCmdLine()
返回指向AutoCAD文本窗口实例的指针
HINSTANCE acedGetAcadResourceInstance()
返回AutoCAD使用的资源句柄
int acedSetStatusBarProgressMeter(
const char* pszLabel,
int nMinPos,
int nMaxPos);
在AutoCAD主程序窗口的状态条上生成一个进度条,
返回值为0,表示函数调用成功
返回值为-1,表示函数调用失败


int acedSetStatusBarProgressMeterPos(int nPos)
设置当前的进度
nPos>=0,则nPos为当前进度值
nPos
void acedRestoreStatusBar()
恢复进度条的原始状态,既进度条消失,不返回任何值


ObjectARX模态对话框与CAD主界面交互转换函数BeginEditorCommand、CompleteEditorCommand 、CancelEditorCommand 的机制

BeginEditorCommand的原理:

// 首先获取CAD的主界面

CWnd* pAcadWnd = CWnd::FromHandle(adsw_acadMainWnd());
// 激活主界面
pAcadWnd->EnableWindow(TRUE);

// 隐藏当前会话框
ShowWindow(SW_HIDE);

// 将主界面设置为焦点
pAcadWnd->SetFocus(); 

用 BeginEditorCommand,会暂时隐藏对话框,此时可以对CAD图形进行操作,操作完毕之后,调用CompleteEditorCommand 恢复显示或CancelEditorCommand 退出对话框。

BEGIN_MESSAGE_MAP(CATMChaRuTuKuai, CAcUiDialog)
ON_MESSAGE(WM_ACAD_KEEPFOCUS, OnAcadKeepFocus)
ON_WM_CLOSE()
ON_BN_CLICKED(IDOK, &CATMChaRuTuKuai::OnBnClickedOk)
ON_LBN_SELCHANGE(IDC_LIST_BLKNAME, &CATMChaRuTuKuai::OnLbnSelchangeListBlkname)
ON_EN_CHANGE(IDC_EDITSEARCH, &CATMChaRuTuKuai::OnEnChangeEditsearch)
ON_BN_CLICKED(IDC_BUTTON1, &CATMChaRuTuKuai::OnBnClickedButton1)
ON_BN_CLICKED(IDC_RADIONUM, &CATMChaRuTuKuai::OnBnClickedRadionum)
ON_BN_CLICKED(IDC_RADIOSCALE, &CATMChaRuTuKuai::OnBnClickedRadioscale)
ON_BN_CLICKED(IDC_BUTTONDELETE, &CATMChaRuTuKuai::OnBnClickedButtondelete)
END_MESSAGE_MAP()

//—– Needed for modeless dialogs to keep focus.

//—– Return FALSE to not keep the focus, return TRUE to keep the focus

LRESULT CATMChaRuTuKuai::OnAcadKeepFocus (WPARAM, LPARAM) {

return (TRUE) ;

}

objectarx MFC 非模态对话框为当前焦点

dialog.h
afx_msg LRESULT OnAcadKeepFocus(WPARAM, LPARAM);

dialog.cpp

 

BEGIN_MESSAGE_MAP(CTextDialog, CDialogEx)
ON_MESSAGE(WM_ACAD_KEEPFOCUS, OnAcadKeepFocus)
END_MESSAGE_MAP()

 

LRESULT CTextDialog::OnAcadKeepFocus(WPARAM, LPARAM) {
return (TRUE);
}

C#CAD二次开发 非模态对话框切换窗口焦点

在C#CAD二次开发 使用非模态对话框时,如果需要点击按钮跳转到CAD操作或者让CAD界面打印输出是,需要人为的点击的一下CAD界面,使其焦点进行切换,交互颇为不友善。可以用以下方案解决:

此时可以用WinAPI中的SetFocus将焦点移到CAD主窗口即可:

C#文件需要添加using 命名空间:

using System.Runtime.InteropServices; 

窗口类初始化加以下代码

[DllImport("user32.dll", EntryPoint = "SetFocus")]

public static extern int SetFocus(IntPtr hWnd);

程序里让程序切换到CAD 里头的焦点,不需要人为点

Document acDoc = Application.DocumentManager.MdiActiveDocument;

SetFocus(acDoc.Window.Handle);

————————————————

版权声明:本文为CSDN博主「木辰AA」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/pengtao779/article/details/100735387

OjbectArx cad非模态对话框无法获取焦点

相比起在普通的环境中建立一个非模态对话框,在cad中建立还是稍微麻烦一些的。

主要还是焦点问题,在cad中的非模态对话框无法获取焦点——或者说刚拿到焦点就丢失了。

处理方法:

增加消息处理函数,处理cad平台的WM_ACAD_KEEPFOCUS消息。

ON_MESSAGE(WM_ACAD_KEEPFOCUS, OnKeepFocus)

 

//OnKeepFocus函数:直接返回TRUE即可。

 

LRESULT Class_name::OnKeepFocus(WPARAM,LPARAM)

{

return TRUE;

}

一般来说,直接返回TRUE即可。

也可以改成判定鼠标所在区域是否为窗口区域来返回对应的值。这样改动后后,只要鼠标离开窗口区域,窗口就会丢失焦点

————————————————

版权声明:本文为CSDN博主「Vis_Stu」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/Vis_Stu/article/details/72178518

如果觉得我的文章对您有用,请随意赞赏。您的支持将鼓励我继续创作!

发表评论

标签云