qiezi的学习园地

AS/C/C++/D/Java/JS/Python/Ruby

  C++博客 :: 首页 :: 新随笔 ::  ::  :: 管理 ::
这是一个从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 {writefln ("In OleInPlaceSite.SetActiveObject");}
    
out {writefln ("Out OleInPlaceSite.SetActiveObject");}
    body{
        
return S_OK;
    }
    
    
// IOleWindow
    HRESULT GetWindow( HWND * phwnd ) 
    
in {writefln ("In OleInPlaceSite.GetWindow");}
    
out {writefln ("Out OleInPlaceSite.GetWindow");}
    body{
        
*phwnd = hWnd;
        
return S_OK;
    }
    HRESULT ContextSensitiveHelp( BOOL fEnterMode ) 
    
in {writefln ("In OleInPlaceSite.ContextSensitiveHelp");}
    
out {writefln ("Out OleInPlaceSite.ContextSensitiveHelp");}
    body{
        
return E_NOTIMPL;
    }
    
    
// IOleInPlaceFrame
    HRESULT CanInPlaceActivate() 
    
in {writefln ("In OleInPlaceSite.CanInPlaceActivate");}
    
out {writefln ("Out OleInPlaceSite.CanInPlaceActivate");}
    body{
        
return S_OK;
    }
    HRESULT OnInPlaceActivate() 
    
in {writefln ("In OleInPlaceSite.OnInPlaceActivate");}
    
out {writefln ("Out OleInPlaceSite.OnInPlaceActivate");}
    body{
        
return S_OK;
    }
    HRESULT OnUIActivate() 
    
in {writefln ("In OleInPlaceSite.OnUIActivate");}
    
out {writefln ("Out OleInPlaceSite.OnUIActivate");}
    body{
        
return S_OK;
    }
    HRESULT GetWindowContext( IOleInPlaceFrame 
* ppFrame, IOleInPlaceUIWindow * ppDoc, LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo ) 
    
in {writefln ("In OleInPlaceSite.GetWindowContext");}
    
out {writefln ("Out OleInPlaceSite.GetWindowContext");}
    body{

        
*ppFrame = cast(IOleInPlaceFrame)this;
    
        
*ppDoc = null;
    
        
// Fill in some other info for the browser
        lpFrameInfo.cb = lpFrameInfo.sizeof;
        lpFrameInfo.fMDIApp 
= FALSE;
        lpFrameInfo.hwndFrame 
= hWnd;
        lpFrameInfo.haccel 
= null;
        lpFrameInfo.cAccelEntries 
= 0;
    
        
return S_OK;
    }
    HRESULT Scroll( SIZE scrollExtant ) 
    
in {writefln ("In OleInPlaceSite.Scroll");}
    
out {writefln ("Out OleInPlaceSite.Scroll");}
    body{
        
return E_NOTIMPL;
    }
    HRESULT OnUIDeactivate( BOOL fUndoable ) 
    
in {writefln ("In OleInPlaceSite.OnUIDeactivate");}
    
out {writefln ("Out OleInPlaceSite.OnUIDeactivate");}
    body{
        
return S_OK;
    }
    HRESULT OnInPlaceDeactivate() 
    
in {writefln ("In OleInPlaceSite.OnInPlaceDeactivate");}
    
out {writefln ("Out OleInPlaceSite.OnInPlaceDeactivate");}
    body{
        
return S_OK;
    }
    HRESULT DiscardUndoState() 
    
in {writefln ("In OleInPlaceSite.DiscardUndoState");}
    
out {writefln ("Out OleInPlaceSite.DiscardUndoState");}
    body{
        
return E_NOTIMPL;
    }
    HRESULT DeactivateAndUndo() 
    
in {writefln ("In OleInPlaceSite.DeactivateAndUndo");}
    
out {writefln ("Out OleInPlaceSite.DeactivateAndUndo");}
    body{
        
return E_NOTIMPL;
    }
    HRESULT OnPosRectChange( LPCRECT lprcPosRect ) 
    
in {writefln ("In OleInPlaceSite.OnPosRectChange");}
    
out {writefln ("Out OleInPlaceSite.OnPosRectChange");}
    body{
        IOleInPlaceObject    inplace;

        
if (!g_browserObject.QueryInterface(&IID_IOleInPlaceObject, cast(void**)&inplace))
        {
            
// Give the browser the dimensions of where it can draw.
            inplace.SetObjectRects(lprcPosRect, lprcPosRect);
            inplace.Release();
        }

        
return S_OK;
    }

    
