⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 childfrm.h

📁 一个使用wtl写的完整的多窗口浏览器
💻 H
📖 第 1 页 / 共 2 页
字号:
// ChildFrm.h : interface of the CChildFrame class
//
/////////////////////////////////////////////////////////////////////////////
#pragma once

#include "MDITabCtrl.h"
#include <vector>

#include "MDIChildUserMessenger.h"

#ifdef _DEBUG
	const bool _Donut_ChildFrame_traceOn = true;
	#define dcfTRACE if (_Donut_ChildFrame_traceOn) ATLTRACE
#else
	#define dcfTRACE
#endif

class CChildFrame :
	public CMDIChildWindowImplFixed<CChildFrame, 2>,
	public IWebBrowserEvents2Impl<CChildFrame, ID_DONUTVIEW>,
	public CWebBrowserCommandHandler<CChildFrame>,
	public CUpdateCmdUI<CChildFrame>,
	public CMDIChildUserMessenger<CChildFrame>,
	public CWebBrowser2
{
public:
// Declarations
	DECLARE_FRAME_WND_CLASS(NULL, IDR_MDICHILD)
	DECLARE_FRAME_WND_MENU(NULL)
	typedef CMDIChildWindowImplFixed<CChildFrame, 2> baseClass;

// Constants
	enum { _nPosFavoriteMenuOfTab = 4 };

// Data members
	CDonutView m_view;
	BOOL m_bNavigateBack, m_bNavigateForward;
	CMDITabCtrl& m_MDITab;
	CDonutAddressBar& m_AddressBar;
	bool m_bNewWindow2;
	bool m_bClosing;
	CContainedWindow m_wndBrowser;
	CChildFavoriteMenu<CChildFrame> m_FavMenu;

	CString m_strStatusBar;
	long m_nProgress, m_nProgressMax;

	bool m_bMozilla;

	bool m_bPageFocusInitialized;
	bool m_bWaitNavigateLock;
	HWND m_hWndFocus;
//	CComPtr<IHTMLElement> m_spElm;

// Constructor/Destructor
	CChildFrame(CMDITabCtrl& MDITab, CDonutAddressBar& addressbar,
				bool bNewWindow2, DWORD dwDefaultDLControlFlags)
		: m_bNavigateBack(FALSE), m_bNavigateForward(FALSE), 
		  m_MDITab(MDITab), m_AddressBar(addressbar),
		  m_bNewWindow2(bNewWindow2),
		  m_wndBrowser(this, 7), m_FavMenu(this, ID_INSERTPOINT_CHILDFAVORITEMENU),
		  m_nProgress(-1), m_nProgressMax(0), m_bMozilla(false), m_bPageFocusInitialized(false),
		  m_bClosing(false), m_bWaitNavigateLock(true), m_hWndFocus(NULL), m_view(dwDefaultDLControlFlags)
	{
	}

	~CChildFrame()
	{
		dcfTRACE(_T("CChildFrame::~CChildFrame\n"));

		if (m_wndBrowser.IsWindow()) // scary
			m_wndBrowser.UnsubclassWindow();

		ATLASSERT(m_hMenu == NULL); // no menu
	}

	static CChildFrame* NewWindow(HWND hWndMDIClient, CMDITabCtrl& tabMDI,
		CDonutAddressBar& adBar, bool bNewWindow2 = false, DWORD dwDLFlags = CDLControlOption::s_dwDLControlFlags)
	{
		if (!CMainOption::IsQualify(tabMDI.GetItemCount()))
			return NULL;

		ATLTRY(CChildFrame* pChild = new CChildFrame(tabMDI, adBar, bNewWindow2, dwDLFlags));
		if (pChild != NULL)
			pChild->CreateEx(hWndMDIClient);
		return pChild;
	}

// Overrides
	virtual void OnFinalMessage(HWND /*hWnd*/)
	{
		delete this;
	}

	void ActivateFrame(int nCmdShow = -1)
	{
		ATLASSERT(::IsWindow(m_hWnd));
		m_MDITab.OnMDIChildCreate(m_hWnd);

		if (_check_flag(m_view.m_ViewOption.m_dwExStyle, DVS_EX_OPENNEWWIN)) {
			m_MDITab.NavigateLockTab(m_hWnd, true);
		}

		baseClass::ActivateFrame(nCmdShow);
	}

	void ActivateFrameForNewWindowDelayed(int nCmdShow = -1)
	{
		dcfTRACE(_T("CChildFrame::ActivateFrameForNewWindowDelayed - now activating!\n"));
		if (MDIGetActive() != NULL && CMainOption::s_dwMainExtendedStyle & MAIN_EX_NOACTIVATE_NEWWIN)
			nCmdShow = SW_SHOWNOACTIVATE;

		ActivateFrame(nCmdShow);
	}

// Message map and handlers
	BEGIN_MSG_MAP(CChildFrame)
		PASS_MSG_MAP_MDICHILD_TO_MDITAB(m_MDITab)
		PASS_MSG_MAP_MENUOWNER_TO_EXPMENU(m_FavMenu)

		MESSAGE_HANDLER(WM_SIZE, OnSize)
		MSG_WM_SYSCOMMAND(OnSysCommand)
		MSG_WM_CREATE(OnCreate)
		MSG_WM_CLOSE(OnClose)
		MSG_WM_DESTROY(OnDestroy)
		MSG_WM_MDIACTIVATE(OnMDIActivate)
		MSG_WM_FORWARDMSG(OnForwardMsg)

		HANDLE_MESSAGE(WM_SETFOCUS)			// baseClass handler is not effective

		USER_MSG_WM_SAVE_OPTION(OnSaveOption)
		MSG_WM_USER_GET_IWEBBROWSER()
		COMMAND_ID_HANDLER_EX(ID_FILE_CLOSE, OnFileClose)
		COMMAND_ID_HANDLER_EX(ID_EDIT_IGNORE, OnEditIgnore)
		COMMAND_ID_HANDLER_EX(ID_EDIT_OPEN_SELECTED_REF, OnEditOpenSelectedRef)
		COMMAND_ID_HANDLER_EX(ID_EDIT_OPEN_SELECTED_TEXT, OnEditOpenSelectedText)

		COMMAND_ID_HANDLER_EX(ATL_IDS_SCPREVWINDOW, OnWindowPrev)
		COMMAND_ID_HANDLER_EX(ATL_IDS_SCNEXTWINDOW, OnWindowNext)

		COMMAND_ID_HANDLER_EX(ID_FAVORITE_GROUP_ADD, OnFavoriteGroupAdd)
		COMMAND_ID_HANDLER_EX(ID_FAVORITE_ADD, OnFavoriteAdd)

		COMMAND_ID_HANDLER_EX(ID_VIEW_SETFOCUS, OnViewSetFocus)
		COMMAND_ID_HANDLER_EX(ID_VIEW_REFRESH, OnViewRefresh)
		COMMAND_ID_HANDLER_EX(ID_VIEW_STOP, OnViewStop)
		COMMAND_ID_HANDLER_EX(ID_VIEW_OPTION, OnViewOption)
		COMMAND_ID_HANDLER_EX(ID_FILE_SAVE_AS, OnFileSaveAs)
		COMMAND_ID_HANDLER_EX(ID_FILE_PAGE_SETUP, OnFilePageSetup)
		COMMAND_ID_HANDLER_EX(ID_FILE_PRINT, OnFilePrint)
		COMMAND_ID_HANDLER_EX(ID_FILE_PROPERTIES, OnFileProperties)

		COMMAND_ID_HANDLER_EX(ID_EDIT_FIND, OnEditFind)

		COMMAND_ID_HANDLER(ID_WINDOW_CLOSE_EXCEPT, OnWindowCloseExcept)

		COMMAND_ID_HANDLER(ID_VIEW_REFRESH_FAVBAR, OnViewRefreshFavBar)

		COMMAND_ID_HANDLER_EX(ID_DOCHOSTUI_OPENNEWWIN, OnDocHostUIOpenNewWin)
		COMMAND_ID_HANDLER_EX(ID_REGISTER_AS_BROWSER, OnRegisterAsBrowser)

		COMMAND_ID_HANDLER_EX(ID_VIEW_BACK1, OnViewBackX)
		COMMAND_ID_HANDLER_EX(ID_VIEW_BACK2, OnViewBackX)
		COMMAND_ID_HANDLER_EX(ID_VIEW_BACK3, OnViewBackX)
		COMMAND_ID_HANDLER_EX(ID_VIEW_BACK4, OnViewBackX)
		COMMAND_ID_HANDLER_EX(ID_VIEW_BACK5, OnViewBackX)
		COMMAND_ID_HANDLER_EX(ID_VIEW_FORWARD1, OnViewForwardX)
		COMMAND_ID_HANDLER_EX(ID_VIEW_FORWARD2, OnViewForwardX)
		COMMAND_ID_HANDLER_EX(ID_VIEW_FORWARD3, OnViewForwardX)
		COMMAND_ID_HANDLER_EX(ID_VIEW_FORWARD4, OnViewForwardX)
		COMMAND_ID_HANDLER_EX(ID_VIEW_FORWARD5, OnViewForwardX)

		COMMAND_ID_HANDLER_EX(ID_TITLE_COPY, OnTitleCopy)
		COMMAND_ID_HANDLER_EX(ID_URL_COPY, OnUrlCopy)

		CHAIN_COMMANDS(CWebBrowserCommandHandler<CChildFrame>)
		CHAIN_MSG_MAP(CUpdateCmdUI<CChildFrame>)
		CHAIN_MSG_MAP(CMDIChildUserMessenger<CChildFrame>)

		CHAIN_COMMANDS_MEMBER(m_view)// CHAIN_CLIENT_COMMANDS() not send, why?
		CHAIN_MSG_MAP(baseClass)
	ALT_MSG_MAP(7)// to hook WM_CLOSE from Browser internal window (for script: "window.close()")
		MSG_WM_CLOSE(OnBrowserClose)
	END_MSG_MAP()

// Command overrides 
	void OnRegisterAsBrowser(WORD wNotifyCode, WORD /*wID*/, HWND /*hWndCtl*/)
	{
		SetRegisterAsBrowser(wNotifyCode == NM_ON);
	}

	void OnDocHostUIOpenNewWin(WORD wNotifyCode, WORD /*wID*/, HWND /*hWndCtl*/)
	{
		if (wNotifyCode == NM_ON) {
			m_view.m_ViewOption.m_dwExStyle |= DVS_EX_OPENNEWWIN;
			m_MDITab.NavigateLockTab(m_hWnd, true);
		}
		else if (wNotifyCode == NM_OFF) {
			m_view.m_ViewOption.m_dwExStyle &= ~DVS_EX_OPENNEWWIN;
			m_MDITab.NavigateLockTab(m_hWnd, false);
		}
		else if (m_view.m_ViewOption.m_dwExStyle & DVS_EX_OPENNEWWIN) {
			m_view.m_ViewOption.m_dwExStyle &= ~DVS_EX_OPENNEWWIN;
			m_MDITab.NavigateLockTab(m_hWnd, false);
		}
		else {
			m_view.m_ViewOption.m_dwExStyle |= DVS_EX_OPENNEWWIN;
			m_MDITab.NavigateLockTab(m_hWnd, true);
		}
	}

	void OnViewSetFocus(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/)
	{
		// NOTE. _SetPageFoucs would fail if document not completed.
		m_bPageFocusInitialized = false;// reset focus
		_SetPageFocus();
	}

	void OnViewRefresh(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/)
	{
		if (::GetAsyncKeyState(VK_CONTROL) < 0)// Inspired by DOGSTORE, Thanks
			Refresh2(REFRESH_COMPLETELY);
		else
			Refresh();
	}

	void OnViewStop(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/)
	{
		Stop();

		// make sure
		m_nDownloadCounter = 0;
		OnStateCompleted(); 
	}

	void OnFavoriteAdd(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/)
	{
		bool bOldShell = _check_flag(MAIN_EX_ADDFAVORITEOLDSHELL, CMainOption::s_dwMainExtendedStyle);
		MtlAddFavorite(GetLocationURL(), MtlGetWindowText(m_hWnd), bOldShell, DonutGetFavoritesFolder(), m_hWnd);
	}

	void OnFavoriteGroupAdd(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/)
	{
		TCHAR szOldPath[MAX_PATH];// save current directory
		::GetCurrentDirectory(MAX_PATH, szOldPath);

		const TCHAR szFilter[] = _T("Donut Favorite Group File(*.dfg)\0*.dfg\0\0");

		::SetCurrentDirectory(DonutGetFavoriteGroupFolder());

		CFileDialog fileDlg(FALSE, _T("dfg"), NULL, OFN_HIDEREADONLY, szFilter);
		fileDlg.m_ofn.lpstrInitialDir = DonutGetFavoriteGroupFolder();
		fileDlg.m_ofn.lpstrTitle = _T("Add to Favorite Group");
		if (fileDlg.DoModal() == IDOK) {
			_AddGroupOption(fileDlg.m_szFileName);
		}

		// restore current directory
		::SetCurrentDirectory(szOldPath);
	}

	void _AddGroupOption(const CString& strFileName)
	{
		CIniSection pr;
		pr.Open(strFileName, _T("Header"));
		DWORD dwCount = 0;
		pr.QueryValue(dwCount, _T("count"));

		OnSaveOption(strFileName, dwCount);
		dwCount += 1;

		pr.SetValue(dwCount, _T("count"));
//		pr.SetValue(f._nActiveIndex, _T("active"));
		pr.Close();
	}

	void OnClose()
	{
		SetMsgHandled(FALSE);
		m_bClosing = true;

		// for mdi tab ctrl
		HWND hWndActiveNext = NULL;
		if (MDIGetActive() == m_hWnd) {
			int nIndex = m_MDITab.ManageClose(m_hWnd);
			if (nIndex != -1) {
				hWndActiveNext = m_MDITab.GetTabHwnd(nIndex);
				ATLASSERT(::IsWindow(hWndActiveNext));
			}
		}
		m_MDITab.OnMDIChildDestroy(m_hWnd);
		if (hWndActiveNext)
			MDIActivate(hWndActiveNext);

		CString strURL = GetLocationURL();
		if (!strURL.IsEmpty())
			CMainOption::s_pMru->AddToList(strURL);
	}

	LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		dcfTRACE(_T("CChildFrame::OnSize type(%d)\n"), wParam);
		if (CMainOption::s_bTabMode && (wParam == SIZE_RESTORED || wParam == SIZE_MINIMIZED)) {
			dcfTRACE(_T(" restored\n"));
			bHandled = TRUE;// eat it!!
			return 0;
		}
		else {
			bHandled = FALSE;
			return -1;
		}
	}

	void OnSysCommand(UINT uCmdType, CPoint pt)
	{
		if (CMainOption::s_bTabMode && (uCmdType == SC_MINIMIZE || uCmdType == SC_RESTORE))
			SetMsgHandled(TRUE);
		else
			SetMsgHandled(FALSE);
	}

	void OnWindowPrev(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/)
	{
		MDINext(m_hWnd, TRUE);
	}

	void OnWindowNext(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/)
	{
		MDINext(m_hWnd, FALSE);
	}

	LRESULT OnWindowCloseExcept(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		if (!CDonutConfirmOption::OnCloseAllExcept(GetTopLevelParent()))
			return 0;

		CWaitCursor cur;
		CLockRedrawMDIClient lock(m_hWndMDIClient);
		CLockRedraw lock2(m_MDITab);
		MtlCloseAllMDIChildrenExcept(m_hWndMDIClient, m_hWnd);
		return 0;
	}

	LRESULT OnForwardMsg(LPMSG pMsg, DWORD)
	{
		if(baseClass::PreTranslateMessage(pMsg))
			return TRUE;

		return m_view.PreTranslateMessage(pMsg);
	}

	LRESULT OnCreate(LPCREATESTRUCT lpcreatestruct)
	{
		dcfTRACE(_T("CChildFrame::OnCreate\n"));
		// Let me initialize itself
		LRESULT lRet = DefWindowProc();

		m_bMozilla = _bMozilla;// mozilla engine?

		//TODO: Replace with a URL of your choice
		CRect rc = rcDefault;
		__CalcDefaultRect(rc);
		m_hWndClient = m_view.Create(m_hWnd, rc, _T("about:blank"), 
			WS_CHILD | WS_VISIBLE/* | WS_CLIPSIBLINGS | WS_CLIPCHILDREN*/, WS_EX_CLIENTEDGE, ID_DONUTVIEW);

		m_view.QueryControl(IID_IWebBrowser2, (void**)&m_spBrowser);

		WebBrowserEvents2Advise();

		if (_check_flag(MAIN_EX_REGISTER_AS_BROWSER, CMainOption::s_dwMainExtendedStyle))
			SetRegisterAsBrowser(true);// for target name resolution

		_SetupWindowCloseHook();

		// set up for mdi tab ctrl
		CMenuHandle menu0 = m_MDITab.m_menuPopup.GetSubMenu(0);
		HMENU hMenu = menu0.GetSubMenu(_nPosFavoriteMenuOfTab);
		m_FavMenu.InstallExplorerMenu(hMenu);

		if (!m_bNewWindow2)
			SetVisible(true);

		CFavoritesMenuOption::Add(m_hWnd);

		return lRet;
	}

	void __CalcDefaultRect(CRect& rc)
	{
		BOOL bMaximized = FALSE;
		HWND hWndActive = MDIGetActive(&bMaximized);
		if (hWndActive == NULL || bMaximized) {
			::GetClientRect(m_hWndMDIClient, &rc);
		}
	}

	void OnDestroy()
	{
		dcfTRACE(_T("CChildFrame::OnDestroy\n"));
		SetMsgHandled(FALSE);
		m_bClosing = true;

		SetRegisterAsBrowser(false);

		// m_view.DestroyWindow makes offline state reset, so
		// save global offline state
		bool bGlobalOffline = MtlIsGlobalOffline();

		// Before AtlAdviseSinkMap(this, false) destroy view,
		// cuz I wanna handle OnNewWindow2 event
		// And while destroying view, a meaningless WM_DRAWCLIPBOARD may be sent, so ignore it.

		CMainOption::s_bIgnoreUpdateClipboard = true;
		dcfTRACE(_T(" m_view.Destroy\n"));
		if (m_view.IsWindow())
			m_view.DestroyWindow();
		CMainOption::s_bIgnoreUpdateClipboard = false;

		dcfTRACE(_T(" DispEventUnadvise\n"));

		WebBrowserEvents2Unadvise();

		// restore global offline state
		MtlSetGlobalOffline(bGlobalOffline);
	}

	LRESULT OnViewRefreshFavBar(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		m_FavMenu.SetRootDirectoryPath(DonutGetFavoritesFolder());
		m_FavMenu.RefreshMenu();
		return 0;
	}

	void OnFileClose(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/)
	{
		m_bClosing = true;
		PostMessage(WM_CLOSE);
	}

	void OnEditIgnore(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/)
	{
		dcfTRACE(_T("CChildFrame::OnEditIgnore\n"));
		CIgnoredURLsOption::Add(GetLocationURL());
		m_bClosing = true;
		PostMessage(WM_CLOSE);
	}

	void OnEditOpenSelectedRef(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/)
	{
		dcfTRACE(_T("CChildFrame::OnEditOpenSelectedRef\n"));
		MtlForEachHTMLDocument2(m_spBrowser, _Function_OpenSelectedRef(m_hWnd));
	}

	void OnEditOpenSelectedText(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/)
	{
		dcfTRACE(_T("CChildFrame::OnEditOpenSelectedTitle\n"));
		MtlForEachHTMLDocument2( m_spBrowser, Mtl_bind_mem_fun_void(&CChildFrame::_OpenSelectedText, this) );
	}

	void _OpenSelectedText(IHTMLDocument2* pDocument)
	{
		CComPtr<IHTMLSelectionObject> spSelection;
		HRESULT hr = pDocument->get_selection(&spSelection);
		if (FAILED(hr))
			return;

		CComPtr<IDispatch> spDisp;
		hr = spSelection->createRange(&spDisp);
		if (FAILED(hr))
			return;
		
		CComQIPtr<IHTMLTxtRange> spTxtRange = spDisp;
		if (!spTxtRange)
			return;

		CComBSTR bstrText;
		hr = spTxtRange->get_text(&bstrText);
		if (FAILED(hr) || !bstrText)
			return;

		CString strUrl(bstrText);
		DonutOpenFile(m_hWnd, strUrl);
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -