DarkBoost Posted December 31, 2009 Share Posted December 31, 2009 I discovered GUIRegisterMsg() and looking for assistance with the below example, obviously $WM_COMMAND is not the correct command and having difficulty with additional supported commands example "GUIRegisterMsg($WM_INPUT..." and "GUIRegisterMsg(WM_INPUT..." failed with undeclared variable messages however using codes like this "GUIRegisterMsg(0x0005..." worked. Any advice would be greatly appreciated: #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> Opt("MustDeclareVars", 1) ;1=Enabled Global $input[5], $msg GUICreate("", 300, 70) $input[1] = GUICtrlCreateInput("", 10, 10, 135, 20) $input[2] = GUICtrlCreateInput("", 10, 40, 135, 20) $input[3] = GUICtrlCreateLabel("", 155, 10, 135, 20) $input[4] = GUICtrlCreateLabel("", 155, 40, 135, 20) GUICtrlSetBkColor($input[3], 0xCCCCCC) GUICtrlSetBkColor($input[4], 0xCCCCCC) GUIRegisterMsg($WM_COMMAND, "input_top") GUIRegisterMsg($WM_COMMAND, "input_bottom") GUISetState() Do $msg = GUIGetMsg() Until $msg = $GUI_EVENT_CLOSE Func input_top() Local $read $read = GUICtrlRead($input[1]) GUICtrlSetData($input[3], $read) EndFunc ;==>INPUT: Top Func input_bottom() Local $read $read = GUICtrlRead($input[2]) GUICtrlSetData($input[4], $read) EndFunc ;==>INPUT: Bottom Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted December 31, 2009 Moderators Share Posted December 31, 2009 (edited) DarkBoost,Not quite...... For a start, all functions called by GUIRegisterMsg must begin something like this:Func MY_WM_COMMAND($hWnd, $Msg, $wParam, $lParam)or you stand no chance!Please explain what you want to do and we will see what we can develop together. M23Edit: Clarity. Edited December 31, 2009 by Melba23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
DarkBoost Posted December 31, 2009 Author Share Posted December 31, 2009 (edited) Cheers... In my example I am trying to execute the GUIRegisterMsg() and update the Label only when the user enters text in the specified Input field. Hope that makes sense Would be awesome if it was as easy as: GUIRegisterMsg($input[1], "input_top") Edited December 31, 2009 by DarkBoost Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted December 31, 2009 Moderators Share Posted December 31, 2009 (edited) DarkBoost, Would be awesome if it was as easy as: GUIRegisterMsg($input[1], "message_top")Well, it is a bit more complicated than that - but not too difficult: #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <EditConstants.au3> ; Added to get the value of $EN_CHANGE for our function Opt("MustDeclareVars", 1) ;1=Enabled Global $input[5], $msg GUICreate("", 300, 70) $input[1] = GUICtrlCreateInput("", 10, 10, 135, 20) $input[2] = GUICtrlCreateInput("", 10, 40, 135, 20) $input[3] = GUICtrlCreateLabel("", 155, 10, 135, 20) $input[4] = GUICtrlCreateLabel("", 155, 40, 135, 20) GUICtrlSetBkColor($input[3], 0xCCCCCC) GUICtrlSetBkColor($input[4], 0xCCCCCC) GUISetState() GUIRegisterMsg($WM_COMMAND, "MY_WM_COMMAND") Do $msg = GUIGetMsg() Until $msg = $GUI_EVENT_CLOSE Func MY_WM_COMMAND($hWnd, $iMsg, $wParam, $lParam) Local $iIDFrom = BitAND($wParam, 0xFFFF) ; LoWord - this gives the control which sent the message Local $iCode = BitShift($wParam, 16) ; HiWord - this gives the message that was sent If $iCode = $EN_CHANGE Then ; If we have the correct message Switch $iIDFrom ; See if it comes from one of the inputs Case $input[1] GUICtrlSetData($input[3], GUICtrlRead($input[1])) Case $input[2] GUICtrlSetData($input[4], GUICtrlRead($input[2])) EndSwitch EndIf EndFunc ;==>MY_WM_COMMAND Ask if there is anything you do not understand. I learnt how to do this by studying the many examples on the forum - you will soon pick it up. But do read the Help file page carefully, especially this bit: "Warning: blocking of running user functions which executes window messages with commands such as "Msgbox()" can lead to unexpected behavior, the return to the system should be as fast as possible !!!" You will crash if you stay in the function too long. I often use the function to set a flag which I then pick up elsewhere in the script to start functions which might take a bit of time. M23 Edit: You do not actually need GUIRegisterMsg to do this, by the way: #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> Opt("MustDeclareVars", 1) ;1=Enabled Global $input[5], $msg GUICreate("", 300, 70) $input[1] = GUICtrlCreateInput("", 10, 10, 135, 20) $input[2] = GUICtrlCreateInput("", 10, 40, 135, 20) $input[3] = GUICtrlCreateLabel("", 155, 10, 135, 20) $input[4] = GUICtrlCreateLabel("", 155, 40, 135, 20) GUICtrlSetBkColor($input[3], 0xCCCCCC) GUICtrlSetBkColor($input[4], 0xCCCCCC) GUISetState() Do $msg = GUIGetMsg() If GUICtrlRead($input[1]) <> GUICtrlRead($input[3]) Then GUICtrlSetData($input[3], GUICtrlRead($input[1])) If GUICtrlRead($input[2]) <> GUICtrlRead($input[4]) Then GUICtrlSetData($input[4], GUICtrlRead($input[2])) Until $msg = $GUI_EVENT_CLOSE But it is a good learning exercise! Happy New Year. M23 Edited December 31, 2009 by Melba23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
DarkBoost Posted December 31, 2009 Author Share Posted December 31, 2009 Thank you for taking the time to write this and to show the alternative method, I am really trying to understand how GUIRegisterMsg() works. a.) GUIRegisterMsg() acts like a HotKey which calls a Function when something in the GUI changes = true/false ? b.) $hWnd, $Msg, $wParam, $lParam are like Array results containing data relating to the change that was made in the GUI = true/false ? I am lost with BitAND and BitShift, do not understand what they are doing I checked $EN_CHANGE in #include <EditConstants.au3> shows as "Global Const $EN_CHANGE = 0x300" but do not understand what this means I apologise for the questions, just want to understand rather than keep asking for solutions. Link to comment Share on other sites More sharing options...
Malkey Posted January 1, 2010 Share Posted January 1, 2010 (edited) On my XP this scripts works. The remark, "!!! To make the user function workable you have to define it with maximum 4 function parameters otherwise the function won't be called !!!", is found in the Help file under the GUIRegisterMsg function. This means you have to define it with a minimum of zero parameters up to a maximum 4 parameters otherwise the function won't be called !!! ;#include <GUIConstantsEx.au3> ;#include <WindowsConstants.au3> Opt("MustDeclareVars", 1) ;1=Enabled Global $input[5], $msg GUICreate("", 300, 70) $input[1] = GUICtrlCreateInput("", 10, 10, 135, 20) $input[2] = GUICtrlCreateInput("", 10, 40, 135, 20) $input[3] = GUICtrlCreateLabel("", 155, 10, 135, 20) $input[4] = GUICtrlCreateLabel("", 155, 40, 135, 20) GUICtrlSetBkColor($input[3], 0xCCCCCC) GUICtrlSetBkColor($input[4], 0xCCCCCC) GUIRegisterMsg(0x0111, "Input") ; $WM_COMMAND from WindowsConstants.au3 GUISetState() Do Until GUIGetMsg() = -3 ; $GUI_EVENT_CLOSE from GUIConstantsEx.au3 ; Remarks Help File - !!! To make the user function workable you have to define it ; with maximum 4 function parameters otherwise the function won't be called !!! Func Input() Local $read $read = GUICtrlRead($input[1]) GUICtrlSetData($input[3], $read) $read = GUICtrlRead($input[2]) GUICtrlSetData($input[4], $read) EndFunc ;==>Input Edited January 1, 2010 by Malkey Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted January 1, 2010 Moderators Share Posted January 1, 2010 DarkBoost,This is how I understand GUIRegisterMsg - purists might quibble over detail, but it works for hobbyists like me! Windows works by sending messages to everything on the system, so that everything knows what is going on. By messages, I mean things like the $GUI_EVENT_CLOSE we look for when we exit a GUI - but the possible range is much, much wider; change of focus, change of state, mouseclicks, mousemoves, key presses, etc, etc, etc.GUIRegisterMsg allows us to intercept certain of these messages as they flash round, allowing us to see who sent what. The function we call must have a maximium of 4 parameters because that is the format Windows uses itself.Let us look at the example I gave above: we used GUIRegisterMsg($WM_COMMAND, "MY_WM_COMMAND") - which translates as "Whenever a WM_COMMAND message is sent, please intercept it and pass it through the MY_WM_COMMAND function in this script". The actual message title is denoted by the constant $WM_COMMAND which is stored in WindowsConstant.au3 #include file.The function itself has the normal 4 parameters - $hWnd, $iMsg, $wParam, $lParam - which relate to the following:$hWnd - the GUI which sent the message$iMsg - the code for the mesasge sent$wParam, $iParam - details of what exactly the message is about. this varies according to the message and details can be found in MSDN.In the example, we needed to look at $wParam, because for the WM_COMMAND message this parameter holds the details of the particular control which was involved and the sub-message it sent. We can ignore the GUI and the main message in this case - WM_COMMAND is a huge set and as we are interested in the control we need not worry about the GUI - if we correctly identify the control, it can only come from our GUI! But in other cases, this is vital information, as you can imagine.In this particular case, the low bytes of the $wParam parameter give us the control and the high bytes the message (MSDN is the bible here). The Bit* operators allow us to extract these values:Local $iIDFrom = BitAND($wParam, 0xFFFF) ; LoWord - this gives the control which sent the message Local $iCode = BitShift($wParam, 16) ; HiWord - this gives the message that was sentWe now know which control sent the message and what the sub-message was - so we check if it is one we are looking for and if it is we do whatever we need to do:If $iCode = $EN_CHANGE Then ; If we have the correct message Switch $iIDFrom ; See if it was one of our controls Case $input[1] Case $input[2]When we have finished, the message gets passed along the chain of all the other message handlers so all the other controls in the system can see if they are interested too. That is why you must not hold up the message for too long - otherwise the system gets behind and becomes unstable.In some cases you might actually want to stop the message going further - my UDF for preventing the focus lines on controls is a good example - so we add a Return line to the function which stops it dead. In the focus case this was to prevent the system adding the dotted lines around the control - passing the message on was exactly what I was trying to prevent. Right, that is enough for you to be getting on with after a night spent seeing in the New Year. As I said earlier, look out for examples in the forum and see if you can work out what they are doing. Then try to write a few simple ones on your own - it is the best way to learn.Have fun. You know where we are if you need help.M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
KaFu Posted January 1, 2010 Share Posted January 1, 2010 This is how I understand - purists might quibble over detail, but it works for hobbyists like me! Melba, a really good explanation of GUIRegisterMsg() , couldn't see anything I understand differently. This is worth a line in my signature ! On my XP this scripts works. Yep, but what it does is read the $input[1] and $input[3] controls value ANY time a WM_COMMAND is sent, even if it is not targeted at $input[1]. Better try something like this (added a ConsoleWrite() function for debugging, this is how I always determine which iCode means what, get focus, lose focus, change of input, click, etc...): expandcollapse popup#cs ---------------------------------------------------------------------------- AutoIt Version: 3.3.2.0 Author: myName Script Function: Template AutoIt script. #ce ---------------------------------------------------------------------------- ; Script Start - Add your code below here ;#include <GUIConstantsEx.au3> ;#include <WindowsConstants.au3> Opt("MustDeclareVars", 1) ;1=Enabled Global $input[5], $msg GUICreate("", 300, 70) $input[1] = GUICtrlCreateInput("", 10, 10, 135, 20) $input[2] = GUICtrlCreateInput("", 10, 40, 135, 20) $input[3] = GUICtrlCreateLabel("", 155, 10, 135, 20) $input[4] = GUICtrlCreateLabel("", 155, 40, 135, 20) GUICtrlSetBkColor($input[3], 0xCCCCCC) GUICtrlSetBkColor($input[4], 0xCCCCCC) GUIRegisterMsg(0x0111, "Input") ; $WM_COMMAND from WindowsConstants.au3 GUISetState() Do Until GUIGetMsg() = -3 ; $GUI_EVENT_CLOSE from GUIConstantsEx.au3 ; Remarks Help File - !!! To make the user function workable you have to define it ; with maximum 4 function parameters otherwise the function won't be called !!! Func Input($hWnd, $msg, $wParam, $lParam) Local $iIDFrom = BitAND($wParam, 0xFFFF) ; LoWord - this gives the control which sent the message Local $iCode = BitShift($wParam, 16) ; HiWord - this gives the message that was sent Local $read ConsoleWrite($hWnd & @TAB & $iIDFrom & @TAB & $iCode & @CRLF) ; Debug, start the program, see which iCode performs which task Switch $iIDFrom Case $input[1] Switch $iCode Case 256 ; Input gets focus, found it by looking at the consolewrite() results GUICtrlSetData($input[1], "") GUICtrlSetData($input[3], "") Case 512 ; Input losses focus $read = GUICtrlRead($input[1]) GUICtrlSetData($input[3], $read) EndSwitch Case $input[2] Switch $iCode Case 256 ; Input gets focus GUICtrlSetData($input[2], "") GUICtrlSetData($input[4], "") Case 512 ; Input losses focus $read = GUICtrlRead($input[2]) GUICtrlSetData($input[4], $read) EndSwitch EndSwitch EndFunc ;==>Input OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2022-Nov-26) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Feb-16) HMW - Hide my Windows (2018-Sep-16) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2023-Jun-03) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
DarkBoost Posted January 1, 2010 Author Share Posted January 1, 2010 Melba23 Thank for taking the time to write this, it is very well written and informative. This has given me alot to process and now time to practice.KaFu That is a great tip using the ConsoleWrite() for debugging, cheers Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now