// IDocHostUIHandler
    HRESULT ShowContextMenu( DWORD dwID, POINT* ppt, IUnknown pcmdtReserved, IDispatch pdispReserved) 
    
in {writefln ("In OleInPlaceSite.ShowContextMenu");}
    
out {writefln ("Out OleInPlaceSite.ShowContextMenu");}
    body {
        
return S_OK;
    }
    HRESULT GetHostInfo( DOCHOSTUIINFO 
* pInfo ) 
    
in {writefln ("In OleInPlaceSite.GetHostInfo");}
    
out {writefln ("Out OleInPlaceSite.GetHostInfo");}
    body {
        pInfo.cbSize 
= DOCHOSTUIINFO.sizeof;
        pInfo.dwFlags 
= DOCHOSTUIFLAG_NO3DBORDER;
        pInfo.dwDoubleClick 
= DOCHOSTUIDBLCLK_DEFAULT;
    
        
return(S_OK);
    }
    HRESULT ShowUI( DWORD dwID, IOleInPlaceActiveObject pActiveObject, IOleCommandTarget pCommandTarget, IOleInPlaceFrame pFrame, IOleInPlaceUIWindow pDoc ) 
    
in {writefln ("In OleInPlaceSite.ShowUI");}
    
out {writefln ("Out OleInPlaceSite.ShowUI");}
    body {
        
return S_OK;
    }
    HRESULT HideUI() 
    
in {writefln ("In OleInPlaceSite.HideUI");}
    
out {writefln ("Out OleInPlaceSite.HideUI");}
    body{
        
return S_OK;
    }
    HRESULT UpdateUI() 
    
in {writefln ("In OleInPlaceSite.UpdateUI");}
    
out {writefln ("Out OleInPlaceSite.UpdateUI");}
    body{
        
return S_OK;
    }
    HRESULT EnableModeless( BOOL fEnable ) 
    
in {writefln ("In OleInPlaceSite.EnableModeless");}
    
out {writefln ("Out OleInPlaceSite.EnableModeless");}
    body{
        
return S_OK;
    }
    HRESULT OnDocWindowActivate( BOOL fActivate ) 
    
in {writefln ("In OleInPlaceSite.OnDocWindowActivate");}
    
out {writefln ("Out OleInPlaceSite.OnDocWindowActivate");}
    body{
        
return S_OK;
    }
    HRESULT OnFrameWindowActivate( BOOL fActivate ) 
    
in {writefln ("In OleInPlaceSite.OnFrameWindowActivate");}
    
out {writefln ("Out OleInPlaceSite.OnFrameWindowActivate");}
    body{
        
return S_OK;
    }
    HRESULT ResizeBorder( LPCRECT prcBorder, IOleInPlaceUIWindow pUIWindow, BOOL fRameWindow ) 
    
in {writefln ("In OleInPlaceSite.ResizeBorder");}
    
out {writefln ("Out OleInPlaceSite.ResizeBorder");}
    body{
        
return S_OK;
    }
    HRESULT TranslateAccelerator( LPMSG lpMsg, GUID 
* pguidCmdGroup, DWORD nCmdID ) 
    
in {writefln ("In OleInPlaceSite.TranslateAccelerator");}
    
out {writefln ("Out OleInPlaceSite.TranslateAccelerator");}
    body{
        
return S_FALSE;
    }
    HRESULT GetOptionKeyPath( LPOLESTR 
* pchKey, DWORD dw ) 
    
in {writefln ("In OleInPlaceSite.GetOptionKeyPath");}
    
out {writefln ("Out OleInPlaceSite.GetOptionKeyPath");}
    body{
        
return S_FALSE;
    }
    HRESULT GetDropTarget( IDropTarget pDropTarget, IDropTarget 
* ppDropTarget ) 
    
in {writefln ("In OleInPlaceSite.GetDropTarget");}
    
out {writefln ("Out OleInPlaceSite.GetDropTarget");}
    body{
        
return S_FALSE;
    }
    HRESULT GetExternal( IDispatch 
* ppDispatch ) 
    
in {writefln ("In OleInPlaceSite.GetExternal");}
    
