• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >vc/mfc > 高分请教:用MFC开发的非可视ActiveX控件,要在内部实现消息传递,如何实现???

高分请教:用MFC开发的非可视ActiveX控件,要在内部实现消息传递,如何实现???

作者:佚名 字体:[增加 减小] 来源:互联网 时间:2017-06-04

佚名通过本文主要向大家介绍了 高分请教:用MFC开发的非可视ActiveX控件,要在内部实现消息传递,如何实现???等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com
问题: 高分请教:用MFC开发的非可视ActiveX控件,要在内部实现消息传递,如何实现???
描述:

高分请教:用MFC开发的非可视ActiveX控件,要在内部实现消息传递,如何实现???


解决方案1:

mark

解决方案2:

用SOCKET,我用过没问题

解决方案3:

连接点不适应FireEvent之类需要用消息来通讯的场合
转成有窗口的吧

解决方案4:

连接点的实现方法
lostall 
    连接点技术是在服务器方声明一个接口,由客户端实现这个接口,服务器方内部调用这个接口的方法,从而可以向客户发送事件消息,客户接收事件并可进行处理。 
    事件接口可以是从IUnknown继承,也可以是从IDispatch继承,考虑到用其他语言也要能实现这个接口,所以应该从IDispatch继承,这其实是双接口形式。实际上用ATL缺省处理的方式,也不是从IDispatch继承的,只是必须通过Invoke实现而已。 
一、服务器端添加事件接口 
    不用做什么工作,在New ATL Object时,选上Support ConnectionPoint就可以了。注意添加的事件接口在IDL文件中,标志的是dispinterface,这表明它既不是从 IUnknown继承也不是从IDispatch继承。 
二、客户端实现事件接口 
(1)用MFC实现.可参阅MFCTestAtl2的代码(下载)。 
    用MFC实现,首先要找一个类来实现事件接口,只要是从CCmdTarget派生的类都可以用来实现这个事件接口。参考ConnectionPoint中的例子,这里选择的是CMainFrame。首先在MainFrame.h中: 
class CMainFrame : public CFrameWnd
{
DECLARE_DISPATCH_MAP() //声明dispatch map表
DECLARE_INTERFACE_MAP() //建立接口映射表,目的是方便QueryInterface的实现
public:
IAtlTest2Ptr m_pIAtlTest2; //声明一个COM组件对象的实例
DWORD m_dwCookie ; //用于标记一个连接点
void OnShow(); //事件处理函数,没有参数的情况
void OnShow2(short); //事件处理函数,有参数的情况
};
然后修改MainFrame.cpp 
#include "afxctl.h" //定义了AfxConnectionAdvise、AfxConnectionUnadvise
....
//填充dispatch map表,以供Invoke()调用
BEGIN_DISPATCH_MAP( CMainFrame, CFrameWnd)
DISP_FUNCTION_ID(CMainFrame, "Show", 1, OnShow, VT_EMPTY, NULL)
DISP_FUNCTION_ID(CMainFrame, "Show2", 2, OnShow2, VT_EMPTY, VTS_I2)
END_DISPATCH_MAP( )
//填充接口映射表,方便QueryInterface处理,因为它是根据IID来判断接口的
//因为IDispatch已被CCmdTarget嵌套了,所以不需要在.h文件中用BEGIN_INTERFACE_PART(,)和
//END_INTERFACE_PART()来声明这个嵌套类,这里是struct XDispatch{...}m_xDispatch
BEGIN_INTERFACE_MAP( CMainFrame, CFrameWnd)
INTERFACE_PART(CMainFrame, DIID__IAtlTest2Events, Dispatch)
END_INTERFACE_MAP()
void CMainFrame::OnShow()
{
AfxMessageBox("connection point success 1");
}
void CMainFrame::OnShow2(short)
{
AfxMessageBox("connection point success 2");
}
CMainFrame::CMainFrame()
{
// TODO: add member initialization code here
m_pIAtlTest2 = NULL;
//Initialize COM  libraries...create MTA...
CoInitialize(NULL);
//这个函数将m_xDispatch与一个COleDispatchImpl对象联系了起来,COleDispatchImpl实现了
//IDispatch接口,且数据结构与m_xDispatch相同,所以可以赋值给它。这样就等于m_xDispatch
//实现了IDispatch,把它传给COM组件后,COM组件就可以调用它的Invoke()函数(如在FireShow()中),
//COleDispatchImpl::Invoke()中用到了dispatch map,这个表由DECLARE_DISPATCHMAP声明,
//在BEGIN_DISPATCHMAP(,)、END_DISPATCHMAP()中被填充,比如Show()、Show2()。这样Invoke()
//就可以根据dispid在dispatch map中找到这两个函数,从而调用它们,从而实现了连接点。
//另一方面,也可以看到用dispinterface声明的事件接口本身并不是从哪个接口继承的,既不是IUnknown
//也不是IDispatch,只不过通过一系列手段,使Invoke()能识别其中的属性、方法而已。
//dispinterface表示这个接口是纯IDispatch接口。
EnableAutomation();
//creat the instance of the calculator server...
m_pIAtlTest2.CreateInstance(__uuidof(AtlTest2));
//advise the server that this (mainframe) is the sink for events...
//这个函数内部将进行QueryInterface(IConnectionPointContainer,..)、FindConnectionPoint()、Advise()等一系列调用
BOOL Ret = AfxConnectionAdvise( 
m_pIAtlTest2, //可连接对象的接口指针
DIID__IAtlTest2Events, //连接接口ID
GetIDispatch(FALSE), //把内嵌的IDispatch实现类的一个对象实例m_xDispatch传了出去
FALSE, //donod addref
&m_dwCookie ); //cookie to break connection later...
}
CMainFrame::~CMainFrame()
{
if(m_pIAtlTest2)
{
//break the connection...donot receive any more events...
//将调用Unadvise()
AfxConnectionUnadvise(  m_pIAtlTest2, 
      DIID__IAtlTest2Events , 
      GetIDispatch(FALSE),  
      FALSE, 
      m_dwCookie );
m_pIAtlTest2.Release();//release the object...stops any threads internal to object...
m_pIAtlTest2 = NULL;
}
//unload com libraries...
CoUninitialize();
}
再在stadafx.h中加入 
#import "..\test2.tlb" no_namespace named_guids
然后就可以在其他地方调用m_pIAtlTest2的函数了 
(2) 用ATL实现事件接口 
    用ATL实现第一步想到的一样也是要找个类来实现事件接口,用IDispEventImpl这个类会很方便。可参阅AtlTestAtl2的代码(下载)。
