はじめましてDelphiビギナーです
既出質問ですみませんが、RichEdit上の"http://〜〜"の部分をクリックするとURLを開くにはどうすれば良いのでしょうか?
IPメッセンジャーのようなものを作っているのですが、発言にURLが含まれる場合それを開けるようにしたいのです
TEditorのソースを見れば解決するのではと思って見てみましたがちんぷんかんぷんでした
・既出質問です・・・
https://www.petitmonte.com/bbs/answers?question_id=200
・TEditorを公開しているHPです
http://homepage3.nifty.com/~katsuhiko/
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;
にしのさんのサンプルコードを試してみましたが、
残念ながら Win98では自動的にURLのハイパーリンクが設定されずダメでした。
Win2000で試したら、自動的にURLのハイパーリンクが設定されるのはURL文字列の
直前がスペース、全角文字、-、タブなどの場合だけで、半角文字やダブルクォーテーションに続くURLの場合はダメです。
この方法ではそれが限界なのでしょうか?
それが限界だと思います。
自前でSetAttributeする手もあります。
TEditorでやるのであれば、Fountainを作る必要があります。
すみません折角 解決方法を教えてくださったのにどうすればいいのかわかりませんでした
とりあえずコンパイルしてみて表示されたエラーは以下の通りです
[エラー] 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' ユニットはコンパイルできませんでした
何が何やら混乱してしまって、一体どうすればいいのか・・・
EM_xxx のメッセージはRichEdit.pasに定義されてます。usesにRichEditを追加すること。
それだけでエラーが半分くらい消えるはずです。また、それに影響されて現れたエラーも消えます。
それ以外はみんな、よく見ればちょっとしたミスが生んだエラーのハズ。冷静に見てみれば分かります。
皆様のおかげで無事解決できそうです
半角文字などに続くURLが含まれる発言についてはログに表示する前に
「http://」→「 http://」と変換しようと思います
本当に有難うございました!
ツイート | ![]() |