Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delphi XE8: TEdit TextHint Disappears When Receiving Focus

Basically, I want the TextHint of my TEdits to disappear when the first character is entered and not when they receive focus, like the Edits on this Microsoft page: Sign in to your Microsoft account. Can someone please walk me through on how to achieve this?

Thank you in advance.

like image 226
Reginald Greyling Avatar asked Jul 21 '15 21:07

Reginald Greyling


2 Answers

The built-in TEdit behavior doesn't allow this, but you can derive a new control from TEdit and override DoSetTextHint. The implementation should be similar to the internal method, but provide a value of 1 for wParam instead of 0.

This is a solution using an interceptor class:

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.  

Make sure to place this unit in the interface uses clause after Vcl.StdCtrls.

like image 74
Uwe Raabe Avatar answered Nov 19 '22 00:11

Uwe Raabe


Based on Uwe Raabe's answer, here is a procedure (for Delphi 2007, should work for newer versions of Delphi as well):

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;

You call it like this:

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

It doesn't check for the Windows version though, you might want to add the if statement Uwe provided:

if CheckWin32Version(5, 1) and StyleServices.Enabled and _ed.HandleAllocated then

I just tested it with a project where I disabled runtime theming: It didn't work.

like image 4
dummzeuch Avatar answered Nov 19 '22 02:11

dummzeuch