pixelsearch Posted December 16, 2018 Share Posted December 16, 2018 (edited) Hi guys, In a listview, when you right click on a column header, why is the associated handle different from the listview handle ? If you look at the example found in the help file, topic _GUICtrlListView_Create, you will notice that the following 5 actions are associated to the same listview handle. These 5 actions are : LEFT click on a column header, single or double left click on items, single or double right click on items. But please notice how a right click on column headers does nothing in the help file example. I can provide a script to show this, just clic everywhere and see how 2 different handles will be shown in the Console, as soon as you right clic on a column header. There is a context menu in the script but even if you comment the 3 lines creating it, you should still get 2 different handles. Thanks to anyone who can explain this behavior (a 2nd question, concerning $GUI_RUNDEFMSG, will be discussed later) expandcollapse popup#include <GuiConstantsEx.au3> #include <GuiListView.au3> #include <WindowsConstants.au3> Global $hGUI = GUICreate("Right click for context menu", 300, 300) Global $idListview = GUICtrlCreateListView(" Col A | Col B", 25, 25, 250, 250) For $i = 0 To 4 GUICtrlCreateListViewItem($i*10 & "|" & $i*10 +1, $idListview) Next Global $idMenu = GUICtrlCreateContextMenu($idListview) Global $idMenu_1 = GUICtrlCreateMenuItem("Option 1", $idMenu) Global $idMenu_2 = GUICtrlCreateMenuItem("Option 2", $idMenu) GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") GUISetState() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) Local $tNMHDR, $hWndFrom, $iIDFrom, $iCode $tNMHDR = DllStructCreate($tagNMHDR, $lParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) ; $iIDFrom = DllStructGetData($tNMHDR, "IDFrom") $iCode = DllStructGetData($tNMHDR, "Code") Local $sMsgConsole = "" Switch $iCode Case $NM_CLICK $sMsgConsole = "Left click" Case $NM_RCLICK $sMsgConsole = "Right click" Case $NM_DBLCLK $sMsgConsole = "Double left click" Case $NM_RDBLCLK $sMsgConsole = "Double right click" Case $LVN_COLUMNCLICK $sMsgConsole = "Column left click" EndSwitch If $sMsgConsole <> "" Then ConsoleWrite($sMsgConsole & " : handle = " & $hWndFrom & @CRLF) EndIf Return $GUI_RUNDEFMSG ; we'll discuss later about Return, Return 0 and Return 1 EndFunc Edited December 16, 2018 by pixelsearch Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted December 16, 2018 Moderators Share Posted December 16, 2018 pixelsearch, Quote In a listview, when you right click on a column header, why is the associated handle different from the listview handle ? Because the header is a separate control from the ListView itself - just as a button is separate from the GUI which contains it. The _GUICtrlListView_GetHeader function will get you the header handle if required. The same thing is true for combo controls, where the combo, input and dropdown list are all separate controls - look at the example for _GUICtrlComboBox_GetComboBoxInfo to see this illustrated. M23 pixelsearch 1 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...
FrancescoDiMuro Posted December 16, 2018 Share Posted December 16, 2018 1 minute ago, Melba23 said: look at the example for _GUICtrlComboBox_GetComboBoxInfo to see this illustrated. @pixelsearch Or just "spy" it using AutoItWindowInfoTool You'll notice that the ListView handle and the ListView header handle are different. pixelsearch 1 Click here to see my signature: Spoiler ALWAYS GOOD TO READ: Forum Rules Forum Etiquette Link to comment Share on other sites More sharing options...
pixelsearch Posted December 16, 2018 Author Share Posted December 16, 2018 (edited) Thanks for your both answers @Francesco : I still wonder how I forgot the AutoIt Window Info to double check the handle ! @Melba23 : glad you mentioned the _GUICtrlListView_GetHeader function (I didn't know it) and it will help me in another script, here, to detect where exactly is pressed the right mouse button, so I can manage the context menu rebuild in a better way. Now the 2nd question concerns $GUI_RUNDEFMSG Here is a part of what we can read in the help file, topic GUIRegisterMsg() : "By default the AutoIt internal message handler (if there is one for that message) will be actioned after the user function exits. The AutoIt internal message handler will also be actioned if the keyword Return is used with the constant $GUI_RUNDEFMSG" "However, if Return is used with any other value (including no value at all) the AutoIt internal message handler will NOT be actioned" Reading this, I understand that Return (without any value), Return 0 or Return 1 will all prevent the AutoIt internal message handler to be actioned, right ? But if you try them all in the script presented above, you will notice that : * Return : same as Return $GUI_RUNDEFMSG : an item is selected when left click, the context menu appears when right click * Return 0 : an item is selected when left click, context menu doesn't show when right click * Return 1 : an item is not selected when left click, context menu doesn't show when right click So can't we conclude that Return and Return $GUI_RUNDEFMSG do exactly the same ? Because if "Return (without any value) doesn't action the AutoIt internal message handler" (as stated in the help file), so why does the context menu appear when you use the single word Return ? Thanks for reading Edited December 16, 2018 by pixelsearch Link to comment Share on other sites More sharing options...
Nine Posted December 16, 2018 Share Posted December 16, 2018 "So an early return from the user function requires Return $GUI_RUNDEFMSG" Early is the keyword, if you put the return at the very end of a func, it doesn't make a difference. It is simply a way to tell the programmer that you want autoit to continue his work. Early return... “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
pixelsearch Posted December 17, 2018 Author Share Posted December 17, 2018 Hi Nine, It's been a long time, at least a few days My concern is that it should maybe be stated : "So an early return from the user function requires Return $GUI_RUNDEFMSG or Return" Because even if I don't place the word "Return" at the very end of the function, then AutoIt internal message handler is actioned. Let's try to place it at an incredible place in the function, did you say early ? Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) Return Local $tNMHDR, $hWndFrom, $iIDFrom, $iCode ; All the rest of the function here... ; etc... EndFunc And here we are, nothing changes in the way I described it : an immediate Return keeps showing the context menu. The question is : does "showing the context menu" mean that AutoIt internal message handler is actioned ? * If the answer is "yes", then Return is equivalent to Return $GUI_RUNDEFMSG, no matter where the word Return is found in the function. * If the answer is "no", then my bad... but one will have to explain then, why Return 0 or Return 1 don't display the context menu, when Return displays it Link to comment Share on other sites More sharing options...
FrancescoDiMuro Posted December 17, 2018 Share Posted December 17, 2018 Hey @pixelsearch 2 hours ago, pixelsearch said: The question is : does "showing the context menu" mean that AutoIt internal message handler is actioned ? Yes, because right click is an event, and if you don't action the AutoIt internal message handler, it won't be processed and you'll not see the context menu to appear. There is a "flow chart" created by @LarsJ which explains the flow of a Windows Message, and the role of $GUI_RUNDEFMSG in a function (WM_*) Click here to see my signature: Spoiler ALWAYS GOOD TO READ: Forum Rules Forum Etiquette Link to comment Share on other sites More sharing options...
pixelsearch Posted December 17, 2018 Author Share Posted December 17, 2018 (edited) Hi Francesco Thanks for your answer and the link you provided concerning $GUI_RUNDEFMSG, gonna consult it now. LarsJ write great posts and a few days ago, I discovered this one concerning ItemParam Very interesting ! Edited December 17, 2018 by pixelsearch Link to comment Share on other sites More sharing options...
LarsJ Posted December 24, 2018 Share Posted December 24, 2018 (edited) I've been asked for a comment in this post. pixelsearch, You're probably right that Return (without a value) and Return $GUI_RUNDEFMSG both causes the AutoIt internal message code to be executed. At least for WM_NOTIFY. There are slightly different explanations in different versions of the help file. I can see from what you've copied from the Help file that you're at 3.3.14.5. I'm still at 3.3.14.2. At 3.3.14.2, the text in the help file and especially the text at the bottom of the WM_COMMAND example is slightly better in accordance with what you have experienced. The text at the bottom of the WM_COMMAND example: ; !!! But only 'Return' (without any value) will not proceed ; the default AutoIt3-message in the future !!! Return $GUI_RUNDEFMSG Note the last 3 words in the comment: "in the future". But in the text above the example it's also mentioned that Return (without a value) does not execute the internal code. So it's not completely clear. If in doubt, just test it. With regard to actual return values, you should check the Microsoft documentation so that you only return valid values. There are, for example, no return values for NM_CLICK (listview), while return values for NM_RCLICK (listview) are zero and non-zero. If you return a value that is not documented by Microsoft, check that it has no unintended effects. It seems that the difficulties of using GUIRegisterMsg and the return values are somewhat overstated. In a real concrete example, it's very easy. Merry Christmas. Edited December 24, 2018 by LarsJ pixelsearch 1 Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Link to comment Share on other sites More sharing options...
pixelsearch Posted December 24, 2018 Author Share Posted December 24, 2018 (edited) 3 hours ago, LarsJ said: pixelsearch, You're probably right that Return (without a value) and Return $GUI_RUNDEFMSG both causes the AutoIt internal message code to be executed. At least for WM_NOTIFY. Now that made my day, thanks LarsJ for your expertise Something should be done to clarify all these Return codes (concerning $GUI_RUNDEFMSG) because it's too complicated actually and Return 0 is definitely not the same as Return 1 (see how Return 1 doesn't allow to select an item in the script above, when Return 0 allows it) and both are different from Return as I clearly explained it earlier (Return allows the context menu to appear, same as Return $GUI_RUNDEFMSG) while Return 0 or 1 don't allow the context menu to appear. I just followed your advice and consulted 2 MSDN web pages concerning Microsoft return codes : * NM_RCLICK (list view) notification code : "Return nonzero to not allow the default processing, or zero to allow the default processing" * WM_SIZE (like in this script ) : "If an application processes this message, it should return zero." Now let's look at the help file. What do we read in it, concerning the "Return" keyword ? We read this : "Unlike built-in functions, user-defined functions return 0 unless another return value is specified." This means that in any udf, the 3 following actions always return 0 : 1) No Return keyword, the UDF ends with EndFunc, 0 is returned (that's important to know) 2) Return keyword anywhere in the UDF, 0 is returned (important too) 3) Return 0 anywhere in the UDF, 0 is returned I wish this behavior had been applied to $GUI_RUNDEFMSG since day 1, I mean grouping these 3 cases, resulting in a one and single action (actioning or not AutoIt internal message handler, you choose, though Microsoft seems to use "0 to allow default processing") Then any "non 0 Return" (like Return 1, Return -1, Return $GUI_RUNDEFMSG) would behave same, doing the opposite of the 3 cases exposed just above, that looks simple ! (too simple ?) I guess it's a bit too late to do it that way, because it would be script breaking until the end of time... Anyway, we'll see how this will be handled in a future AutoIt release I wish you all a Merry Christmas and a good year 2019. Be safe and have a happy life Edit : LarsJ, I would like to ask why you didn't upgrade with the last AutoIt release ? Edited December 24, 2018 by pixelsearch Forgot to ask LarsJ why he didn't upgrade ! 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