InunoTaishou Posted April 17, 2016 Share Posted April 17, 2016 Trying to sort my items in the list view and was wanting to use my window proc instead of GUIRegisterMsg. My current problem is GUIRegisterMsg with $WM_NOTIFY works and does sort the item but $WM_NOTIFY inside the Window Proc does not work, it's not getting the $LVN_COLUMNCLICK code. Anyone know why the GUI message $WM_NOTIFY works but the subclassed $WM_NOTIFY does not? In other instances I've used $WM_NOTIFY on controls it has been the same. expandcollapse popup#include <GUIConstants.au3> #include <GuiListView.au3> #include <WindowsConstants.au3> #include <WinAPIShellEx.au3> Global $hNewWindowProc = DllCallbackRegister("NewWindowProc", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr") Global $pNewWindowProc = DllCallbackGetPtr($hNewWindowProc) Global $hMain = GUICreate("listview items", 220, 250, 100, 200) Global $idListview = GUICtrlCreateListView("col1|col2|col3 ", 10, 10, 200, 150) Global $idButton = GUICtrlCreateButton("Value?", 75, 170, 70, 20) Global $idItem2 = GUICtrlCreateListViewItem("2|2|2", $idListview) Global $idItem1 = GUICtrlCreateListViewItem("1|1|1", $idListview) Global $idItem4 = GUICtrlCreateListViewItem("4|4|4", $idListview) Global $idItem3 = GUICtrlCreateListViewItem("3|3|3", $idListview) Global $hListView = GUICtrlGetHandle($idListview) GUISetState(@SW_SHOW) _WinAPI_SetWindowSubclass($hListView, $pNewWindowProc, 9999) ; This does not work ;~ GUIRegisterMsg($WM_NOTIFY, WM_NOTIFY) ; This works _GUICtrlListView_RegisterSortCallBack($hListView) ; Loop until the user exits. While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd _GUICtrlListView_UnRegisterSortCallBack($hListView) DllCallbackFree($hNewWindowProc) Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam, $lParam Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam) Local $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) Local $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom Case $hListView Switch $iCode Case $LVN_COLUMNCLICK ; A column was clicked Local $tInfo = DllStructCreate($tagNMLISTVIEW, $lParam) _GUICtrlListView_SortItems($hWndFrom, DllStructGetData($tInfo, "SubItem")) EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY Func NewWindowProc($hWnd, $iMsg, $wParam, $lParam, $uIdSubclass, $dwRefData) #forceref $hWnd, $iMsg, $wParam, $lParam, $uIdSubclass, $dwRefData Switch ($iMsg) Case $WM_NOTIFY Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam) Local $iCode = DllStructGetData($tNMHDR, "Code") Switch ($iCode) Case $LVN_COLUMNCLICK Local $tInfo = DllStructCreate($tagNMLISTVIEW, $lParam) _GUICtrlListView_SortItems($hWnd, DllStructGetData($tInfo, "SubItem")) EndSwitch EndSwitch Return _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) EndFunc ;==>NewWindowProc Link to comment Share on other sites More sharing options...
LarsJ Posted April 17, 2016 Share Posted April 17, 2016 Because WM_NOTIFY messages are sent to the parent window of the listview. In your case the parent window is the GUI, so you have to subclass the GUI. InunoTaishou 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...
InunoTaishou Posted April 17, 2016 Author Share Posted April 17, 2016 That makes sense. I did this ConsoleWrite($hWndFrom & " | " & $hListView & " | " & $hWnd & " | " & _GUICtrlListView_GetHeader($hListView) & @CRLF) In the NewWindowProc function and see that I'm getting the lParam for the header, not the listview. After doing some debugging, gathering all of the possible listview codes into an array and seeing what I'm getting in the subclass function I can still use it without having to subclasss the gui. I may end up subclassing the gui later but for now I don't need it. I was already using Local $tNMHeader = DllStructCreate($tagNMHEADER, $lParam) Local $iCol = DllStructGetData($tNMHeader, "Item") In my main program to keep track of the width of the headers. So I just used the click code to sort Func NewWindowProc($hWnd, $iMsg, $wParam, $lParam, $uIdSubclass, $dwRefData) #forceref $hWnd, $iMsg, $wParam, $lParam, $uIdSubclass, $dwRefData Switch ($iMsg) Case $WM_NOTIFY Local $tNMHeader = DllStructCreate($tagNMHEADER, $lParam) Local $iCol = DllStructGetData($tNMHeader, "Item") Local $iCode = DllStructGetData($tNMHeader, "Code") ConsoleWrite($aListViewCodes[Abs($iCode)] & " | " & $iCode & @CRLF) Switch ($iCode) Case $HDN_ITEMCLICKW _GUICtrlListView_SortItems($hWnd, $iCol) EndSwitch EndSwitch Return _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) EndFunc ;==>NewWindowProc This also might be useful for anyone else debugging a listview control. Let you see the variable of the code you're getting. Spoiler expandcollapse popupGlobal $aListViewCodes[$HDM_SETUNICODEFORMAT + 2] $aListViewCodes[Abs($NM_CUSTOMDRAW)] = "NM_CUSTOMDRAW" $aListViewCodes[Abs($HDN_BEGINDRAG)] = "HDN_BEGINDRAG" $aListViewCodes[Abs($HDN_BEGINTRACK)] = "HDN_BEGINTRACK" $aListViewCodes[Abs($HDN_DIVIDERDBLCLICK)] = "HDN_DIVIDERDBLCLICK" $aListViewCodes[Abs($HDN_ENDDRAG)] = "HDN_ENDDRAG" $aListViewCodes[Abs($HDN_ENDTRACK)] = "HDN_ENDTRACK" $aListViewCodes[Abs($HDN_FILTERBTNCLICK)] = "HDN_FILTERBTNCLICK" $aListViewCodes[Abs($HDN_FILTERCHANGE)] = "HDN_FILTERCHANGE" $aListViewCodes[Abs($HDN_GETDISPINFO)] = "HDN_GETDISPINFO" $aListViewCodes[Abs($HDN_ITEMCHANGED)] = "HDN_ITEMCHANGED" $aListViewCodes[Abs($HDN_ITEMCHANGING)] = "HDN_ITEMCHANGING" $aListViewCodes[Abs($HDN_ITEMCLICK)] = "HDN_ITEMCLICK" $aListViewCodes[Abs($HDN_ITEMDBLCLICK)] = "HDN_ITEMDBLCLICK" $aListViewCodes[Abs($HDN_TRACK)] = "HDN_TRACK" $aListViewCodes[Abs($HDN_BEGINTRACKW)] = "HDN_BEGINTRACKW" $aListViewCodes[Abs($HDN_DIVIDERDBLCLICKW)] = "HDN_DIVIDERDBLCLICKW" $aListViewCodes[Abs($HDN_ENDTRACKW)] = "HDN_ENDTRACKW" $aListViewCodes[Abs($HDN_GETDISPINFOW)] = "HDN_GETDISPINFOW" $aListViewCodes[Abs($HDN_ITEMCHANGEDW)] = "HDN_ITEMCHANGEDW" $aListViewCodes[Abs($HDN_ITEMCHANGINGW)] = "HDN_ITEMCHANGINGW" $aListViewCodes[Abs($HDN_ITEMCLICKW)] = "HDN_ITEMCLICKW" $aListViewCodes[Abs($HDN_ITEMDBLCLICKW)] = "HDN_ITEMDBLCLICKW" $aListViewCodes[Abs($HDN_TRACKW)] = "HDN_TRACKW" $aListViewCodes[Abs($LVN_FIRST)] = "LVN_FIRST" $aListViewCodes[Abs($LVN_LAST)] = "LVN_LAST" $aListViewCodes[Abs($LVN_BEGINDRAG)] = "LVN_BEGINDRAG" $aListViewCodes[Abs($LVN_BEGINLABELEDITA)] = "LVN_BEGINLABELEDITA" $aListViewCodes[Abs($LVN_BEGINLABELEDITW)] = "LVN_BEGINLABELEDITW" $aListViewCodes[Abs($LVN_BEGINRDRAG)] = "LVN_BEGINRDRAG" $aListViewCodes[Abs($LVN_BEGINSCROLL)] = "LVN_BEGINSCROLL" $aListViewCodes[Abs($LVN_COLUMNCLICK)] = "LVN_COLUMNCLICK" $aListViewCodes[Abs($LVN_COLUMNDROPDOWN)] = "LVN_COLUMNDROPDOWN" $aListViewCodes[Abs($LVN_COLUMNOVERFLOWCLICK)] = "LVN_COLUMNOVERFLOWCLICK" $aListViewCodes[Abs($LVN_DELETEALLITEMS)] = "LVN_DELETEALLITEMS" $aListViewCodes[Abs($LVN_DELETEITEM)] = "LVN_DELETEITEM" $aListViewCodes[Abs($LVN_ENDLABELEDITA)] = "LVN_ENDLABELEDITA" $aListViewCodes[Abs($LVN_ENDLABELEDITW)] = "LVN_ENDLABELEDITW" $aListViewCodes[Abs($LVN_ENDSCROLL)] = "LVN_ENDSCROLL" $aListViewCodes[Abs($LVN_GETDISPINFOA)] = "LVN_GETDISPINFOA" $aListViewCodes[Abs($LVN_GETDISPINFOW)] = "LVN_GETDISPINFOW" $aListViewCodes[Abs($LVN_GETDISPINFO)] = "LVN_GETDISPINFO" $aListViewCodes[Abs($LVN_GETEMPTYMARKUP)] = "LVN_GETEMPTYMARKUP" $aListViewCodes[Abs($LVN_GETINFOTIPA)] = "LVN_GETINFOTIPA" $aListViewCodes[Abs($LVN_GETINFOTIPW)] = "LVN_GETINFOTIPW" $aListViewCodes[Abs($LVN_HOTTRACK)] = "LVN_HOTTRACK" $aListViewCodes[Abs($LVN_INCREMENTALSEARCHA)] = "LVN_INCREMENTALSEARCHA" $aListViewCodes[Abs($LVN_INCREMENTALSEARCHW)] = "LVN_INCREMENTALSEARCHW" $aListViewCodes[Abs($LVN_INSERTITEM)] = "LVN_INSERTITEM" $aListViewCodes[Abs($LVN_ITEMACTIVATE)] = "LVN_ITEMACTIVATE" $aListViewCodes[Abs($LVN_ITEMCHANGED)] = "LVN_ITEMCHANGED" $aListViewCodes[Abs($LVN_ITEMCHANGING)] = "LVN_ITEMCHANGING" $aListViewCodes[Abs($LVN_KEYDOWN)] = "LVN_KEYDOWN" $aListViewCodes[Abs($LVN_LINKCLICK)] = "LVN_LINKCLICK" $aListViewCodes[Abs($LVN_MARQUEEBEGIN)] = "LVN_MARQUEEBEGIN" $aListViewCodes[Abs($LVN_ODCACHEHINT)] = "LVN_ODCACHEHINT" $aListViewCodes[Abs($LVN_ODFINDITEMA)] = "LVN_ODFINDITEMA" $aListViewCodes[Abs($LVN_ODFINDITEMW)] = "LVN_ODFINDITEMW" $aListViewCodes[Abs($LVN_ODFINDITEM)] = "LVN_ODFINDITEM" $aListViewCodes[Abs($LVN_ODSTATECHANGED)] = "LVN_ODSTATECHANGED" $aListViewCodes[Abs($LVN_SETDISPINFOA)] = "LVN_SETDISPINFOA" $aListViewCodes[Abs($LVN_SETDISPINFOW)] = "LVN_SETDISPINFOW" $aListViewCodes[Abs($NM_RELEASEDCAPTURE)] = "NM_RELEASEDCAPTURE" $aListViewCodes[$HDM_FIRST] = "HDM_FIRST" $aListViewCodes[$HDM_CLEARFILTER] = "HDM_CLEARFILTER" $aListViewCodes[$HDM_CREATEDRAGIMAGE] = "HDM_CREATEDRAGIMAGE" $aListViewCodes[$HDM_DELETEITEM] = "HDM_DELETEITEM" $aListViewCodes[$HDM_EDITFILTER] = "HDM_EDITFILTER" $aListViewCodes[$HDM_GETBITMAPMARGIN] = "HDM_GETBITMAPMARGIN" $aListViewCodes[$HDM_GETFOCUSEDITEM] = "HDM_GETFOCUSEDITEM" $aListViewCodes[$HDM_GETIMAGELIST] = "HDM_GETIMAGELIST" $aListViewCodes[$HDM_GETITEMA] = "HDM_GETITEMA" $aListViewCodes[$HDM_GETITEMW] = "HDM_GETITEMW" $aListViewCodes[$HDM_GETITEMCOUNT] = "HDM_GETITEMCOUNT" $aListViewCodes[$HDM_GETITEMDROPDOWNRECT] = "HDM_GETITEMDROPDOWNRECT" $aListViewCodes[$HDM_GETITEMRECT] = "HDM_GETITEMRECT" $aListViewCodes[$HDM_GETORDERARRAY] = "HDM_GETORDERARRAY" $aListViewCodes[$HDM_GETOVERFLOWRECT] = "HDM_GETOVERFLOWRECT" $aListViewCodes[$HDM_GETUNICODEFORMAT] = "HDM_GETUNICODEFORMAT" $aListViewCodes[$HDM_HITTEST] = "HDM_HITTEST" $aListViewCodes[$HDM_INSERTITEMA] = "HDM_INSERTITEMA" $aListViewCodes[$HDM_INSERTITEMW] = "HDM_INSERTITEMW" $aListViewCodes[$HDM_LAYOUT] = "HDM_LAYOUT" $aListViewCodes[$HDM_ORDERTOINDEX] = "HDM_ORDERTOINDEX" $aListViewCodes[$HDM_SETBITMAPMARGIN] = "HDM_SETBITMAPMARGIN" $aListViewCodes[$HDM_SETFILTERCHANGETIMEOUT] = "HDM_SETFILTERCHANGETIMEOUT" $aListViewCodes[$HDM_SETFOCUSEDITEM] = "HDM_SETFOCUSEDITEM" $aListViewCodes[$HDM_SETHOTDIVIDER] = "HDM_SETHOTDIVIDER" $aListViewCodes[$HDM_SETIMAGELIST] = "HDM_SETIMAGELIST" $aListViewCodes[$HDM_SETITEMA] = "HDM_SETITEMA" $aListViewCodes[$HDM_SETITEMW] = "HDM_SETITEMW" $aListViewCodes[$HDM_SETORDERARRAY] = "HDM_SETORDERARRAY" $aListViewCodes[$HDM_SETUNICODEFORMAT] = "HDM_SETUNICODEFORMAT" Link to comment Share on other sites More sharing options...
LarsJ Posted April 18, 2016 Share Posted April 18, 2016 WM_NOTIFY messages from the header control are also sent to the parent window - which is the listview. To get WM_NOTIFY messages from the header control you have to subclass the listview as you have done. If you also are going to subclass the header control don't forget this nasty little issue. To avoid subclassing the GUI I ususally create a child window and create the listview in the child window. Then you can subclass the child window and avoids receiving messages from the entire GUI. It's quite simple and works flawlessly. 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...
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