Delphi XE8: TEdit TextHint Disappears When Receiving Focus
Asked Answered
S

2

6

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.

Swaraj answered 21/7, 2015 at 21:22 Comment(0)
D
4

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.

Disconnection answered 22/7, 2015 at 12:38 Comment(6)
Regarding your edit to my answer: SendMessage doesn't compile as Value is a string. That is why SendTextMessage is used (at least in D2009+).Eolian
Ooops, sorry. I looked up SendTextMessage and couldn't find anything apart from sending SMS. Where is SendTextMessage declared? Is it an RTL function or Windows API?Disconnection
It is declared in (Winapi.)Messages since D2009 and wraps the ugly casting. Quite handy when LPARAM must point to a string.Eolian
Thanks a lot @Uwe and dummzeuch for submitting your answers! I really appreciate it. After some research on creating components I was finally able to create my own (sorry, I don’t know how to highlight text) THintEdit and THintLabeledEdit, which worked perfectly!Swaraj
Will this work with TComboBox as well dummzeach and @UweRaabe?Swaraj
@LuiP3rd I haven't tested it, but it might. Did you try it?Disconnection
E
8

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.

Eolian answered 21/7, 2015 at 21:34 Comment(0)
D
4

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.

Disconnection answered 22/7, 2015 at 12:38 Comment(6)
Regarding your edit to my answer: SendMessage doesn't compile as Value is a string. That is why SendTextMessage is used (at least in D2009+).Eolian
Ooops, sorry. I looked up SendTextMessage and couldn't find anything apart from sending SMS. Where is SendTextMessage declared? Is it an RTL function or Windows API?Disconnection
It is declared in (Winapi.)Messages since D2009 and wraps the ugly casting. Quite handy when LPARAM must point to a string.Eolian
Thanks a lot @Uwe and dummzeuch for submitting your answers! I really appreciate it. After some research on creating components I was finally able to create my own (sorry, I don’t know how to highlight text) THintEdit and THintLabeledEdit, which worked perfectly!Swaraj
Will this work with TComboBox as well dummzeach and @UweRaabe?Swaraj
@LuiP3rd I haven't tested it, but it might. Did you try it?Disconnection

© 2022 - 2024 — McMap. All rights reserved.