Jump to content

_GUIRegisterMsgEx (UDF) - Like native, but for controls.


JScript
 Share

Recommended Posts

Function Reference


_GUIRegisterMsgEx.au3

Register a user defined function for a known Windows Message ID (WM_MSG) to an individual ctrl using Call Back!

Sintax:

_GUICtrlMsg_Register( controlID, MsgID, "Function" )
_GUICtrlMsg_UnRegister( hWnd [, MsgID ])

Supports:

; AutoIt GUI controls to register message!

Downloads:

Version: 0.9b

_GUIRegisterMsgEx_(RedirectLink).html

Note: The functions have new parameters!, see fixes below!

You can use this UDF in controls that consume internally specific Windows Message ID that we could not register with the GUIRegisterMsg function, eg: WM_CHAR, WM_KEYDOWN, WM_KEYUP are consumed by an edit control.

Usage example is included!

Sample:

Posted Image

Fixes:

  • 0.9.1412.2600b
  • 14/09/2012 -> _GUICtrlMsg_Register() and __GRM_CallBack() by @SmOke_N - - Thank you!

    0.9.1112.2600b

  • 11/09/2012 -> New parameter added: iMsgID!

    Remarks:

    EXACTLY 4 function parameters, otherwise the function won't be called!

    To make the user function workable you have to define it with

    Up to 256 user functions can be registered for message IDs.

    By default after finishing the user function the UDF pass the unhandled messages to default WindowProc, same as if you use the variable $GUI_RUNDEFMSG (in GUIConstantsEx.au3) in return keyword.

    Note: You can blocking of running user functions which executes window messages with commands such as "Msgbox()".

    You can use in controls that consume internally specific Windows Message ID eg: WM_CHAR, WM_KEYDOWN, WM_KEYUP!

    I.e:

    Func _MyRegisterFunc( $hCtrlID, $iMsgID, $WParam, $LParam )
    ;...
    EndFunc

    The 4 parameters have the following values:

  • hCtrlID, The control handle in which the message is registered.
  • iMsg, The Windows message ID.
  • wParam, The first message parameter as hex value.
  • lParam, The second message parameter as hex value.

    (Position. Parameter, Meaning)

  • 0.9.0812.2600b
  • 09/09/2012 -> First release!

I like to use UDFs, although I think this will not be very useful, I hope someone will find useful!

Regards,

João Carlos.

Edited by JScript

http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!)

Somewhere Out ThereJames Ingram

somewh10.png

dropbo10.pngDownload Dropbox - Simplify your life!
Your virtual HD wherever you go, anywhere!

Link to comment
Share on other sites

Thanks for Sharing

My code:

PredictText: Predict Text of an Edit Control Like Scite. Remote Gmail: Execute your Scripts through Gmail. StringRegExp:Share and learn RegExp.

Run As System: A command line wrapper around PSEXEC.exe to execute your apps scripts as System (LSA). Database: An easier approach for _SQ_LITE beginners.

MathsEx: A UDF for Fractions and LCM, GCF/HCF. FloatingText: An UDF for make your text floating. Clipboard Extendor: A clipboard monitoring tool. 

Custom ScrollBar: Scroll Bar made with GDI+, user can use bitmaps instead. RestrictEdit_SRE: Restrict text in an Edit Control through a Regular Expression.

Link to comment
Share on other sites

Looks good JScript, but what happened to the $iMsgID parameter in _GUICtrlMsg_Register?

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

Hi @martin and @PhoenixXL, I'm glad you liked it!

Still in the implementation phase, because I thought nobody would be interested in the UDF, so I let this parameter to later.

Wait for new changes!

Regards,

João Carlos.

Edited by JScript

http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!)

Somewhere Out ThereJames Ingram

somewh10.png

dropbo10.pngDownload Dropbox - Simplify your life!
Your virtual HD wherever you go, anywhere!

Link to comment
Share on other sites

  • 0.9.1112.2600b
  • 11/09/2012 -> New parameter added: iMsgID!

    Remarks:

    To make the user function workable you have to define it with

    EXACTLY 4 function parameters, otherwise the function won't be called!

    I.e:

    Func _MyRegisterFunc( $hCtrlID, $iMsgID, $WParam, $LParam )
    ;...
    EndFunc

    The 4 parameters have the following values:

  • hCtrlID, The control handle in which the message is registered.
  • iMsg, The Windows message ID.
  • wParam, The first message parameter as hex value.
  • lParam, The second message parameter as hex value.

    (Position. Parameter, Meaning)

    Up to 256 user functions can be registered for message IDs.

By default after finishing the user function the UDF pass the unhandled messages to default WindowProc, same as if you use the variable $GUI_RUNDEFMSG (in GUIConstantsEx.au3) in return keyword.

Note: You can blocking of running user functions which executes window messages with commands such as "Msgbox()".

You can use in controls that consume internally specific Windows Message ID eg: WM_CHAR, WM_KEYDOWN, WM_KEYUP!

Regards,

João Carlos.

Edited by JScript

http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!)

Somewhere Out ThereJames Ingram

somewh10.png

dropbo10.pngDownload Dropbox - Simplify your life!
Your virtual HD wherever you go, anywhere!

Link to comment
Share on other sites

No problem, tell me what name would look better and I'll change!

JS

Maybe GUICtrlRegisterMsg and GUICtrlUnRegisterMsg. To be more handly, make the last paramter optinal, if it was an empty string, unregiter it, just like GUIRegisterMsg (Of course it needs more works, just a suggestion).

A question:

How can I monitor EN_CHANGE message for an Edit control? Maybe I missunderstood the whole usage of this function.

