D语言调用ActiveX(在窗口中嵌入ActiveX)

这是一个从C移植到D的代码,原文请见“ Embed an HTML control in your own window using plain C”,它用C结构模拟了虚表,并且实现了多个接口以完成对Web Browser控件的调用。

在看完他的代码之后,我对于COM/OLE的了解加深了一些,以前使用VC做过COM方面的应用,也看过不少COM方面的书,不过没有涉及到界面,所以一直不知道如何把ActiveX嵌入到自己的项目中,我指的是纯手工实现,不依赖MFC/ATL。

既然是理解了,当然要把它作出来才算数,以日久又忘了。

另外要解释一下使用D语言的原因。实际上使用C++也可达到一样的效果,只是最近突然觉得使用C++很烦,而D语言又是一个很好的补充,又一直仰慕D语言作者的大名,再加上想检验D语言实际开发能力,所以这次就用它做刀了。

注:对C++觉得烦的一个重要原因,是在阅读很多优秀的C++库时,被那些宏搞得火冒三丈,难道代码非得这样写?现代的计算机语言只需要处理记号,而不是字符串,而宏却是字符串的典型,这也影响了C++程序的编译速度。或许D语言不能真正解决这个问题,但暂时还没看到令我特别不爽的东西,所以将就着用吧,反正还在Alpha阶段,也就是说语言本身也一直在改进,也一直有人在提一些改进意见,还是有些希望的。D语言作者作为优秀的Symantic C++编译器的作者,把C++的高效也带进D里面,所以我对D语言还是有很大期望的。

言规正传,先来看看要在自己在窗口里嵌入HTML control要做哪些事。简单罗列如下:
1、初始化OLE环境
2、创建一个窗口,作为ActiveX的宿主窗口
3、实现一个IStorage对象,实际上不用它来做任何事,只是OleCreate函数需要这样一个对象
4、实现IOleInPlaceSite, IOleInPlaceFrame, IOleClientSite, IDocHostUIHandler接口
5、其它就是调用了。。。
这里所列的项目没有明确的分类标准,大概同时讲了要实现的接口和代码处理过程,具体看代码吧。

由于D语言的标准库phobos没有列出我们所需要的大部分COM接口,所以需要core32,可以从 http://www.dsource.org/projects/core32/下载(或SVN)。这个也不是很完整,所以在程序里我还是要定义几个变量:

static   const  IID IID_IWebBrowser2  =  
    {
0xD30C1661 0xCDAF 0x11d0 , [ 0x8A 0x3E 0x0 0xC0 0x4F 0xC9 0xE2 0x6E ]};

static   const  CLSID CLSID_WebBrowser  =  
    {
0x8856F961 0x340A 0x11D0 , [ 0xA9 0x6B 0x0 0xC0 0x4F 0xD7 0x05 0xA2 ]};

static   const  IID IID_IDocHostUIHandler  =  
    {
0xbd3f23c0 0xd43e 0x11cf , [ 0x89 0x3b 0x0 0xaa 0x0 0xbd 0xce 0x1a ]};

下面是完整代码:

private  import std.stdio;
private  import std. string ;
private  import win32.ole2;
private  import win32.com.OAIDL;
private  import win32.com.OLEIDL;
private  import win32.com.EXDISP;
private  import win32.com.MSHTMHST;

char [] ClassName  =   " Test Wnd Class " ;

static   const  IID IID_IWebBrowser2  =  
    {
0xD30C1661 0xCDAF 0x11d0 , [ 0x8A 0x3E 0x0 0xC0 0x4F 0xC9 0xE2 0x6E ]};

static   const  CLSID CLSID_WebBrowser  =  
    {
0x8856F961 0x340A 0x11D0 , [ 0xA9 0x6B 0x0 0xC0 0x4F 0xD7 0x05 0xA2 ]};

static   const  IID IID_IDocHostUIHandler  =  
    {
0xbd3f23c0 0xd43e 0x11cf , [ 0x89 0x3b 0x0 0xaa 0x0 0xbd 0xce 0x1a ]};

