#include-once #include #include #include #include #include #include #include #include #include Global Const $SW_HIDE = 0 Global Const $SW_SHOW = 5 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 Global $aProgress[1][4], $hListView GUIRegisterMsg($WM_NOTIFY, "_ListView_Notify") GUIRegisterMsg($WM_SIZE, "_ListView_Notify") ; #FUNCTION# ====================================================================================== ; Function Name: _ListView_InsertProgressBar() ; Description: Inserts a progressbar control in the ListView control. ; Syntax.........: _ListView_InsertProgressBar($sHwnd, $sItemIndex[, $sSubItemIndex]) ; Parameter(s): $sHwnd - Handle to the ListView control. ; $sItemIndex - Zero based index of the item at which the progressbar should be inserted. ; $sSubItemIndex - [Optional] One based index of the subitem where progressbar should be placed, default is 1. ; ; Return Value(s): Returns the identifier (controlID) of the new progressbar control. ; Requirement(s): AutoIt 3.2.10.0 and above ; Note(s): Optimal amount of progressbar controls is 5-10. Don`t abuse with many amount of progressbar controls. ; ; Author(s): R.Gilman (a.k.a rasim), arcker ;================================================================================================== Func _ListView_InsertProgressBar($sHwnd, $sItemIndex, $sSubItemIndex = 0) If Not IsHWnd($sHwnd) Then $sHwnd = GUICtrlGetHandle($sHwnd) Local $iStyle = _WinAPI_GetWindowLong($sHwnd, $GWL_STYLE) If BitAND($iStyle, $WS_CLIPCHILDREN) <> $WS_CLIPCHILDREN Then _WinAPI_SetWindowLong($sHwnd, $GWL_STYLE, BitOR($iStyle, $WS_CLIPCHILDREN)) EndIf Local $aRect If $sSubItemIndex = 0 Then $aRect = _GUICtrlListView_GetItemRect($sHwnd, $sItemIndex, 2) Else $aRect = _GUICtrlListView_GetSubItemRect($sHwnd, $sItemIndex, $sSubItemIndex) EndIf $aProgress[0][0] += 1 ReDim $aProgress[$aProgress[0][0] + 1][4] $aProgress[$aProgress[0][0]][0] = _Progress_Create($sHwnd, $aRect[0], $aRect[1], $aRect[2] - $aRect[0], $aRect[3] - $aRect[1]) $aProgress[$aProgress[0][0]][1] = $sItemIndex $aProgress[$aProgress[0][0]][2] = $sSubItemIndex $aProgress[$aProgress[0][0]][3] = $sHwnd Return $aProgress[$aProgress[0][0]][0] EndFunc ;==>_ListView_InsertProgressBar Func _Progress_Create($hWnd, $iX, $iY, $iWidth = -1, $iHeight = -1, $iStyle = 0, $iExStyle = 0x00000200) $iStyle = BitOR($iStyle, $WS_CHILD, $WS_VISIBLE, $WS_TABSTOP, $WS_CHILD, $WS_VISIBLE, $ES_LEFT, $ES_AUTOHSCROLL, $ES_NOHIDESEL) Return _WinAPI_CreateWindowEx($iExStyle, "Edit", "", $iStyle, $iX, $iY, $iWidth, $iHeight, $hWnd) EndFunc ;==>_Progress_Create Func _ListView_Notify($hWnd, $Msg, $wParam, $lParam) If $Msg = $WM_SIZE Then _WinAPI_InvalidateRect($hWnd) Return $GUI_RUNDEFMSG EndIf Local $tNMHEADER, $hWndFrom, $iCode, $i $tNMHEADER = DllStructCreate($tagNMHEADER, $lParam) $hWndFrom = DllStructGetData($tNMHEADER, "hwndFrom") $iCode = DllStructGetData($tNMHEADER, "Code") Switch $iCode Case $HDN_ITEMCHANGED, $HDN_ITEMCHANGEDW, $LVN_ENDSCROLL If $iCode <> $LVN_ENDSCROLL Then $hWndFrom = _WinAPI_GetParent($hWndFrom) For $i = 1 To $aProgress[0][0] _MoveProgress($hWndFrom, $aProgress[$i][0], $aProgress[$i][1], $aProgress[$i][2]) ;~ Local $aSubItmRect = _GUICtrlListView_GetSubItemRect($hWndFrom, $aProgress[$i][1], $aProgress[$i][2]) ;~ ; the function above accepts not only subitems (one-based index), but also main item (index=0) ;~ ; 3. pass the coordinates to a DLL struct ;~ Local $iSubItmRect = DllStructCreate("long[4]") ;~ DllStructSetData($iSubItmRect, 1, $aSubItmRect[0] + 6, 1) ; +6 is left margin (X) ;~ DllStructSetData($iSubItmRect, 1, $aSubItmRect[1] + (-2), 2) ; + (-2) is upper margin (Y) ;~ DllStructSetData($iSubItmRect, 1, $aSubItmRect[2], 3) ;~ DllStructSetData($iSubItmRect, 1, $aSubItmRect[3], 4) ;~ _WinAPI_invalidateRect($hWndFrom, $iSubItmRect) Next _WinAPI_InvalidateRect($hWndFrom) EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>_ListView_Notify Func WM_MEASUREITEM($hWnd, $Msg, $wParam, $lParam) Local $tMEASUREITEMS = DllStructCreate("uint cType;uint cID;uint itmID;uint itmW;uint itmH;ulong_ptr itmData", $lParam) If DllStructGetData($tMEASUREITEMS, "cType") <> $ODT_LISTVIEW Then Return $GUI_RUNDEFMSG DllStructSetData($tMEASUREITEMS, "itmH", 25);row height Return 1 EndFunc ;==>WM_MEASUREITEM 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;" & _ "handle hDC;" & _ "long itmRect[4];" & _ "ulong_ptr 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 $cID ; will look for ControlID, not window handle. Case $hListView Switch $itmAction Case $ODA_DRAWENTIRE ; don't forget, this is BGR, not RGB If $itmState = $bSelected Then ; item is not selected $iBrushColor = 0xCCEECC Else ; item is selected $iBrushColor = 0xEEDDBB 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 + 1, 1) ; rectangle coordinates for coloring ; +1 is the left margin _WinAPI_FillRect($hDC, DllStructGetPtr($tagDRAWITEMSTRUCT, "itmRect"), $aBrush[0]) _WinAPI_SelectObject($hDC, $aBrushOld) _WinAPI_DeleteObject($aBrush[0]) ; for all columns of the row: $local_alignment = $DT_LEFT For $i = 0 To _GUICtrlListView_GetColumnCount($hItm) - 1 ; 1. get subitem text: Local $iSubItmText = _GUICtrlListView_GetItemText($hItm, $itmID, $i) ; 2. get subitem coordinates for drawing its respective text Local $aSubItmRect = _GUICtrlListView_GetSubItemRect($hItm, $itmID, $i) ; the function above accepts not only subitems (one-based index), but also main item (index=0) ; 3. pass the coordinates to a DLL struct Local $iSubItmRect = DllStructCreate("long[4]") DllStructSetData($iSubItmRect, 1, $aSubItmRect[0] + 6, 1) ; +6 is left margin (X) DllStructSetData($iSubItmRect, 1, $aSubItmRect[1] + (-2), 2) ; + (-2) is upper margin (Y) DllStructSetData($iSubItmRect, 1, $aSubItmRect[2], 3) DllStructSetData($iSubItmRect, 1, $aSubItmRect[3], 4) DllCall("user32.dll", "int", "DrawTextW", "hwnd", $hDC, "wstr", $iSubItmText, "int", StringLen($iSubItmText), _ "ptr", DllStructGetPtr($iSubItmRect), "int", $local_alignment) Next ;~ _WinAPI_InValidateRect($hListView) EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_DRAWITEM Func _MoveProgress($hListView, $hProgress, $sItemIndex, $sSubItemIndex) Local $aRect If $sSubItemIndex = 0 Then $aRect = _GUICtrlListView_GetItemRect($hListView, $sItemIndex, 2) Else $aRect = _GUICtrlListView_GetSubItemRect($hListView, $sItemIndex, $sSubItemIndex) EndIf If $aRect[1] < 10 Then _WinAPI_ShowWindow($hProgress, $SW_HIDE) ElseIf $aRect[1] >= 10 Then _WinAPI_ShowWindow($hProgress, $SW_SHOW) EndIf _WinAPI_MoveWindow($hProgress, $aRect[0], $aRect[1], $aRect[2] - $aRect[0], $aRect[3] - $aRect[1], True) EndFunc ;==>_MoveProgress