Trolleule Posted October 11, 2014 Share Posted October 11, 2014 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? expandcollapse popup#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 Link to comment Share on other sites More sharing options...
LarsJ Posted October 12, 2014 Share Posted October 12, 2014 I'm pretty sure it's this issue. Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Link to comment Share on other sites More sharing options...
Trolleule Posted October 12, 2014 Author Share Posted October 12, 2014 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? Link to comment Share on other sites More sharing options...
LarsJ Posted October 12, 2014 Share Posted October 12, 2014 1) Yes2) 3.3.10 Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions 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