extern  (C)  void  gc_init();
extern  (C)  void  gc_term();
extern  (C)  void  _minit();
extern  (C)  void  _moduleCtor();
extern  (C)  void  _moduleDtor();
extern  (C)  void  _moduleUnitTests();

extern  (Windows)
int  WinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    
int  nCmdShow)
{
    
int  result;

    gc_init();            
//  initialize garbage collector
    _minit();             //  initialize module constructor table

    
try
    {
    _moduleCtor();        
//  call module constructors
    _moduleUnitTests();     //  run unit tests (optional)

    result 
=  myWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);

    _moduleDtor();        
//  call module destructors
    }

    
catch  (Object o)         //  catch any uncaught exceptions
    {
    MessageBoxA(
null , cast( char   * )o.toString(),  " Error " ,
            MB_OK 
|  MB_ICONEXCLAMATION);
    result 
=   0 ;         //  failed
    }

    gc_term();            
//  run finalizers; terminate garbage collector
     return  result;
}

//  A running count of how many windows we have open that contain a browser object
uint  WindowCount  =   0 ;


//  This is used by DisplayHTMLStr(). It can be global because we never change it.
static   const  SAFEARRAYBOUND ArrayBound  =  { 1 0 };

IOleObject g_browserObject 
=   null ;


class  MyStorage : IStorage
{
    
this  ()
    
in  {writefln ( " In MyStorage.this " );}
    
out  {writefln ( " Out MyStorage.this " );}
    body{
    }
    
    
~ this ()
    
in  {writefln ( " In MyStorage.~this " );}
    
out  {writefln ( " Out MyStorage.~this " );}
    body{
    }
    
