📄 childfrm.h
字号:
// 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 + -