Delphi XE8:TEdit TextHint在接收焦点时消失

Reg*_*ing 5 delphi focus editcontrol delphi-xe8

基本上,我希望我的TEdits的TextHint在输入第一个字符时消失,而不是在它们获得焦点时消失,如此Microsoft页面上的编辑:登录到您的Microsoft帐户.有人可以告诉我如何实现这一目标吗?

先感谢您.

Uwe*_*abe 7

内置的TEdit行为不会允许这样做,但你可以从派生新的控制TEdit和重写DoSetTextHint.实现应类似于内部方法,但提供值1 wParam而不是0.

这是一个使用拦截器类的解决方案:

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.  
Run Code Online (Sandbox Code Playgroud)

确保在Vcl.StdCtrls之后将此单元放在interface uses子句中.


dum*_*uch 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;
Run Code Online (Sandbox Code Playgroud)

你这样称呼它:

constructor TForm1.Create(_Owner: TComponent);
begin
  inherited;
  TEdit_SetCueBanner(ed_HideOnFocus, 'hide on focus', cbhHideOnFocus);
  TEdit_SetCueBanner(ed_HideOnText, 'hide on text', cbhHideOnText);
end;
Run Code Online (Sandbox Code Playgroud)

不过它不会检查 Windows 版本,您可能需要添加 Uwe 提供的 if 语句:

if CheckWin32Version(5, 1) and StyleServices.Enabled and _ed.HandleAllocated then
Run Code Online (Sandbox Code Playgroud)

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