您的位置:首页 > 编程语言

IE 实现代码示例

2016-02-22 10:34 525 查看
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 <windows.h>
// Include the automation definitions...
#include <exdisp.h>
#include <exdispid.h>
#include <mshtmdid.h> // AMBIENT_DLCONTROL

#include <objbase.h>

#include <tchar.h>

#include <wininet.h>
#include <afdfunc.h>  //ras stuff
#include <pkfuncs.h>  // GetOwnerProcess
#include <mshtml.h>
#include <commctrl.h>
#include <commdlg.h>
#include "MainWnd.h"
#include "resource.h"

#define INITGUID
#include "initguid.h"
#include <hshell.h>

#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\n", 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\n",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\n"));

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\n",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\n",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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: