WM_PAINT friert ListView ein

  • Hi,
    ich habe die Window Prozedur von meinem ListView Control abgeleitet um das WM_PAINT event abzufangen um dort dann eine Positionsberechnung+Verschieben von Controls durchzuführen. Allerdings friert die GUI bereits bei einem einfachen Aufruf von _GUICtrlListView_GetItemRectEx($hWnd, $i, $LVIR_BOUNDS) ein. Der Code Auszug enthält nur das nötigste und trotzdem friert mir die GUI ein, hat jemand eine Idee woran das liegt? Durch Minimieren taut es übrigens wieder auf.

    Die Idee habe ich von hier:
    Embedding Controls in a ListView


    [autoit]

    #include <GuiListView.au3>
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>

    [/autoit][autoit][/autoit][autoit]

    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

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    Global $GUI_main = GUICreate("", 600, 800, -1, -1, -1, $WS_EX_ACCEPTFILES)
    Global $hGUI_tab_listview[2][10]
    $hGUI_tab_listview[0][0] = GUICtrlCreateListView("", 10, 10, 580, 780, _
    BitOR($LVS_REPORT, $LVS_SHOWSELALWAYS), _
    BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_GRIDLINES)) ; + $LVS_EX_CHECKBOXES + $LVS_SINGLESEL
    _GUICtrlListView_AddColumn(-1, "Name")
    _GUICtrlListView_AddColumn(-1, "Count")
    _GUICtrlListView_AddColumn(-1, "Test")
    _GUICtrlListView_AddColumn(-1, "Gih")

    [/autoit][autoit][/autoit][autoit]

    For $i = 0 To 10 ; populate the listview for testing purposes
    _GUICtrlListView_AddItem(-1, "test " & $i)
    _GUICtrlListView_AddSubItem(-1, $i, $i, 1)
    _GUICtrlListView_AddSubItem(-1, $i, $i, 2)
    _GUICtrlListView_AddSubItem(-1, $i, $i, 3)
    Next

    [/autoit][autoit][/autoit][autoit]

    Global $lv = GUICtrlGetHandle($hGUI_tab_listview[0][0])
    Global $g_hDll = DllCallbackRegister('Proc', 'ptr', 'hwnd;uint;wparam;lparam')
    Global $g_hProc1 = _WinAPI_SetWindowLong($lv, $GWL_WNDPROC, DllCallbackGetPtr($g_hDll))

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    GUISetState(@SW_SHOW)
    While 1
    Sleep(100)
    WEnd

    [/autoit][autoit][/autoit][autoit]

    Exit
    _WinAPI_SetWindowLong($lv, $GWL_WNDPROC, $g_hProc1)
    DllCallbackFree($g_hDll)

    [/autoit][autoit][/autoit][autoit][/autoit][autoit][/autoit][autoit]

    Func Proc($hWnd, $iMsg, $wParam, $lParam)
    Switch $iMsg
    Case $WM_PAINT
    ;~ ConsoleWrite("$WM_PAINT" & @CRLF)
    _WinAPI_CallWindowProc($g_hProc1, $hWnd, $iMsg, $wParam, $lParam)
    ;~ _WinAPI_DefWindowProc($hWnd, $iMsg, $wParam, $lParam)

    [/autoit][autoit][/autoit][autoit]

    For $i = 0 To _GUICtrlListView_GetItemCount($hWnd)-1
    Local $struct = _GUICtrlListView_GetItemRectEx($hWnd, $i, $LVIR_BOUNDS)
    ConsoleWrite("$i: " & $i & @CRLF)
    ;~ __MoveControl($oExtCtrls, $hWnd, $i) ; move extended controls
    Next
    ;~ EndIf
    EndSwitch
    Return _WinAPI_CallWindowProc($g_hProc1, $hWnd, $iMsg, $wParam, $lParam)
    EndFunc ;==>_WinProc

    [/autoit]
  • Bei mir friert nichts ein. Vielleicht liegt's daran, dass es bei mir relativ warm ist. Kann aber auch an meiner Aura liegen. :D


    Spaß bei Seite. Welches BS benutzt du?


    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Ich benutze Windows 7 SP1 x86. Sorry ich vergaß zu erwähen, dass die GUI einfriert, sobald ich das ListView fordere, also scrolle oder die Spaltenbreite verändere. Der Plan ist es ja später, dass sich die Controls automatisch verschieben, sobald man scrollt oder die Splatenbreite verändert.

    Schau dir mal den Original Code in C# an, ich habe das event genauso abgefangen wie er, aber egal was ich anstelle, die GUI friert ein. Die Datei befindet sich im Anhang, schau dir den Teil an wo der Autor die Prozedur overrided.

  • Ich verstehe zwar kaum C/C++/C#, aber ich schaue es mir morgen an.

    Willst du die Zeile verschieben oder was genau?

    Ansonsten kannst du die hier mal näher anschauen: http://www.autoitscript.com/forum/topic/70…stview-progress http://www.autoitscript.com/forum/topic/12…rsion-9-oct-14/

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

    Einmal editiert, zuletzt von UEZ (9. Oktober 2014 um 19:42)

  • Der Thread war mir bekannt, das Beispiel habe ich damals als Basis benutzt. Hab mir das Beispiel aber gerade nochmal gründlich angeguckt und sehe, dass ich damals einige wichtige Codeabschnitte ausgelassen habe.

    Er benutzt als Trigger das WM_NOTIFY event und die Notifications $HDN_ITEMCHANGED, $HDN_ITEMCHANGEDW, $LVN_ENDSCROLL, um die Controls zu verschieben, so habe ich das aktuell im Einsatz. Bei mir bin ich aber an einem Punkt angelangt, wo AUtoIT anfängt langsam zu werden und zu ruckeln, da ich viele extra Controls im ListView habe und daher kam der Gedanke, das Ganze mal zu optimieren und zwar mit WM_PAINT als trigger.

    Bin gerade aber auf eine interessante Entdeckung gestoßen und werde an der alten Methode mit WM_NOTIFY weiter basteln. Ich meld mich, wenn ich mit dem testen fertig bin. Danke für die Anregung :thumbup:

  • Ich hab etwas am ListView Progress Beispiel von rasim rumgebastelt, schaffe es aber nicht, das Ganze im Ownerdraw Modus zum laufen zu bringen. Das Script scheint robust zu sein, stürzt nie ab, wird aber nun durch das setzen des Ownerdraw style nicht mehr korrekt gezeichnet, genauso wie die Controls.

    Du sagtest du schaust dir das morgen mal an, darauf würde ich gerne zurück kommen. Im Anhang das Script zum testen. Kommentiere mal GUIRegisterMsg($WM_DRAWITEM, "WM_DRAWITEM") aus und du siehst wie flüssig, das Ganze läuft und dann aktiviere es wieder, ich weiß echt nicht weiter ?(

  • Aus irgendeinem Grund wird kein WM_DRAWITEM message mehr gesendet, wenn WM_NOTIFY und WM_DRAWITEM aktiv sind. Wenn ich die Spaltenbreite ändere, löscht er die Items und anschließend wird kein WM_DRAWITEM mehr gesendet, da ja kein Item mehr vorhanden ist.

    Die Ursache versteh ich nun, aber ich finde keine Lösung... ?(