out {writefln ("Out OleInPlaceSite.GetExternal");}
    body{
        
*ppDispatch = null;
        
return S_FALSE;
    }
    HRESULT TranslateUrl( DWORD dwTranslate, OLECHAR 
* pchURLIn, OLECHAR ** ppchURLOut ) 
    
in {writefln ("In OleInPlaceSite.TranslateUrl");}
    
out {writefln ("Out OleInPlaceSite.TranslateUrl");}
    body{
        
*ppchURLOut = null;
        
return S_FALSE;
    }
    HRESULT FilterDataObject( IDataObject pDO, IDataObject 
* ppDORet ) 
    
in {writefln ("In OleInPlaceSite.FilterDataObject");}
    
out {writefln ("Out OleInPlaceSite.FilterDataObject");}
    body{
        
*ppDORet = null;
        
return S_FALSE;
    }
    
    
// IStorage
    HRESULT CreateStream( OLECHAR *pwcsName, DWORD grfMode, DWORD reserved1, DWORD reserved2, IStream * ppstm) 
    
in {writefln ("In OleInPlaceSite.CreateStream");}
    
out {writefln ("Out OleInPlaceSite.CreateStream");}
    body{
        
return E_NOTIMPL;
    }
    HRESULT OpenStream( OLECHAR 
*pwcsName, void *reserved1, DWORD grfMode, DWORD reserved2, IStream * ppstm) 
    
in {writefln ("In OleInPlaceSite.OpenStream");}
    
out {writefln ("Out OleInPlaceSite.OpenStream");}
    body{
        
return E_NOTIMPL;
    }
    HRESULT CreateStorage( OLECHAR 
*pwcsName, DWORD grfMode, DWORD reserved1, DWORD reserved2, IStorage * ppstg) 
    
in {writefln ("In OleInPlaceSite.CreateStorage");}
    
out {writefln ("Out OleInPlaceSite.CreateStorage");}
    body{
        
return E_NOTIMPL;
    }
    HRESULT OpenStorage( OLECHAR 
*pwcsName, IStorage pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage * ppstg ) 
    
in {writefln ("In OleInPlaceSite.OpenStorage");}
    
out {writefln ("Out OleInPlaceSite.OpenStorage");}
    body{
        
return E_NOTIMPL;
    }
    HRESULT CopyTo( DWORD ciidExclude, IID 
*rgiidExclude, SNB snbExclude, IStorage pstgDest ) 
    
in {writefln ("In OleInPlaceSite.CopyTo");}
    
out {writefln ("Out OleInPlaceSite.CopyTo");}
    body{
        
return E_NOTIMPL;
    }
    HRESULT MoveElementTo( OLECHAR 
* pwcsName, IStorage pstgDest, OLECHAR *pwcsNewName, DWORD grfFlags ) 
    
in {writefln ("In OleInPlaceSite.MoveElementTo");}
    
out {writefln ("Out OleInPlaceSite.MoveElementTo");}
    body{
        
return E_NOTIMPL;
    }
    HRESULT Commit( DWORD grfCommitFlags ) 
    
in {writefln ("In OleInPlaceSite.Commit");}
    
out {writefln ("Out OleInPlaceSite.Commit");}
    body{
        
return E_NOTIMPL;
    }
    HRESULT Revert() 
    
in {writefln ("In OleInPlaceSite.Revert");}
    
out {writefln ("Out OleInPlaceSite.Revert");}
    body{
        
return E_NOTIMPL;
    }
    HRESULT EnumElements( DWORD reserved1, 
void *reserved2, DWORD reserved3, IEnumSTATSTG * ppenum) 
    
in {writefln ("In OleInPlaceSite.EnumElements");}
    
out {writefln ("Out OleInPlaceSite.EnumElements");}
    body{
        
return E_NOTIMPL;
    }
    HRESULT DestroyElement( OLECHAR 
* pwcsName ) 
    
in {writefln ("In OleInPlaceSite.DestroyElement");}
    
out {writefln ("Out OleInPlaceSite.DestroyElement");}
    body{
        
return E_NOTIMPL;
    }
    HRESULT RenameElement( OLECHAR 
*pwcsOldName, OLECHAR *pwcsNewName ) 
    
in {writefln ("In OleInPlaceSite.RenameElement");}
    
