Jump to content

UDF: _GuiEditSetToolTip() _GUICtrlEdit_SetCueBanner()


rover
 Share

Recommended Posts

Two UDF's _GuiEditSetToolTip() and _GUICtrlEdit_SetCueBanner()

Subclass an Edit control and intercept keyboard or clipboard paste events for blocking, filtering or processing.

Directly control internal tooltips of edit controls for custom messages in language of your choice triggered by keyboard or clipboard paste events.

Add cue banners to GUICtrlCreateInput() or _GUICtrlEdit_Create() (without multiline style)

Convert the 'numbers only' tooltip error message of

GUICtrlCreateInput() or GUICtrlCreateEdit() controls with $ES_NUMBER style

to title, text, icon and language of your choice.

Optional system sound event with tooltip - _WinAPI_MessageBeep()

Thanks to MrCreator and kmetski for the idea:

GuiInputSetOnlyNumbers() using registered messages and RegExp

http://www.autoitscript.com/forum/index.php?showtopic=56930

Input style with ES_NUMBER, negative number with ES_NUMBER

http://www.autoitscript.com/forum/index.php?showtopic=66517

QUESTION ABOUT $ES_NUMBER

http://www.autoitscript.com/forum/index.php?showtopic=82084

_GuiEditSetToolTip()

For GUICtrlCreateInput(), GUICtrlCreateEdit() and _GUICtrlEdit_Create()

Minimum OS is WinXP.

_GUICtrlEdit_SetCueBanner()

Minimum OS is WinXP.

Does not work with multiline edit control GUICtrlCreateEdit() (has default forced style $ES_MULTILINE)

use with GUICtrlCreateInput() or _GUICtrlEdit_Create() without multiline style

see remarks in UDF for language localization problem in XP

MSDN references:

EDITBALLOONTIP Structure: http://msdn.microsoft.com/en-us/library/bb775466(VS.85).aspx

EM_SHOWBALLOONTIP Message: http://msdn.microsoft.com/en-us/library/bb761668(VS.85).aspx

EM_SETCUEBANNER Message: http://msdn.microsoft.com/en-us/library/bb761639(VS.85).aspx

Edit control subclassing demo with custom tooltip messages, cue banners and keyboard/clipboard event text processing.

;#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
#include <GUIConstantsEX.au3>
#include <Constants.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
#include <WinAPI.au3>
#include <GuiEdit.au3>

Opt('MustDeclareVars', 1)

#cs ; tooltip icon constants in EditConstants.au3
    ; Edit Balloon Tool Tip Icons
    Global Const $TTI_NONE = 0
    Global Const $TTI_INFO = 1
    Global Const $TTI_WARNING = 2
    Global Const $TTI_ERROR = 3
    
    ; Vista Edit Balloon Tool Tip Icons
    Global Const $TTI_INFO_LARGE = 4
    Global Const $TTI_WARNING_LARGE = 5
    Global Const $TTI_ERROR_LARGE = 6
#ce

Global $hGui, $msg, $Input1, $Input2, $Edit
Global $wProcNew, $wProcOld, $hInput1, $hInput2, $hEdit ; Global vars required for callback function
;variables for tooltip title, text and icon (GUICtrlCreateInput() or GUICtrlCreateEdit() controls)
;custom messages for edit tooltip in the language of your choice.
;Input1
Global $sTipTitle1a = "Unacceptable Character"
Global $sTipText1a = "You can only type digits 0 to 9 here."
Global $iTipIcon1a = $TTI_ERROR

Global $sTipTitle1b = "Unacceptable Clipboard Content"
Global $sTipText1b = "You can only paste numbers here"
Global $iTipIcon1b = $TTI_WARNING

;Input2
Global $sTipTitle2a = "Unacceptable Character"
Global $sTipText2a = "You can only type 'word' character: a-z, A-Z, 0-9 or _ here."
Global $iTipIcon2a = $TTI_ERROR

Global $sTipTitle2b = "Unacceptable Clipboard Content"
Global $sTipText2b = "You can only paste 'word' characters: a-z, A-Z, 0-9 or _ here."
Global $iTipIcon2b = $TTI_WARNING

;Edit
Global $sTipTitle3a = "Edit control"
Global $sTipText3a = "You cannot type numbers here."
Global $iTipIcon3a = $TTI_ERROR

Global $sTipTitle3b = "Edit control"
Global $sTipText3b = "Clipboard pasting blocked"
Global $iTipIcon3b = $TTI_WARNING

