IE実装コード例

36116 ワード

IEはCEの標準的な機能ですが、多くの人がIEブラウザをカスタマイズして、この特殊なニーズを実現したいと思っています.以前にMSが提供したIEの例を見たことがありますが、検討してみました.コードを共有して、みんなで勉強します.なお、IESIMPLEはフォームのクラス名としては変更できませんので、コードのコメントを参照してください.resource.hヘッダファイル:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
#define IDC_STATIC                      -1

#define IDR_ACCELERATOR 			100

#define IDD_OPEN_DIALOG				1000

#define IDC_URL_EDIT				3000
#define IDC_BROWSE				3001
#define IDC_NEWWINDOW				3002

#define IDS_IE					20000
#define IDS_ADDRESS				20001
#define IDS_FILESCHEME				20002
#define IDS_HYPHEN				20003
#define IDS_BROWSEFILTER			20010

#define ID_VIEW_STOP				500
#define ID_VIEW_REFRESH				501
#define ID_GO_BACK				502
#define ID_GO_FORWARD				503
#define ID_FOCUS_URL				504
#define ID_OPEN					505
#define ID_GO_HOME				506
#define ID_GO_SEARCH				507
#define ID_FULLSCREEN				508
#define ID_INTERNET_OPTIONS			509
#define ID_FIND					510
#define ID_CLOSE                            511
#define ID_ZOOMUP                        512
#define ID_ZOOMDOWN                  513

mainwnd.hヘッダファイル:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name:  mainwnd.h

Abstract:  Implements the main window, the container for the webbrowser

Functions:

Notes: This class implements the container and its interaction with the webbrowser control,
        commandbar, statusbar etc.


--*/

#ifndef _MAINWND_H
#define _MAINWND_H_

#include "mshtmhst.h"
#include "interned.h"

#define MAX_URL  2048

