Trackin Caps-Lock Status

I have an app that requires a user password be provided in two different areas. On one tab sheet if the user mouses or tabs to the tedit password field, I test for and notify the user if the caps lock is on.

I just added another tedit password field and was about to add the caps test and noticed as I arrived at the field, a balloon pop-up appeared with an appropriately worded warning.

My questions are: Where did the balloon pop-up come from? And how can I force the balloon to appear on my first, original tedit field? (I like it better than my warning)

If the balloon warning is supplied by windows, shouldn't it appear on arrival at both fields?
If its Delphi supplied, properties for both fields appear to be exactly the same.

I somehow feel into the balloon warning and I like it and would really like to know how to control it.

TIA - Ed Screen shot of balloon warning
Ed CovneyRetiredAsked:
Who is Participating?
epasquierConnect With a Mentor Commented:
I've checked with TEdit, for this behaviour to apply you only need to set PasswordChar.
I believe that will be the case then for all TCustomEdit descendants

2 things you can do :
a) copy/paste your faulty component to a new project form, just to see if that is working again or not.
If yes => problem  is between your app and windows system, but the poor component code is not guilty
if no => then you have some parameter set that is faulty. Post here your new simple form .DFM file

b) do the opposite test : copy/paste your working component to the same form as your faulty component
will it be faulty as well ?
haven't you heard of google "delphi get caps lock status" ? first link


I think the crux of the question involves the pop-up warning.
The 14th Annual Expert Award Winners

The results are in! Meet the top members of our 2017 Expert Awards. Congratulations to all who qualified!

You are so right !
I read the title and the image, and only very quickly the text between.

Sorry for being an ass.
Ok, it is not Delphi code, I checked in TMaskEdit. It is most certainly system specific, based on the fact that the edit zone has ES_PASSWORD in its window creation parameters.
That is normally the case each time you set a PasswordChar <> #0

procedure TCustomEdit.SetPasswordChar(Value: Char);
  if FPasswordChar <> Value then
    FPasswordChar := Value;
    if HandleAllocated then

// called each time the window is created (here, by RecreateWnd above)
procedure TCustomEdit.CreateParams(var Params: TCreateParams);
  Alignments: array[Boolean, TAlignment] of DWORD =
 Passwords: array[Boolean] of DWORD = (0, ES_PASSWORD);
  ReadOnlys: array[Boolean] of DWORD = (0, ES_READONLY);
  CharCases: array[TEditCharCase] of DWORD = (0, ES_UPPERCASE, ES_LOWERCASE);
  HideSelections: array[Boolean] of DWORD = (ES_NOHIDESEL, 0);
  OEMConverts: array[Boolean] of DWORD = (0, ES_OEMCONVERT);
  NumbersOnlyStyle: array[Boolean] of DWORD = (0, ES_NUMBER);
  inherited CreateParams(Params);
  CreateSubClass(Params, 'EDIT');
  with Params do
    Style := Style or (ES_AUTOHSCROLL or ES_AUTOVSCROLL) or
      Alignments[UseRightToLeftAlignment, FAlignment] or
      BorderStyles[FBorderStyle] or
     Passwords[FPasswordChar <> #0] or
     NumbersOnlyStyle[FNumbersOnly] or
      ReadOnlys[FReadOnly] or CharCases[FCharCase] or
      HideSelections[FHideSelection] or OEMConverts[FOEMConvert];
    if NewStyleControls and Ctl3D and (FBorderStyle = bsSingle) then
      Style := Style and not WS_BORDER;
      ExStyle := ExStyle or WS_EX_CLIENTEDGE;

About why you have a diff :
1) make sure you use TMaskEdit, not TEdit
2) make sure that you have a PasswordChar set to some char (usually '*')

if that is the case in both, then I don't know, you have found some kind of bug.

Can you have two password controls on the same form?  I know that you can't have more than one Default=True or Cancel=True command buttons on form.
You can have as many password edits on a form as you want.  It is just an option to obfuscate (or redact) what is being typed.
Ed CovneyRetiredAuthor Commented:

Both tedit fields warn the user if the caps lock is on. But if I could get the balloon warning on both, I could eliminate some code and object events. But if its not dependable or controllable, my code should stand in which case I need to kill the ballooon which is redundant. But how?  

When I get some time this weekend, I'll do as you suggest and copy each tedit to a new form and see what happens. Also each tedit field has an associated checkbox to show password characters (#0) or hide them (*). Everything works as designed . . . except I don't know from where I get the balloon warning !!!
"except I don't know from where I get the balloon warning !!!"

I'm about sure it comes from OS. The very design and look of that baloon tip is different in XP and Seven.
The text is the same but not the width, font, word wrap... Too much difference for being a single text passed by the application and interpreted by the OS with a Hint ( title , text ) kind of function.
I could be wrong, but that seems very unlikely. And not only it does not looks like coming from application, I can't find any specific code in TEdit / TCustomEdit that could explain such behaviour. It's loads of code, and I've only spent half an hour to look at it, but usually if there was something to see it would have been enough to spot something.

So that leaves me again with my opinion that OS knows that it must implement this behaviour based on PasswordChar character (set at OS level as a windowed edit field parameter)

The real question is why is it not working on both situations.... Only experimenting will tell us
Maybe your code interfere with OS on the caps lock checking, anyway, I recommend you removing all your code and rely on OS to show that warning.
ah, found some proof finaly :
and it also tells how to suppress it (C code, but not too hard to convert)
developmentguruConnect With a Mentor PresidentCommented:
 I have had to do the balloon style windows in my code before and I subclassed a Delphi class (THintWindow or something similar).  As far as killing the redundant window, I ran into the same situation (A delphi hint would come up looking like my hint).  I was able to solve it by making my hint window use the same mechanism as Delphi does.  Delphi's own mechanism only allows one.  You set a new hint window and the old one closes.

  As far as checking for change in status I would use a background thread and have it check the status 4 or 5 times per second.  When the status changes, fire an event that the main code can respond to.

  I have not had much time to look into this, I apologize.  I hope the comments here help you find what you are looking for.  If not, let me know and I will see if I can make an example.
Ed CovneyRetiredAuthor Commented:

>> I'm about sure it comes from OS.

Me too, but apparently with an assist from Delphi?  I FINALLY FOUND the culprit and it was me.
When I programatically toggled a "Show Password" check box (to false), then balloon happened.
I think you mentioned that specifically in an earlier post, but I didn't make the connection, SORRY.
Thanks so much for all the help.  

>>As far as checking for change in status I would use a background thread and have it check the status 4 or 5 times per second.

Probably a little much for my skill level, but absolutely something I should endeavor to accomplish.
A great methodology.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.