a. 用MFC生成一个对话框程序。
b. 用New ATL Object添加对ATL的支持,但并不真的添加新的ATL对象。
c. 在stadafx.h中加入 
  #import "..\test2.tlb" raw_interfaces_only, no_namespace, named_guids
d. 添加一个从IDispEventImpl派生的新类。 
  #ifndef __EVENTSINK_H
  #define __EVENTSINK_H
  namespace
  {
static const int DISPID_SHOW = 1;
static const int DISPID_SHOW2 = 2;
_ATL_FUNC_INFO OnShowInfo =
{
CC_STDCALL, //calling conv...
VT_EMPTY, //return value...
0 , //number of arguments...
NULL //argumnent types...
};
_ATL_FUNC_INFO OnShow2Info =
{
CC_STDCALL, //calling conv...
VT_EMPTY, //return value...
1 , //number of arguments...
{VT_I2} //argumnent types...
};
  }
  class CEventSink : public IDispEventImpl<1, CEventSink, &DIID__IAtlTest2Events, &LIBID_TEST2Lib>
  {
  public:
CEventSink(){};
virtual ~CEventSink(){};
void __stdcall OnShow(); //没有参数的情况
void __stdcall OnShow2(short);//有参数的情况
//必须要用SINK_ENTRY_INFO,必须指定参数信息
BEGIN_SINK_MAP(CEventSink)
SINK_ENTRY_INFO(1,DIID__IAtlTest2Events,DISPID_SHOW,OnShow,&OnShowInfo)
SINK_ENTRY_INFO(1,DIID__IAtlTest2Events,DISPID_SHOW2,OnShow2,&OnShow2Info)
END_SINK_MAP()
  };
  #endif

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 高分请教:用MFC开发的非可视ActiveX控件,要在内部实现消息传递,如何实现???

相关文章

  • 2017-06-05 为何我的DLL参数用指针的形式传入传出都会发生错误?
  • 2017-06-05 ocx新开贴,再问
  • 2017-06-04 关于realplayDSP插件的问题
  • 2017-06-05 如何注册OCX进Office2007到插件->对象中
  • 2017-06-05 LINK问题,有谁能帮我看看?LNK2005和LNK4006
  • 2017-06-04 c#使用variant的问题,大家进来看看吧!!!
  • 2017-06-04 怎样得到控件在SCREEN上的准确位置?(ATL)
  • 2017-06-04 ActiveX和DirectX指的是什么?望不吝赐教!
  • 2017-06-04 简单问题:如何在VC程序中,将一个EXCEL文件打开,并插入一行?
  • 2017-06-05 如何在线程中控制鼠标形状?

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 为什么VC60下编译不过去密友高清源文件呢?
    • ATLcom的应用问题
    • 如何在MFC中传递一个VARIANT数组给vbscript函数
    • returnCComPtr<Ixxxxx>
    • 创建一个ActiveX控件,在控件里怎么使用ADO或者别的来连接数据库,并对数据库进行操作。
    • 如何编程实现对已经打开的WORD窗口的控制?
    • 哎呀!各位大哥!小弟在vc中作了mark,却不知如何去掉?
    • 各位大哥:ATL中怎么创建和显示Toolbar呀!
    • 知道进程id如何得到进程名
    • MFCActiveX在Release时报错未能注册输出,但是DEBUG下正常

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有