4

ダイアログに読み取り専用のリッチエディット2.0コントロールを追加しました(コードはC Windows APIを使用し、ダイアログは関数DialogBoxを使用して作成されます)

ダイアログのコールバックで、WM_INITDIALOGで、次のコードを追加して、URL検出を有効にし、リッチ編集コントロール自体ではなく、イベントENM_LINKが親ダイアログに送信されるようにします。

LRESULT mask = SendMessage(hWndText, EM_GETEVENTMASK, 0, 0); //hWndText is rich edit control
SendMessage(hWndText, EM_SETEVENTMASK, 0, mask | ENM_LINK);
::SendMessage(hWndText, EM_AUTOURLDETECT, TRUE, NULL);  

ダイアログが最初に起動されたときにURL検出を有効にするのに少し問題がありました(リッチエディットコントロールは変更されたテキストのURL検出しか有効にしないため、これは既知の問題または動作のようです)。ただし、すべてのWM_PAINTイベントでダイアログテキストを再度設定することで、この問題を回避しました。

コードは一般的に機能しています。また、マウスがURLにカーソルを合わせたときに、ブラウザーでURLを起動するために、次のコードを実装しました。

case WM_NOTIFY:
    plink = (ENLINK *) lParam;
    switch(LOWORD(wParam))
    {   
        case IDC_DISPLAY_TEXT_2: //this is ID for my rich edit control
            szURL =m_strDisplay.Mid(plink->chrg.cpMin, plink->chrg.cpMax - plink->chrg.cpMin);          
            LaunchURL(szURL); //function to launch the url with default browser
            break;
        default:
            break;
    }

URLの上にマウスを置くたびにWM_NOTIFYイベントが発生するようです。ただし、クリックすると、マウスを合わせると常に同じイベントが発生します。

ENLINKの構造に基づいて、NMHDR構造でより詳細なNMイベントを取得する必要がありますが、値plink-> nmhdr.codeは常に1803であり、NM_HOVERでもありません(定義された値は(NM_FIRST-13)であり、NM_FIRSTは( 0U-0U)、したがって、NM_HOVER値は私の64ビットマシンでは4294967283です)。私はここで何かが欠けていることを知っています。誰かがここでいくつかの光を当てることができますか?リッチエディットコントロールのマウスクリックイベントを取得するにはどうすればよいですか?

4

3 に答える 3

7

EN_LINK通知をキャプチャする必要があると思います。次のコードを実装しました。ダイアログではなく、親ウィンドウに配置されたリッチエディットコントロールのURLリンクを有効にします。ダイアログに合わせて調整することもできます。

コードから始めることを検討してください。

case WM_NOTIFY: {
switch (((LPNMHDR)lParam)->code) { //NMHDR structure contains information about a notification message.
        case EN_LINK: {
            ENLINK *enLinkInfo = (ENLINK *)lParam; // pointer to a ENLINK structure

次に、LBUTTONUPでURLを起動することを選択した場合は、に含まれている値を確認する必要がありますenLinkInfo->msg(ただし、ダイアログに合わせて調整することを忘れないでください)。

 if (enLinkInfo->msg == WM_LBUTTONUP) {
// select all the text from enLinkInfo->chrg.cpMin to enLinkInfo->chrg.cpMax
// lauch the url

}

さらに、WM_MOUSEMOVEをインターセプトできます。

if(enLinkInfo->msg == WM_MOUSEMOVE) {
                ; // do nothing
}

それが役に立てば幸い。

于 2012-07-09T16:12:54.977 に答える
4

@ A_nto2による回答が示すように、マウスクリックをインターセプトするには次のようにします。

case WM_NOTIFY: {
    //NMHDR structure contains information about a notification message.
    switch (((LPNMHDR)lParam)->code) {
        case EN_LINK: {
            ENLINK *enLinkInfo = (ENLINK *)lParam; // pointer to a ENLINK structure
            if (enLinkInfo->msg == WM_LBUTTONUP) {

ただし、注意が必要なのは、クリックされたリンクを取得することです。

enLinkInfo->chrgタイプのでクリックされた「範囲」を取得しますCHARRANGE

RichEditでURLのクリックを検出するための回答は、を使用することを提案してEM_EXSETSELenLinkInfo->chrgます。次に、を使用しEM_GETSELTEXTてテキストを取得します。

これは、自動検出されたプレーンテキストURL(EM_AUTOURLDETECT)で機能します。

問題は、フレンドリ名のハイパーリンク(つまり、URL自体とは異なるアンカーテキストを持つハイパーリンク)にあります。

{\rtf1{\field{\*\fldinst{ HYPERLINK "https://www.example.com"}}{\fldrslt{Example}}}}

(これらはRich Edit 4.1以降でのみサポートされていることに注意してください)

これらの場合、CHARRANGEポイントHYPERLINK "https://www.example.com"は非表示であり、を使用して選択できないパーツを指しEM_EXSETSELます。実際にはWindows10で選択できますが、Windows 7、Vista、XPでは選択できません。これらのシステムにを送信するEM_EXSETSELと、非表示部分の直後に長さゼロのブロックが選択されます。

したがって、リッチエディットバッファに戻ってリンクをスキャンする必要があります。または、別の方法を使用してクリックされたテキストを取得します。

私の場合、リッチエディットにのみ小さなテキストがあるので、を使用しましたWM_GETTEXT。リッチエディットドキュメントのプレーンテキストバージョンを返しますが、フレンドリ名のハイパーリンクは次の形式で保持されます。

HYPERLINK "https://www.example.com" Example

奇妙なことに先頭のCHARRANGE引用符を含むURLを指します:( "https://www.example.com)。

ただし、索引は、1文字(LF)の行区切り記号が付いたテキストに対応しています。一方、WM_GETTEXTはCRLFセパレーターを返します。したがって、を使用してURLを抽出する前に、テキストをLFに変換する必要がありますCHARRANGE

于 2016-01-16T08:37:17.373 に答える
2

EM_AUTOURLDETECTのドキュメントによると、 EN_LINK通知を受け取ることになっています。これは、に反映されている必要がありnmhdr.codeます。グーグルによると、

#define EN_LINK 0x70B

これは7*256 + 11 = 1750 + 42 + 11=1803です。

コードがのチェックを見逃していることに注意してくださいnmhdr.code == EN_LINK

NM_HOVERコントロールがメッセージを送信するかどうかはわかりません。

于 2012-07-09T15:37:56.020 に答える