out {writefln ("Out OleInPlaceSite.RenameElement");}
    body{
        
return E_NOTIMPL;
    }
    HRESULT SetElementTimes( OLECHAR 
* pwcsName, FILETIME * pctime, FILETIME *patime, FILETIME *pmtime ) 
    
in {writefln ("In OleInPlaceSite.SetElementTimes");}
    
out {writefln ("Out OleInPlaceSite.SetElementTimes");}
    body{
        
return E_NOTIMPL;
    }
    HRESULT SetClass( REFCLSID clsid ) 
    
in {writefln ("In OleInPlaceSite.SetClass");}
    
out {writefln ("Out OleInPlaceSite.SetClass");}
    body{
        
return S_OK;
    }
    HRESULT SetStateBits( DWORD grfStateBits, DWORD grfMask ) 
    
in {writefln ("In OleInPlaceSite.SetStateBits");}
    
out {writefln ("Out OleInPlaceSite.SetStateBits");}
    body{
        
return E_NOTIMPL;
    }
    HRESULT Stat( STATSTG 
*pstatstg, DWORD grfStatFlag ) 
    
in {writefln ("In OleInPlaceSite.Stat");}
    
out {writefln ("Out OleInPlaceSite.Stat");}
    body{
        
return E_NOTIMPL;
    }

    
// IOleClientSite
    HRESULT SaveObject() 
    
in {writefln ("In OleInPlaceSite.SaveObject");}
    
out {writefln ("Out OleInPlaceSite.SaveObject");}
    body{
        
return E_NOTIMPL;
    }
    HRESULT GetMoniker( DWORD dwAssign, DWORD dwWhichMoniker, IMoniker 
* ppmk ) 
    
in {writefln ("In OleInPlaceSite.GetMoniker");}
    
out {writefln ("Out OleInPlaceSite.GetMoniker");}
    body{
        
return E_NOTIMPL;
    }
    HRESULT GetContainer( IOleContainer 
* ppContainer ) 
    
in {writefln ("In OleInPlaceSite.GetContainer");}
    
out {writefln ("Out OleInPlaceSite.GetContainer");}
    body{
        
*ppContainer = null;
        
return E_NOINTERFACE;
    }
    HRESULT ShowObject() 
    
in {writefln ("In OleInPlaceSite.ShowObject");}
    
out {writefln ("Out OleInPlaceSite.ShowObject");}
    body{
        
return S_OK;
    }
    HRESULT OnShowWindow( BOOL fShow ) 
    
in {writefln ("In OleInPlaceSite.OnShowWindow");}
    
out {writefln ("Out OleInPlaceSite.OnShowWindow");}
    body{
        
return E_NOTIMPL;
    }
    HRESULT RequestNewObjectLayout() 
    
in {writefln ("In OleInPlaceSite.RequestNewObjectLayout");}
    
out {writefln ("Out OleInPlaceSite.RequestNewObjectLayout");}
    body{
        
return E_NOTIMPL;
    }






/*************************** UnEmbedBrowserObject() ************************
 * Called to detach the browser object from our host window, and free its
 * resources, right before we destroy our window.
 *
 * hwnd =        Handle to the window hosting the browser object.
 *
 * NOTE: The pointer to the browser object must have been stored in the
 * window's USERDATA field. In other words, don't call UnEmbedBrowserObject().
 * with a HWND that wasn't successfully passed to EmbedBrowserObject().
 
*/

void UnEmbedBrowserObject(HWND hwnd)
{
    
// Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when
    
// we initially attached the browser object to this window.
    if (g_browserObject != null)
    {
        
// Unembed the browser object, and release its resources.
        g_browserObject.Close(OLECLOSE.OLECLOSE_NOSAVE);
        g_browserObject.Release();

        
return;
    }
    assert (
false);
}


enum {
    WEBPAGE_GOBACK,
    WEBPAGE_GOFORWARD,
    WEBPAGE_GOHOME,
    WEBPAGE_SEARCH,
    WEBPAGE_REFRESH,
    WEBPAGE_STOP
}

