我使用Visual Studio 2017 c ++ MFC和CHtmlEditCtrl的Web链接进行对话框。
不过,在href链接不工作...
我期望以下行为。
如何修复我的代码?
BOOL CTestDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// ...
CHtmlEditCtrl* htmledit = new CHtmlEditCtrl();
CEdit* edit = (CEdit*)GetDlgItem(IDC_EDIT_HTML);
CRect rc;
edit->GetWindowRect(&rc);
this->ScreenToClient(&rc);
htmledit->Create(0, (WS_CHILD | WS_VISIBLE), rc, this, IDC_EDIT_HTML, 0);
CComPtr<IHTMLDocument2> document;
htmledit->GetDocument(&document);
WaitForComplete(document);
htmledit->SetDocumentHTML(_T("<a href=\"https://www.google.co.jp/\" target=\"_blank\">Google</a><br><a href=\"https://stackoverflow.com/\" target=\"_blank\">stackoverflow</a>"));
WaitForComplete(document);
return TRUE;
}
void CTestDlg::WaitForComplete(IHTMLDocument2* document)
{
BSTR ready;
document->get_readyState(&ready);
while (wcscmp(ready, L"complete"))
{
AfxPumpMessage();
document->get_readyState(&ready);
};
}
我提到了以下站点。
答案 0 :(得分:3)
CHtmlEditCtrl
会覆盖NavigateComplete2
并调用SetDesignMode(TRUE)
。如果要查看器而不是编辑器,请按如下所示进行覆盖:
class CMyHtmlEditCtrl : public CHtmlEditCtrl
{
virtual void _OnNavigateComplete2(LPDISPATCH, VARIANT FAR*)
{
//SetDesignMode(TRUE);
}
public:
DECLARE_EVENTSINK_MAP()
};
BEGIN_EVENTSINK_MAP(CMyHtmlEditCtrl, CHtmlEditCtrl)
ON_EVENT_REFLECT(CMyHtmlEditCtrl, 252 /* NavigateComplete2 */, _OnNavigateComplete2, VTS_DISPATCH VTS_PVARIANT)
END_EVENTSINK_MAP()
使用此类代替CHtmlEditCtrl
。您不再需要WaitForComplete
,因为SetDesignMode
不会阻止OnInitDialog
中的呼叫。
_OnBeforeNavigate
此外,将#
添加到链接:href="#http://www.google.com"
,以使浏览器控件不知道如何处理链接,而让您处理它。然后,您将#http://www.google.com
转换为http://www.google.com
并打开链接。
声明为CMyHtmlEditCtrl browser;
作为类成员,以避免泄漏。
示例:
class CMyHtmlEditCtrl : public CHtmlEditCtrl
{
public:
virtual void _OnNavigateComplete2(LPDISPATCH, VARIANT FAR*)
{
//SetDesignMode(TRUE);
}
void _OnBeforeNavigate2(LPDISPATCH,
VARIANT* URL, VARIANT*, VARIANT*, VARIANT*, VARIANT*, VARIANT_BOOL*)
{
CString str(V_BSTR(URL));
int pos = str.Find(L'#');
if(pos >= 0)
{
str = str.Mid(pos + 1);
ShellExecute(NULL, L"open", str, NULL, NULL, SW_SHOWNORMAL);
}
}
DECLARE_EVENTSINK_MAP()
};
BEGIN_EVENTSINK_MAP(CMyHtmlEditCtrl, CHtmlEditCtrl)
ON_EVENT_REFLECT(CMyHtmlEditCtrl, 250, _OnBeforeNavigate2, VTS_DISPATCH VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PBOOL)
ON_EVENT_REFLECT(CMyHtmlEditCtrl, 252, _OnNavigateComplete2, VTS_DISPATCH VTS_PVARIANT)
END_EVENTSINK_MAP()
...
//declare class member for CMyDialog:
CMyHtmlEditCtrl browser;
...
CMyHtmlEditCtrl browser;
BOOL CMyDialog::OnInitDialog()
{
CDialogEx::OnInitDialog();
CWnd* edit = GetDlgItem(IDC_EDIT1);
CRect rc;
edit->GetWindowRect(&rc);
ScreenToClient(&rc);
browser.Create(0, WS_CHILD | WS_VISIBLE, rc, this, 301, 0);
CString html = LR"(<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01
Transitional//EN">
<html>
<head>
<style type="text/css">
body
{
border:1px solid gray;
}
</style>
</head>
<body>
<a href="#http://www.stackoverflow.com">http://www.stackoverflow.com</a>
</body>
</html>
)";
browser.SetDocumentHTML(html);
return TRUE;
}