    HRESULT QueryInterface(IID
*  riid,  void **  pvObject) 
    
in  {writefln ( " In MyStorage.QueryInterface " );}
    
out  {writefln ( " Out MyStorage.QueryInterface " );}
    body{
        
return  E_NOTIMPL;
    }
    ULONG AddRef () 
    
in  {writefln ( " In MyStorage.AddRef " );}
    
out  {writefln ( " Out MyStorage.AddRef " );}
    body {
        
return   1 ;
    }
    ULONG Release () 
    
in  {writefln ( " In MyStorage.Release " );}
    
out  {writefln ( " Out MyStorage.Release " );}
    body {
        
return   1 ;
    }
    HRESULT CreateStream( OLECHAR 
* pwcsName, DWORD grfMode, DWORD reserved1, DWORD reserved2, IStream  *  ppstm) 
    
in  {writefln ( " In MyStorage.CreateStream " );}
    
out  {writefln ( " Out MyStorage.CreateStream " );}
    body {
        
return  E_NOTIMPL;
    }
    HRESULT OpenStream( OLECHAR 
* pwcsName,  void   * reserved1, DWORD grfMode, DWORD reserved2, IStream  *  ppstm) 
    
in  {writefln ( " In MyStorage.OpenStream " );}
    
out  {writefln ( " Out MyStorage.OpenStream " );}
    body {
        
return  E_NOTIMPL;
    }
    HRESULT CreateStorage( OLECHAR 
* pwcsName, DWORD grfMode, DWORD reserved1, DWORD reserved2, IStorage  *  ppstg) 
    
in  {writefln ( " In MyStorage.CreateStorage " );}
    
out  {writefln ( " Out MyStorage.CreateStorage " );}
    body {
        
return  E_NOTIMPL;
    }
    HRESULT OpenStorage( OLECHAR 
* pwcsName, IStorage pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage  *  ppstg ) 
    
in  {writefln ( " In MyStorage.OpenStorage " );}
    
out  {writefln ( " Out MyStorage.OpenStorage " );}
    body {
        
return  E_NOTIMPL;
    }
    HRESULT CopyTo( DWORD ciidExclude, IID 
* rgiidExclude, SNB snbExclude, IStorage pstgDest ) 
    
in  {writefln ( " In MyStorage.CopyTo " );}
    
out  {writefln ( " Out MyStorage.CopyTo " );}
    body {
        
return  E_NOTIMPL;
    }
    HRESULT MoveElementTo( OLECHAR 
*  pwcsName, IStorage pstgDest, OLECHAR  * pwcsNewName, DWORD grfFlags ) 
    
in  {writefln ( " In MyStorage.MoveElementTo " );}
    
out  {writefln ( " Out MyStorage.MoveElementTo " );}
    body {
        
return  E_NOTIMPL;
    }
    HRESULT Commit( DWORD grfCommitFlags ) 
    
in  {writefln ( " In MyStorage.Commit " );}
    
out  {writefln ( " Out MyStorage.Commit " );}
    body {
        
return  E_NOTIMPL;
    }
    HRESULT Revert() 
    
in  {writefln ( " In MyStorage.Revert " );}
    
out  {writefln ( " Out MyStorage.Revert " );}
    body {
        
return  E_NOTIMPL;
    }
    HRESULT EnumElements( DWORD reserved1, 
void   * reserved2, DWORD reserved3, IEnumSTATSTG  *  ppenum) 
    
in  {writefln ( " In MyStorage.EnumElements " );}
    
out  {writefln ( " Out MyStorage.EnumElements " );}
    body {
        
return  E_NOTIMPL;
    }
    HRESULT DestroyElement( OLECHAR 
*  pwcsName ) 
    
in  {writefln ( " In MyStorage.DestroyElement " );}
    
out  {writefln ( " Out MyStorage.DestroyElement " );}
    body {
        
return  E_NOTIMPL;
    }
    HRESULT RenameElement( OLECHAR 
* pwcsOldName, OLECHAR  * pwcsNewName ) 
    
in  {writefln ( " In MyStorage.RenameElement " );}
    
out  {writefln ( " Out MyStorage.RenameElement " );}
    body {
        
return  E_NOTIMPL;
    }
    HRESULT SetElementTimes( OLECHAR 
*  pwcsName, FILETIME  *  pctime, FILETIME  * patime, FILETIME  * pmtime ) 
    
in  {writefln ( " In MyStorage.SetElementTimes " );}
    
out  {writefln ( " Out MyStorage.SetElementTimes " );}
    body {
        
return  E_NOTIMPL;
    }
    HRESULT SetClass( REFCLSID clsid ) 
    
in  {writefln ( " In MyStorage.SetClass " );}
    
out  {writefln ( " Out MyStorage.SetClass " );}
    body {
        
return  S_OK;
    }
    HRESULT SetStateBits( DWORD grfStateBits, DWORD grfMask ) 
    
in  {writefln ( " In MyStorage.SetStateBits " );}
    
out  {writefln ( " Out MyStorage.SetStateBits " );}
    body {
        
return  E_NOTIMPL;
    }
    HRESULT Stat( STATSTG 
* pstatstg, DWORD grfStatFlag ) 
    
in  {writefln ( " In MyStorage.Stat " );}
    
out  {writefln ( " Out MyStorage.Stat " );}
    body {
        
return  E_NOTIMPL;
    }


bool  compare(IID *  iid1, IID *  iid2)
{
    
return   ! memcmp(iid1, iid2, IID. sizeof );
}

class  OleInPlaceSite : IOleInPlaceSite, IOleInPlaceFrame, IOleClientSite, IDocHostUIHandler
{
    
private :
    HWND hWnd;    
public :
    
this  (HWND hwnd) 
    
in  {writefln ( " In OleInPlaceSite.this " );}
    
out  {writefln ( " Out OleInPlaceSite.this " );}
    body {
        
this .hWnd  =  hwnd;
    }
    
~ this  () 
    
in  {writefln ( " In OleInPlaceSite.~this " );}
    
out  {writefln ( " Out OleInPlaceSite.~this " );}
    body {
    }
protected :
    ULONG AddRef () 
    
in  {writefln ( " In OleInPlaceSite.AddRef " );}
    
out  {writefln ( " Out OleInPlaceSite.AddRef " );}
    body {
        
return   1 ;
    }
    ULONG Release () 
    
in  {writefln ( " In OleInPlaceSite.Release " );}
    
out  {writefln ( " Out OleInPlaceSite.Release " );}
    body {
        
return   1 ;
    }
    HRESULT QueryInterface (IID
*  riid,  void   **  ppvObject) 
    
in  {writefln ( " In OleInPlaceSite.QueryInterface " );}
    
out  {writefln ( " Out OleInPlaceSite.QueryInterface " );}
    body {
        
if  (compare(riid,  & IID_IUnknown))
            
* ppvObject  =  cast(IUnknown) this ;
        
else   if  (compare(riid,  & IID_IOleClientSite))
            
* ppvObject  =  cast(IOleClientSite) this ;
        
else   if  (compare(riid,  & IID_IOleInPlaceSite))
        {
            writefln (
" Ole In Place Site " );
            
* ppvObject  =  cast(IOleInPlaceSite) this ;
            }
        
// else if (compare(riid, &IID_IOleInPlaceFrame))
        
//     *ppvObject = cast(IOleInPlaceFrame)this;
         else   if  (compare(riid,  & IID_IDocHostUIHandler))
            
* ppvObject  =  cast(IDocHostUIHandler) this ;
        
else
            
return  E_NOINTERFACE;

        
return  S_OK;
    }

    
//  IOleInPlaceFrame
    HRESULT InsertMenus( HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths ) 
    
in  {writefln ( " In OleInPlaceSite.InsertMenus " );}
    
out  {writefln ( " Out OleInPlaceSite.InsertMenus " );}
    body{
        
return  E_NOTIMPL;
    }
    HRESULT SetMenu( HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject ) 
    
in  {writefln ( " In OleInPlaceSite.SetMenu " );}
    
out  {writefln ( " Out OleInPlaceSite.SetMenu " );}
    body{
        
return  S_OK;
    }
    HRESULT RemoveMenus( HMENU hmenuShared ) 
    
in  {writefln ( " In OleInPlaceSite.RemoveMenus " );}
    
out  {writefln ( " Out OleInPlaceSite.RemoveMenus " );}
    body{
        
return  E_NOTIMPL;
    }
    HRESULT SetStatusText( LPCOLESTR pszStatusText ) 
    
in  {writefln ( " In OleInPlaceSite.SetStatusText " );}
    
out  {writefln ( " Out OleInPlaceSite.SetStatusText " );}
    body{
        
return  S_OK;
    }