/******************************* DoPageAction() **************************
 * Implements the functionality of a "Back". "Forward", "Home", "Search",
 * "Refresh", or "Stop" button.
 *
 * hwnd =        Handle to the window hosting the browser object.
 * action =        One of the following:
 *                0 = Move back to the previously viewed web page.
 *                1 = Move forward to the previously viewed web page.
 *                2 = Move to the home page.
 *                3 = Search.
 *                4 = Refresh the page.
 *                5 = Stop the currently loading page.
 *
 * NOTE: EmbedBrowserObject() must have been successfully called once with the
 * specified window, prior to calling this function. You need call
 * EmbedBrowserObject() once only, and then you can make multiple calls to
 * this function to display numerous pages in the specified window.
 
*/



void DoPageAction(HWND hwnd, DWORD action)
{    
    IWebBrowser2    webBrowser2;

    
// We want to get the base address (ie, a pointer) to the IWebBrowser2 object embedded within the browser
    
// object, so we can call some of the functions in the former's table.
    if (!g_browserObject.QueryInterface(&IID_IWebBrowser2, cast(void**)&webBrowser2))
    {
        
// Ok, now the pointer to our IWebBrowser2 object is in 'webBrowser2', and so its VTable is
        
// webBrowser2->lpVtbl.

        
// Call the desired function
        switch (action)
        {
            
case WEBPAGE_GOBACK:
            {
                
// Call the IWebBrowser2 object's GoBack function.
                webBrowser2.GoBack();
                
break;
            }

            
case WEBPAGE_GOFORWARD:
            {
                
// Call the IWebBrowser2 object's GoForward function.
                webBrowser2.GoForward();
                
break;
            }

            
case WEBPAGE_GOHOME:
            {
                
// Call the IWebBrowser2 object's GoHome function.
                webBrowser2.GoHome();
                
break;
            }

            
case WEBPAGE_SEARCH:
            {
                
// Call the IWebBrowser2 object's GoSearch function.
                webBrowser2.GoSearch();
                
break;
            }

            
case WEBPAGE_REFRESH:
            {
                
// Call the IWebBrowser2 object's Refresh function.
                webBrowser2.Refresh();
            }

            
case WEBPAGE_STOP:
            {
                
// Call the IWebBrowser2 object's Stop function.
                webBrowser2.Stop();
            }
        }

        
// Release the IWebBrowser2 object.
        webBrowser2.Release();
    }
}

long DisplayHTMLPage(HWND hwnd, wchar[] webPageName)
{
    IWebBrowser2    webBrowser2;
    VARIANT            myURL;

    
if (!g_browserObject.QueryInterface(&IID_IWebBrowser2, cast(void**)&webBrowser2))
    {
        myURL.n1.n2.vt 
= VT_BSTR;

        myURL.n1.n2.n3.bstrVal 
= webPageName;

        
if (!myURL.n1.n2.n3.bstrVal)
        {
            webBrowser2.Release();
            
return(-6);
        }

        webBrowser2.Navigate2(
&myURL, nullnullnullnull);

        webBrowser2.Release();
        writefln (
"display html page success");
        
return(0);
    }
    writefln (
"display html page failed");
    
return(-5);
}

void ResizeBrowser(HWND hwnd, DWORD width, DWORD height)
{
    IWebBrowser2    webBrowser2;

    
if (!g_browserObject.QueryInterface(&IID_IWebBrowser2, cast(void**)&webBrowser2))
    {
        webBrowser2.Put_Width(width);
        webBrowser2.Put_Height(height);

        webBrowser2.Release();
    }
}

long EmbedBrowserObject(HWND hwnd)
{
    IWebBrowser2        webBrowser2;
    RECT                rect;
    IStorage            storage 
= new MyStorage;
    IOleClientSite         _iOleClientSite 
= new OleInPlaceSite(hwnd);

    
if (!OleCreate(cast(REFCLSID)&CLSID_WebBrowser, cast(REFIID)&IID_IOleObject, OLERENDER.OLERENDER_DRAW, 
                    
null, _iOleClientSite, storage, cast(void**)&g_browserObject))
    {
        writefln(
"create ole object success");
        g_browserObject.SetHostNames(
"My Host Name"w, null);

        GetClientRect(hwnd, 
&rect);

        
// Let browser object know that it is embedded in an OLE container.
        if (!OleSetContainedObject(g_browserObject, TRUE))
        {
           writefln(
"set contained object success");
            
if(!g_browserObject.DoVerb(OLEIVERB_SHOW, null, _iOleClientSite, -1, hwnd, &rect))
            {
                writefln(
"do verb success");
                
if(!g_browserObject.QueryInterface(&IID_IWebBrowser2, cast(void**)&webBrowser2))
                {
                    writefln(
"query IID_IWebBrowser2 interface success");
                    webBrowser2.Put_Left(
0);
                    webBrowser2.Put_Top(
0);
                    webBrowser2.Put_Width(rect.right);
                    webBrowser2.Put_Height(rect.bottom);

                    webBrowser2.Release();

                    
// Success
                    return(0);
                }
                
else
                {
                    writefln(
"query IID_IWebBrowser2 interface failed");
                }
            }
            
else
            {
                writefln(
"do verb failed");
            }
        }
        
else
        {
            writefln(
"set contained object failed");
        }
        writefln(
"embed failed");
        
// Something went wrong!
        UnEmbedBrowserObject(hwnd);
        
return(-3);
    }

    
return(-2);
}






