创建ATL控件
点击菜单File-New
点击按钮OK
点击按钮Finish
点击按钮OK
点击菜单Insert-New ATL Object
点击按钮Next
点击按钮确定
加入方法
右键点击窗口Class-Ixxxx
点击右键菜单Add Method
点击按钮OK
参数框输入:
[in] int *piIValue, [out,retval] int *piORValue
表示输入参数:int * piIValue,返回值类型:int
对应于xxxx.h中的
STDMETHOD(Fun)(/*[in]*/ int *piIValue, /*[out,retval]*/ int *piORValue);
和xxxx.cpp中的
STDMETHODIMP CDemo::Fun(int *piIValue, int *piORValue)
加入属性
右键点击窗口Class-Ixxxx
点击右键菜单Add Property
点击按钮OK
(GetFunction输出函数,对应于xxxx.h中的
STDMETHOD(get_Var)(/*[out, retval]*/ BSTR *pVal); 和xxxx.cpp中的STDMETHODIMP CDemo::get_Var(BSTR *pVal);
PutFunction输入函数,对应于xxxx.h中的
STDMETHOD(put_Var)(/*[in]*/ BSTR newVal);和xxxx.cpp中的STDMETHODIMP CDemo::put_Var(BSTR newVal));
加入事件
右键点击窗口Class-_IxxxxEvents
点击右键菜单Add Method
点击按钮OK
(所有事件函数添加完毕,再执行下面的操作)
右键点击窗口File-xxxxCOM.idl
点击右键菜单Compile xxxxCOM.idl
右键点击窗口Class-Cxxxx
点击右键菜单Implement Connection Point
点击按钮OK
(使用方法:在函数中直接调用Fire_FireFun();,上层应用实现该函数并响应调用)
修改方法参数
修改以下3处
xxxx.h中
STDMETHOD(Fun)(/*[in]*/ int *piIValue, /*[out,retval]*/ int *piORValue);
xxxx.cpp中
STDMETHODIMP CDemo::Fun(int *piIValue, int *piORValue)
xxxxCOM.idl中
[id(1), helpstring("method Fun")] HRESULT Fun([in] int *piIValue, [out,retval] int *piORValue);
处理返回值
返回值需要单独赋值处理,不能直接return,如下所示
*piORValue = 0;
*piORValue = -1;
同步异步
同步:在接口函数中做循环处理
异步:控件一开始开启线程,每次调用接口函数时检测一下线程是否活着,并通过设置事件句柄的信号量来控制线程是否运行到特定的循环中(注意事件句柄的名字设置为NULL,让系统自己来管理事件句柄,可有效地防止外部程序非法修改事件句柄的信号量)
测试工具导入控件
点击菜单File-New
点击按钮OK
点击按钮Finish
点击按钮OK
右键点击窗口Resource-Dialog-IDD_TESTxxxxCOM_DIALOG
点击右键菜单Insert ActiveX Control
点击按钮OK
右键点击COM控件(刚添加的)
点击右键菜单ClassWizard
点击按钮Add Variable
点击按钮确定
点击按钮OK
点击按钮OK
点击按钮OK
右键点击COM控件(刚添加的)
点击右键菜单ClassWizard
双击窗口Messages里的函数
点击按钮OK
点击按钮OK
最后吐槽一下,微软的VS越来越不友好了,以VS2020为例,用来写ATL,复杂了不止一倍