Jump to content

Recommended Posts

Posted

Hi,

i have covered the old ListView_Progress UDF but instead of moving the controls on WM_NOTIFY, i want to move them on WM_PAINT, cause i think i can get better performance with it, but on rezising the columns the GUI gets freezed.

Doese someone know how to avoid to get stucked?

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <FontConstants.au3>
#include <GuiListView.au3>
#include <Constants.au3>
#include <WinAPIGdi.au3>
#include <ListView_Progress.au3>
#include <WinAPISys.au3>
#include <WinAPIShellEx.au3>

Opt('MustDeclareVars', 1)

Global $hGUI, $cListView, $hListView
Global $iDllUSER32 = DllOpen("user32.dll")

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("Set Listview Header Colour ", 500, 500)
$cListView = GUICtrlCreateListView("Items List", 10, 10, 480, 480, BitOR($LVS_REPORT, $LVS_SHOWSELALWAYS, $WS_BORDER));, $LVS_OWNERDRAWFIXED))
$hListView = GUICtrlGetHandle($cListView)
_GUICtrlListView_SetExtendedListViewStyle($hListView, BitOR($LVS_EX_DOUBLEBUFFER, $LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT))

; Register DLL callback that will be used as window subclass procedure
Global $g_hDll = DllCallbackRegister('_SubclassProc', 'lresult', 'hwnd;uint;wparam;lparam;uint_ptr;dword_ptr')
Global $g_pDll = DllCallbackGetPtr($g_hDll)

; Install window subclass callback
_WinAPI_SetWindowSubclass($hListView, $g_pDll, 1000, 0)


_SendMessage($hListView, $LVM_SETTEXTBKCOLOR, 0, 0xFFFFFF) ; trick to get better performance

_GUICtrlListView_BeginUpdate($hListView)
For $i = 1 To 15
    GUICtrlCreateListViewItem("", $cListView)
    _ListView_InsertProgressBar($hListView, $i-1, 0) ; insert control
Next
_GUICtrlListView_EndUpdate($hListView)


GUIRegisterMsg($WM_DRAWITEM, "WM_DRAWITEM")
GUISetState()

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

GUIDelete()
Exit


Func _SubclassProc($hWnd, $iMsg, $wParam, $lParam, $iID, $pData)
    #forceref $iID, $pData

    ConsoleWrite("Proc $hWnd: " & $hWnd  & " imsg: " & $iMsg & " $wParam: " & $wParam & " $lParam: " & $lParam & @CRLF)

    Switch $iMsg
        Case $WM_NCPAINT
        Case $WM_SIZE
        Case $WM_ERASEBKGND
        Case $WM_PAINT
            Local $struct
            _WinAPI_BeginPaint($hWnd, $struct)

            For $i = 1 To $aProgress[0][0]
                If $aProgress[$i][3] = $hWnd Then _
                _MoveProgress($hWnd, $aProgress[$i][0], $aProgress[$i][1], $aProgress[$i][2]) ; move controls
            Next
            _WinAPI_EndPaint($hWnd, $struct)
    EndSwitch


    Return _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam)
EndFunc   ;==>_SubclassProc


; not used yet
Func WM_DRAWITEM($hWnd, $Msg, $wParam, $lParam)
;~  ConsoleWrite("Draw   $hWnd: " & $hWnd  & " imsg: " & $Msg & " $wParam: " & $wParam & " $lParam: " & $lParam & @CRLF)
    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 $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:
                ConsoleWrite("hITm: " & $hItm & @CRLF)
                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", $DT_LEFT)
                Next
        EndSwitch

    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_DRAWITEM

ListView_Progress.au3

Posted

wow thanks for this information, i never thought about a bug. But what is the solution? Do i take

Func CallWindowProc($lpPrevWndFunc, $hWnd, $Msg, $wParam, $lParam)
  Return DllCall("user32.dll", "lresult", "CallWindowProc", "ptr", $lpPrevWndFunc, "hwnd", $hWnd, "uint", $Msg, "wparam", $wParam, "lparam", $lParam)[0]
EndFunc 

instead of _WinAPI_CallWindowProc?

And since when is it possible to access an array in this way?

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...