WEB开发网
开发学院软件开发汇编语言 Win32编程点滴 - 简单ActiveX控件的使用 阅读

Win32编程点滴 - 简单ActiveX控件的使用

 2010-01-10 09:37:18 来源:WEB开发网   
核心提示:虽然这里一片的.net气氛,到处充斥着像MVC、WPF、WorkFlow、LINQ等各种niubility的术语,Win32编程点滴 - 简单ActiveX控件的使用,但我们使用的Windows还是由COM技术主宰着;我们在选择日常使用的软件时,也会避免使用.net开发的软件,代码如下(这里的代码去除了 出错的处理):

虽然这里一片的.net气氛,到处充斥着像MVC、WPF、WorkFlow、LINQ等各种niubility的术语。但我们使用的Windows还是由COM技术主宰着;我们在选择日常使用的软件时,也会避免使用.net开发的软件。即便是.net的桌面程序,也会经常使用ActiveX控件。这篇文章就让我们用最原始的方式来使用ActiveX,不使用任何MFC,ATL等框架,也不使用编译器提供的#import之类的指令,也不使用任何ide提供的向导。

像OLE、ActiveX等COM的术语,即便是微软也说不清它们的关系,所以下面说的我也这样模棱两可下去,只要明白意思即可。

首先,要了解一下的是ActiveX技术是为了做“嵌 入”这样的功能而诞生的,比如:在Word中插入一张Bitmap图片,双击此图片,Word会调用画笔程序的功能来编辑图片,整个Word的菜单栏也会变成画笔程序的菜单栏。所以,ActiveX控件相当的复杂,有着几十个相关的接口。简单的说来,ActiveX控件的父窗口被称为“容器”,所以作为 ActiveX控件的使用者来说,要实现的接口基本上都是IOleXXXXContainer或IOleXXXXSite之类的;而 ActiveX则实现了IOleXXXXObject等接口。在这些接口中,大多有“InPlace”这个术语,指 的是“InPlace edit”,也就是Word通过双击图片调用画笔编辑图片就称为“InPlace edit”(仅仅了解一下,和这篇文章说的使用AcitveX控件无关)。

在这样一篇文章中,我并不想讲很多COM或者AcitveX的知识,只是讲使用ActiveX所必须涉及的接口,然后你就可以去查MSDN中 的其他一些可选的接口来一步步对这个ActiveX加强控制。

作为一个最简单的程序,我们需要实现的接口有:IOleClientSite和IOleInPlaceSite。使用到的AcitveX提供的接口有:IOleObject和 IOleInPlaceObject。创建ActiveX控件的步骤:

创建一个类,实现IOleClientSite和IOleInPlaceSite。

使用CoCreateInstance创建相应 ActiveX控件的实例,并获取它的IOleObject接口指针。

调用IOleObject::SetClientSite传入第 一步中的类的指针。

调用IOleObject::DoVerb完成ActiveX控件的创建。

之后,可以调用 ActiveX控件的IOleInPlaceObject::SetObjectRects调整控件的大小和位置。

根据以上步骤,创 建如下函数:

HRESULT CreateAxControl(HWND hWnd,const wchar_t *  ProgId,IUnknown ** ppControlUnknown,IUnknown ** ppContainerUnknown);

第一 个参数hWnd是父窗口句柄。ProgId是ActiveX控件的ProgId,因为我们不使用编译器的#import,一般不 知道所要创建控件的CLSID。ppControlUnknown是用来返回ActiveX控件的IUnknown指针。 ppContainerUnknown是用来返回用来代表父窗口的IUnknown指针。

代码如下(这里的代码去除了 出错的处理):

HRESULT CreateAxControl(HWND hWnd,const wchar_t *  ProgId,IUnknown ** ppControlUnknown,IUnknown ** ppContainerUnknown)
{
   HRESULT hr;
  CLSID cls;
  IOleObject * pObject = NULL;
   CControlContainer * pContainer = NULL;
  //通过ProgId得到CLSID 
   CLSIDFromProgID(ProgId,&cls);

  //创建ActiveX控件的对象,顺便得到 IOleObject指针
  CoCreateInstance (cls,NULL,CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER|CLSCTX_LOCAL_SERVER,
     IID_IOleObject,(void**)&pObject);

  //CControlContainer是实现了 IOleClientSite和IOleInPlaceSite接口的类 
  pContainer = new CControlContainer (hWnd);

  //调用IOleObject::SetClientSite,传入容器指针
  pObject- >SetClientSite(pContainer);

  //调用IOleObject::DoVerb,显示控件
   pObject->DoVerb(OLEIVERB_SHOW,0,pContainer,0,hWnd,0);

  //一些返回的参数
  pObject->QueryInterface(IID_IUnknown,(void**)ppControlUnknown);
   pContainer->QueryInterface(IID_IUnknown,(void**)ppContainerUnknown);

  if  (pObject) pObject->Release();
  if (pContainer) pContainer->Release();
  return S_OK;
}

1 2 3  下一页

Tags:Win 编程 点滴

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接