Delphi XE8:当接收焦点时,TEdit的TextHint消失

6
基本上,我希望我的TEdits的TextHint在输入第一个字符时消失,而不是在它们获得焦点时消失,就像这个Microsoft页面上的Edits一样:登录到您的Microsoft帐户。请问有人能够指导我如何实现这个功能吗?
提前感谢您。
2个回答

8
内置的TEdit行为不允许此操作,但是您可以从TEdit派生一个新控件并覆盖DoSetTextHint。实现方式应该与内部方法类似,但是将wParam的值更改为1。
以下是使用拦截器类的解决方案:
unit EditInterceptor;

uses
  Vcl.StdCtrls, System.SysUtils, Winapi.Messages, Windows;

type
  TEdit = class(Vcl.StdCtrls.TEdit)
  protected
    procedure DoSetTextHint(const Value: string); override;
  end;

implementation

uses
  Vcl.Themes, Winapi.CommCtrl;

procedure TEdit.DoSetTextHint(const Value: string);
begin
  if CheckWin32Version(5, 1) and StyleServices.Enabled and HandleAllocated then
    SendTextMessage(Handle, EM_SETCUEBANNER, WPARAM(1), Value);
end;

end.  

请确保将此单元放置在Vcl.StdCtrls之后的接口使用子句中。

4

根据Uwe Raabe的回答,这里是一个过程(适用于Delphi 2007,也适用于更新的Delphi版本):

type
  TCueBannerHideEnum = (cbhHideOnFocus, cbhHideOnText);

procedure TEdit_SetCueBanner(_ed: TEdit; const _s: WideString; _WhenToHide: TCueBannerHideEnum = cbhHideOnFocus);
const
  EM_SETCUEBANNER = $1501;
var
  wParam: Integer;
begin
  case _WhenToHide of
    cbhHideOnText: wParam := 1;
  else //    cbhHideOnFocus: ;
    wParam := 0;
  end;
  SendMessage(_ed.Handle, EM_SETCUEBANNER, wParam, Integer(PWideChar(_s)));
end;

您可以这样调用它:
constructor TForm1.Create(_Owner: TComponent);
begin
  inherited;
  TEdit_SetCueBanner(ed_HideOnFocus, 'hide on focus', cbhHideOnFocus);
  TEdit_SetCueBanner(ed_HideOnText, 'hide on text', cbhHideOnText);
end;

它没有检查Windows版本,您可能需要添加Uwe提供的if语句:
if CheckWin32Version(5, 1) and StyleServices.Enabled and _ed.HandleAllocated then

我刚刚用一个禁用运行时主题的项目进行了测试:它没有起作用。


关于您对我的回答所做的编辑:SendMessage不能编译,因为Value是一个字符串。这就是为什么在D2009+中使用SendTextMessage的原因。 - Uwe Raabe
抱歉,我查找了SendTextMessage,除了发送短信之外什么都没找到。 SendTextMessage在哪里声明?它是RTL函数还是Windows API? - dummzeuch
它在(Winapi.)Messages中声明,自D2009以来包装了丑陋的转换。当LPARAM必须指向一个字符串时非常方便。 - Uwe Raabe
非常感谢@Uwe和dummzeuch提交的答案!我真的很感激。经过一些关于创建组件的研究,我终于能够创建自己的(抱歉,我不知道如何突出文本)THintEdit和THintLabeledEdit,它们完美地工作了! - Reginald Greyling
这个能够和 TComboBox 一起使用吗,dummzeach 和 @UweRaabe? - Reginald Greyling
1
@LuiP3rd 我还没有测试过,但有可能可以。你试过了吗? - dummzeuch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接