Global $sLabel1 = "Edit controls with custom tooltip messages, cue banners and typed/clipboard paste filtering"
Global $sLabel2 = "Delete input control content to restore cue banner"
Global $sLabel3 = "Ctrl-V, Shift-Ins or right click paste into input or edit controls for custom tooltip"

$hGui = GUICreate("Subclassed edit controls /w custom tooltips and cue banners", 500, 300)
GUISetBkColor(0xFFFFFF)
GUICtrlCreateLabel($sLabel1, 10, 10, 480, 20)
GUICtrlCreateLabel($sLabel2, 10, 25, 480, 20)

GUICtrlCreateLabel($sLabel3, 10, 125, 480, 20)
GUICtrlSetColor(-1, 0x0000FF)
GUICtrlCreateLabel("Type numbers into edit control for custom tooltip", 10, 140, 480, 20)
GUICtrlSetColor(-1, 0x0000FF)

$Input1 = GUICtrlCreateInput("", 10, 50, 140, 20, $ES_NUMBER) ;numbers only input
$hInput1 = GUICtrlGetHandle(-1) ;get handle of input control for subclassing
_GUICtrlEdit_SetCueBanner($hInput1, "Enter numbers only")
GUICtrlCreateLabel("Numbers only input control with ES_NUMBER style, " & _
        "custom tooltips, cue banner and clipboard paste filter", 160, 48, 330, 30)
GUICtrlSetBkColor(-1, 0xE8E8E8)

$Input2 = GUICtrlCreateInput("", 10, 90, 140, 20)
$hInput2 = GUICtrlGetHandle(-1) ;get handle of input control for subclassing
_GUICtrlEdit_SetCueBanner($hInput2, "Enter word characters only")
GUICtrlCreateLabel("Word characters only input control ( a-z, A-Z, 0-9 or _ ) with " & _
        "custom tooltips, cue banner, clipboard paste filter and forced uppercase", 160, 88, 330, 30)
GUICtrlSetBkColor(-1, 0xE8E8E8)

$Edit = GUICtrlCreateEdit("", 2, 160, 496, 138);, BitOR($GUI_SS_DEFAULT_EDIT, $ES_READONLY))
GUICtrlSetFont(-1, 9, 400, 0, "Courier New")
GUICtrlSetBkColor(-1, 0xFFFFFF)
GUICtrlSetState(-1, $GUI_FOCUS)
$hEdit = GUICtrlGetHandle(-1) ;get handle of input control for subclassing


;create callback function: subclass Input (Edit) controls
$wProcNew = DllCallbackRegister("_EditWindowProc", "int", "hwnd;uint;wparam;lparam")
$wProcOld = _WinAPI_SetWindowLong($hInput1, $GWL_WNDPROC, DllCallbackGetPtr($wProcNew))
_WinAPI_SetWindowLong($hInput2, $GWL_WNDPROC, DllCallbackGetPtr($wProcNew))
_WinAPI_SetWindowLong($hEdit, $GWL_WNDPROC, DllCallbackGetPtr($wProcNew))
GUISetState()

While 1
    $msg = GUIGetMsg()
    If $msg = $GUI_EVENT_CLOSE Then _Exit()
WEnd

Func _Exit()
    ;Delete callback function
    If $wProcOld Then
        _WinAPI_SetWindowLong($hInput1, $GWL_WNDPROC, $wProcOld)
        _WinAPI_SetWindowLong($hInput2, $GWL_WNDPROC, $wProcOld)
        _WinAPI_SetWindowLong($hEdit, $GWL_WNDPROC, $wProcOld)
    EndIf
    If $wProcNew Then DllCallbackFree($wProcNew)
    GUIDelete($hGui)
    Exit
EndFunc   ;==>_Exit

Func MemoWrite($sMessage = '')
    GUICtrlSetData($Edit, $sMessage & @CRLF, 1)
EndFunc   ;==>MemoWrite

