【问题标题】:Using "|" symbol for a hint-text in Delphi使用“|” Delphi 中提示文本的符号
【发布时间】:2017-10-26 01:55:32
【问题描述】:

由于某种原因,当我指定“|”时任何 Delphi 控件的提示字符串中的符号提示终止于第一次出现的“|”所以工具提示窗口只包含部分文本,直到第一个“|”遇到...

我已经在 C++(WinApi + MFC)中测试了这个符号,它用“|”显示了漂亮的 K 提示符号,所以它看起来像是一些 Delphi 特定的错误。

整个程序运行良好,但这个带有提示的东西让我很烦 =\

那么,有什么办法可以解决这个问题吗?

【问题讨论】:

    标签: winapi windows-7 delphi-7


    【解决方案1】:

    这是设计使然,并且记录在案的行为:

    TControl. Hint property

    TApplication.Hint property

    提示字符串有两部分 - 短和长 - 由 | 字符分隔。弹出工具提示使用简短提示。状态栏使用长提示。使用 Controls 单元中的 GetShortHint 和 GetLongHint 全局函数从提示字符串中提取长提示和短提示。

    要“修复”此问题以便您可以显示 | 字符,您必须:

    在准备弹出窗口时,Hint 文本被拆分之后和实际显示弹出窗口之前,都会触发两者。两者都提供对THintInfo 记录的访问,您可以根据需要自定义该记录。它有一个HintStr 字段,您可以将其设置为您想要的任何文本,包括| 字符。它有一个HintControl 字段,指向显示弹出窗口的控件。

    最简单的解决方案是使用OnShowHint 事件来设置HintStr := HintControl.Hint。

    使用TApplication.OnShowHint:

    procedure TForm1.FormCreate(Sender: TObject);
    begin
      Application.OnShowHint := AppShowHint;
    end;
    
    procedure TForm1.FormDestroy(Sender: TObject);
    begin
      Application.OnShowHint := nil;
    end;
    
    procedure TForm1.AppShowHint(var HintStr: string; var CanShow: boolean; var HintInfo: THintInfo);
    begin
      HintStr := HintInfo.HintControl.Hint;
    end;
    

    使用TApplicationEvents.OnShowHint:

    procedure TForm1.ApplicationEvents1ShowHint(var HintStr: string; var CanShow: boolean; var HintInfo: THintInfo);
    begin
      HintStr := HintInfo.HintControl.Hint;
    end;
    

    【讨论】:

    • 感谢您的信息,多年来不知道,也许是因为我不使用 StatusBars 哈哈。但它是“可修复的”吗?我真的很想在弹出窗口中显示这些符号......我的意思是 - 可以在原始 winapi 中没有手动工具提示系统重新创建的情况下完成吗??
    【解决方案2】:

    嗯,我想出的最简单的解决方案就是编辑“Controls.pas”:

    function GetShortHint(const Hint: string): string;
    var
      I: Integer;
    begin
    {$IFDEF _ONLY_SIMPLE_HINTS_}
      Result:=Hint;
    {$ELSE}
      I := AnsiPos('|', Hint);
      if I = 0 then
        Result := Hint else
        Result := Copy(Hint, 1, I - 1);
    {$ENDIF}
    end;
    
    function GetLongHint(const Hint: string): string;
    var
      I: Integer;
    begin
    {$IFDEF _ONLY_SIMPLE_HINTS_}
      Result:=Hint;
    {$ELSE}
      I := AnsiPos('|', Hint);
      if I = 0 then
        Result := Hint else
        Result := Copy(Hint, I + 1, Maxint);
    {$ENDIF}
    end;
    

    所以我刚刚在我的项目中添加了“{$DEFINE _ONLY_SIMPLE_HINTS_}”=)

    免责声明:如果您不像我那么懒惰,请按照 Remy Lebeau 的建议使用 TApplication.OnShowHint 或 CM_HINTSHOW 拦截。

    【讨论】:

    • 这不是最简单的解决方案,甚至不是最好的解决方案。 正确的解决方案是使用已经提供的钩子来正式处理这种情况:TApplication(Events).OnShowHint 事件,或CM_HINTSHOW 消息。详情见我的回答
    • 好吧,我从来没有使用过这整个多提示功能(我只是在几分钟前读到你的答案时才知道它=),所以这对我来说是最简单的解决方案,实际上我可以直接替换这两个函数,但为了更灵活一点,我选择了条件编译方法,这对我来说绝对没问题。
    • 重新编译供应商提供的单元来修复根本不需要重新编译就可以处理的问题是完全错误的。就像我说的,通过官方渠道提供了解决这个问题的钩子
    • 好吧,对于我尘土飞扬的Delphi7来说,这没问题。这些“供应商提供”的单元无论如何都像 15 岁,如果它是一些 c++ 标准模块,我会选择另一种方式,但对于 Delphi7,我认为保持它的神圣性毫无意义。我不是第一次编辑它们。实际上,在不同的大容量单元中使用我的条件编译标志有时我在某些项目上编译后最多可以节省最终二进制大小的 20%。
    猜你喜欢
    • 2014-11-05
    • 1970-01-01
    • 1970-01-01
    • 2013-04-19
    • 2016-08-31
    • 1970-01-01
    • 2015-08-02
    • 2018-02-04
    • 2011-06-09
    相关资源
    最近更新 更多