pub.cpp
来自「一个在IExplorer中运行」· C++ 代码 · 共 1,736 行 · 第 1/4 页
CPP
1,736 行
if (SUCCEEDED(hr) && spClientSite)
{
m_spDefaultDocHostUIHandler = spClientSite;
m_spDefaultOleCommandTarget = spClientSite;
}
}
// Set this class to be the IDocHostUIHandler
CComQIPtr<ICustomDoc, &IID_ICustomDoc> spCustomDoc(spDisp);
if (spCustomDoc)
{
hr = spCustomDoc->SetUIHandler(this);
ATLASSERT(SUCCEEDED(hr));
}
// Create a CPubDomExtender object that will be used by
// window.external
CComObject<CPubDomExtender>* pDomExt;
hr = CComObject<CPubDomExtender>::CreateInstance (&pDomExt);
ATLASSERT(SUCCEEDED(hr));
if (SUCCEEDED(hr))
{
CComQIPtr<IDispatch> spDisp = pDomExt;
m_spExtDispatch = spDisp;
pDomExt->m_pPub = this;
}
// Check for flash here because READYSTATE_COMPLETE
// seems to be unreliable.
if (IsEnabled() )
{
DWORD dwElemTypes = 0;
if (g_bBlockFlash)
dwElemTypes |= ELEMTYPE_FLASH | ELEMTYPE_IMAGES;
BlockWebPageElements(dwElemTypes);
}
}
}
}
m_bHotkeysEnabled = TRUE;
break;
//
// No parameters
//
// Fires when a navigation operation is beginning.
//
case DISPID_DOWNLOADBEGIN:
ATLTRACE(_T("(%ld) DISPID_DOWNLOADBEGIN\n"), ::GetCurrentThreadId());
break;
//
// No parameters
//
// Fires when a navigation operation finishes, is halted, or fails.
//
case DISPID_DOWNLOADCOMPLETE:
ATLTRACE(_T("(%ld) DISPID_DOWNLOADCOMPLETE\n"), ::GetCurrentThreadId());
{
if (IsEnabled() )
{
DWORD dwElemTypes = 0;
if (g_bBlockFlash)
dwElemTypes |= ELEMTYPE_FLASH | ELEMTYPE_IMAGES;
BlockWebPageElements(dwElemTypes);
}
}
break;
//
// The parameters for this DISPID:
// [0]: Enabled state - VT_BOOL
// [1]: Command identifier - VT_I4
//
case DISPID_COMMANDSTATECHANGE:
break;
//
// The parameters for this DISPID:
// [0]: Document title - VT_BSTR
// [1]: An object that evaluates to the top-level or frame
// WebBrowser object corresponding to the event.
//
case DISPID_TITLECHANGE:
break;
//
// The parameters for this DISPID:
// [0]: Name of property that changed - VT_BSTR
//
case DISPID_PROPERTYCHANGE:
break;
//
// No parameters
//
// The BHO docs in MSDN say to use DISPID_QUIT, but this is an error.
// The BHO never gets a DISPID_QUIT and thus the browser connection
// never gets unadvised and so the BHO never gets the FinalRelease().
// This is bad. So use DISPID_ONQUIT instead and everything is cool --
// EXCEPT when you exit the browser when viewing a page that launches
// a popup in the onunload event! In that case the BHO is already
// unadvised so it does not intercept the popup. So the trick is to
// navigate to a known page (I used the about:blank page) that does
// not have a popup in the onunload event before unadvising.
//
case DISPID_ONQUIT:
ATLTRACE(_T("(%ld) DISPID_QUIT\n"), ::GetCurrentThreadId());
{
NavigateToSafePage();
// OK, we are now on a 'safe' page with no popups.
// Set the shutting down flag to stop all normal
// processing, like checking the whitelist, while
// the bho is shut down.
m_bShuttingDown = TRUE;
// Unadvise
HRESULT hr = ManagePropertyNotifyConnection(ConnType_Unadvise);
ATLASSERT(SUCCEEDED(hr));
while (m_deqEventHandlers.size() > 0)
{
CConnInfo* pConnInfo = m_deqEventHandlers.front();
ManageEventHandlers(pConnInfo, ConnType_Unadvise);
delete pConnInfo;
m_deqEventHandlers.pop_front();
}
hr = ManageBrowserConnection(ConnType_Unadvise);
ATLASSERT(SUCCEEDED(hr));
// Release the document
if (m_spHTMLDocument)
m_spHTMLDocument.Release();
if (RemoveInstance(this, m_hwndIE, GetCurrentProcessId()) && m_hHook)
UnhookWindowsHookEx(m_hHook);
// FinalRelease should get called next.
// If not, you have not released everything.
}
break;
default:
break;
}
return S_OK;
}
//
// IDocHostUIHandler Methods
//
//
// Window procedure for handling enabling/disabling/checking in our context menu.
//
LRESULT CALLBACK CtxMenuWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (uMsg == WM_INITMENUPOPUP)
{
if (wParam == (WPARAM) g_hPubMenu)
{
// This is our menu
::CheckMenuItem(g_hPubMenu, ID_CTXMENU_ENABLEPOPUPBLOCKER,
MF_BYCOMMAND | (g_bEnabled ? MF_CHECKED : MF_UNCHECKED));
::CheckMenuItem(g_hPubMenu, ID_CTXMENU_DELETEFLASHANIMATIONS,
MF_BYCOMMAND | (g_bBlockFlash ? MF_CHECKED : MF_UNCHECKED));
return 0;
}
}
return CallWindowProc(g_lpPrevWndProc, hwnd, uMsg, wParam, lParam);
}
//
// Insert our Popup Blocker sub menu into the context menu
//
HRESULT CPub::ShowContextMenu(DWORD dwID,
POINT *ppt,
IUnknown *pcmdTarget,
IDispatch *pdispObject)
{
// Return S_OK to tell MSHTML not to display its own menu
// Return S_FALSE displays default MSHTML menu
#define IDR_BROWSE_CONTEXT_MENU 24641
#define SHDVID_GETMIMECSETMENU 27
#define SHDVID_ADDMENUEXTENSIONS 53
HRESULT hr;
CComPtr<IOleCommandTarget> spCT;
hr = pcmdTarget->QueryInterface(IID_IOleCommandTarget, (void**)&spCT);
if (FAILED(hr))
return S_FALSE;
CComPtr<IOleWindow> spWnd;
hr = pcmdTarget->QueryInterface(IID_IOleWindow, (void**)&spWnd);
if (FAILED(hr))
return S_FALSE;
HWND hwnd;
hr = spWnd->GetWindow(&hwnd);
if (FAILED(hr))
return S_FALSE;
hr = S_FALSE;
HINSTANCE hinstSHDOCLC = LoadLibrary(_T("SHDOCLC.DLL"));
if (hinstSHDOCLC)
{
HMENU hCtxMenu = LoadMenu(hinstSHDOCLC, MAKEINTRESOURCE(IDR_BROWSE_CONTEXT_MENU));
if (hCtxMenu)
{
HMENU hSubMenu = GetSubMenu(hCtxMenu, dwID);
if (hSubMenu)
{
// Get the language submenu
CComVariant var;
hr = spCT->Exec(&CGID_ShellDocView, SHDVID_GETMIMECSETMENU, 0, NULL, &var);
if (SUCCEEDED(hr))
{
MENUITEMINFO mii = {0};
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_SUBMENU;
mii.hSubMenu = (HMENU) var.byref;
// Add language submenu to Encoding context item
SetMenuItemInfo(hSubMenu, IDM_LANGUAGE, FALSE, &mii);
// Insert Shortcut Menu Extensions from registry
CComVariant var1;
V_VT(&var1) = VT_INT_PTR;
V_BYREF(&var1) = hSubMenu;
CComVariant var2;
V_VT(&var2) = VT_I4;
V_I4(&var2) = dwID;
// This fails under Win98, but is OK under Win98SE
hr = spCT->Exec(&CGID_ShellDocView, SHDVID_ADDMENUEXTENSIONS, 0, &var1, &var2);
if (SUCCEEDED(hr))
{
// Insert our menu at the top of the context menu
HMENU hMenu = NULL;
HINSTANCE hInst = (*_pModule).GetResourceInstance();
if (hInst)
{
hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_PUBMENU));
if (hMenu)
{
CString s;
s.LoadString(IDS_MENU_TEXT);
g_hPubMenu = ::GetSubMenu(hMenu, 0);
::InsertMenu(hSubMenu, 0, MF_POPUP | MF_BYPOSITION, (UINT_PTR) g_hPubMenu, s);
::InsertMenu(hSubMenu, 1, MF_BYPOSITION | MF_SEPARATOR, NULL, NULL);
}
}
// Subclass IE window.
// This is required in order to enable our menu. Otherwise, IE
// disregards menu items it doesn't recognize.
#pragma warning( push )
#pragma warning( disable : 4311 )
#pragma warning( disable : 4312 )
g_lpPrevWndProc = (WNDPROC)::SetWindowLong(hwnd, GWL_WNDPROC, (LONG)CtxMenuWndProc);
#pragma warning( pop )
// Show shortcut menu
int nCmd = ::TrackPopupMenu(hSubMenu,
TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,
ppt->x,
ppt->y,
0,
hwnd,
(RECT*)NULL);
// Unsubclass IE window
#pragma warning( push )
#pragma warning( disable : 4311 )
::SetWindowLong(hwnd, GWL_WNDPROC, (LONG)g_lpPrevWndProc);
g_lpPrevWndProc = NULL;
#pragma warning( pop )
if (hMenu)
{
DestroyMenu(hMenu);
g_hPubMenu = NULL;
}
if (nCmd == ID_CTXMENU_ENABLEPOPUPBLOCKER)
{
EnablePopupBlocker();
}
else if (nCmd == ID_CTXMENU_DELETEFLASHANIMATIONS)
{
g_bBlockFlash = !g_bBlockFlash;
DWORD dwElemTypes = 0;
if (g_bBlockFlash)
{
try
{
CRegKey rk;
DWORD dwErr = rk.Open(HKEY_CURRENT_USER, g_sCoRegKey + g_sPubRegKey);
if (dwErr == ERROR_SUCCESS)
rk.SetDWORDValue(_T("BlockFlash"), g_bBlockFlash);
}
catch(...)
{
}
dwElemTypes |= ELEMTYPE_FLASH | ELEMTYPE_IMAGES;
BlockWebPageElements(dwElemTypes);
}
}
//else if (nCmd == ID_CTXMENU_OPTIONS)
//{
// EditOptions(0);
//}
//else if (nCmd == ID_CTXMENU_WHITELIST)
//{
// EditOptions(3);
//}
//else if (nCmd == ID_CTXMENU_HISTORY)
//{
// EditOptions(4);
//}
//else if (nCmd == ID_CTXMENU_ABOUT)
//{
// EditOptions(5);
//}
else
{
// ATLTRACE(_T("ContextMenu cmd = %d\n"), nCmd);
if (nCmd == IDM_FOLLOWLINKN)
{
// Allow user to open link in new window
m_bBlockNewWindow = FALSE;
}
// Send selected shortcut menu item command to shell
LRESULT lr = ::SendMessage(hwnd, WM_COMMAND, nCmd, NULL);
}
}
}
}
DestroyMenu(hCtxMenu);
}
FreeLibrary(hinstSHDOCLC);
}
return (SUCCEEDED(hr) ? hr : S_FALSE);
}
//
// IPropertyNotifySink methods
//
STDMETHODIMP CPub::OnChanged(DISPID dispID)
{
if (DISPID_READYSTATE == dispID)
{
// check the value of the readystate property
if (m_spHTMLDocument)
{
VARIANT vResult = {0};
EXCEPINFO excepInfo;
UINT uArgErr;
DISPPARAMS dp = {NULL, NULL, 0, 0};
HRESULT hr = m_spHTMLDocument->Invoke(DISPID_READYSTATE, IID_NULL, LOCALE_SYSTEM_DEFAULT,
DISPATCH_PROPERTYGET, &dp, &vResult, &excepInfo, &uArgErr);
if (SUCCEEDED(hr))
{
ATLASSERT(VT_I4 == V_VT(&vResult));
READYSTATE m_lReadyState = (READYSTATE)V_I4(&vResult);
switch (m_lReadyState)
{
case READYSTATE_UNINITIALIZED:
ATLTRACE(_T("OnChanged: readyState = Uninitialized\n"));
break;
case READYSTATE_LOADING:
ATLTRACE(_T("OnChanged: readyState = Loading\n"));
break;
case READYSTATE_LOADED:
ATLTRACE(_T("OnChanged: readyState = Loaded\n"));
break;
case READYSTATE_INTERACTIVE:
ATLTRACE(_T("OnChanged: readyState = Interactive\n"));
break;
case READYSTATE_COMPLETE:
ATLTRACE(_T("OnChanged: readyState = Complete\n"));
// Check for flash here because DISPID_DOCUMENTCOMPLETE
// seems to be unreliable.
if (IsEnabled() )
{
DWORD dwElemTypes = 0;
if (g_bBlockFlash)
dwElemTypes |= ELEMTYPE_FLASH | ELEMTYPE_IMAGES;
BlockWebPageElements(dwElemTypes);
}
break;
}
VariantClear(&vResult);
}
else
{
ATLTRACE(_T("OnChanged: Unable to obtain readyState value\n"));
}
}
}
else
{
ATLTRACE(_T("OnChanged: %ld\n"), dispID);
}
return S_OK;
}
//
// Return TRUE if the popup blocker is enabled.
//
BOOL CPub::IsEnabled()
{
return (!m_bShuttingDown && g_bEnabled );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?