RichEdit 的 EM_AUTOURLDETECT 消息并不总是发送

发布于 2024-08-29 16:26:18 字数 2935 浏览 3 评论 0原文

要描述此问题,您最好使用以下用例测试我的应用程序:

应用程序:http://ubuntuone .com/p/nF/

  1. 打开应用程序;
  2. 单击“>”带标题的按钮;
  3. 再次单击同一按钮;
  4. 再次单击同一按钮。

正如您所看到的 - URL 在第一次扩展中被正确检测到,但在任何进一步的扩展中都无法正确检测到。

希望在您的帮助下解决这个问题:)

目前,我每次展开对话框时都会发送 WM,但它仍然不起作用...

展开/折叠按钮代码片段:

    if (PreviewOpn.Caption = '<') and (Width >= 499) then                          // if form is expanded
  begin
   PreviewOpn.Caption := '>';
   if CheckWin32Version(6,0) then begin
     Constraints.MinWidth := 252; ClientWidth := Round(252 - ((Width - ClientWidth) / 2));
    end else begin
     Constraints.MinWidth := 248; ClientWidth := Round(248 - ((Width - ClientWidth) / 2));
    end;
   PopupActionBar1.Items[1].Enabled := False; PopupActionBar1.Items[1].Checked := False;
   if (PreviewOpn.Caption = '<') and (Width >= 248) then PreviewOpn.Caption := '>';
  end else                                                                      // else if form is collapsed
  begin
   SendMessage(RichEdit1.Handle, EM_SETEVENTMASK, 0, EM_GETEVENTMASK or ENM_LINK);       //|
   SendMessage(RichEdit1.Handle, EM_AUTOURLDETECT, Integer(True), 0);
   PreviewOpn.Caption := '<';
   if CheckWin32Version(6,0) then begin
    Constraints.MinWidth := 252; ClientWidth := Round(510 - ((Width - ClientWidth) / 2));
   end else begin
    Constraints.MinWidth := 248; ClientWidth := Round(499 - ((Width - ClientWidth) / 2));
   end;
   PopupActionBar1.Items[1].Enabled := True; PopupActionBar1.Items[1].Checked := True;
   if (PreviewOpn.Caption = '>') and (Width >= 499) then PreviewOpn.Caption := '<';
   if (FileExists(Edit1.Text)) or (FileExists(Edit2.Text)) or (FileExists(ParamStr(1)))
    then RAWInputBtnClick(TabSet1);
  end;
 vClick(VKPInputBtn);                                                           // calls PopuMenu items enabling triggers
 for n := 0 to RichEdit1.Lines.Count - 1 do if RichEdit1.Width < Canvas.TextWidth(RichEdit1.Lines[n]) then  // enable automatic scroolbar settup
  RichEdit1.ScrollBars := ssBoth;

内部表单 OnCreate 事件:

 SendMessage(RichEdit1.Handle, EM_SETEVENTMASK, 0, EM_GETEVENTMASK or ENM_LINK);       //|
 SendMessage(RichEdit1.Handle, EM_AUTOURLDETECT, Integer(True), 0);                    //|
 RichEdit1.Lines[5] := RichEdit1.Lines[5] + ' ';                                       //| resend message for line to fix update issue

As http://msdn.microsoft.com/en-us/library/bb787991 %28VS.85%29.aspx 文档指出,URL 是通过文本修改来检测的,这意味着重新调用检测的唯一方法是发送某种添加/删除字符的消息,但是:

在之后立即检测到 URL键盘上的键被按下并且仅在 INSIDE 行中。 可能的修复将非常令人讨厌,因此我什至不认为为此开发代码 sinpp :) 想法:遍历所有可用字符,例如添加 Char(#10),然后删除 Char(#10)。 缺点:想象一下 RichEdit 控件内的大型 RTF 文本会发生什么......

To describe this issue, the best would that you would test my application with following usecase:

Application: http://ubuntuone.com/p/nF/

  1. Open application;
  2. Click on the ">" captioned button;
  3. Click on same button again;
  4. Click on the same button again.

As you can see - URL is correctly detected in first expanding, but in any further is not.

Hope to have fix for this issue with your help :)

Currently I do send WM every time dialog is expanded, but it still does not work ...

