Как я могу создать href ссылки на CHtmlEditCtrl? - PullRequest
0 голосов
/ 02 февраля 2019

Я создаю диалог, используя Visual Studio 2017 c ++ MFC и веб-ссылки CHtmlEditCtrl.

Но ссылки href не работают ...

Я ожидаю следующего поведения.

  1. щелкнув ссылку
  2. запуск браузера (например, хром)
  3. отображение веб-страницы в браузере

Как исправитьмой код?

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);
    };
}

enter image description here

Я ссылался на следующий сайт.

1 Ответ

0 голосов
/ 02 февраля 2019

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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...