    HRESULT TranslateAccelerator( LPMSG lpmsg, WORD wID ) 
    
in  {writefln ( " In OleInPlaceSite.TranslateAccelerator " );}
    
out  {writefln ( " Out OleInPlaceSite.TranslateAccelerator " );}
    body{
        
return  E_NOTIMPL;
    }

    
//  IOleInPlaceUIWindow
    HRESULT GetBorder( LPRECT lprectBorder ) 
    
in  {writefln ( " In OleInPlaceSite.GetBorder " );}
    
out  {writefln ( " Out OleInPlaceSite.GetBorder " );}
    body{
        
return  E_NOTIMPL;
    }
    HRESULT RequestBorderSpace( LPCBORDERWIDTHS pborderwidths ) 
    
in  {writefln ( " In OleInPlaceSite.RequestBorderSpace " );}
    
out  {writefln ( " Out OleInPlaceSite.RequestBorderSpace " );}
    body{
        
return  E_NOTIMPL;
    }
    HRESULT SetBorderSpace( LPCBORDERWIDTHS pborderwidths ) 
    
in  {writefln ( " In OleInPlaceSite.SetBorderSpace " );}
    
out  {writefln ( " Out OleInPlaceSite.SetBorderSpace " );}
    body{
        
return  E_NOTIMPL;
    }
    HRESULT SetActiveObject( IOleInPlaceActiveObject pActiveObject, LPCOLESTR pszObjName ) 
    
in
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值