IE 实现代码示例
2016-02-22 10:34
525 查看
IE 是 CE 的一个标准功能,但 很多人想定制 IE 浏览器,以实现某此特殊的需求。
以早以前看过 MS 提供的 IE 示例,研究了一下,现将代码分享出来,大家一起学习。
需要注意的是,IESIMPLE 做为窗体的类名不能修改,详细见代码中的注释。
resource.h 头文件:
mainwnd.h 头文件:
mainwnd.cpp 源文件:
以早以前看过 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; }
相关文章推荐
- 如何利用开发开具调试程序-VC++6.0篇
- php函数
- java-web总结--jsp--会话
- php判断是否为手机站
- 加载properties文件属性的Java工具类实现
- C语言的预处理
- java读取excel文件并写入另一个excel文件
- Socket编程
- c语言中的结构体
- C++ | boost库 类的序列化
- phpstorm10.0.3破解版安装教程及汉化方法
- Eclipse的Jar包解压出System.js里String与Boolean定义分号可有可无吗?
- java的zip解压
- selenium入门第一个脚本(python篇)
- C# 定时器运用
- java的zip压缩
- 技术笔记:Indy IdSMTP支持腾讯QQ邮箱邮件发送
- 如何优化 Django REST Framework 的性能?
- C++ and C Combination Compile Extern
- Java的IO操作