Jump to content

mLipok

MVPs
  • Posts

    11,910
  • Joined

  • Last visited

  • Days Won

    67

mLipok last won the day on May 8

mLipok had the most liked content!

About mLipok

  • Birthday 07/19/1978

Profile Information

  • Member Title
    Sometimes... even usually I'm nitpicky.
  • Location
    Europe, Poland, Upper Silesia, Zabrze
  • Interests
    ¯\_(ツ)_/¯

Recent Profile Visitors

30,532 profile views

mLipok's Achievements

  1. Please let me know what you think about this example also if I did any mistake in understanding the ListView or even any mistake in my "English" wording in this example. EDIT: I added it to HelpFile as _GUICtrlListView_MapIndexToID[2].au3
  2. I did it #include <ColorConstants.au3> #include <GUIConstantsEx.au3> #include <GuiListView.au3> #include <MsgBoxConstants.au3> Global Enum $__Example_LVColumn_Name, $__Example_LVColumn_ItemIndex, $__Example_LVColumn_ItemID Example() Func Example() Local $iID, $idListview GUICreate("ListView Map ID To Index", 530, 300) $idListview = GUICtrlCreateListView("", 2, 2, 524, 268, -1, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT)) GUISetState(@SW_SHOW) GUIRegisterMsg($WM_NOTIFY, MY_WM_NOTIFY) ; Add column _GUICtrlListView_AddColumn($idListview, "Item (row name given by user)", 100) ; $__Example_LVColumn_Name _GUICtrlListView_AddColumn($idListview, "ItemIndex (current row index)", 100) ; $__Example_LVColumn_ItemIndex _GUICtrlListView_AddColumn($idListview, "ItemID (creation order index)", 100) ; $__Example_LVColumn_ItemID _GUICtrlListView_SetColumnWidth($idListview, $__Example_LVColumn_Name, $LVSCW_AUTOSIZE_USEHEADER) _GUICtrlListView_SetColumnWidth($idListview, $__Example_LVColumn_ItemIndex, $LVSCW_AUTOSIZE_USEHEADER) _GUICtrlListView_SetColumnWidth($idListview, $__Example_LVColumn_ItemID, $LVSCW_AUTOSIZE_USEHEADER) ; Add items - always as first item - it creates "Revert Order" last element on top - as ItemIndex 0 For $i = 1 To 9 _GUICtrlListView_InsertItem($idListview, "Item " & $i, 0) Next ; Show ID for item 2 Local $i_CheckItem = 2 $iID = _GUICtrlListView_MapIndexToID($idListview, $i_CheckItem) Local $s_Info = _ "Index " & $i_CheckItem & " to ID: " & $iID & @CRLF & _ "ID " & $iID & " to Index: " & _GUICtrlListView_MapIDToIndex($idListview, $iID) MsgBox($MB_TOPMOST, "TEST #" & @ScriptLineNumber, $s_Info) MsgBox($MB_TOPMOST, "TEST #" & @ScriptLineNumber, _ 'Before deleting "Item 8"' & @CRLF & _ 'Note "Item 7" Index and ID' & @CRLF & _ 'also other lower ListView items (rows)' _ ) _GUICtrlListView_DeleteItem($idListview, 1) _GUICtrlListView_RedrawItems($idListview, 0, _GUICtrlListView_GetItemCount($idListview) - 1) MsgBox($MB_TOPMOST, "TEST #" & @ScriptLineNumber, _ 'Afer deleting "Item 8"' & @CRLF & _ 'Note "Item 7" : The index has changed, but the ID has not' & @CRLF & _ 'also other lower ListView items (rows)' & @CRLF & _ '' & @CRLF & _ '' & @CRLF & _ '') ; remove almost all - keep "Item 9" as last added For $i = 7 To 1 Step -1 _GUICtrlListView_DeleteItem($idListview, $i) Next _GUICtrlListView_InsertItem($idListview, "Item 10", 0) _GUICtrlListView_RedrawItems($idListview, 0, _GUICtrlListView_GetItemCount($idListview) - 1) MsgBox($MB_TOPMOST, "TEST #" & @ScriptLineNumber, _ 'Afer adding "Item 10"' & @CRLF & _ 'Note "Item 10" : The index has changed, new ID is 9' & @CRLF & _ '') _GUICtrlListView_DeleteAllItems($idListview) For $i = 11 To 90 _GUICtrlListView_InsertItem($idListview, "Item " & $i, 0) Next _GUICtrlListView_DeleteAllItems($idListview) For $i = 91 To 100 _GUICtrlListView_InsertItem($idListview, "Item " & $i, 0) Next _GUICtrlListView_RedrawItems($idListview, 0, _GUICtrlListView_GetItemCount($idListview) - 1) MsgBox($MB_TOPMOST, "TEST #" & @ScriptLineNumber, _ 'Afer adding "Item 100"' & @CRLF & _ 'Note "Item 100" : new ID is 99' & @CRLF & _ '') _GUICtrlListView_DeleteAllItems($idListview) _GUICtrlListView_InsertItem($idListview, "Item 101", 0) _GUICtrlListView_RedrawItems($idListview, 0, _GUICtrlListView_GetItemCount($idListview) - 1) MsgBox($MB_TOPMOST, "TEST #" & @ScriptLineNumber, _ 'Afer adding "Item 101" to empty list' & @CRLF & _ 'Note "Item 101" : new ID is 100' & @CRLF & _ '') ; Loop until the user exits. Do Until GUIGetMsg() = $GUI_EVENT_CLOSE GUIDelete() EndFunc ;==>Example Func MY_WM_NOTIFY($hWnd, $msg, $wParam, $lParam) ; https://learn.microsoft.com/en-us/windows/win32/controls/wm-notify #forceref $hWnd, $msg, $wParam, $lParam Local $tItem = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam) ; $tagNMLVCUSTOMDRAW is defined in #include <StructureConstants.au3> ; https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmlvcustomdraw If $tItem.Code <> $NM_CUSTOMDRAW Then Return $GUI_RUNDEFMSG Local $dwDrawStage = $tItem.dwDrawStage If $dwDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW If $dwDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW Local $iItemIndex = $tItem.dwItemSpec Local $iItemID = _GUICtrlListView_MapIndexToID($tItem.hWndFrom, $iItemIndex) Local $hDC = $tItem.hdc ; Device context Local $tRect = DllStructCreate($tagRECT, DllStructGetPtr($tItem, "left")) If $tItem.iSubitem = $__Example_LVColumn_ItemIndex Then _WinAPI_SetTextColor($hDC, $CLR_RED) _WinAPI_DrawText($hDC, $iItemIndex, $tRect, $DT_CENTER) Return $CDRF_SKIPDEFAULT ElseIf $tItem.iSubitem = $__Example_LVColumn_ItemID Then _WinAPI_SetTextColor($hDC, $CLR_BLUE) _WinAPI_DrawText($hDC, $iItemID, $tRect, $DT_CENTER) Return $CDRF_SKIPDEFAULT EndIf Return $GUI_RUNDEFMSG EndFunc ;==>MY_WM_NOTIFY ItemIndex in column 1 ($__Example_LVColumn_ItemIndex) and ItemID in column 2 ($__Example_LVColumn_ItemID) are updated automaticaly by MY_WM_NOTIFY() Conclusion: ItemIndex - is index showing current Item position in ListView ItemID - is auto counted ID showing creation/adding order
  3. This issue should be fixed now. what was the solution ? EDIT: sorry I not follow code, only discussion
  4. https://www.autoitscript.com/trac/autoit/ticket/4091 all hope in @jpm
  5. Finally AI helpded with: #include <GUIConstantsEx.au3> #include <GuiListView.au3> #include <WindowsConstants.au3> _Example() Func _Example() Local $hGUI = GUICreate("Explorer-style ListView group enumeration", 600, 400) #forceref $hGUI Local $idList = GUICtrlCreateListView("Name", 10, 10, 580, 320) GUISetState(@SW_SHOW) Local $hList = GUICtrlGetHandle($idList) ; ===================================================== ; Enable groups ; ===================================================== Local Const $LVM_ENABLEGROUPVIEW = 0x109D _SendMessage($hList, $LVM_ENABLEGROUPVIEW, True, 0) ; ===================================================== ; Groups (GroupID = 100 / 200) ; ===================================================== _GUICtrlListView_InsertGroup($hList, 0, 100, "Group A") _GUICtrlListView_InsertGroup($hList, 1, 200, "Group B") ; ===================================================== ; Items ; ===================================================== _GUICtrlListView_AddItem($hList, "A0") _GUICtrlListView_AddItem($hList, "A1") _GUICtrlListView_AddItem($hList, "B0") _GUICtrlListView_AddItem($hList, "B1") ; ===================================================== ; Assign GroupIDs ; ===================================================== _GUICtrlListView_SetItemGroupID($hList, 0, 100) _GUICtrlListView_SetItemGroupID($hList, 1, 100) _GUICtrlListView_SetItemGroupID($hList, 2, 200) _GUICtrlListView_SetItemGroupID($hList, 3, 200) ; ===================================================== ; ENUM GROUP B (200) ; ===================================================== Local $aItems = _ListView_GetItemsByGroupID($hList, 200) ConsoleWrite("Group B items: " & UBound($aItems) & @CRLF) For $i = 0 To UBound($aItems) - 1 ConsoleWrite("ItemIndex: " & $aItems[$i] & @CRLF) Next While GUIGetMsg() <> $GUI_EVENT_CLOSE WEnd EndFunc ;==>_Example ; ========================================================= ; WINAPI-CORRECT GROUP ENUMERATION (Explorer style) ; ========================================================= Func _ListView_GetItemsByGroupID($hWnd, $iGroupID) Local $iCount = _GUICtrlListView_GetItemCount($hWnd) Local $tagLVITEM = _ "uint Mask;" & _ "int Item;" & _ "int SubItem;" & _ "uint State;" & _ "uint StateMask;" & _ "ptr Text;" & _ "int TextMax;" & _ "int Image;" & _ "lparam Param;" & _ "int Indent;" & _ "int GroupID" Local $tItem = DllStructCreate($tagLVITEM) Local Const $LVIF_GROUPID = 0x0100 Local Const $LVM_FIRST = 0x1000 Local Const $LVM_GETITEM = $LVM_FIRST + 75 Local $aResult[0] For $i = 0 To $iCount - 1 DllStructSetData($tItem, "Mask", $LVIF_GROUPID) DllStructSetData($tItem, "Item", $i) _SendMessage($hWnd, $LVM_GETITEM, 0, DllStructGetPtr($tItem)) If DllStructGetData($tItem, "GroupID") = $iGroupID Then ReDim $aResult[UBound($aResult) + 1] $aResult[UBound($aResult) - 1] = $i EndIf Next Return $aResult EndFunc ;==>_ListView_GetItemsByGroupID
  6. Finall example with _GUICtrlListView_ReSetItemGroupID() ;~ https://www.autoitscript.com/forum/topic/213681-listview-with-groups-inserting-new-rows-issue-with-_guictrllistview_insertitem/ #AutoIt3Wrapper_UseX64=n ; From Nine #include <WindowsConstants.au3> #include <ColorConstants.au3> #include <GUIConstants.au3> #include <GuiListView.au3> #include <WinAPI.au3> #include <WinAPIDiag.au3> #include <WinAPITheme.au3> Opt("MustDeclareVars", True) Global $hHeader Example() Func Example() GUICreate("Example", 480) Local $idListview = GUICtrlCreateListView("", 10, 10, 450, 300, -1, BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_DOUBLEBUFFER)) $hHeader = GUICtrlSendMsg($idListview, $LVM_GETHEADER, 0, 0) _WinAPI_SetWindowTheme($hHeader, "", "") ;Turn off theme for header Local $iStyle = _WinAPI_GetWindowLong($hHeader, $GWL_STYLE) _WinAPI_SetWindowLong($hHeader, $GWL_STYLE, BitOR($iStyle, $HDS_FLAT)) ; remove header 3D button effect Local $idButton = GUICtrlCreateButton("Enable/Disable GroupView", 10, 320, 200, 20) GUISetState(@SW_SHOW) GUIRegisterMsg($WM_NOTIFY, WM_NOTIFY) _GUICtrlListView_AddColumn($idListview, "Column 1", 100) _GUICtrlListView_AddColumn($idListview, "Column 2", 100) _GUICtrlListView_AddColumn($idListview, "Column 3", 142) _GUICtrlListView_AddItem($idListview, "Row 1: Col 1", 0) _GUICtrlListView_AddSubItem($idListview, 0, "Row 1: Col 2", 1, 1) _GUICtrlListView_AddSubItem($idListview, 0, "Row 1: Col 3 - speciall long info", 2, 2) _GUICtrlListView_AddItem($idListview, "Row 2: Col 1", 0) _GUICtrlListView_AddSubItem($idListview, 1, "Row 2: Col 2", 1, 2) _GUICtrlListView_AddItem($idListview, "Row 3: Col 1", 0) _GUICtrlListView_AddItem($idListview, "Row 4: Col 1", 0) _GUICtrlListView_InsertGroup($idListview, -1, 101, "Group 1") _GUICtrlListView_InsertGroup($idListview, -1, 202, "Group 2") _GUICtrlListView_InsertGroup($idListview, -1, 303, "Group 3") _GUICtrlListView_SetItemGroupID($idListview, 0, 101) _GUICtrlListView_SetItemGroupID($idListview, 1, 202) _GUICtrlListView_SetItemGroupID($idListview, 2, 202) _GUICtrlListView_SetItemGroupID($idListview, 3, 303) _GUICtrlListView_SetColumnWidth($idListview, 0, 80) _GUICtrlListView_SetColumnWidth($idListview, 1, 150) _GUICtrlListView_SetColumnWidth($idListview, 2, $LVSCW_AUTOSIZE_USEHEADER) MsgBox($MB_TOPMOST, "TEST #" & @ScriptLineNumber, "Before InsertItem") _GUICtrlListView_InsertItem($idListview, "NEW ITEM 1", 2) ; insert as 2 ID .... before "Row 3: Col 1" _GUICtrlListView_SetItemGroupID($idListview, 2, 202) MsgBox($MB_TOPMOST, "TEST #" & @ScriptLineNumber, "After InsertItem NEW ITEM 1 .. before EnableGroupView") _GUICtrlListView_InsertItem($idListview, "NEW ITEM 2", 3) ; insert as 2 ID .... before "Row 3: Col 1" _GUICtrlListView_SetItemGroupID($idListview, 3, 202) MsgBox($MB_TOPMOST, "TEST #" & @ScriptLineNumber, "After InsertItem NEW ITEM 2 .. before EnableGroupView" & @CRLF & @CRLF & "Take a note that NEW ITEM 1 and 2 are before ROW 3: Col 1") _GUICtrlListView_EnableGroupView($idListview, True) ;~ _GUICtrlListView_RedrawItems($idListview, 1, 4) MsgBox($MB_TOPMOST, "TEST #" & @ScriptLineNumber, "After EnableGroupView" & @CRLF & @CRLF & "Take a note that NEW ITEM 1 and 2 are after ROW 3: Col 1" & @CRLF & "but they were put before ROW 3: Col 1") MsgBox($MB_TOPMOST, "TEST #" & @ScriptLineNumber, "before RE-setting for each Item from Group 2") _GUICtrlListView_ReSetItemGroupID($idListview, 202) While True Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $idButton _GUICtrlListView_EnableGroupView($idListview, Not _GUICtrlListView_GetGroupViewEnabled($idListview)) ConsoleWrite('"Enable/Disable GroupView" button clicked' & @CRLF) EndSwitch WEnd EndFunc ;==>Example Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam Local $tItem = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam) If $tItem.Code <> $NM_CUSTOMDRAW Then Return $GUI_RUNDEFMSG Local Static $clrHighlight = _WinAPI_GetSysColor($COLOR_HIGHLIGHT) Local Static $clrBack = _WinAPI_SwitchColor($COLOR_LIGHTBLUE) Local Static $clrText = _WinAPI_SwitchColor($COLOR_BLUE) Local Static $hPenGroup_GuideLine = _WinAPI_CreatePen($PS_DASH, 1, $clrBack) Local Static $hPenItem_Borders = _WinAPI_CreatePen($PS_SOLID, 1, _WinAPI_SwitchColor($COLOR_RED)) Local Static $hPenHeader_Borders = _WinAPI_CreatePen($PS_SOLID, 1, _WinAPI_SwitchColor($COLOR_RED)) Local Static $hBrushGroup = _WinAPI_CreateSolidBrush($COLOR_BLACK) Local Static $hBrushItem_Selected = _WinAPI_CreateSolidBrush($clrHighlight) Local Static $hBrushItem_Unselected = _WinAPI_CreateSolidBrush(0xFFFFFF) Local Static $hBrushHeader = _WinAPI_CreateSolidBrush(0xFFCCDD) ;~ Local Static $tRect = DllStructCreate($tagRECT, DllStructGetPtr($tItem, "left")) Local $tRect = DllStructCreate($tagRECT, DllStructGetPtr($tItem, "left")) Local $hDC = $tItem.hDC If $tItem.hWndFrom = $hHeader Then If $tItem.dwDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW If Not $tItem.dwItemSpec Then $tRect.left += 5 $tRect.bottom -= 1 _WinAPI_SelectObject($tItem.hDC, $hPenHeader_Borders) _WinAPI_SelectObject($tItem.hDC, $hBrushHeader) _WinAPI_Rectangle($tItem.hDC, $tRect) $tRect.Left += 5 $tRect.Top += 3 _WinAPI_SetTextColor($tItem.hDC, 0) _WinAPI_SetBkMode($tItem.hDC, $TRANSPARENT) _WinAPI_DrawText($tItem.hDC, _GUICtrlHeader_GetItemText($tItem.hWndFrom, $tItem.dwItemSpec), $tRect, $DT_LEFT) Return $CDRF_SKIPDEFAULT ElseIf _WinAPI_GetClassName($tItem.hWndFrom) = "SysListView32" And $tItem.Code = $NM_CUSTOMDRAW And $tItem.dwItemSpec >= 0 Then If $tItem.dwItemType = $LVCDI_GROUP Then If $tItem.dwDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW If $tItem.dwDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW $tRect.bottom = $tRect.top + 15 _WinAPI_FillRect($hDC, $tRect, $hBrushGroup) _WinAPI_SelectObject($hDC, $hPenGroup_GuideLine) _WinAPI_DrawLine($hDC, $tRect.left + 5, $tRect.top + 8, $tRect.right - 5, $tRect.top + 8) _WinAPI_SetBkColor($hDC, $clrBack) _WinAPI_SetBkMode($hDC, $OPAQUE) _WinAPI_SetTextColor($hDC, $clrText) $tRect.left += 20 _WinAPI_DrawText($hDC, " " & _GUICtrlListView_GetGroupInfo($tItem.hWndFrom, $tItem.dwItemSpec)[0] & " ", $tRect, BitOR($DT_LEFT, $DT_WORDBREAK, $DT_WORD_ELLIPSIS)) Return $CDRF_SKIPDEFAULT Else If $tItem.dwDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW If $tItem.dwDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW Local $bIsSelected = _GUICtrlListView_GetItemState($tItem.hWndFrom, $tItem.dwItemSpec, $LVIS_SELECTED) If $bIsSelected Then _WinAPI_SelectObject($hDC, $hBrushItem_Selected) Else _WinAPI_SelectObject($hDC, $hBrushItem_Unselected) EndIf _WinAPI_SelectObject($hDC, $hPenItem_Borders) If $tItem.dwItemSpec > 0 Then $tRect.top -= 1 $tRect.bottom += 1 _WinAPI_Rectangle($hDC, $tRect) _WinAPI_SetTextColor($hDC, $bIsSelected ? 0xFFFFFF : $clrHighlight) _WinAPI_SetBkMode($hDC, $TRANSPARENT) $tRect.Left += 5 $tRect.Top += 2 _WinAPI_DrawText($hDC, _GUICtrlListView_GetItemText($tItem.hWndFrom, $tItem.dwItemSpec, $tItem.iSubitem), $tRect, BitOR($DT_LEFT, $DT_INTERNAL, $DT_WORDBREAK)) Return $CDRF_SKIPDEFAULT EndIf EndIf Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY Func _GUICtrlListView_ReSetItemGroupID($idListview, $iGroupID) For $IDX = 0 To _GUICtrlListView_GetItemCount($idListview) -1 If _GUICtrlListView_GetItemGroupID($idListview, $IDX) = $iGroupID Then _GUICtrlListView_SetItemGroupID($idListview, $IDX, -2) _GUICtrlListView_SetItemGroupID($idListview, $IDX, $iGroupID) EndIf Next EndFunc
  7. I talked to the AI for a while and it turned out that: LVITEMINDEX is used by several messages, but not all of them write the iGroup back to the structure. LVM_GETITEMINDEXRECT uses the iGroup as input, not output. so far I have these 3 functions: Func _GUICtrlListView_GetGroupIndexByGroupID($hWnd, $iGroupID) Local $iMaxIndex = _GUICtrlListView_GetGroupCount($hWnd) - 1 Local $aInfo For $i = 0 To $iMaxIndex $aInfo = _GUICtrlListView_GetGroupInfoByIndex($hWnd, $i) If $aInfo[2] = $iGroupID Then Return $i Next Return SetError(1, 0, -1) EndFunc ;==>_GUICtrlListView_GetGroupIndexByGroupID Func _GUICtrlListView_GetGroupIndexByItemIndex($hWnd, $iItem) Local $iGroupID = _GUICtrlListView_GetItemGroupID($hWnd, $iItem) Return _GUICtrlListView_GetGroupIndexByGroupID($hWnd, $iGroupID) EndFunc ;==>_GUICtrlListView_GetGroupIndexByItemIndex Func _GUICtrlListView_GetItemIndexesByGroupID($hWnd, $iGroupID) Local $aResult[0] Local $iCount = _GUICtrlListView_GetItemCount($hWnd) For $iItemIndex = 0 To $iCount - 1 If _GUICtrlListView_GetItemGroupID($hWnd, $iItemIndex) = $iGroupID Then ReDim $aResult[UBound($aResult) + 1] $aResult[UBound($aResult) - 1] = $iItemIndex EndIf Next Return $aResult EndFunc ;==>_GUICtrlListView_GetItemIndexesByGroupID
  8. Maybe someone could show how to use LVITEMINDEX structure ? https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-lvitemindex I have searched UDF and the forum and have not seen it used anywhere.
  9. I did here some work with TIDY, Au3Check, but get into issue. Maybe this will be handy for someone to further work. Wordpad_2026-05-10_mLipok.zip
  10. I think it would be usefull to add new wiki page about handling Thems and as example of course Dark Theme I mean to cumulate the knowledge how, why, when to use Themes. And how to do it well.
  11. Thanks. But this means next one to add to my Browser.au3 UDF Oh boy.
  12. @WildByDesign Try change theme for the secret hidden window created automaticaly by AutoIt.
  13. Conclusion: After adding new items to a Grouped ListView, To maintain the correct order of items within a group, it is often necessary to regroup the items within the group by removing the item's group assignment and then reassigning it to the group. EDIT: Please let me know if I am wrong about any technical details or linguistic aspects of the conclusion. I used Google Translate because I am not a native English speaker.
  14. New example: ;~ https://www.autoitscript.com/forum/topic/213681-listview-with-groups-inserting-new-rows-issue-with-_guictrllistview_insertitem/ #AutoIt3Wrapper_UseX64=n ; From Nine #include <WindowsConstants.au3> #include <ColorConstants.au3> #include <GUIConstants.au3> #include <GuiListView.au3> #include <WinAPI.au3> #include <WinAPIDiag.au3> #include <WinAPITheme.au3> Opt("MustDeclareVars", True) Global $hHeader Example() Func Example() GUICreate("Example", 480) Local $idListview = GUICtrlCreateListView("", 10, 10, 450, 300, -1, BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_DOUBLEBUFFER)) $hHeader = GUICtrlSendMsg($idListview, $LVM_GETHEADER, 0, 0) _WinAPI_SetWindowTheme($hHeader, "", "") ;Turn off theme for header Local $iStyle = _WinAPI_GetWindowLong($hHeader, $GWL_STYLE) _WinAPI_SetWindowLong($hHeader, $GWL_STYLE, BitOR($iStyle, $HDS_FLAT)) ; remove header 3D button effect Local $idButton = GUICtrlCreateButton("Enable/Disable GroupView", 10, 320, 200, 20) GUISetState(@SW_SHOW) GUIRegisterMsg($WM_NOTIFY, WM_NOTIFY) _GUICtrlListView_AddColumn($idListview, "Column 1", 100) _GUICtrlListView_AddColumn($idListview, "Column 2", 100) _GUICtrlListView_AddColumn($idListview, "Column 3", 142) _GUICtrlListView_AddItem($idListview, "Row 1: Col 1", 0) _GUICtrlListView_AddSubItem($idListview, 0, "Row 1: Col 2", 1, 1) _GUICtrlListView_AddSubItem($idListview, 0, "Row 1: Col 3 - speciall long info", 2, 2) _GUICtrlListView_AddItem($idListview, "Row 2: Col 1", 0) _GUICtrlListView_AddSubItem($idListview, 1, "Row 2: Col 2", 1, 2) _GUICtrlListView_AddItem($idListview, "Row 3: Col 1", 0) _GUICtrlListView_AddItem($idListview, "Row 4: Col 1", 0) _GUICtrlListView_InsertGroup($idListview, -1, 101, "Group 1") _GUICtrlListView_InsertGroup($idListview, -1, 202, "Group 2") _GUICtrlListView_InsertGroup($idListview, -1, 303, "Group 3") _GUICtrlListView_SetItemGroupID($idListview, 0, 101) _GUICtrlListView_SetItemGroupID($idListview, 1, 202) _GUICtrlListView_SetItemGroupID($idListview, 2, 202) _GUICtrlListView_SetItemGroupID($idListview, 3, 303) _GUICtrlListView_SetColumnWidth($idListview, 0, 80) _GUICtrlListView_SetColumnWidth($idListview, 1, 150) _GUICtrlListView_SetColumnWidth($idListview, 2, $LVSCW_AUTOSIZE_USEHEADER) MsgBox($MB_TOPMOST, "TEST #" & @ScriptLineNumber, "Before InsertItem") _GUICtrlListView_InsertItem($idListview, "NEW ITEM 1", 2) ; insert as 2 ID .... before "Row 3: Col 1" _GUICtrlListView_SetItemGroupID($idListview, 2, 202) MsgBox($MB_TOPMOST, "TEST #" & @ScriptLineNumber, "After InsertItem NEW ITEM 1 .. before EnableGroupView") _GUICtrlListView_InsertItem($idListview, "NEW ITEM 2", 3) ; insert as 2 ID .... before "Row 3: Col 1" _GUICtrlListView_SetItemGroupID($idListview, 3, 202) MsgBox($MB_TOPMOST, "TEST #" & @ScriptLineNumber, "After InsertItem NEW ITEM 2 .. before EnableGroupView" & @CRLF & @CRLF & "Take a note that NEW ITEM 1 and 2 are before ROW 3: Col 1") _GUICtrlListView_EnableGroupView($idListview, True) ;~ _GUICtrlListView_RedrawItems($idListview, 1, 4) MsgBox($MB_TOPMOST, "TEST #" & @ScriptLineNumber, "After EnableGroupView" & @CRLF & @CRLF & "Take a note that NEW ITEM 1 and 2 are after ROW 3: Col 1" & @CRLF & "but they were put before ROW 3: Col 1") MsgBox($MB_TOPMOST, "TEST #" & @ScriptLineNumber, "before RE-setting for each Item from Group 2") For $IDX = 0 To _GUICtrlListView_GetItemCount($idListview) -1 If _GUICtrlListView_GetItemGroupID($idListview, $IDX) = 202 Then _GUICtrlListView_SetItemGroupID($idListview, $IDX, -2) _GUICtrlListView_SetItemGroupID($idListview, $IDX, 202) EndIf Next While True Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $idButton _GUICtrlListView_EnableGroupView($idListview, Not _GUICtrlListView_GetGroupViewEnabled($idListview)) ConsoleWrite('"Enable/Disable GroupView" button clicked' & @CRLF) EndSwitch WEnd EndFunc ;==>Example Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam Local $tItem = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam) If $tItem.Code <> $NM_CUSTOMDRAW Then Return $GUI_RUNDEFMSG Local Static $clrHighlight = _WinAPI_GetSysColor($COLOR_HIGHLIGHT) Local Static $clrBack = _WinAPI_SwitchColor($COLOR_LIGHTBLUE) Local Static $clrText = _WinAPI_SwitchColor($COLOR_BLUE) Local Static $hPenGroup_GuideLine = _WinAPI_CreatePen($PS_DASH, 1, $clrBack) Local Static $hPenItem_Borders = _WinAPI_CreatePen($PS_SOLID, 1, _WinAPI_SwitchColor($COLOR_RED)) Local Static $hPenHeader_Borders = _WinAPI_CreatePen($PS_SOLID, 1, _WinAPI_SwitchColor($COLOR_RED)) Local Static $hBrushGroup = _WinAPI_CreateSolidBrush($COLOR_BLACK) Local Static $hBrushItem_Selected = _WinAPI_CreateSolidBrush($clrHighlight) Local Static $hBrushItem_Unselected = _WinAPI_CreateSolidBrush(0xFFFFFF) Local Static $hBrushHeader = _WinAPI_CreateSolidBrush(0xFFCCDD) ;~ Local Static $tRect = DllStructCreate($tagRECT, DllStructGetPtr($tItem, "left")) Local $tRect = DllStructCreate($tagRECT, DllStructGetPtr($tItem, "left")) Local $hDC = $tItem.hDC If $tItem.hWndFrom = $hHeader Then If $tItem.dwDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW If Not $tItem.dwItemSpec Then $tRect.left += 5 $tRect.bottom -= 1 _WinAPI_SelectObject($tItem.hDC, $hPenHeader_Borders) _WinAPI_SelectObject($tItem.hDC, $hBrushHeader) _WinAPI_Rectangle($tItem.hDC, $tRect) $tRect.Left += 5 $tRect.Top += 3 _WinAPI_SetTextColor($tItem.hDC, 0) _WinAPI_SetBkMode($tItem.hDC, $TRANSPARENT) _WinAPI_DrawText($tItem.hDC, _GUICtrlHeader_GetItemText($tItem.hWndFrom, $tItem.dwItemSpec), $tRect, $DT_LEFT) Return $CDRF_SKIPDEFAULT ElseIf _WinAPI_GetClassName($tItem.hWndFrom) = "SysListView32" And $tItem.Code = $NM_CUSTOMDRAW And $tItem.dwItemSpec >= 0 Then If $tItem.dwItemType = $LVCDI_GROUP Then If $tItem.dwDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW If $tItem.dwDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW $tRect.bottom = $tRect.top + 15 _WinAPI_FillRect($hDC, $tRect, $hBrushGroup) _WinAPI_SelectObject($hDC, $hPenGroup_GuideLine) _WinAPI_DrawLine($hDC, $tRect.left + 5, $tRect.top + 8, $tRect.right - 5, $tRect.top + 8) _WinAPI_SetBkColor($hDC, $clrBack) _WinAPI_SetBkMode($hDC, $OPAQUE) _WinAPI_SetTextColor($hDC, $clrText) $tRect.left += 20 _WinAPI_DrawText($hDC, " " & _GUICtrlListView_GetGroupInfo($tItem.hWndFrom, $tItem.dwItemSpec)[0] & " ", $tRect, BitOR($DT_LEFT, $DT_WORDBREAK, $DT_WORD_ELLIPSIS)) Return $CDRF_SKIPDEFAULT Else If $tItem.dwDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW If $tItem.dwDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW Local $bIsSelected = _GUICtrlListView_GetItemState($tItem.hWndFrom, $tItem.dwItemSpec, $LVIS_SELECTED) If $bIsSelected Then _WinAPI_SelectObject($hDC, $hBrushItem_Selected) Else _WinAPI_SelectObject($hDC, $hBrushItem_Unselected) EndIf _WinAPI_SelectObject($hDC, $hPenItem_Borders) If $tItem.dwItemSpec > 0 Then $tRect.top -= 1 $tRect.bottom += 1 _WinAPI_Rectangle($hDC, $tRect) _WinAPI_SetTextColor($hDC, $bIsSelected ? 0xFFFFFF : $clrHighlight) _WinAPI_SetBkMode($hDC, $TRANSPARENT) $tRect.Left += 5 $tRect.Top += 2 _WinAPI_DrawText($hDC, _GUICtrlListView_GetItemText($tItem.hWndFrom, $tItem.dwItemSpec, $tItem.iSubitem), $tRect, BitOR($DT_LEFT, $DT_INTERNAL, $DT_WORDBREAK)) Return $CDRF_SKIPDEFAULT EndIf EndIf Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY
  15. Hm... here is my partial solution to explain this problem #Region ; *** Dynamically added Include files *** #include <ColorConstants.au3> ; added:05/09/26 05:11:48 #EndRegion ; *** Dynamically added Include files *** #include <GUIConstantsEx.au3> #include <GuiListView.au3> #include <MsgBoxConstants.au3> Example() Func Example() Local $iID, $idListview GUICreate("ListView Map ID To Index", 500, 300) $idListview = GUICtrlCreateListView("", 2, 2, 494, 268, -1, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT)) GUISetState(@SW_SHOW) GUIRegisterMsg($WM_NOTIFY, MY_WM_NOTIFY) ; Add column _GUICtrlListView_AddColumn($idListview, "Items name/text", 100) _GUICtrlListView_AddColumn($idListview, "ItemIndex (current row index)", 100) _GUICtrlListView_AddColumn($idListview, "ItemID (creation order index)", 100) _GUICtrlListView_SetColumnWidth($idListview, 0, $LVSCW_AUTOSIZE_USEHEADER) _GUICtrlListView_SetColumnWidth($idListview, 1, $LVSCW_AUTOSIZE_USEHEADER) _GUICtrlListView_SetColumnWidth($idListview, 2, $LVSCW_AUTOSIZE_USEHEADER) ; Add items _GUICtrlListView_InsertItem($idListview, "Item 1", 0) _GUICtrlListView_InsertItem($idListview, "Item 2", 0) _GUICtrlListView_InsertItem($idListview, "Item 3", 0) _GUICtrlListView_InsertItem($idListview, "Item 4", 0) _GUICtrlListView_InsertItem($idListview, "Item 5", 0) _GUICtrlListView_InsertItem($idListview, "Item 6", 0) _GUICtrlListView_InsertItem($idListview, "Item 7", 0) _GUICtrlListView_InsertItem($idListview, "Item 8", 0) _GUICtrlListView_InsertItem($idListview, "Item 9", 0) ; show all Item's ID For $IDX = 0 To _GUICtrlListView_GetItemCount($idListview) - 1 $iID = _GUICtrlListView_MapIndexToID($idListview, $IDX) _GUICtrlListView_AddSubItem($idListview, $IDX, $iID, 2) Next ; Show ID for item 2 $iID = _GUICtrlListView_MapIndexToID($idListview, 2) MsgBox($MB_SYSTEMMODAL, "Information", "Index to ID: " & $iID) MsgBox($MB_SYSTEMMODAL, "Information", "ID to Index: " & _GUICtrlListView_MapIDToIndex($idListview, $iID)) MsgBox($MB_TOPMOST, "TEST #" & @ScriptLineNumber, 'before deleting "Item 8"' & @CRLF & 'Note "Item 7" Index and ID' & @CRLF & 'also other lower ListView items (rows)') _GUICtrlListView_DeleteItem($idListview , 1) MsgBox($MB_TOPMOST, "TEST #" & @ScriptLineNumber, 'afer deleting "Item 8"' & @CRLF & 'Note "Item 7" : The index has changed, but the ID has not' & @CRLF & 'also other lower ListView items (rows)') ; Loop until the user exits. Do Until GUIGetMsg() = $GUI_EVENT_CLOSE GUIDelete() EndFunc ;==>Example Func MY_WM_NOTIFY($hWnd, $msg, $wParam, $lParam) ; https://learn.microsoft.com/en-us/windows/win32/controls/wm-notify #forceref $hWnd, $msg, $wParam, $lParam Local Static $clrRed = _WinAPI_SwitchColor($COLOR_RED) Local $tItem = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam) ; $tagNMLVCUSTOMDRAW is defined in #include <StructureConstants.au3> ; https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmlvcustomdraw If $tItem.Code <> $NM_CUSTOMDRAW Then Return $GUI_RUNDEFMSG Local $dwDrawStage = $tItem.dwDrawStage If $dwDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW If $dwDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW If $tItem.iSubitem <> 1 Then Return $GUI_RUNDEFMSG Local $dwItemSpec = $tItem.dwItemSpec Local $hDC = $tItem.hdc ; Device context Local $s_Text = $dwItemSpec Local $tRect = DllStructCreate($tagRECT, DllStructGetPtr($tItem, "left")) _WinAPI_SetTextColor($hDC, $clrRed) _WinAPI_DrawText($hDC, $s_Text, $tRect, $DT_LEFT) Return $CDRF_SKIPDEFAULT EndFunc ;==>MY_WM_NOTIFY My issue with this scirpt is that my intention was to automatically update values in "ItemIndex (current row index)" column after _GUICtrlListView_DeleteItem($idListview , 1) but I'm still not feeling too confident with this whole WM_NOTIFY stuff, and I did something else wrong there. Any help with WM_NOTIFY here would be welcome.
×
×
  • Create New...