1 #pragma once
2 
3 #include "ActiveXHost.h"
4 #include <ExDisp.h>
5 #include <MsHTML.h>
6 #include <MsHtmHst.h>
7 #include <set>
8 
9 namespace Framework
10 {
11 	namespace Win32
12 	{
13 		class CWebBrowser : public CActiveXHost
14 		{
15 		public:
16 			enum
17 			{
18 				NOTIFICATION_BEFORENAVIGATE = 0xA000,
19 			};
20 
21 			struct BEFORENAVIGATE_INFO : public NMHDR
22 			{
23 				std::tstring		navigateUrl;
24 				bool				cancel;
25 			};
26 
27 										CWebBrowser();
28 										CWebBrowser(HWND, const RECT&);
29 			virtual						~CWebBrowser();
30 
31 			CWebBrowser&				operator =(CWebBrowser&&);
32 
33 			CComPtr<IHTMLDocument2>		GetDocument();
34 
35 			void						Navigate(const TCHAR*);
36 			void						Stop();
37 
38 		protected:
39 			class CWebBrowserClientSite : public IDocHostUIHandler
40 			{
41 			public:
42 										CWebBrowserClientSite(HWND);
43 				virtual					~CWebBrowserClientSite();
44 
45 				//IUnknown
46 				STDMETHODIMP			QueryInterface(const IID&, void**);
47 				STDMETHODIMP_(ULONG)	AddRef();
48 				STDMETHODIMP_(ULONG)	Release();
49 
50 				//IDocHostUIHandler
51 				STDMETHODIMP			ShowContextMenu(DWORD, POINT*, IUnknown*, IDispatch*);
52 				STDMETHODIMP			GetHostInfo(DOCHOSTUIINFO*);
53 				STDMETHODIMP			ShowUI(DWORD, IOleInPlaceActiveObject*, IOleCommandTarget*, IOleInPlaceFrame*, IOleInPlaceUIWindow*);
54 				STDMETHODIMP			HideUI();
55 				STDMETHODIMP			UpdateUI();
56 				STDMETHODIMP			EnableModeless(BOOL);
57 				STDMETHODIMP			OnDocWindowActivate(BOOL);
58 				STDMETHODIMP			OnFrameWindowActivate(BOOL);
59 				STDMETHODIMP			ResizeBorder(LPCRECT, IOleInPlaceUIWindow*, BOOL);
60 				STDMETHODIMP			TranslateAccelerator(LPMSG, const GUID*, DWORD);
61 				STDMETHODIMP			GetOptionKeyPath(LPOLESTR*, DWORD);
62 				STDMETHODIMP			GetDropTarget(IDropTarget*, IDropTarget**);
63 				STDMETHODIMP			GetExternal(IDispatch**);
64 				STDMETHODIMP			TranslateUrl(DWORD, LPWSTR, LPWSTR*);
65 				STDMETHODIMP			FilterDataObject(IDataObject*, IDataObject**);
66 
67 			private:
68 				CComPtr<IUnknown>		m_clientSite;
69 				ULONG					m_refCount;
70 			};
71 
72 			void						Reset();
73 			void						MoveFrom(CWebBrowser&&);
74 
75 		private:
76 			class CEventSink : public DWebBrowserEvents2
77 			{
78 			public:
79 										CEventSink(HWND);
80 				virtual					~CEventSink();
81 
82 				//IUnknown
83 				STDMETHODIMP			QueryInterface(const IID&, void**);
84 				STDMETHODIMP_(ULONG)	AddRef();
85 				STDMETHODIMP_(ULONG)	Release();
86 
87 				//IDispatch
88 				STDMETHODIMP			GetTypeInfoCount(UINT*);
89 				STDMETHODIMP			GetTypeInfo(UINT, LCID, ITypeInfo**);
90 				STDMETHODIMP			GetIDsOfNames(const IID&, LPOLESTR*, UINT, LCID, DISPID*);
91 				STDMETHODIMP			Invoke(DISPID, const IID&, LCID, WORD, DISPPARAMS*, VARIANT*, EXCEPINFO*, UINT*);
92 
93 			private:
94 				ULONG					m_refCount;
95 				HWND					m_browserWnd;
96 			};
97 
98 			static void							EnsureIE9ModeIsActivated();
99 			static UnknownPtr					WebBrowserClientSiteFactory(HWND);
100 
101 			static LRESULT CALLBACK				MsgFilterHook(int, WPARAM, LPARAM);
102 			static void							RegisterFilterHook(CWindow*);
103 			static void							UnregisterFilterHook(CWindow*);
104 			static void							ExchangeFilterHook(CWindow*, CWindow*);
105 
106 			static ULONG __declspec(thread)		g_hookCount;
107 			static HHOOK __declspec(thread)		g_hookHandle;
108 			static std::set<CWindow*>			g_hookListeners;
109 
110 			CComPtr<IWebBrowser2>				m_webBrowser;
111 			CComPtr<IConnectionPoint>			m_eventsConnectionPoint;
112 			CComPtr<CEventSink>					m_eventSink;
113 			DWORD								m_adviseCookie;
114 		};
115 	};
116 }
117