class CMainWnd :    
    public IOleContainer,
    public IOleClientSite,
    public IOleInPlaceSite,
    public IServiceProvider,
    public DWebBrowserEvents2,
    public IDocHostUIHandler,
    public IDocHostShowUI,              // msgbox, help window
    public IHTMLOMWindowServices   // for window move, resize events
{

public:
    CMainWnd();
    ~CMainWnd();

    BOOL Create();

    //IUnknown methods
    STDMETHOD(QueryInterface) (REFIID riid, LPVOID * ppv)
	{
		if ((riid == IID_IOleContainer) || (riid == IID_IUnknown))
		{
			*ppv = (IOleContainer *) this;
		}
		else if (riid == IID_IOleClientSite)
		{
			*ppv = (IOleClientSite *)this;
		}
		else if (riid == IID_IOleInPlaceSite)
		{
			*ppv = (IOleInPlaceSite *)this;
		}
		else if (riid == IID_IOleWindow)
		{
			*ppv = (IOleWindow *)this;
		}
		else if ((riid == DIID_DWebBrowserEvents2) || (riid == IID_IDispatch))
		{
			*ppv = (DWebBrowserEvents2 *)this;
		}
		else if(riid == IID_IServiceProvider)
		{
			*ppv = (IServiceProvider *)this;
		}
		else if (riid == IID_IDocHostUIHandler)
		{
			*ppv = (IDocHostUIHandler *)this;
		}
		else if (riid == IID_IDocHostShowUI)
		{
			*ppv = (IDocHostShowUI *)this;
		}
		else if (riid == IID_IHTMLOMWindowServices)
		{
			*ppv = (IHTMLOMWindowServices *)this;
		}
		else
		{
			*ppv = NULL;
			return E_NOINTERFACE;
		}
		AddRef();
		return S_OK;
	}

    STDMETHOD_(ULONG, AddRef) (void)
    {
        InterlockedIncrement((LONG*)&m_unRefs);
        return m_unRefs;
    }

    STDMETHOD_(ULONG, Release) (void)
    {
        ULONG ulRefs = m_unRefs;
        if (InterlockedDecrement((LONG*)&m_unRefs) == 0)
        {
            delete this;
            return 0;
        }
        return ulRefs - 1;
    }

    // IOleContainer methods
    STDMETHOD(ParseDisplayName)(IBindCtx *, LPOLESTR, ULONG *, IMoniker **) { return E_NOTIMPL;}
    STDMETHOD(EnumObjects)(DWORD, IEnumUnknown **)
    {
        return E_NOTIMPL;
    }
    STDMETHOD(LockContainer)(BOOL)                          { return S_OK;}

    // IOleClientSite methods
    STDMETHOD(SaveObject) (void)                            { return E_NOTIMPL;}
    STDMETHOD(GetMoniker) (DWORD dwAssign, DWORD dwWhichMoniker, LPMONIKER * ppmk) { return E_NOTIMPL;}
    STDMETHOD(GetContainer) (LPOLECONTAINER * ppContainer)
    {
        return E_NOINTERFACE;
    }
    STDMETHOD(ShowObject) (void)                            { return E_NOTIMPL;}
    STDMETHOD(OnShowWindow) (BOOL fShow)                    { return E_NOTIMPL;}
    STDMETHOD(RequestNewObjectLayout) (void)                { return E_NOTIMPL;}

    // IOleWindow methods
    STDMETHOD(GetWindow)(HWND *phwnd)
    {
        *phwnd = m_hWndMain;
        return S_OK;
    }
    STDMETHOD(ContextSensitiveHelp)(BOOL fEnterMode)        { return E_NOTIMPL;}

    // IOleInPlaceSite methods
    STDMETHOD(CanInPlaceActivate)   (void)                  { return S_OK;}
    STDMETHOD(OnInPlaceActivate)    (void)
    {
        m_bInPlaceActive = TRUE;
        return S_OK;
    }

    STDMETHOD(OnUIActivate)         (void)                  { return E_NOTIMPL;}
    STDMETHOD(GetWindowContext) (
                                LPOLEINPLACEFRAME FAR *     lplpFrame,
                                LPOLEINPLACEUIWINDOW FAR *  lplpDoc,
                                LPRECT                      lprcPosRect,
                                LPRECT                      lprcClipRect,
                                LPOLEINPLACEFRAMEINFO       lpFrameInfo)
    {
        
        GetClientRect(m_hWndMain, lprcPosRect);
        GetClientRect(m_hWndMain, lprcClipRect);

        return S_OK;
    }

    STDMETHOD(Scroll)               (SIZE scrollExtent)     { return E_NOTIMPL;}
    STDMETHOD(OnUIDeactivate)       (BOOL fUndoable)        { return E_NOTIMPL;}
    STDMETHOD(OnInPlaceDeactivate)  (void)
    {
        m_bInPlaceActive = FALSE;
        return S_OK;
    }

    STDMETHOD(DiscardUndoState)     (void)                  { return E_NOTIMPL;}
    STDMETHOD(DeactivateAndUndo)    (void)                  { return E_NOTIMPL;}
    STDMETHOD(OnPosRectChange)      (LPCRECT lprcPosRect)   { return E_NOTIMPL;}

    // IServiceProvider

    STDMETHOD(QueryService)(REFGUID guidService, REFIID riid, void **ppvObj)
    {
                if(guidService == IID_IHTMLOMWindowServices)
                {
                    return QueryInterface(riid, ppvObj);
                }
                else
                    return E_FAIL;
    }

    //DWebBrowserEvents
    //IDispatch methods
    STDMETHOD(GetTypeInfoCount)(UINT FAR* pctinfo)          { return E_NOTIMPL;}

    STDMETHOD(GetTypeInfo)(UINT itinfo,LCID lcid,ITypeInfo FAR* FAR* pptinfo)   { return E_NOTIMPL;}

    STDMETHOD(GetIDsOfNames)(REFIID riid,OLECHAR FAR* FAR* rgszNames,UINT cNames,
                             LCID lcid, DISPID FAR* rgdispid)                  { return E_NOTIMPL;}

    STDMETHOD(Invoke)(DISPID dispidMember,REFIID riid,LCID lcid,WORD wFlags,
                      DISPPARAMS FAR* pdispparams, VARIANT FAR* pvarResult,
                      EXCEPINFO FAR* pexcepinfo,UINT FAR* puArgErr);

    // IDocHostUIHandler methods
    STDMETHOD(EnableModeless)(BOOL fEnable) { return E_NOTIMPL; }
    STDMETHOD(FilterDataObject)(IDataObject *pDO, IDataObject **ppDORet) { return E_NOTIMPL; }
    STDMETHOD(GetDropTarget)(IDropTarget *pDropTarget, IDropTarget **ppDropTarget) { return E_NOTIMPL; }
    STDMETHOD(GetExternal)(IDispatch **ppDispatch) { return E_NOTIMPL; }
    STDMETHOD(GetHostInfo)(DOCHOSTUIINFO *pInfo);
    STDMETHOD(GetOptionKeyPath)(LPOLESTR *pchKey, DWORD dw) { return E_NOTIMPL; }
    STDMETHOD(HideUI)(void) { return E_NOTIMPL; }
    STDMETHOD(OnDocWindowActivate)(BOOL fActivate) { return E_NOTIMPL; }
    STDMETHOD(OnFrameWindowActivate)(BOOL fActivate) { return E_NOTIMPL; }
    STDMETHOD(ResizeBorder)(LPCRECT prcBorder, IOleInPlaceUIWindow *pUIWindow, BOOL fFrameWindow) { return E_NOTIMPL; }
    STDMETHOD(ShowContextMenu)(DWORD dwID, POINT *ppt, IUnknown *pcmdtReserved, IDispatch *pdispReserved) { return E_NOTIMPL; }
    STDMETHOD(ShowUI)(DWORD dwID, IOleInPlaceActiveObject *pActiveObject,
			IOleCommandTarget *pCommandTarget, IOleInPlaceFrame *pFrame,
			IOleInPlaceUIWindow *pDoc) { return E_NOTIMPL; }
    STDMETHOD(TranslateAccelerator)(LPMSG lpMsg, const GUID *pgudCmdGroup, DWORD nCmdID) { return E_NOTIMPL; }
    STDMETHOD(TranslateUrl)(DWORD dwTranslate, OLECHAR *pchURLIn, OLECHAR **ppchURLOut) { return E_NOTIMPL; }
    STDMETHOD(UpdateUI)(void) { return E_NOTIMPL; }

    // IDocHostShowUI methods
    STDMETHOD(ShowHelp)( HWND hwnd, LPOLESTR pszHelpFile, UINT uCommand,
                        DWORD dwData, POINT ptMouse, IDispatch *pDispatchObjectHit)
                        { return E_NOTIMPL; }


    STDMETHOD(ShowMessage)( HWND hwnd, LPOLESTR lpstrText, LPOLESTR lpstrCaption, DWORD dwType,
                            LPOLESTR lpstrHelpFile, DWORD dwHelpContext, LRESULT *plResult)
    {
		int iRes = MessageBox(hwnd, lpstrText, lpstrCaption, dwType);
        if(plResult)
		*plResult = iRes;
        return S_OK;
    }

   // IHTMLOMWindowServices methods
    STDMETHOD(moveTo)( LONG x, LONG y);     
    STDMETHOD(moveBy)( LONG x, LONG y);
    STDMETHOD(resizeTo)( LONG x,LONG y);
    STDMETHOD(resizeBy)( LONG x, LONG y);
   

public:
    BOOL                    PreTranslateMessage(LPMSG pMsg);
    VOID                    Close();
    HWND                    GetWindow() {   return m_hWndMain;}
    LRESULT                 HandleCommand(WPARAM wParam, LPARAM lParam);

    HANDLE                  m_hEvent;
    IWebBrowser2            *m_pBrowser;



    static LRESULT  CALLBACK MainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

protected:



    //Added for HTML Find Dialogs
    HRESULT                 FindString();

    VOID CMainWnd::ChangeFontSize(BOOL fInit);

    BOOL                    RegisterMainWnd();
    HWND                    CreateBrowser();
    HRESULT                 Activate(IOleObject *pObject);
    HRESULT                 InitEvents();
    

public:
    LPTSTR                 m_lpszUrl;
    BOOL                   m_bEmpty;
    BOOL                   m_bFullScreen;
    RECT                   m_rcWnd;
protected:
    HACCEL                  m_hAccelTbl;			//a handle to the accelerator table
    HWND                    m_hWndMain;			//the main window

    ULONG                   m_unRefs;            //reference count for the interfaces supported by the container
    
    HWND                    m_hWndBrowser;       //handle to the browser window

    IOleObject              *m_pObject;
    IConnectionPoint        *m_pCP;
    IOleInPlaceActiveObject *m_pIPActiveObj;
    BOOL                    m_bInPlaceActive;
    DWORD                   m_dwEventCookie;

    TCHAR                   m_tcTitle[MAX_URL];   //title of the current document
    HWND                    m_hWndProgress;          // progress bar
    RECT					m_rcProgress;

    int						m_iZoom;
    int						m_iDLCCounter;

};