Expand / Collapse buttons code snipp:

    if (PreviewOpn.Caption = '<') and (Width >= 499) then                          // if form is expanded
  begin
   PreviewOpn.Caption := '>';
   if CheckWin32Version(6,0) then begin
     Constraints.MinWidth := 252; ClientWidth := Round(252 - ((Width - ClientWidth) / 2));
    end else begin
     Constraints.MinWidth := 248; ClientWidth := Round(248 - ((Width - ClientWidth) / 2));
    end;
   PopupActionBar1.Items[1].Enabled := False; PopupActionBar1.Items[1].Checked := False;
   if (PreviewOpn.Caption = '<') and (Width >= 248) then PreviewOpn.Caption := '>';
  end else                                                                      // else if form is collapsed
  begin
   SendMessage(RichEdit1.Handle, EM_SETEVENTMASK, 0, EM_GETEVENTMASK or ENM_LINK);       //|
   SendMessage(RichEdit1.Handle, EM_AUTOURLDETECT, Integer(True), 0);
   PreviewOpn.Caption := '<';
   if CheckWin32Version(6,0) then begin
    Constraints.MinWidth := 252; ClientWidth := Round(510 - ((Width - ClientWidth) / 2));
   end else begin
    Constraints.MinWidth := 248; ClientWidth := Round(499 - ((Width - ClientWidth) / 2));
   end;
   PopupActionBar1.Items[1].Enabled := True; PopupActionBar1.Items[1].Checked := True;
   if (PreviewOpn.Caption = '>') and (Width >= 499) then PreviewOpn.Caption := '<';
   if (FileExists(Edit1.Text)) or (FileExists(Edit2.Text)) or (FileExists(ParamStr(1)))
    then RAWInputBtnClick(TabSet1);
  end;
 vClick(VKPInputBtn);                                                           // calls PopuMenu items enabling triggers
 for n := 0 to RichEdit1.Lines.Count - 1 do if RichEdit1.Width < Canvas.TextWidth(RichEdit1.Lines[n]) then  // enable automatic scroolbar settup
  RichEdit1.ScrollBars := ssBoth;

Inside Forms OnCreate Event:

 SendMessage(RichEdit1.Handle, EM_SETEVENTMASK, 0, EM_GETEVENTMASK or ENM_LINK);       //|
 SendMessage(RichEdit1.Handle, EM_AUTOURLDETECT, Integer(True), 0);                    //|
 RichEdit1.Lines[5] := RichEdit1.Lines[5] + ' ';                                       //| resend message for line to fix update issue

As http://msdn.microsoft.com/en-us/library/bb787991%28VS.85%29.aspx documentation states, URL is detected by text modification, which means only way to re-invoke detection is to send some kind of message adding / removing characters, BUT:

URL is detected instantly after key on keyboard isp ressed and only INSIDE line.
Possible fix would be pretty nasty and therefore I do not even think to develop code sinpp for this :)
Idea: Lopp through all avail characters and, for example, add Char(#10) and then remove Char(#10).
Drawback: Imagine what happens on large RTF text inside RichEdit control ...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我不是你的备胎 2024-09-05 16:26:18

您没有正确设置事件掩码,EM_GETEVENTMASK 是一条消息 - 而不是标志。你应该这样设置;

  SendMessage(RichEdit1.Handle, EM_SETEVENTMASK, 0,
      SendMessage(RichEdit1.Handle, EM_GETEVENTMASK, 0, 0) or ENM_LINK);

我不知道在获得 URL 检测后如何丢失它,但如果上述方法没有帮助,据我所知,没有其他方法可以清除并重新分配文本,或者正如您所注意到的,修改 URL 文本本身。

作为旁注,您根据线宽设置两个滚动条,这似乎是错误的,垂直滚动条应该与线宽无关。

作为另一个侧面节点,您关于更改表单宽度的测试是错误的。

 if (PreviewOpn.Caption = '<') and (Width >= 499) then
  begin
  ...
  end else
  begin
   if CheckWin32Version(6,0) then begin
    Constraints.MinWidth := 252;
    ClientWidth := Round(510 - ((Width - ClientWidth) / 2));
  ...

在上面,当你的表单展开时,它的宽度约为 510
最小宽度为 252。这意味着可以调整表单大小以具有
宽度小于 499,那么你的“if”将会失败,尽管形式是
扩大了就不会收缩。忘记标题和宽度
并使用像 FFormExpanded 这样的私有字段标志并将其设置为 true 或
假的..等等..

You are not setting the event mask correctly, EM_GETEVENTMASK is a message - not a flag. You should set it like this;

  SendMessage(RichEdit1.Handle, EM_SETEVENTMASK, 0,
      SendMessage(RichEdit1.Handle, EM_GETEVENTMASK, 0, 0) or ENM_LINK);

I don't know how you're losing the URL detection after once you've got it, but if the above does not help, as far as I know there's no other way then to clear and reassign the text, or modify the URL text itself as you've noticed.

As a side note, you're setting both of the scroll bars depending on line widths, that seems wrong, the vertical scroll bar should have nothing to do with line widths.

As another side node, your test regarding changing the form's width is faulty.

 if (PreviewOpn.Caption = '<') and (Width >= 499) then
  begin
  ...
  end else
  begin
   if CheckWin32Version(6,0) then begin
    Constraints.MinWidth := 252;
    ClientWidth := Round(510 - ((Width - ClientWidth) / 2));
  ...

In the above, when your form is expanded, it will have a width of ~510
and minimum width of 252. That means the form can be resized to have a
smaller width than 499, then your "if" will fail and though the form is
expanded it will not contract. Forget about the caption and the width
and employ a private field flag like FFormExpanded and set it to true or
false.. etc...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文