/****************************** WindowProc() ***************************
 * Our message handler for our window to host the browser.
 
*/

extern(Windows)
LRESULT WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    
switch (uMsg)
    {
        
case WM_SIZE:
        {
            
// Resize the browser object to fit the window
            
//ResizeBrowser(hwnd, LOWORD(lParam), HIWORD(lParam));
            return(0);
        }

        
case WM_CREATE:
        {
            
// Embed the browser object into our host window. We need do this only
            
// once. Note that the browser object will start calling some of our
            
// IOleInPlaceFrame and IOleClientSite functions as soon as we start
            
// calling browser object functions in EmbedBrowserObject().
            if (EmbedBrowserObject(hwnd)) return(-1);

            
// Another window created with an embedded browser object
            ++WindowCount;

            
// Success
            return(0);
        }

        
case WM_DESTROY:
        {
            
// Detach the browser object from this window, and free resources.
            UnEmbedBrowserObject(hwnd);

            
// One less window
            --WindowCount;

            
// If all the windows are now closed, quit this app
            if (!WindowCount) PostQuitMessage(0);

            
return(TRUE);
        }
        
default:
            
return(DefWindowProc(hwnd, uMsg, wParam, lParam));
    }
}





/****************************** WinMain() ***************************
 * C program entry point.
 *
 * This creates a window to host the web browser, and displays a web
 * page.
 
*/

int myWinMain(HINSTANCE hInstance, HINSTANCE hInstNULL, LPSTR lpszCmdLine, int nCmdShow)
{
    MSG            msg;

    
// Initialize the OLE interface. We do this once-only.
    if (OleInitialize(null== S_OK)
    {
        WNDCLASSEX        wc;

        
// Register the class of our window to host the browser. 'WindowProc' is our message handler
        
// and 'ClassName' is the class name. You can choose any class name you want.

        wc.cbSize 
= WNDCLASSEX.sizeof;
        wc.hInstance 
= hInstance;
        wc.lpfnWndProc 
= &WindowProc;
        wc.lpszClassName 
= &ClassName[0];
        RegisterClassEx(
&wc);

        
// Create a window. NOTE: We embed the browser object duing our WM_CREATE handling for
        
// this window.
        msg.hwnd = CreateWindowEx(0, ClassName, "An HTML string", WS_OVERLAPPEDWINDOW,
                            CW_USEDEFAULT, 
0, CW_USEDEFAULT, 0,
                            HWND_DESKTOP, 
null, hInstance, null);
        
if (msg.hwnd == null)
        {
            writefln (
"create window failed");
            OleUninitialize();
            
return -2;
        }

        
// For this window, display a URL. This could also be a HTML file on disk such as "c:\\myfile.htm".
        DisplayHTMLPage(msg.hwnd, "http://www.microsoft.com");

        
// Show the window.
        ShowWindow(msg.hwnd, nCmdShow);
        UpdateWindow(msg.hwnd);
                        
        
// Do a message loop until WM_QUIT.
        while (GetMessage(&msg, null00))
        {
            TranslateMessage(
&msg);
            DispatchMessage(
&msg);
        }

        
// Free the OLE library.
        OleUninitialize();

        
return(0);
    }

    writefln(
"Can't open OLE!");
    
return(-1);
}
posted on 2005-11-11 12:16 qiezi 阅读(1490) 评论(1)  编辑 收藏 引用 所属分类: 学习方向D