Func _EditWindowProc($hWnd, $msg, $wParam, $lParam)
    ;Callback procedure for Input (Edit) control
    ;ConsoleWrite('-$Msg = ' & $Msg & @crlf)
    #forceref $hWnd, $Msg, $wParam, $lParam
    Local $sString
    Switch $msg
        Case $WM_PASTE ;Intercept clipboard paste events to input controls
            $sString = ClipGet() ;get clipboard content
            Switch $hWnd
                Case $hInput1 ;verify clipboard content is digits only. if not block paste and create custom error tooltip.
                    ;Return 0 ; block pasting from clipboard
                    MemoWrite($sString)
                    If StringRegExp($sString, "[^\d]", 0) Then
                        ;if string not digits then block $WM_PASTE message and popup warning tooltip
                        DllCall("user32.dll", "int", "MessageBeep", "int", 0x0)
                        Return _GuiEditSetToolTip($hWnd, $msg, $wParam, $lParam, $sTipTitle1b, $sTipText1b, $iTipIcon1b)
                    EndIf
                    ;allow $WM_PASTE message to paste content to input edit control
                Case $hInput2 ;verify clipboard content is "word" character: a-z, A-Z, 0-9 or underscore.
                    ;Return 0 ; block pasting from clipboard
                    MemoWrite($sString)
                    If StringRegExp($sString, "\W", 0) Then
                        ;if string not word character then block $WM_PASTE message and popup warning tooltip
                        DllCall("user32.dll", "int", "MessageBeep", "int", 0x0)
                        Return _GuiEditSetToolTip($hWnd, $msg, $wParam, $lParam, $sTipTitle2b, $sTipText2b, $iTipIcon2b)
                    EndIf
                    ;allow $WM_PASTE message to paste content to input edit control
                    ClipPut(StringUpper($sString));replace clipboard content with uppercase text
                Case $hEdit
                    ;block clipboard pasting to Edit control and display tooltip
                    Return _GuiEditSetToolTip($hWnd, $msg, $wParam, $lParam, $sTipTitle3b, $sTipText3b, $iTipIcon3b)
            EndSwitch
        Case $EM_SHOWBALLOONTIP ;Intercept ES_NUMBER style EM_SHOWBALLOONTIP tooltip message
            Switch $hWnd

                Case $hInput1
                    ;Return 0 ; blocks tootip from appearing
                    DllCall("user32.dll", "int", "MessageBeep", "uint", 0x0)
                    Return _GuiEditSetToolTip($hWnd, $msg, $wParam, $lParam, $sTipTitle1a, $sTipText1a, $iTipIcon1a)
            EndSwitch
        Case $WM_CHAR ;Intercept typed characters and perform RegExp check
            $sString = Chr($wParam) ;get typed character from ASCII code
            Switch $hWnd
                Case $hInput2
                    ;block characters other than "word" character: a-z, A-Z, 0-9 or underscore from being typed.
                    ;ConsoleWrite('-$wParam = ' & $wParam & @crlf) ; keypress ASCII code
                    If StringRegExp($sString, "\W", 0) And $wParam <> 8 And $wParam <> 22 Then ; 8 = backspace, 22 = Ctrl-V (paste)
                        MemoWrite($wParam & @TAB & $sString)
                        DllCall("user32.dll", "int", "MessageBeep", "int", 0x0)
                        Return _GuiEditSetToolTip($hWnd, $msg, $wParam, $lParam, $sTipTitle2a, $sTipText2a, $iTipIcon2a)
                    EndIf
                    ;ConsoleWrite('-$wParam = ' & $wParam & @crlf)
                    $wParam = Asc(StringUpper($sString)) ; return forced uppercase for typed text
                    ;ConsoleWrite('-$wParam = ' & $wParam & @crlf)
                Case $hEdit
                    ;block typing of numbers in Edit control and display tooltip
                    If StringRegExp(Chr($wParam), "\d", 0) Then
                        DllCall("user32.dll", "int", "MessageBeep", "int", 0x0)
                        Return _GuiEditSetToolTip($hWnd, $msg, $wParam, $lParam, $sTipTitle3a, $sTipText3a, $iTipIcon3a)
                    EndIf
            EndSwitch
    EndSwitch

    ;pass the unhandled messages to default WindowProc
    Return _WinAPI_CallWindowProc($wProcOld, $hWnd, $msg, $wParam, $lParam)
EndFunc   ;==>_EditWindowProc