What king of messages can be registered to a control using this UDF? :sweating:

Edited by D4RKON3
Link to comment
Share on other sites

Maybe GUICtrlRegisterMsg and GUICtrlUnRegisterMsg. To be more handly, make the last paramter optinal, if it was an empty string, unregiter it, just like GUIRegisterMsg (Of course it needs more works, just a suggestion).

OK, I'll see what I can do about it!

A question:

How can I monitor EN_CHANGE message for an Edit control? Maybe I missunderstood the whole usage of this function.

According to the following link http://msdn.microsoft.com/en-us/library/windows/desktop/bb761676%28v=vs.85%29.aspx :

"Sent when the user has taken an action that may have altered text in an edit control. This notification code is sent after the system updates the screen. The parent window of the edit control receives this notification code through a WM_COMMAND message."

So you should use the native function to the window, not to control!

What king of messages can be registered to a control using this UDF? :sweating:

I'm still discovering too!

This UDF is only for messages, as well as native: not for notifications

EN_CHANGE is not a message, this is an notification!

Regards,

João Carlos.

Edited by JScript

http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!)

Somewhere Out ThereJames Ingram

somewh10.png

dropbo10.pngDownload Dropbox - Simplify your life!
Your virtual HD wherever you go, anywhere!

Link to comment
Share on other sites

  • Moderators

I had an idea like this a couple of years ago, I opted to just use GUIRegisterMsg() and make functions and stick them inside the the regular WM command functions I created.

However, looking over your code, I noticed a few things ( I didn't look to much, and probably went on a tangent with it ).

Where you have the below:

; Get window handle...
$hWndForm = _WinAPI_GetParent($hCtrlID)
If Not $hWndForm Then Return SetError(5, 0, 0)

(This is just a thought, off the top of my head right this second, I haven't thought of total consequences, but I'd think you might want to do something like:

; Get window handle...
$hWndForm = _WinAPI_GetParent($hCtrlID)
If Not $hWndForm Then
$hwndForm = _WinAPI_GetAncestor($hCtrlID)
Return SetError(5, 0, 0)
EndIf

I also noticed this in your callback function

; line 267 - __GRM_CallBack
; IsString() is called before @error, therefore you won't get a the @error

Case (IsString($vRet) And $vRet = 'GUI_RUNDEFMSG') Or @error = 0xDEAD

; I'd expect something more like:
Case (@error = 0xDEAD) Or (IsString($vRet) And $vRet = 'GUI_RUNDEFMSG')

Example of why it wouldn't work:

; Demonstration to show that Test # 2 will be the only one catching the error
; because the call to IsString() reset the error
; and if it's not a string, then the @error will
; never equal 0xDEAD because it has no error number

Global $gi_testerr = _TestFunc()
If IsString($gi_testerr) Or @error Then
MsgBox(64, "Test #1", "@error caught with test # 1")
EndIf

$gi_testerr = _TestFunc()
If @error Or IsString($gi_testerr) Then
MsgBox(64, "Test #2", "@error caught with test # 2")
EndIf

Func _TestFunc()
Return SetError(1, 0, 0)
EndFunc

However, I'd probably re-write the function more like:

Func __GRM_CallBack($hWnd, $iMsg, $wParam, $lParam)
#forceref $hWnd, $iMsg, $wParam, $lParam

Local $iIndex = __GRM_GetHWndIndex($hWnd)
Local $iIndex2 = __GRM_GetMsgIndex($iMsg, $iIndex)
If Not $iIndex Or Not $iIndex2 Then
Return _WinAPI_CallWindowProc($avGRM_MSGIDS[$iIndex][2], _
$hWnd, $iMsg, $wParam, $lParam)
EndIf

Local $asSubArray = $avGRM_MSGIDS[$iIndex][3]
Local $vRet = Call($asSubArray[$iIndex2][1], $hWnd, $iMsg, $wParam, $lParam)
If @error = 0xDEAD Or (IsString($vRet) And $vRet = 'GUI_RUNDEFMSG') Then
; Pass the unhandled messages to default WindowProc
Return _WinAPI_CallWindowProc($avGRM_MSGIDS[$iIndex][2], $hWnd, $iMsg, $wParam, $lParam)
EndIf

Return $vRet
EndFunc

I'd also look at maybe putting another global or 2, 1 to know the total number of indexes currently for your $avGRM_MSGIDS, and 1 for the max number of indexes to start with for sure so maybe you can get rid of that ReDim

Example:

Global $giGRM_MSGIDSMaxIndex = 100
Global $giGRM_MSGIDSMaxIndex2 = 2
Global $avGRM_MSGIDS[$giGRM_MSGIDSMaxIndex + 1][$giGRM_MSGIDSMaxIndex2 + 1]
Global $giGRM_MSGIDSLastIndex = 0

; $giGRM_MSGIDSLastIndex would be like your $avGRM_MSGIDS[0][0]

Then somewhere where you'd have your Redims, create a function or insert code.

Maybe something like:

If Mod($giGRM_MSGIDSLastIndex + 1, $giGRM_MSGIDSMaxIndex) = 0 Then
$giGRM_MSGIDSMaxIndex += $giGRM_MSGIDSLastIndex
Redim $avGRM_MSGIDS[$giGRM_MSGIDSMaxIndex + 1][$giGRM_MSGIDSMaxIndex2 + 1]
EndIf
$giGRM_MSGIDSLastIndex += 1
$avGRM_MSGIDS[$giGRM_MSGIDSLastIndex][number] = whatever

Having a higher index count to start and with fewer ReDims, you'll see a faster creation process.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

  • 2 months later...
  • 8 years later...

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

×
×
  • Create New...