#endif	//_MAINWND_H_

mainwnd.cppソースファイル:
/*++

Module Name:  mainwnd.cpp

Abstract:  Implements the main window, the container for the webbrowser

Functions:

Notes: Most of the code resides here. The container and its interaction with the webbrowser control,
commandbar, statusbar etc.


--*/
#include 
// Include the automation definitions...
#include 
#include 
#include  // AMBIENT_DLCONTROL

#include 

#include 

#include 
#include 	//ras stuff
#include 	// GetOwnerProcess
#include 
#include 
#include 
#include "MainWnd.h"
#include "resource.h"

#define INITGUID
#include "initguid.h"
#include 

#define START_FULLSCREEN // Remove this if you don't want IESIMPLE to be full-screen at startup

DEFINE_GUID(CLSID_WebBrowser,       0x8856F961L, 0x340A, 0x11D0, 0xA9, 0x6B, 0x00, 0xC0, 0x4F, 0xD7, 0x05, 0xA2);
DEFINE_GUID(IID_IWebBrowser,        0xEAB22AC1L, 0x30C1, 0x11CF, 0xA7, 0xEB, 0x00, 0x00, 0xC0, 0x5B, 0xAE, 0x0B);
DEFINE_GUID(IID_IWebBrowser2,       0xD30C1661L, 0xCDAF, 0x11D0, 0x8A, 0x3E, 0x00, 0xC0, 0x4F, 0xC9, 0xE2, 0x6E);
DEFINE_GUID(DIID_DWebBrowserEvents, 0xEAB22AC2L, 0x30C1, 0x11CF, 0xA7, 0xEB, 0x00, 0x00, 0xC0, 0x5B, 0xAE, 0x0B);
DEFINE_GUID(DIID_DWebBrowserEvents2, 0x34A715A0L, 0x6587, 0x11D0, 0x92, 0x4A, 0x00, 0x20, 0xAF, 0xC7, 0xAC, 0x4D);
DEFINE_GUID(IID_IWebBrowserApp,     0x0002DF05L, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);

const GUID SID_SDocHost = { 0xc6504990, 0xd43e, 0x11cf, { 0x89, 0x3b, 0x00, 0xaa, 0x00, 0xbd, 0xce, 0x1a}};

#define MAX(a,b)  (a > b) ? a : b
#define MIN(a,b)  (a > b) ? b : a

LONG        glThreadCount	= 0;
HWND		ghWndAddressEdit= NULL;
HANDLE      ghExitEvent		= NULL;
HINSTANCE   g_hInstance		= NULL;
DWORD      g_dwMainWindowStackSize = 0x20000;

void GetProxyOption();


static HRESULT FindString();
HRESULT HandleNewWindow2(LPTSTR lpszUrl, DISPPARAMS FAR* pdparams);
BOOL RegisterMainWnd();


DWORD WINAPI NewWindow(LPVOID pParam)
{
	CMainWnd *pWnd = (CMainWnd *)pParam;
	MSG msg;
	BOOL fRet;

	HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);

	fRet = pWnd->Create();

	SetEvent(pWnd->m_hEvent);

	if(!fRet)
	{
		pWnd->m_pBrowser = NULL;
		return 0;
	}

	while(GetMessage( &msg, NULL, 0, 0 ) )
	{
		if(msg.message == WM_QUIT)
			break;

		if(!pWnd->PreTranslateMessage(&msg) && !(msg.message == WM_CHAR && msg.wParam == VK_TAB))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	pWnd->Release();

	CoUninitialize();

	InterlockedDecrement(&glThreadCount);
	SetEvent(ghExitEvent);

	return msg.wParam;
}

