Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

[fn][L] Placeholder() - placeholder text for edit controls


  • Please log in to reply
13 replies to this topic
infogulch
  • Moderators
  • 717 posts
  • Last active: Jul 31 2014 08:27 PM
  • Joined: 27 Mar 2008
Note: For single-line edit controls SetEditCueBanner() would be better suited.

For edit controls with multiple lines and other isolated cases, this function will work better.

Function:
; Placeholder() - by infogulch for AutoHotkey v1.1.05+
; 
; to set up your edit control with a placeholder, call: 
;   Placeholder(hwnd_of_edit_control, "your placeholder text")
; 
; If called with only the hwnd, the function returns True if a 
;   placeholder is being shown, and False if not.
;   isPlc := Placeholder(hwnd_edit)
; 
; to remove the placeholder call with a blank text param
;   Placeholder(hwnd_edit, "")
; 
; http://www.autohotkey.com/forum/viewtopic.php?p=482903#482903
; 

Placeholder(wParam, lParam = "`r", msg = "") {
    static init := OnMessage(0x111, "Placeholder"), list := []
    
    if (msg != 0x111) {
        if (lParam == "`r")
            return list[wParam].shown
        list[wParam] := { placeholder: lParam, shown: false }
        if (lParam == "")
            return "", list.remove(wParam, "")
        lParam := wParam
        wParam := 0x200 << 16
    }
    if (wParam >> 16 == 0x200) && list.HasKey(lParam) && !list[lParam].shown ;EN_KILLFOCUS  :=  0x200 
    {
        GuiControlGet, text, , %lParam%
        if (text == "")
        {
            Gui, Font, Ca0a0a0
            GuiControl, Font, %lParam%
            GuiControl,     , %lParam%, % list[lParam].placeholder
            list[lParam].shown := true
        }
    }
    else if (wParam >> 16 == 0x100) && list.HasKey(lParam) && list[lParam].shown ;EN_SETFOCUS := 0x100 
    {
        Gui, Font, cBlack
        GuiControl, Font, %lParam%
        GuiControl,     , %lParam%
        list[lParam].shown := false
    }
}

Example:
gui, add, edit, w300 hwndhEdit
    gui, add, edit, wp r4 hwndhEdit2
    gui, add, button, vButton, Exit
    
    Placeholder(hEdit, "Enter some text")
    Placeholder(hEdit2, "Another text entry point")
    gui, show
    guicontrol, focus, button
return

ButtonExit:
ExitApp

Uses WM_COMMAND notifications for edit controls EN_KILLFOCUS and EN_SETFOCUS to determine when a control gets/loses focus, and based on whether the control's text is empty displays a placeholder in a gray color.

TODO:
Ability to specify the exact fonts you want for each state.

Cragaha
  • Members
  • 265 posts
  • Last active: Jan 04 2016 02:24 AM
  • Joined: 19 Nov 2010
That is a very nice function, but I think both colors should be optional in the function.

tidbit
  • Administrators
  • 2709 posts
  • Hates playing Janitor
  • Last active: Jan 15 2016 11:37 PM
  • Joined: 09 Mar 2008
Yes, a very nice function. I'll be using this for sure! thank you.

rawr. be very afraid
*poke*
. Populate the AutoHotkey city. Pointless but somewhat fun. .


infogulch
  • Moderators
  • 717 posts
  • Last active: Jul 31 2014 08:27 PM
  • Joined: 27 Mar 2008
thanks, tidbit!

Nazzal: I completely agree. (note my TODO at the end of the post)

I just spent several hours and it's almost working.

Unfortunately, it turns out that last "almost" makes it unreachable.

I need a method of determining the current font so I can save it and restore it before putting the user's font options into effect.

The user's font and font options specified to Placeholder() would logically be relative to the font at the time of the the call to Placeholder(), but in reality the options are relative to the most recent Gui, Font setting, which is very possibly not the same thing.

In fact this can be demonstrated with the example above. To break it, change the font size for just the button and start clicking around.

Edit: I made a post in the wishlist forum for something that would fix this problem.

Cragaha
  • Members
  • 265 posts
  • Last active: Jan 04 2016 02:24 AM
  • Joined: 19 Nov 2010
Thanks infogulch,
I will be using your function in a lot of my scripts as I don't like edit controls to have descriptive text controls, appreciate your effort and will be watching this thread for future improvements.

nimda
  • Members
  • 4368 posts
  • Last active: Aug 09 2015 02:36 AM
  • Joined: 26 Dec 2010
<!-- m -->http://www.autohotke... ... 022#510022<!-- m --> :arrow: EM_SETCUEBANNER :shock:

aaffe
  • Members
  • 1045 posts
  • Last active: Jan 16 2014 01:32 PM
  • Joined: 17 May 2007
Sorry, but whats the difference between EM_SETCUEBANNER and this function?

infogulch
  • Moderators
  • 717 posts
  • Last active: Jul 31 2014 08:27 PM
  • Joined: 27 Mar 2008
Hmm, apparently the difference between them is that EM_SETCUEBANNER is better than this function and has the advantage of being built into the edit control. *facepalm*

You know, I've always enjoyed reinventing the wheel. :lol:

Perhaps since it's built into windows we could get a new GuiControl option to change it?

nimda
  • Members
  • 4368 posts
  • Last active: Aug 09 2015 02:36 AM
  • Joined: 26 Dec 2010
Hmmm... GuiControl, or maybe right in the Gui, Add... (though how could that be done without breaking compatibility? v2?)

It is much better than a Text control; if I knew C++ I'd add it myself :lol:

aaffe
  • Members
  • 1045 posts
  • Last active: Jan 16 2014 01:32 PM
  • Joined: 17 May 2007
Perhaps we could use:
Gui, Add, Text, vText, This is text., This is shown when no text is there.

GuiUser
  • Guests
  • Last active:
  • Joined: --

Sorry, but whats the difference between EM_SETCUEBANNER and this function?

The difference is, that EM_SETCUEBANNER does not work on multi-line edit controls, while this method by Infogulch allows this. 8)

aaffe
  • Members
  • 1045 posts
  • Last active: Jan 16 2014 01:32 PM
  • Joined: 17 May 2007
Ah, ok, thanks!

Sorry, but whats the difference between EM_SETCUEBANNER and this function?

The difference is, that EM_SETCUEBANNER does not work on multi-line edit controls, while this method by Infogulch allows this. 8)



hoppfrosch
  • Members
  • 399 posts
  • Last active: Feb 26 2016 05:31 AM
  • Joined: 25 Jan 2006

Sorry, but whats the difference between EM_SETCUEBANNER and this function?

One more difference: EM_SETCUEBANNER restores the cue text when you delete the complete contents of the edit box - and placeholder leaves an empty edit box ... ( :? or :) - depends on what you need ..)

EDIT Incorrect - see Infogulchs reply below ...

infogulch
  • Moderators
  • 717 posts
  • Last active: Jul 31 2014 08:27 PM
  • Joined: 27 Mar 2008
No, the difference is that Placeholder() only checks when the edit control itself is focused or unfocused.

After you do: ^a{Del}, the focus is still in the edit control. It will not add placeholder text until you've moved to a different control.