Func _GuiEditSetToolTip(ByRef $hWnd, ByRef $msg, ByRef $wParam, ByRef $lParam, $sTitle = "", $sText = "", $iIcon = $TTI_NONE)
    ;Author: rover - code modified from GUICtrlEdit_ShowBalloonTip()
    ;NOTE: can only be run from inside subclassed control callback function
    ;these 4 variables must be passed from subclassed controls: $hWnd, $Msg, $wParam, $lParam
    ;return from this function must be 'Returned' in callback function
    ;e.g. Return _GuiEditSetToolTip($hWnd, $msg, $wParam, $lParam, $sTitle, $sText, $iIcon)
    ;MSDN references:
    ;EDITBALLOONTIP Structure: http://msdn.microsoft.com/en-us/library/bb775466(VS.85).aspx
    ;EM_SHOWBALLOONTIP Message: http://msdn.microsoft.com/en-us/library/bb761668(VS.85).aspx
    If Not IsDeclared("EM_SHOWBALLOONTIP") Then Assign("EM_SHOWBALLOONTIP", 0X1503, 2)
    If Not IsHWnd($hWnd) Then Return 0 ;no control hwnd to pass message to.
    Local $tTitle, $tText, $tTT
    $tTitle = _WinAPI_MultiByteToWideChar($sTitle)
    $tText = _WinAPI_MultiByteToWideChar($sText)
    If $lParam And ($msg = $EM_SHOWBALLOONTIP) Then ;use existing pointer to struct if $Msg = $EM_SHOWBALLOONTIP
        $tTT = DllStructCreate($tagEDITBALLOONTIP, $lParam)
        ;"Size" element already set to struct size, using mem supplied by ptr $lParam
    Else
        $tTT = DllStructCreate($tagEDITBALLOONTIP) ;allocate memory for struct
        DllStructSetData($tTT, "Size", DllStructGetSize($tTT))
    EndIf
    If Not IsDllStruct($tTitle) Or Not IsDllStruct($tText) Or Not IsDllStruct($tTT) Then
        ;on error pass the messages to default WindowProc
        Return _WinAPI_CallWindowProc($wProcOld, $hWnd, $msg, $wParam, $lParam)
    EndIf
    DllStructSetData($tTT, "Title", DllStructGetPtr($tTitle))
    DllStructSetData($tTT, "Text", DllStructGetPtr($tText))
    DllStructSetData($tTT, "Icon", $iIcon)
    ;$lParam is 0 if $Msg <> $EM_SHOWBALLOONTIP. will also handle $lParam = 0 with $Msg = $EM_SHOWBALLOONTIP error
    If ($msg <> $EM_SHOWBALLOONTIP) Or (Not $lParam) Then $lParam = DllStructGetPtr($tTT)
    ;pass EM_SHOWBALLOONTIP message to default WindowProc with edited EDITBALLOONTIP struct
    Return _WinAPI_CallWindowProc($wProcOld, $hWnd, $EM_SHOWBALLOONTIP, $wParam, $lParam)
EndFunc   ;==>_GuiEditSetToolTip


;problem with cue banner and Asian Language support in XP, this issue has been fixed in Vista.
;Sorting it all Out : EM_SETCUEBANNER vs. international support in XP and Server 2003
;https://blogs.msdn.com/michkap/archive/2006/02/25/538735.aspx

;EM_SETCUEBANNER Message, wParam TRUE - not working for XP. - MSDN Forums
;http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2799112&SiteID=1

; #FUNCTION# ====================================================================================================================
; Name...........: _GUICtrlEdit_SetCueBanner
; Description ...: Sets the cue banner text that is displayed for edit controls
;                  GUICtrlCreateInput(), GUICtrlCreateEdit() or _GUICtrlEdit_Create()
; Syntax.........: _GUICtrlEdit_SetCueBanner($hWnd, $sText)
; Parameters ....: $hWnd        - Handle to control
;                  $sText       - String that contains the text
;                  $wParam      - False: (Default) cue banner disappears when the user clicks in the control.
;                               - True: cue banner should show even when the edit control has focus. **
; Return values .: Success      - True
;                  Failure      - False
; Author ........: rover
; Modified.......:
; Remarks .......: The cue banner is grey text that is displayed in an edit control when there is no selection
;                  When the user clicks the text, the text goes away and the user can type.
;                  You cannot set a cue banner on a multiline edit control or on a rich edit control.
;                  There is a problem with cue banner and Asian Language support in XP, this issue has been fixed in Vista.
;                  ** wParam TRUE - only appears to work on Vista.
;                  ** Under XP the cue text always disappears when the control gets focus regardless of this parameter.
;+
;                  Minimum Operating Systems: Windows XP
; Related .......:
; Link ..........; @@MsdnLink@@ EM_SETCUEBANNER Message
;                  http://msdn.microsoft.com/en-us/library/bb761639(VS.85).aspx
; Example .......; Yes
; ===============================================================================================================================
Func _GUICtrlEdit_SetCueBanner($hWnd, $sText, $wParam = False)
    If $Debug_Ed Then _GUICtrlEdit_ValidateClassName($hWnd)
    If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)
    Local $tText = _WinAPI_MultiByteToWideChar($sText)
    Return _SendMessage($hWnd, $EM_SETCUEBANNER, $wParam, DllStructGetPtr($tText)) = 1
EndFunc   ;==>_GUICtrlEdit_SetCueBanner
Edited by rover

I see fascists...

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...