Burgaud Posted April 14, 2018 Share Posted April 14, 2018 I was looking for scripts/functions/methods to make a highlighted listview item remain highlighted even when mouse is removed from focus of the listview. This is a script from a post (not mine) long ago that seems to work. expandcollapse popup#include <GuiConstantsEx.au3> #include <WindowsConstants.au3> #include <GuiListView.au3> #include <WinAPI.au3> Global Const $ODT_LISTVIEW = 102 Global Const $ODA_DRAWENTIRE = 0x1 Global Const $ODA_SELECT = 0x2 Global Const $ODA_FOCUS = 0x4 Global Const $ODS_SELECTED = 0x0001 $hGUI = GUICreate("Test GUI", 410, 320) $hListView = _GUICtrlListView_Create($hGUI, "Items|SubItems", 10, 10, 300, 200, BitOR($LVS_REPORT, $LVS_OWNERDRAWFIXED)) _GUICtrlListView_SetExtendedListViewStyle($hListView, $LVS_EX_FULLROWSELECT) $XhListView = _GUICtrlListView_Create($hGUI, "Items|SubItems", 10, 210, 300, 100, BitOR($LVS_REPORT, $LVS_OWNERDRAWFIXED)) _GUICtrlListView_SetExtendedListViewStyle($XhListView, $LVS_EX_FULLROWSELECT) For $i = 1 To 10 _GUICtrlListView_AddItem($hListView, "Item " & $i) _GUICtrlListView_AddSubItem($hListView, $i - 1, "SubItem " & $i, 1) _GUICtrlListView_AddItem($XhListView, "Item " & $i) _GUICtrlListView_AddSubItem($XhListView, $i - 1, "SubItem " & $i, 1) Next GUIRegisterMsg($WM_DRAWITEM, "WM_DRAWITEM") GUISetState() Do Until GUIGetMsg() = $GUI_EVENT_CLOSE Func WM_DRAWITEM($hWnd, $Msg, $wParam, $lParam) Local $tagDRAWITEMSTRUCT, $iBrushColor, $cID, $itmID, $itmAction, $itmState, $hItm, $hDC, $bSelected $tagDRAWITEMSTRUCT = DllStructCreate("uint cType;uint cID;uint itmID;uint itmAction;uint itmState;" & _ "hwnd hItm;hwnd hDC;int itmRect[4];dword itmData", $lParam) If DllStructGetData($tagDRAWITEMSTRUCT, "cType") <> $ODT_LISTVIEW Then Return $GUI_RUNDEFMSG $cID = DllStructGetData($tagDRAWITEMSTRUCT, "cID") $itmID = DllStructGetData($tagDRAWITEMSTRUCT, "itmID") $itmAction = DllStructGetData($tagDRAWITEMSTRUCT, "itmAction") $itmState = DllStructGetData($tagDRAWITEMSTRUCT, "itmState") $hItm = DllStructGetData($tagDRAWITEMSTRUCT, "hItm") $hDC = DllStructGetData($tagDRAWITEMSTRUCT, "hDC") $bSelected = BitAND($itmState, $ODS_SELECTED) Switch $itmAction Case $ODA_DRAWENTIRE If $itmState = $bSelected Then $iBrushColor = 0xFFFFFF Else $iBrushColor = 0x0000FF EndIf Local $aBrush = DLLCall("gdi32.dll","hwnd","CreateSolidBrush", "int", $iBrushColor) Local $aBrushOld = _WinAPI_SelectObject($hDC, $aBrush[0]) Local $iLeft = DllStructGetData($tagDRAWITEMSTRUCT, "itmRect", 1) DllStructSetData($tagDRAWITEMSTRUCT, "itmRect", $iLeft + 5, 1) _WinAPI_FillRect($hDC, DllStructGetPtr($tagDRAWITEMSTRUCT, "itmRect"), $aBrush[0]) _WinAPI_SelectObject($hDC, $aBrushOld) _WinAPI_DeleteObject($aBrush[0]) Local $itmText = _GUICtrlListView_GetItemText($hListView, $itmID) DllStructSetData($tagDRAWITEMSTRUCT, "itmRect", DllStructGetData($tagDRAWITEMSTRUCT, "itmRect", 1) + 2, 1) DllCall("user32.dll", "int", "DrawText", "hwnd", $hDC, "str", $itmText, "int", StringLen($itmText), _ "ptr", DllStructGetPtr($tagDRAWITEMSTRUCT, "itmRect"), "int", $DT_LEFT) Local $iSubItmText = _GUICtrlListView_GetItemText($hListView, $itmID, 1) Local $aSubItmRect = _GUICtrlListView_GetSubItemRect($hListView, $itmID, 1) Local $iSubItmRect = DllStructCreate("int[4]") DllStructSetData($iSubItmRect, 1, $aSubItmRect[0], 1) DllStructSetData($iSubItmRect, 1, $aSubItmRect[1], 2) DllStructSetData($iSubItmRect, 1, $aSubItmRect[2], 3) DllStructSetData($iSubItmRect, 1, $aSubItmRect[3], 4) DllCall("user32.dll", "int", "DrawText", "hwnd", $hDC, "str", $iSubItmText, "int", StringLen($iSubItmText), _ "ptr", DllStructGetPtr($iSubItmRect), "int", $DT_LEFT) EndSwitch Return $GUI_RUNDEFMSG EndFunc Here is my question: I read the documentations on: DllStructCreate DllStructGetData DLLCall . . . every DLL therein All were too cryptic to understand. Can anyone please explain the WM_DRAWITEM function, if possible, line per line? I really would like to understand Autoit in its innards. Thanks! Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted April 14, 2018 Moderators Share Posted April 14, 2018 Burgaud, I suggest you start by reading the GUIRegisterMsg tutorial in the Wiki if you are not sure quite what Windows message handlers do. Then the following might make more sense: expandcollapse popup; Tell AutoIt to intercept $WM_DRAWITEM messages GUIRegisterMsg($WM_DRAWITEM, "WM_DRAWITEM") ; This handler will run when a $WM_DRAWITEM message is ibntercepted Func WM_DRAWITEM($hWnd, $Msg, $wParam, $lParam) ; Create a struct - a type of variable with very closely defined sections, ech of which is given a name (optional) and a datatype Local $tagDRAWITEMSTRUCT, $iBrushColor, $cID, $itmID, $itmAction, $itmState, $hItm, $hDC, $bSelected $tagDRAWITEMSTRUCT = DllStructCreate("uint cType;uint cID;uint itmID;uint itmAction;uint itmState;" & _ "hwnd hItm;hwnd hDC;int itmRect[4];dword itmData", $lParam) ; $lParam - one of the parameters received by the message handler - gives us a pointer ; This is the address of an area of memory filled when Windows gets a $WM_DRAWITEM message ; We map this area of memory using the struct we created ; Look at what is in the "cType" section of the struct If DllStructGetData($tagDRAWITEMSTRUCT, "cType") <> $ODT_LISTVIEW Then Return $GUI_RUNDEFMSG ; If that was valid then get other useful data from other sections ofthe struct $cID = DllStructGetData($tagDRAWITEMSTRUCT, "cID") $itmID = DllStructGetData($tagDRAWITEMSTRUCT, "itmID") $itmAction = DllStructGetData($tagDRAWITEMSTRUCT, "itmAction") $itmState = DllStructGetData($tagDRAWITEMSTRUCT, "itmState") $hItm = DllStructGetData($tagDRAWITEMSTRUCT, "hItm") $hDC = DllStructGetData($tagDRAWITEMSTRUCT, "hDC") $bSelected = BitAND($itmState, $ODS_SELECTED) ; Now determine whether the action that took place was the one we needed to intercept Switch $itmAction Case $ODA_DRAWENTIRE ; Determine the colour needed - wil depend if the ListView element is selected or not If $itmState = $bSelected Then $iBrushColor = 0xFFFFFF Else $iBrushColor = 0x0000FF EndIf ; Create a brush Local $aBrush = DLLCall("gdi32.dll","hwnd","CreateSolidBrush", "int", $iBrushColor) Local $aBrushOld = _WinAPI_SelectObject($hDC, $aBrush[0]) ; Create a struct to show the position of the ListView element Local $iLeft = DllStructGetData($tagDRAWITEMSTRUCT, "itmRect", 1) DllStructSetData($tagDRAWITEMSTRUCT, "itmRect", $iLeft + 5, 1) ; Paint the element _WinAPI_FillRect($hDC, DllStructGetPtr($tagDRAWITEMSTRUCT, "itmRect"), $aBrush[0]) ; delete the bruch we created _WinAPI_SelectObject($hDC, $aBrushOld) _WinAPI_DeleteObject($aBrush[0]) ; This next section write the text into the user drawn elements ; The item (left-most element) Local $itmText = _GUICtrlListView_GetItemText($hListView, $itmID) DllStructSetData($tagDRAWITEMSTRUCT, "itmRect", DllStructGetData($tagDRAWITEMSTRUCT, "itmRect", 1) + 2, 1) DllCall("user32.dll", "int", "DrawText", "hwnd", $hDC, "str", $itmText, "int", StringLen($itmText), _ "ptr", DllStructGetPtr($tagDRAWITEMSTRUCT, "itmRect"), "int", $DT_LEFT) ; And now the subitem - I imagine this woudl be looped if there were mor ethan 2 columns Local $iSubItmText = _GUICtrlListView_GetItemText($hListView, $itmID, 1) Local $aSubItmRect = _GUICtrlListView_GetSubItemRect($hListView, $itmID, 1) Local $iSubItmRect = DllStructCreate("int[4]") DllStructSetData($iSubItmRect, 1, $aSubItmRect[0], 1) DllStructSetData($iSubItmRect, 1, $aSubItmRect[1], 2) DllStructSetData($iSubItmRect, 1, $aSubItmRect[2], 3) DllStructSetData($iSubItmRect, 1, $aSubItmRect[3], 4) DllCall("user32.dll", "int", "DrawText", "hwnd", $hDC, "str", $iSubItmText, "int", StringLen($iSubItmText), _ "ptr", DllStructGetPtr($iSubItmRect), "int", $DT_LEFT) EndSwitch ; Tell Autoit to do its normal actions when it receives the message Return $GUI_RUNDEFMSG EndFunc I hope this helps. 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...
Burgaud Posted April 19, 2018 Author Share Posted April 19, 2018 What is the difference between: GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") and GUIRegisterMsg($WM_DRAWITEM, "WM_DRAWITEM") Several sample scripts I saw them using WM_NOTIFY while some uses WM_DRAWITEM to perform the same result (ie, highlight/change color of a listview item). THIS is very confusing. Link to comment Share on other sites More sharing options...
Earthshine Posted April 19, 2018 Share Posted April 19, 2018 well, you start with Google and look up the messages. WM_DRAWITEM message WM_NOTIFY message My resources are limited. You must ask the right questions Link to comment Share on other sites More sharing options...
Burgaud Posted April 29, 2018 Author Share Posted April 29, 2018 The last 3-4 weeks, I have been trying to port over my book keeping perl script into Autoit. After weeks with this project, I barely made any progress. AutoIt's GUI module requires EXTENSIVE knowledge of Win32::GUI. It was steep learning curve. Documentations and examples were little help as these were cryptic at best. Simple GUI like buttons, labels and entry boxes were easy; but ListBoxes, ListViews and others was the high wall. Little progress and huge amount of time and effort spent was NOT worth it. Sadly, in the end, I gave up on this Autoit port project. Link to comment Share on other sites More sharing options...
Zedna Posted April 29, 2018 Share Posted April 29, 2018 When you do standard actions with ListView/ListBox then it's easy too. It becomes complex only when you want to achieve non-standard behaviour. So for you as AutoIt/Win32 API novice avoid non-standard behaviour and be happy with standards. Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
jchd Posted April 30, 2018 Share Posted April 30, 2018 I wonder how you can compare perl scripts and customized behavior Windows GUI, using AutoIt or whatever else. You seem to be upset by Windows' GUI complexity when trying to achieve non-standard behavior and that isn't surprising: no GUI-ed OS is simple in this regard. You're drowning yourself in cosmetic details. Rather focus on having the real job done first using a bare-bone interface (even console I/O will do) and when the core job is working fine, only then add a GUI harness, simple at first then make it prettier/sophisticated as you feel need. Earthshine 1 This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt) Link to comment Share on other sites More sharing options...
Earthshine Posted April 30, 2018 Share Posted April 30, 2018 Yes. Get it working first without Gui then add that later as stated above. Don’t blame Windows My resources are limited. You must ask the right questions 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