`
qiezi
  • 浏览: 492908 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

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

    博客分类:
  • D
阅读更多
这是一个从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 = 
    {
0xD30C16610xCDAF0x11d0, [0x8A0x3E0x00xC00x4F0xC90xE20x6E]};

static const CLSID CLSID_WebBrowser = 
    {
0x8856F9610x340A0x11D0, [0xA90x6B0x00xC00x4F0xD70x050xA2]};

static const IID IID_IDocHostUIHandler = 
    {
0xbd3f23c00xd43e0x11cf, [0x890x3b0x00xaa0x00xbd0xce0x1a]};

下面是完整代码:

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 = 
    {
0xD30C16610xCDAF0x11d0, [0x8A0x3E0x00xC00x4F0xC90xE20x6E]};

static const CLSID CLSID_WebBrowser = 
    {
0x8856F9610x340A0x11D0, [0xA90x6B0x00xC00x4F0xD70x050xA2]};

static const IID IID_IDocHostUIHandler = 
    {
0xbd3f23c00xd43e0x11cf, [0x890x3b0x00xaa0x00xbd0xce0x1a]};

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 = {10};

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
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics