RichEdit上の"http://〜〜"をクリックするとURLを開く方法

解決


ビギナー  2005-03-25 05:53:12  No: 13949

はじめましてDelphiビギナーです

既出質問ですみませんが、RichEdit上の"http://〜〜"の部分をクリックするとURLを開くにはどうすれば良いのでしょうか?

IPメッセンジャーのようなものを作っているのですが、発言にURLが含まれる場合それを開けるようにしたいのです

TEditorのソースを見れば解決するのではと思って見てみましたがちんぷんかんぷんでした

・既出質問です・・・
https://www.petitmonte.com/bbs/answers?question_id=200

・TEditorを公開しているHPです
http://homepage3.nifty.com/~katsuhiko/


にしの  2005-03-25 06:33:58  No: 13950

Delphian Worldのコンポーネントを使わないのであれば(と言ってもC++Builder用でしたが)、次のようにすればよろしいかと。

TForm1に、
    OldRichEditWndProc: TWndMethod;
    procedure RichEditWndProc(var Msg: TMessage);
を定義。

以下実装。

//フォーム作成時に、URLを認識できるようにする
//RichEdit1をサブクラス化
procedure TForm1.FormCreate(Sender: TObject);
var
  Mask: DWORD;
begin
  Mask := SendMessage(RichEdit1.Handle, EM_GETEVENTMASK, 0, 0);
        SendMessage(RichEdit1.Handle, EM_SETEVENTMASK, 0,     Mask or ENM_LINK);
        SendMessage(RichEdit1.Handle, EM_AUTOURLDETECT, 1, 0);
  OldRichEditWndProc := RichEdit1.WindowProc;
  RichEdit1.WindowProc := RichEditWndProc;
end;

//URLをどうにかしたときに、CN_NOTIFYイベントが飛んでくるので処理。それ以外はデフォルト。
procedure TForm1.RichEditWndProc(var Msg: TMessage);
var
  NotifyMsg: TWMNotify;
  Enl: TENLink;
  L: Integer;
  tmp: CHARRANGE;
  Url: String;
begin
  if Msg.Msg = CN_NOTIFY then
  begin
    NotifyMsg := TWMNotify(Msg);
      if NotifyMsg.NMHdr^.code = EN_LINK then
    begin
      CopyMemory(@Enl, PCHAR(Msg.LParam), SizeOf(TENLink));
//Enl.msgに、左クリックだとか右クリックだとかのメッセージが入るので、適宜処理。
//ここではWM_LBUTTONUP
      if Enl.msg = WM_LBUTTONUP then
      begin
              L := Enl.chrg.cpMax - Enl.chrg.cpMin;
        SetLength(Url, L);
        SendMessage(RichEdit1.Handle, EM_EXGETSEL,   0, LPARAM(@tmp));
                    SendMessage(RichEdit1.Handle, EM_EXSETSEL,   0, LPARAM(@Enl.chrg));
                    SendMessage(RichEdit1.Handle, EM_GETSELTEXT, 0, LPARAM(@Url[1]));
                    SendMessage(RichEdit1.Handle, EM_EXSETSEL,   0, LPARAM(@tmp));

//この時点で、Url変数にURLが入ってくるので、どうとでも処理してください。
//ここではForm1のCaptionにURLを表示するだけ。
        Caption := Url;
      end;
    end
    else
    begin
      OldRichEditWndProc(Msg);
    end;
  end
  else
  begin
    OldRichEditWndProc(Msg);
  end;
end;


過去のOS  2005-03-25 12:29:13  No: 13951

にしのさんのサンプルコードを試してみましたが、
残念ながら Win98では自動的にURLのハイパーリンクが設定されずダメでした。
Win2000で試したら、自動的にURLのハイパーリンクが設定されるのはURL文字列の
直前がスペース、全角文字、-、タブなどの場合だけで、半角文字やダブルクォーテーションに続くURLの場合はダメです。
この方法ではそれが限界なのでしょうか?


にしの  2005-03-25 20:24:01  No: 13952

それが限界だと思います。
自前でSetAttributeする手もあります。

TEditorでやるのであれば、Fountainを作る必要があります。


ビギナー  2005-03-26 08:17:24  No: 13953

すみません折角 解決方法を教えてくださったのにどうすればいいのかわかりませんでした

とりあえずコンパイルしてみて表示されたエラーは以下の通りです

[エラー] Unit1.pas(33): 未定義の識別子 : 'EM_GETEVENTMASK'
[エラー] Unit1.pas(34): 未定義の識別子 : 'EM_SETEVENTMASK'
[エラー] Unit1.pas(34): 未定義の識別子 : 'ENM_LINK'
[エラー] Unit1.pas(35): 未定義の識別子 : 'EM_AUTOURLDETECT'
[エラー] Unit1.pas(44): 未定義の識別子 : 'TENLink'
[エラー] Unit1.pas(46): 未定義の識別子 : 'CHARRANGE'
[エラー] Unit1.pas(52): 未定義の識別子 : 'EN_LINK'
[エラー] Unit1.pas(57): 'THEN' が必要な場所に 識別子 'msg' があります
[エラー] Unit1.pas(59): 演算子またはセミコロン (';') が必要です
[エラー] Unit1.pas(59): 演算子またはセミコロン (';') が必要です
[エラー] Unit1.pas(61): 未定義の識別子 : 'EM_EXGETSEL'
[エラー] Unit1.pas(62): 未定義の識別子 : 'EM_EXSETSEL'
[エラー] Unit1.pas(62): ')' が必要な場所に 識別子 'chrg' があります
[エラー] Unit1.pas(76): ';' が必要な場所に 'ELSE' があります
[エラー] Unit1.pas(78): 未定義の識別子 : 'OldRichEditWndProc'
[エラー] Unit1.pas(78): '(' が必要な場所に ')' があります
[エラー] Unit1.pas(79): '.' が必要な場所に ';' があります
[警告] Unit1.pas(80): コンパイラは 'end.' 以降の文字を無視します
[致命的エラー] Project1.dpr(5): 'Unit1.pas' ユニットはコンパイルできませんでした

何が何やら混乱してしまって、一体どうすればいいのか・・・


たかみちえ  URL  2005-03-26 09:03:29  No: 13954

EM_xxx のメッセージはRichEdit.pasに定義されてます。usesにRichEditを追加すること。
それだけでエラーが半分くらい消えるはずです。また、それに影響されて現れたエラーも消えます。
それ以外はみんな、よく見ればちょっとしたミスが生んだエラーのハズ。冷静に見てみれば分かります。


ビギナー  2005-03-26 09:47:21  No: 13955

皆様のおかげで無事解決できそうです

半角文字などに続くURLが含まれる発言についてはログに表示する前に
http://」→「 http://」と変換しようと思います

本当に有難うございました!


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加