int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPTSTR lpCmdLine, int nCmdShow)
{
	INITCOMMONCONTROLSEX iccsex;
	HKEY hKey;
	DWORD dwSize = sizeof(DWORD);
	MSG msg;

	// HKCU is where IE\Main settings are
	if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\Internet Explorer\\Main"), 0, 0, &hKey))
	{
		RegQueryValueEx(hKey, TEXT("StackRes"), NULL, NULL, (LPBYTE)&g_dwMainWindowStackSize, &dwSize);
		RegCloseKey(hKey);
	}

	// provide a default stack size if the one given is too small or too large. 
	if(g_dwMainWindowStackSize < 0x10000 || g_dwMainWindowStackSize > 0x80000)
	{
		// default to 128k
		g_dwMainWindowStackSize = 0x20000;
	}
	RETAILMSG(1,(L"IESIMPLE Using Stack size: 0x%x\r
", g_dwMainWindowStackSize)); HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); if(FAILED(hr)) { return FALSE; } if(!RegisterMainWnd()) { return FALSE; } ghExitEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if(!ghExitEvent) { return FALSE; } iccsex.dwSize = sizeof(INITCOMMONCONTROLSEX); iccsex.dwICC = ICC_COOL_CLASSES; InitCommonControlsEx(&iccsex); g_hInstance = hInst; // Create a message queue on this thread PeekMessage(&msg, NULL, 0,0,PM_NOREMOVE); if(FAILED(HandleNewWindow2(lpCmdLine, NULL))) { goto Cleanup; } while(glThreadCount > 0) { WaitForSingleObject(ghExitEvent, INFINITE); } Cleanup: CoUninitialize(); RETAILMSG(1, (L"IESIMPLE exited. Cmdline was: %s\r
",lpCmdLine ? lpCmdLine : L"")); return TRUE; } CMainWnd::CMainWnd() { m_unRefs = 1; m_hWndMain = NULL; m_pBrowser = NULL; m_pObject = NULL; m_pCP = NULL; m_lpszUrl = NULL; m_bFullScreen = FALSE; m_bEmpty = FALSE; m_tcTitle[0] = 0; m_iZoom = 2; // default zoom m_iDLCCounter = 0; // counter for Download Completes } CMainWnd::~CMainWnd() { RETAILMSG(1,(L"IESIMPLE Exiting ~CMainWnd\r
")); if(m_pBrowser) m_pBrowser->Release(); } BOOL RegisterMainWnd() { WNDCLASS wc; wc.style = 0; wc.lpfnWndProc = (WNDPROC)CMainWnd::MainWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = g_hInstance; wc.hIcon = NULL; // LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_IE)); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)GetSysColorBrush(COLOR_WINDOW); wc.lpszMenuName = NULL; wc.lpszClassName = TEXT("IESIMPLE"); if(!(RegisterClass(&wc))) return FALSE; return TRUE; } BOOL CMainWnd::Create() { RECT rcArea; DWORD dwTick; DWORD dwStyle = WS_VISIBLE | WS_OVERLAPPED | WS_THICKFRAME | WS_SYSMENU; /*|WS_OVERLAPPED|WS_BORDER|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX*/ DWORD dwExStyle = 0/*WS_EX_OVERLAPPEDWINDOW*/; HMENU hMenu = NULL; SystemParametersInfo(SPI_GETWORKAREA, 0, &rcArea, 0); m_hWndMain = ::CreateWindowEx(dwExStyle, TEXT("IESIMPLE"), // Add ZH - Leo , (WCHAR *)LoadString(g_hInstance, IDS_IE, NULL, 0), dwStyle, rcArea.left + 20, rcArea.top + 20, rcArea.right - rcArea.left - 40, rcArea.bottom - rcArea.top - 30, NULL, hMenu, g_hInstance, 0); if(!m_hWndMain) { return FALSE; } SetWindowLong(m_hWndMain, GWL_USERDATA, (DWORD)this); GetWindowRect(m_hWndMain, &m_rcWnd); // create a progress bar m_rcProgress.left = 5; m_rcProgress.right = m_rcProgress.left + (m_rcWnd.right - m_rcWnd.left)/3; m_rcProgress.top = 5; m_rcProgress.bottom = m_rcProgress.top + 15; m_hWndProgress = CreateWindowEx(WS_EX_NOACTIVATE, PROGRESS_CLASS, _T(""), WS_CHILD|PBS_SMOOTH|WS_BORDER, m_rcProgress.left, m_rcProgress.top, m_rcProgress.right-m_rcProgress.left, m_rcProgress.bottom-m_rcProgress.top, m_hWndMain, NULL, g_hInstance, NULL); if(m_hWndProgress) { SendMessage(m_hWndProgress, PBM_SETRANGE32, 0, 1000); } // /progress bar dwTick = GetTickCount(); if(!(m_hWndBrowser = CreateBrowser())) return FALSE; RETAILMSG(1,(L"Create browser tick count: %d\r
",GetTickCount() - dwTick)); // 2 // LONG lStyle = GetWindowLong(_hWndBrowser, GWL_STYLE); // SetWindowLong(_hWndBrowser, GWL_STYLE, lStyle|WS_BORDER); SetFocus(m_hWndMain); m_hAccelTbl = LoadAccelerators(g_hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR)); #ifdef START_FULLSCREEN HandleCommand( ID_FULLSCREEN, 0 ); #endif return TRUE; } void GetProxyOption() { INTERNET_PER_CONN_OPTION_LIST iOptionList; INTERNET_PER_CONN_OPTION iOptions[3]; ULONG uSize = sizeof(iOptionList); iOptionList.dwSize = uSize; iOptionList.pszConnection = NULL; iOptionList.dwOptionCount = 3; iOptionList.pOptions = iOptions; // set proxy type direct or proxy server iOptions[0].dwOption = INTERNET_PER_CONN_FLAGS; iOptions[1].dwOption = INTERNET_PER_CONN_PROXY_SERVER; iOptions[2].dwOption = INTERNET_PER_CONN_PROXY_BYPASS; if(InternetQueryOption(NULL,INTERNET_OPTION_PER_CONNECTION_OPTION ,(LPVOID)(&iOptionList),&uSize)) { GlobalFree(iOptionList.pOptions[1].Value.pszValue); GlobalFree(iOptionList.pOptions[2].Value.pszValue); } } HWND CMainWnd::CreateBrowser() { HRESULT hr; IUnknown *pUnk = NULL; IOleObject *pObject = NULL; if(!m_pBrowser) { GetProxyOption(); hr = CoCreateInstance(CLSID_WebBrowser, NULL, CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, IID_IUnknown, (LPVOID *)(&pUnk)); if(FAILED(hr)) return FALSE; hr = pUnk->QueryInterface(IID_IOleObject, (LPVOID *)(&pObject)); if(FAILED(hr)) goto Cleanup; DWORD dwFlags; hr = pObject->GetMiscStatus(DVASPECT_CONTENT, &dwFlags); if(FAILED(hr)) goto Cleanup; if(dwFlags & OLEMISC_SETCLIENTSITEFIRST) { IOleClientSite *pClientSite; hr = QueryInterface(IID_IOleClientSite, (LPVOID *)(&pClientSite)); if(FAILED(hr)) goto Cleanup; hr = pObject->SetClientSite(pClientSite); pClientSite->Release(); if(FAILED(hr)) goto Cleanup; } hr = Activate(pObject); if(FAILED(hr)) goto Cleanup; hr = m_pObject->QueryInterface(IID_IWebBrowser2, (void **)&m_pBrowser); if(FAILED(hr)) goto Cleanup; // See if there might be a url in lpszUrl hr = pUnk->QueryInterface(IID_IOleInPlaceActiveObject, (LPVOID *)(&m_pIPActiveObj)); if(FAILED(hr)) m_pIPActiveObj = NULL; hr = S_FALSE; if(m_bEmpty) { // Leo Test: m_lpszUrl = L"http://www.baidu.com"; BSTR bstrURL = SysAllocString(m_lpszUrl); if(bstrURL && bstrURL[0]) m_pBrowser->Navigate(bstrURL, NULL, NULL, NULL, NULL); else m_pBrowser->GoHome(); SysFreeString(bstrURL); } hr = InitEvents(); } Cleanup: if(pUnk) pUnk->Release(); if(pObject) pObject->Release(); IOleWindow *pWnd = NULL; HWND hwndBrowser = NULL; if(m_pBrowser) { hr = m_pBrowser->QueryInterface(IID_IOleWindow, (LPVOID *)(&pWnd)); if(FAILED(hr)) return NULL; } if(pWnd) { hr = pWnd->GetWindow(&hwndBrowser); pWnd->Release(); } return hwndBrowser; } HRESULT CMainWnd::Activate(IOleObject *pObject) { m_pObject = pObject; m_pObject->AddRef(); RECT rc; ::GetClientRect(m_hWndMain, &rc); HRESULT hr; hr = m_pObject->DoVerb( OLEIVERB_UIACTIVATE, NULL, this, 0, m_hWndMain, &rc); if(FAILED(hr)) goto Cleanup; Cleanup: return hr; } HRESULT CMainWnd::InitEvents() { HRESULT hr; IConnectionPointContainer *pCPCont = NULL; DWebBrowserEvents *pEvents = NULL; if(!m_pBrowser) return S_FALSE; hr = m_pBrowser->QueryInterface(IID_IConnectionPointContainer, (LPVOID *)&pCPCont); if(FAILED(hr)) return S_FALSE; hr = pCPCont->FindConnectionPoint(DIID_DWebBrowserEvents2, &m_pCP); if(FAILED(hr)) { m_pCP = NULL; goto Cleanup; } hr = QueryInterface(DIID_DWebBrowserEvents2, (LPVOID *)(&pEvents)); if(FAILED(hr)) goto Cleanup; hr = m_pCP->Advise(pEvents, &(m_dwEventCookie)); if(FAILED(hr)) goto Cleanup; Cleanup: if(pCPCont) pCPCont->Release(); if(pEvents) pEvents->Release(); return hr; } HRESULT HandleNewWindow2(LPTSTR lpszUrl, DISPPARAMS FAR* pdparams) { HANDLE hThread; CMainWnd *pNewWnd; IDispatch *pDispatch; HRESULT hr = S_OK; DWORD dwThreadID = 0; pNewWnd = new CMainWnd; if(!pNewWnd) { return E_OUTOFMEMORY; } pNewWnd->m_lpszUrl = lpszUrl; if(!pdparams) pNewWnd->m_bEmpty = TRUE; pNewWnd->m_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if(!pNewWnd->m_hEvent) { } InterlockedIncrement(&glThreadCount); hThread = CreateThread(NULL, g_dwMainWindowStackSize, NewWindow, (LPVOID)pNewWnd, STACK_SIZE_PARAM_IS_A_RESERVATION, &dwThreadID); if(!hThread) { delete pNewWnd; InterlockedDecrement(&glThreadCount); return E_OUTOFMEMORY; } RETAILMSG(1,(L"[HandleNewWindow2]Create thread,ID is: 0x%x\r
",dwThreadID)); WaitForSingleObject(pNewWnd->m_hEvent, INFINITE); CloseHandle(hThread); if(pdparams) { if(pNewWnd->m_pBrowser) { hr = pNewWnd->m_pBrowser->QueryInterface(IID_IDispatch, (LPVOID *)(&pDispatch)); } else { hr = E_FAIL; pDispatch = NULL; } *(pdparams->rgvarg[0].pboolVal) = 0; *(pdparams->rgvarg[1].ppdispVal) = pDispatch; } return hr; } STDMETHODIMP CMainWnd::GetHostInfo(DOCHOSTUIINFO *pInfo) { pInfo->cbSize = sizeof(DOCHOSTUIINFO); //pInfo->dwFlags = DOCHOSTUIFLAG_NO3DBORDER|DOCHOSTUIFLAG_FLAT_SCROLLBAR; //pInfo->dwFlags |= DOCHOSTUIFLAG_SCROLL_NO; return S_OK; } STDMETHODIMP CMainWnd::Invoke ( DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR* pdparams, VARIANT FAR* pvarResult, EXCEPINFO FAR* pexcepinfo, UINT FAR* puArgErr ) { switch (dispidMember) { case DISPID_AMBIENT_DLCONTROL: if(pvarResult) { V_VT(pvarResult) = VT_I4; // always set these three unless they should be disabled pvarResult->lVal = DLCTL_DLIMAGES|DLCTL_VIDEOS|DLCTL_BGSOUNDS; // put the browser in download only mode // pvarResult->lVal |= DLCTL_DOWNLOADONLY; } break; case DISPID_STATUSTEXTCHANGE: { } break; case DISPID_SETSECURELOCKICON: { } break; case DISPID_PROGRESSCHANGE: { LONG lProgMax = pdparams->rgvarg[0].lVal; LONG lProg = pdparams->rgvarg[1].lVal; UINT nPos = (lProg == -1) ? 999 : ((lProg-1)%1000); SendMessage(m_hWndProgress, PBM_SETPOS, nPos, 0); } break; // notification for file download case DISPID_FILEDOWNLOAD: break; case DISPID_NAVIGATECOMPLETE2: break; case DISPID_COMMANDSTATECHANGE: break; case DISPID_TITLECHANGE: if(pdparams && pdparams->rgvarg[0].vt == VT_BSTR) { TCHAR szTitle[85]; int len = wcslen(pdparams->rgvarg[0].bstrVal); _tcsncpy(m_tcTitle, pdparams->rgvarg[0].bstrVal, MAX_URL-1); _tcsncpy(szTitle, pdparams->rgvarg[0].bstrVal, 80); if(len > 80) _tcscat(szTitle, L"..."); SetWindowText(m_hWndMain, szTitle); } break; case DISPID_ONQUIT: PostMessage(m_hWndMain, WM_CLOSE, 0, 0L); break; case DISPID_DOWNLOADBEGIN: m_iDLCCounter++; SetWindowPos(m_hWndProgress, HWND_TOP, 0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_SHOWWINDOW); break; case DISPID_DOWNLOADCOMPLETE: case DISPID_DOCUMENTCOMPLETE: m_iDLCCounter--; if(m_iDLCCounter <= 0) { SetWindowPos(m_hWndProgress,NULL, 0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_HIDEWINDOW); ChangeFontSize(TRUE); m_iDLCCounter = 0; } break; case DISPID_NEWWINDOW2: //pdparams->rgvarg[1].boolVal = VARIANT_TRUE; //break; return HandleNewWindow2(NULL, pdparams); break; case DISPID_PROPERTYCHANGE: case DISPID_BEFORENAVIGATE2: break; default: return DISP_E_MEMBERNOTFOUND; } return S_OK; } STDMETHODIMP CMainWnd::moveTo( LONG x, LONG y) { SetWindowPos(m_hWndMain, NULL, x, y, 0, 0, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE); return S_OK; } STDMETHODIMP CMainWnd::moveBy( LONG x, LONG y) { RECT rcWindow; GetWindowRect(m_hWndMain, &rcWindow); SetWindowPos(m_hWndMain, NULL, rcWindow.left + x, rcWindow.top + y, 0, 0, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE); return S_OK; } STDMETHODIMP CMainWnd::resizeTo( LONG x, LONG y) { // We do not want the size to be less then 100 for top level windows in browser if(x < 100) x = 100; if(y < 100) y = 100; SetWindowPos(m_hWndMain, NULL, 0, 0, x, y, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE); return S_OK; } STDMETHODIMP CMainWnd::resizeBy( LONG x, LONG y) { RECT rcWindow; long w, h; GetWindowRect(m_hWndMain, &rcWindow); w = rcWindow.right - rcWindow.left + x; h = rcWindow.bottom - rcWindow.top + y; if(w < 100) w = 100; if(h < 100) h = 100; SetWindowPos(m_hWndMain, NULL, 0, 0, w, h, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE); return S_OK; } EXTERN_C const GUID CGID_MSHTML; extern "C" BOOL APIENTRY OpenURLDlgProc (HWND hDlg, UINT message, UINT wParam, LONG lParam); LRESULT CMainWnd::HandleCommand(WPARAM wParam, LPARAM lParam) { UINT nID = LOWORD(wParam); switch (nID) { case ID_INTERNET_OPTIONS: { SHELLEXECUTEINFO sei; sei.cbSize = sizeof(sei); sei.fMask = SEE_MASK_FLAG_NO_UI; sei.hwnd = m_hWndMain; sei.lpVerb = NULL; sei.lpFile = L"ctlpnl"; sei.lpParameters = L"inetcpl.cpl"; sei.lpDirectory = NULL; sei.nShow = SW_SHOWNORMAL; ShellExecuteEx(&sei); } break; case ID_FIND: FindString(); break; case ID_GO_BACK: m_pBrowser->GoBack(); return 0; case ID_GO_FORWARD: m_pBrowser->GoForward(); return 0; case ID_GO_HOME: m_pBrowser->GoHome(); return 0; case ID_GO_SEARCH: m_pBrowser->GoSearch(); return 0; case ID_VIEW_REFRESH: m_pBrowser->Refresh(); return 0; case ID_VIEW_STOP: m_pBrowser->Stop(); return 0; case ID_ZOOMUP: m_iZoom++; if(m_iZoom > 4) m_iZoom = 4; ChangeFontSize(FALSE); return 0; case ID_ZOOMDOWN: m_iZoom--; if(m_iZoom < 0) m_iZoom = 0; ChangeFontSize(FALSE); return 0; case ID_CLOSE: m_pBrowser->ExecWB(OLECMDID_CLOSE, OLECMDEXECOPT_DODEFAULT, NULL, NULL); return 0; case ID_FOCUS_URL: case ID_OPEN: { WCHAR *szURL = new TCHAR[MAX_URL]; if(szURL) { int nRet = 0; BSTR bstrURL = NULL; m_pBrowser->get_LocationURL(&bstrURL); nRet = StringCchCopy(szURL, MAX_URL, (LPCTSTR)bstrURL); SysFreeString(bstrURL); nRet = DialogBoxParam(g_hInstance, MAKEINTRESOURCE(IDD_OPEN_DIALOG), m_hWndMain, OpenURLDlgProc, (long)szURL); bstrURL = SysAllocString(szURL); if(nRet == 1) { m_pBrowser->Navigate(bstrURL, NULL, NULL, NULL, NULL); } else if(nRet == 2) { HandleNewWindow2(bstrURL,NULL); } SysFreeString(bstrURL); delete[] szURL; } } return 0; case ID_FULLSCREEN: { DWORD dwStyle = GetWindowLong(m_hWndMain, GWL_STYLE); if(m_bFullScreen) { dwStyle |= (WS_OVERLAPPED | WS_SYSMENU | WS_THICKFRAME); SetWindowLong(m_hWndMain, GWL_STYLE, dwStyle); SetWindowPos(m_hWndMain,NULL, m_rcWnd.left, m_rcWnd.top, m_rcWnd.right-m_rcWnd.left, m_rcWnd.bottom-m_rcWnd.top, SWP_NOZORDER); m_bFullScreen = FALSE; } else { RECT rcWorkArea; SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWorkArea, 0); m_bFullScreen = TRUE; dwStyle &= ~(WS_OVERLAPPED | WS_SYSMENU | WS_THICKFRAME); SetWindowLong(m_hWndMain, GWL_STYLE, dwStyle); SetWindowPos(m_hWndMain,NULL, rcWorkArea.left, rcWorkArea.top, rcWorkArea.right-rcWorkArea.left, rcWorkArea.bottom-rcWorkArea.top, SWP_NOZORDER); } } return 0; } return 0; } EXTERN_C const GUID CGID_ShellDocView; LRESULT CALLBACK CMainWnd::MainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { CMainWnd *pMainWnd = (CMainWnd*)GetWindowLong(hwnd, GWL_USERDATA); if(pMainWnd) { switch (message) { case WM_CLOSE: case WM_DESTROY: if(pMainWnd) pMainWnd->Close(); SetWindowLong(hwnd, GWL_USERDATA, (DWORD)0); ::PostQuitMessage(0); break; case WM_SETFOCUS: if(pMainWnd->m_pIPActiveObj) { pMainWnd->m_pIPActiveObj->OnFrameWindowActivate(LOWORD(wParam) != WA_INACTIVE); } return 0; case WM_SIZE: { RECT rcWnd; GetClientRect(hwnd, &rcWnd); SetWindowPos(pMainWnd->m_hWndBrowser, NULL, 0, 0, rcWnd.right-rcWnd.left, rcWnd.bottom - rcWnd.top, SWP_NOZORDER); } // FALL THROUGH case WM_MOVE: if(!pMainWnd->m_bFullScreen) GetWindowRect(hwnd, &pMainWnd->m_rcWnd); break; case WM_COMMAND: return pMainWnd->HandleCommand(wParam, lParam); break; case WM_NOTIFY: break; case WM_INITMENUPOPUP: break; case WM_SETTINGCHANGE: if(wParam == SPI_SETWORKAREA) { if(pMainWnd->m_bFullScreen) { RECT rcWorkArea; // no need to change the window style here, just adjust for the new work-area. SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWorkArea, 0); SetWindowPos(pMainWnd->m_hWndMain,NULL, rcWorkArea.left, rcWorkArea.top, rcWorkArea.right-rcWorkArea.left, rcWorkArea.bottom-rcWorkArea.top, SWP_NOZORDER); } } break; default: break; } } return DefWindowProc(hwnd, message, wParam, lParam); } BOOL CMainWnd::PreTranslateMessage(LPMSG pMsg) { if(::TranslateAccelerator(m_hWndMain, m_hAccelTbl, pMsg)) //first shot to the main frame return TRUE; //then to mshtml if(m_pIPActiveObj && pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST) { HRESULT hr = m_pIPActiveObj->TranslateAccelerator(pMsg); return (hr != S_FALSE); } return FALSE; } VOID CMainWnd::ChangeFontSize(BOOL fInit) { VARIANT vaSize; vaSize.vt = VT_I4; if(fInit) { // Setting initial value vaSize.vt = 0; HRESULT hr = m_pBrowser->ExecWB(OLECMDID_ZOOM, OLECMDEXECOPT_DONTPROMPTUSER, NULL, &vaSize); m_iZoom = vaSize.lVal; } else { vaSize.lVal = m_iZoom; HRESULT hr = m_pBrowser->ExecWB(OLECMDID_ZOOM, OLECMDEXECOPT_DONTPROMPTUSER, &vaSize, NULL); } } VOID CMainWnd::Close() { RETAILMSG(1,(L"IESIMPLE CMainWnd::Close")); // Tell the shell to die off SendMessage(m_hWndBrowser, WM_CLOSE, 0,0); if(m_pIPActiveObj) { m_pIPActiveObj->Release(); } m_pIPActiveObj = NULL; if(m_pCP) { m_pCP->Unadvise(m_dwEventCookie); m_pCP->Release(); } m_pCP = NULL; if(m_pObject) { m_pObject->Close(FALSE); m_pObject->Release(); } m_pObject = NULL; if(m_pBrowser) m_pBrowser->Release(); m_pBrowser = NULL; } HRESULT CMainWnd::FindString() { LPDISPATCH pDisp = NULL; LPOLECOMMANDTARGET pCmdTarg = NULL; HRESULT sts = S_OK; VARIANTARG var; #define GOERROR_S(bNotCond) {if(!(bNotCond)) goto errorS; } if(!m_pBrowser) return S_OK; sts = m_pBrowser->get_Document(&pDisp); GOERROR_S(pDisp); sts = pDisp->QueryInterface(IID_IOleCommandTarget, (LPVOID*)&pCmdTarg); GOERROR_S(pCmdTarg); var.vt = VT_I4; var.lVal = 0; sts = pCmdTarg->Exec( NULL, OLECMDID_FIND, MSOCMDEXECOPT_PROMPTUSER, NULL, &var); errorS: if(pCmdTarg) pCmdTarg->Release(); // release document's command target if(pDisp) pDisp->Release(); // release document's dispatch interface return sts; } BOOL HandleBrowse(HWND hwndOwner, WCHAR *szURL); extern "C" BOOL APIENTRY OpenURLDlgProc (HWND hDlg, UINT message, UINT wParam, LONG lParam) { WCHAR *szURL = (WCHAR *)GetWindowLong(hDlg,DWL_USER); int nRet = 4; switch(message) { case WM_INITDIALOG: { if(!lParam) { EnableWindow(GetDlgItem(hDlg, IDOK), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_BROWSE), FALSE); } else { szURL = (WCHAR *)lParam; SetWindowLong(hDlg, DWL_USER, (LONG)szURL); SendMessage(GetDlgItem(hDlg, IDC_URL_EDIT), EM_LIMITTEXT, MAX_URL-1, 0); if(szURL[0]) { SetDlgItemText(hDlg, IDC_URL_EDIT, szURL); } } } return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: { GetDlgItemText(hDlg, IDC_URL_EDIT, szURL, MAX_URL-1); BOOL bNewWnd = SendMessage(GetDlgItem(hDlg, IDC_NEWWINDOW), BM_GETCHECK, 0L, 0L); nRet = (bNewWnd) ? 2 : 1; } case IDCANCEL: EndDialog(hDlg, nRet); return TRUE; case IDC_BROWSE: if(HandleBrowse(hDlg, szURL)) { SetDlgItemText(hDlg, IDC_URL_EDIT, szURL); } default: return (TRUE); } break; case WM_DESTROY: SetWindowLong(hDlg, DWL_USER, 0); break; } return (FALSE); } extern HINSTANCE g_hInstance; BOOL HandleBrowse(HWND hwndOwner, WCHAR *szURL) { OPENFILENAME ofn; WCHAR wchFilter[MAX_PATH]; WCHAR wchFile[MAX_PATH+8]; int cbLen; // Initialize ofn struct memset(&ofn, 0, sizeof(ofn)); ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = hwndOwner; ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY; cbLen = LoadString(g_hInstance, IDS_BROWSEFILTER, wchFilter, MAX_PATH-2); if(cbLen>0) { for (; cbLen >= 0; cbLen--) { if(wchFilter[cbLen]== L'@') { wchFilter[cbLen] = 0; } } } else { return FALSE; } ofn.lpstrFilter = wchFilter; ofn.nFilterIndex = 1; wcscpy(wchFile, L"file://"); ofn.lpstrFile = wchFile+wcslen(wchFile); // prefix the string with "file://" ofn.nMaxFile = MAX_PATH; if(GetOpenFileName(&ofn)) { wcsncpy(szURL, wchFile, MAX_URL-1); return TRUE; } return FALSE; }