albertmaathuis Posted May 5 Posted May 5 Hello, I have a gui consisting of two listviews. I have attached both programmes as attachments In the first programme "listview changing colours", I can change the colours of individual fields. In the second programme ‘listview changing and doublclick’, I can move a line between the listviews and see via double-click which line I have clicked. The idea is to make 1 programme out of it, where I can therefore both colour individual items, make the contents visible via double-click and transfer the line to another listview via ‘drag and drop’. Because my main programme uses about 40 individual listviews, some speed is important. After several days of searching and trying, I still get stuck every time. Anyone have any idea how I can solve this? Many thanks in advance for your reactions, Albert Listview changing colors.au3 Listview changing and doubleclick.au3
Nine Posted May 5 Posted May 5 (edited) Here a working example of one listview with color and double click. You can add as many listviews as you want. I included a map to register all the colors of the different listviews. expandcollapse popup#include <GUIConstants.au3> #include <GuiListView.au3> Opt("MustDeclareVars", True) Global $idListView, $mColor[] Example() Func Example() Local $hGUI = GUICreate("Colored ListView", 350, 250) $idListView = GUICtrlCreateListView("Number|Number|Number", 5, 5, 300, 150) Local $hListView = GUICtrlGetHandle($idListView) Local $idButton = GUICtrlCreateButton("Change", 5, 180, 100, 20) GUIRegisterMsg($WM_NOTIFY, WM_NOTIFY) GUISetState() For $i = 1 To 50 GUICtrlCreateListViewItem($i & '|' & $i & '|' & $i, $idListView) Next ;init background colors for ListView 1 (could be many of these) Local $aColor[ControlListView($hGUI, "", $idListView, "GetItemCount")][ControlListView($hGUI, "", $idListView, "GetSubItemCount")] $aColor[0][1] = 0xFFAAFF $aColor[1][2] = 0x00AA00 $aColor[2][0] = 0xCCCCCC $mColor[$idListView] = $aColor While True Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $idButton $aColor = $mColor[$idListView] $aColor[5][1] = 0xFF $mColor[$idListView] = $aColor _WinAPI_RedrawWindow($hListView) EndSwitch WEnd EndFunc ;==>Example Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam) Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam) Switch $tNMHDR.IDFrom Case $idListView Switch $tNMHDR.Code Case $NM_CUSTOMDRAW Local $tCustDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam) Local $iDrawStage = $tCustDraw.dwDrawStage If $iDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW If $iDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW ; Paint item and subitem Local $iSubItem = $tCustDraw.iSubItem Local $iItem = $tCustDraw.dwItemSpec If ControlListView($hWnd, "", $tNMHDR.hWndFrom, "IsSelected", $iItem) Then Return $CDRF_DODEFAULT $tCustDraw.clrTextBk = ($mColor[$tCustDraw.IDFrom])[$iItem][$iSubItem] ? ($mColor[$tCustDraw.IDFrom])[$iItem][$iSubItem] : 0xFFFFFF Return $CDRF_NEWFONT Case $NM_DBLCLK Local $tItem = DllStructCreate($tagNMITEMACTIVATE, $lParam) ConsoleWrite("Double click for ListView : " & $tItem.IDFrom & " on item : " & $tItem.Index & " on subitem : " & $tItem.SubItem & @CRLF) EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY Edited May 5 by Nine added change color “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Debug Messages Monitor UDF Screen Scraping Round Corner GUI UDF Multi-Threading Made Easy Interface Object based on Tag
albertmaathuis Posted May 5 Author Posted May 5 Thank you very much for the quick response. I managed to create 2 listview side by side with different colours in the cells. Also, the double-click works quite well I still fail to move a row from listview[1] to listview[2]. I tried: $idListView[1] = GUICtrlCreateListView("Number|Number|Number", 5, 5, 300, 150) to expand with: $idListView[1] = GUICtrlCreateListView("Number|Number|Number", 5, 5, 300, 150,BitOR($LVS_SHOWSELALWAYS, $LVS_REPORT, $WS_BORDER)) _GUICtrlListView_SetExtendedListViewStyle($idListView[1], $LVS_EX_FULLROWSELECT) (As in the previous program), but that gives no result. Should I add something in the WM_Notify ?
Nine Posted May 5 Posted May 5 Please provide the code you are working with. So I do not have to create it from scratch. When you post code, please use the method shown in the link. Thanks. “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Debug Messages Monitor UDF Screen Scraping Round Corner GUI UDF Multi-Threading Made Easy Interface Object based on Tag
albertmaathuis Posted May 5 Author Posted May 5 expandcollapse popup#include <GUIConstants.au3> #include <GuiListView.au3> #include <GUIListViewEx.au3> #include <GuiStatusBar.au3> Opt("MustDeclareVars", True) Global $idListView[28] global $hListView[28] global $mColor[28] global $g_hStatus Example() Func Example() Local $hGUI = GUICreate("Colored ListView", 750, 250) $idListView[1] = GUICtrlCreateListView("Number|Number|Number", 5, 5, 300, 150,BitOR($LVS_SHOWSELALWAYS, $LVS_REPORT, $WS_BORDER)) _GUICtrlListView_SetExtendedListViewStyle($idListView[1], $LVS_EX_FULLROWSELECT) $hListView[1] = GUICtrlGetHandle($idListView[1]) $idListView[2] = GUICtrlCreateListView("Number|Number|Number", 305, 5, 300, 150,BitOR($LVS_SHOWSELALWAYS, $LVS_REPORT, $WS_BORDER)) _GUICtrlListView_SetExtendedListViewStyle($idListView[2], $LVS_EX_FULLROWSELECT) $hListView[2] = GUICtrlGetHandle($idListView[2]) GUIRegisterMsg($WM_NOTIFY, WM_NOTIFY) GUISetState() For $i = 1 To 50 GUICtrlCreateListViewItem($i & '|' & $i & '|' & $i, $idListView[1]) GUICtrlCreateListViewItem($i & '|' & "OK" & '|' & $i, $idListView[2]) Next ;init background colors for ListView 1 (could be many of these) Local $aColor[ControlListView($hGUI, "", $idListView[1], "GetItemCount")][ControlListView($hGUI, "", $idListView[1], "GetSubItemCount")] $aColor[0][1] = 0xFFAAFF $aColor[1][2] = 0x00AA00 $aColor[2][0] = 0xCCCCCC $mColor[$idListView[1]] = $aColor ;init background colors for ListView 2 (could be many of these) Local $bColor[ControlListView($hGUI, "", $idListView[2], "GetItemCount")][ControlListView($hGUI, "", $idListView[2], "GetSubItemCount")] $bColor[0][1] = 0xCCCCCC $bColor[1][2] = 0x00AA00 $bColor[2][0] = 0xFFAAFF $mColor[$idListView[2]] = $bColor While True Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd EndFunc ;==>Example Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam) Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam) Switch $tNMHDR.IDFrom Case $idListView[1] Switch $tNMHDR.Code Case $NM_CUSTOMDRAW Local $tCustDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam) Local $iDrawStage = $tCustDraw.dwDrawStage If $iDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW If $iDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW ; Paint item and subitem Local $iSubItem = $tCustDraw.iSubItem Local $iItem = $tCustDraw.dwItemSpec If ControlListView($hWnd, "", $tNMHDR.hWndFrom, "IsSelected", $iItem) Then Return $CDRF_DODEFAULT $tCustDraw.clrTextBk = ($mColor[$tCustDraw.IDFrom])[$iItem][$iSubItem] ? ($mColor[$tCustDraw.IDFrom])[$iItem][$iSubItem] : 0xFFFFFF Return $CDRF_NEWFONT Case $NM_DBLCLK Local $tItem = DllStructCreate($tagNMITEMACTIVATE, $lParam) ConsoleWrite("Double click for ListView : " & $tItem.IDFrom & " on item : " & $tItem.Index & " on subitem : " & $tItem.SubItem & @CRLF) EndSwitch Case $idListView[2] Switch $tNMHDR.Code Case $NM_CUSTOMDRAW Local $tCustDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam) Local $iDrawStage = $tCustDraw.dwDrawStage If $iDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW If $iDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW ; Paint item and subitem Local $iSubItem = $tCustDraw.iSubItem Local $iItem = $tCustDraw.dwItemSpec If ControlListView($hWnd, "", $tNMHDR.hWndFrom, "IsSelected", $iItem) Then Return $CDRF_DODEFAULT $tCustDraw.clrTextBk = ($mColor[$tCustDraw.IDFrom])[$iItem][$iSubItem] ? ($mColor[$tCustDraw.IDFrom])[$iItem][$iSubItem] : 0xFFFFFF Return $CDRF_NEWFONT Case $NM_DBLCLK Local $tItem = DllStructCreate($tagNMITEMACTIVATE, $lParam) ConsoleWrite("Double click for ListView : " & $tItem.IDFrom & " on item : " & $tItem.Index & " on subitem : " & $tItem.SubItem & @CRLF) EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY
albertmaathuis Posted May 5 Author Posted May 5 The code can of course be more efficient, but that will come later when it all works
Nine Posted May 5 Posted May 5 (edited) Here one simple way. You can make it more and more complex as you wish to. Not all exceptions are verified BTW. ps. requires latest version (because of the map) expandcollapse popup#include <GUIConstants.au3> #include <GuiListView.au3> #include <WinAPISysWin.au3> Opt("MustDeclareVars", True) Global $mColor[], $bDragging, $tDragItem = DllStructCreate($tagNMHDR) Example() Func Example() Local $hGUI = GUICreate("Colored ListView", 700, 250) Local $idListView1 = GUICtrlCreateListView("Number|Number|Number", 5, 5, 300, 150) Local $idListView2 = GUICtrlCreateListView("Number|Number|Number", 350, 5, 300, 150) Local $idButton = GUICtrlCreateButton("Change", 5, 180, 100, 20) GUIRegisterMsg($WM_NOTIFY, WM_NOTIFY) GUIRegisterMsg($WM_LBUTTONUP, WM_LBUTTONUP) GUISetState() For $i = 1 To 10 GUICtrlCreateListViewItem($i & '|' & $i & '|' & $i, $idListView1) GUICtrlCreateListViewItem($i & '|' & "OK" & '|' & $i, $idListView2) Next ;init background colors for ListView 1 (could be many of these) Local $aColor[ControlListView($hGUI, "", $idListView1, "GetItemCount")][ControlListView($hGUI, "", $idListView1, "GetSubItemCount")] $aColor[0][1] = 0xFFAAFF $aColor[1][2] = 0x00AA00 $aColor[2][0] = 0xCCCCCC $mColor[$idListView1] = $aColor Local $aColor[ControlListView($hGUI, "", $idListView2, "GetItemCount")][ControlListView($hGUI, "", $idListView2, "GetSubItemCount")] $aColor[2][1] = 0xFFAAFF $aColor[3][2] = 0x00AA00 $aColor[4][0] = 0xCCCCCC $mColor[$idListView2] = $aColor While True Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $idButton $aColor = $mColor[$idListView1] $aColor[5][1] = 0xFF $mColor[$idListView1] = $aColor _WinAPI_RedrawWindow(GUICtrlGetHandle($idListView1)) $aColor = $mColor[$idListView2] $aColor[6][1] = 0xFF $mColor[$idListView2] = $aColor _WinAPI_RedrawWindow(GUICtrlGetHandle($idListView2)) EndSwitch WEnd EndFunc ;==>Example Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam) If _WinAPI_GetClassName($tNMHDR.hWndFrom) <> "SysListView32" Then Return $GUI_RUNDEFMSG Switch $tNMHDR.Code Case $NM_CUSTOMDRAW Local $tCustDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam) Local $iDrawStage = $tCustDraw.dwDrawStage If $iDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW If $iDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW ; Paint item and subitem Local $iSubItem = $tCustDraw.iSubItem Local $iItem = $tCustDraw.dwItemSpec If ControlListView($hWnd, "", $tNMHDR.hWndFrom, "IsSelected", $iItem) Then Return $CDRF_DODEFAULT $tCustDraw.clrTextBk = ($mColor[$tCustDraw.IDFrom])[$iItem][$iSubItem] ? ($mColor[$tCustDraw.IDFrom])[$iItem][$iSubItem] : 0xFFFFFF Return $CDRF_NEWFONT Case $NM_DBLCLK Local $tItem = DllStructCreate($tagNMITEMACTIVATE, $lParam) ConsoleWrite("Double click for ListView : " & $tItem.IDFrom & " on item : " & $tItem.Index & " on subitem : " & $tItem.SubItem & @CRLF) Case $LVN_BEGINDRAG Local $tDrag = DllStructCreate($tagNMLISTVIEW, $lParam) $tDragItem.hWndFrom = $tDrag.hWndFrom $tDragItem.IDFrom = $tDrag.IDFrom $tDragItem.Code = $tDrag.Item $bDragging = True EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY Func WM_LBUTTONUP($hWnd, $iMsg, $wParam, $lParam) If Not $bDragging Then Return $GUI_RUNDEFMSG $bDragging = False Local $tPoint = _WinAPI_GetMousePos() Local $hPoint = _WinAPI_WindowFromPoint($tPoint) If Not $hPoint Then Return $GUI_RUNDEFMSG If _WinAPI_GetClassName($hPoint) <> "SysListView32" Then Return $GUI_RUNDEFMSG If $hPoint = $tDragItem.hWndFrom Then Return $GUI_RUNDEFMSG Local $aColorSrc = $mColor[$tDragItem.IDFrom] Local $idDest = _WinAPI_GetDlgCtrlID($hPoint) Local $aColorDest = $mColor[$idDest] If UBound($aColorSrc, 2) <> UBound($aColorDest, 2) Then Return $GUI_RUNDEFMSG _GUICtrlListView_CopyItems($tDragItem.hWndFrom, $hPoint, True) Local $nDest = UBound($aColorDest) + 1 ReDim $aColorDest[$nDest][UBound($aColorDest, 2)] For $i = 0 To UBound($aColorSrc, 2) - 1 $aColorDest[$nDest - 1][$i] = $aColorSrc[$tDragItem.Code][$i] Next _ArrayDelete($aColorSrc, $tDragItem.Code) $mColor[$tDragItem.IDFrom] = $aColorSrc $mColor[$idDest] = $aColorDest Return $GUI_RUNDEFMSG EndFunc ;==>WM_LBUTTONUP Edited May 5 by Nine “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Debug Messages Monitor UDF Screen Scraping Round Corner GUI UDF Multi-Threading Made Easy Interface Object based on Tag
albertmaathuis Posted May 6 Author Posted May 6 Hello Nine, Thank you very much for this solution. It works very well and I can move forward with this. Albert
albertmaathuis Posted May 7 Author Posted May 7 Hello Nine, Sorry to bother you again, but I'm running into a limit(?). The attached code is an extension of your last code. Here I am using 24 listviews (30 rows and 2 columns ) side by side (no problems) If I fill some listviews (less then 15) with data everything goes fine. But as soon as I go above 15 listviews (sometimes even less), I get an error message from the WM_NOTIFY: $tCustDraw.clrTextBk = ($mColor[$tCustDraw.IDFrom])[$iItem][$iSubItem] ? ($mColor[$tCustDraw.IDFrom])[$iItem][$iSubItem] : 0xFFFFFF $tCustDraw.clrTextBk = ($mColor[$tCustDraw.IDFrom])^ ERROR expandcollapse popup#include <GUIConstants.au3> #include <GuiListView.au3> #include <WinAPISysWin.au3> Opt("MustDeclareVars", True) Global $mColor[], $bDragging, $tDragItem = DllStructCreate($tagNMHDR) Global $idListview_secties[25]; voorgaand $cLv_secties global $i_listview_number,$left,$cel_info_1,$cel_info_2 Example() Func Example() Local $MainGui = GUICreate("Colored ListView", 1600, 600) $left =5 for $i_listview_number=0 to 23 $idListview_secties[$i_listview_number] = GUICtrlCreateListView("Number|Number", $left, 30, 60, 480) _GUICtrlListView_SetColumnWidth($idListview_secties[$i_listview_number], 0, 50) _GUICtrlListView_SetColumnWidth($idListview_secties[$i_listview_number], 1, 1000) $left=$left+65 next Local $idButton = GUICtrlCreateButton("Change", 5, 550, 100, 20) GUIRegisterMsg($WM_NOTIFY, WM_NOTIFY) GUIRegisterMsg($WM_LBUTTONUP, WM_LBUTTONUP) GUISetState() For $i_listview_number = 0 To 20; for $i_positie=0 to 29 GUICtrlCreateListViewItem($i_positie & '|' & "y" , $idListview_secties[$i_listview_number]) next Next ;init background colors for ListView 1 (could be many of these) for $i_listview_number = 0 To 20; Local $aColor[ControlListView($MainGui, "", $idListview_secties[$i_listview_number], "GetItemCount")][ControlListView($MainGui, "", $idListview_secties[$i_listview_number], "GetSubItemCount")] $aColor[2+$i_listview_number][0] = 0xFFFF00; $mColor[$idListview_secties[$i_listview_number]] = $aColor Next While True Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $idButton $aColor = $mColor[$idListview_secties[1]] $aColor[5][0] = 0xFF $mColor[$idListview_secties[1]] = $aColor _WinAPI_RedrawWindow(GUICtrlGetHandle($idListview_secties[1])) $aColor = $mColor[$idListview_secties[2]] $aColor[6][0] = 0xFF $mColor[$idListview_secties[2]] = $aColor _WinAPI_RedrawWindow(GUICtrlGetHandle($idListview_secties[2])) EndSwitch WEnd EndFunc ;==>Example Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam) If _WinAPI_GetClassName($tNMHDR.hWndFrom) <> "SysListView32" Then Return $GUI_RUNDEFMSG Switch $tNMHDR.Code Case $NM_CUSTOMDRAW Local $tCustDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam) Local $iDrawStage = $tCustDraw.dwDrawStage If $iDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW If $iDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW ; Paint item and subitem Local $iSubItem = $tCustDraw.iSubItem Local $iItem = $tCustDraw.dwItemSpec If ControlListView($hWnd, "", $tNMHDR.hWndFrom, "IsSelected", $iItem) Then Return $CDRF_DODEFAULT $tCustDraw.clrTextBk = ($mColor[$tCustDraw.IDFrom])[$iItem][$iSubItem] ? ($mColor[$tCustDraw.IDFrom])[$iItem][$iSubItem] : 0xFFFFFF Return $CDRF_NEWFONT Case $NM_DBLCLK Local $tItem = DllStructCreate($tagNMITEMACTIVATE, $lParam) ConsoleWrite("Double click for ListView : " & $tItem.IDFrom & " on item : " & $tItem.Index & " on subitem : " & $tItem.SubItem & @CRLF) Case $LVN_BEGINDRAG Local $tDrag = DllStructCreate($tagNMLISTVIEW, $lParam) $tDragItem.hWndFrom = $tDrag.hWndFrom $tDragItem.IDFrom = $tDrag.IDFrom $tDragItem.Code = $tDrag.Item $bDragging = True EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY Func WM_LBUTTONUP($hWnd, $iMsg, $wParam, $lParam) If Not $bDragging Then Return $GUI_RUNDEFMSG $bDragging = False Local $tPoint = _WinAPI_GetMousePos() Local $hPoint = _WinAPI_WindowFromPoint($tPoint) If Not $hPoint Then Return $GUI_RUNDEFMSG If _WinAPI_GetClassName($hPoint) <> "SysListView32" Then Return $GUI_RUNDEFMSG If $hPoint = $tDragItem.hWndFrom Then Return $GUI_RUNDEFMSG Local $aColorSrc = $mColor[$tDragItem.IDFrom] Local $idDest = _WinAPI_GetDlgCtrlID($hPoint) Local $aColorDest = $mColor[$idDest] If UBound($aColorSrc, 2) <> UBound($aColorDest, 2) Then Return $GUI_RUNDEFMSG _GUICtrlListView_CopyItems($tDragItem.hWndFrom, $hPoint, True) Local $nDest = UBound($aColorDest) + 1 ReDim $aColorDest[$nDest][UBound($aColorDest, 2)] For $i = 0 To UBound($aColorSrc, 2) - 1 $aColorDest[$nDest - 1][$i] = $aColorSrc[$tDragItem.Code][$i] Next _ArrayDelete($aColorSrc, $tDragItem.Code) $mColor[$tDragItem.IDFrom] = $aColorSrc $mColor[$idDest] = $aColorDest Return $GUI_RUNDEFMSG EndFunc ;==>WM_LBUTTONUP Do you perhaps have a solution?
Nine Posted May 7 Posted May 7 (edited) @albertmaathuis Good job on your script. But you should learn how to debug your own code. By putting ConsoleWrite to check the evolution path of the script you would have learned where the issue is. BTW it is quite an obvious problem. On the side note, you should always try to eliminate global variables when possible and you should never hardcode constants when you can use a function that will provide it to you (e.g. UBound). It is just good programming practices. Back to your issue, I will not give you the answer. I will let you debug it by yourself. But I will give you a hint, since the AutoIt error tells you that the color arrays are incorrectly created, you should search in that direction. Put some ConsoleWrite as I already told you and you should discover the nasty culprit rapidly... Edited May 7 by Nine “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Debug Messages Monitor UDF Screen Scraping Round Corner GUI UDF Multi-Threading Made Easy Interface Object based on Tag
albertmaathuis Posted May 8 Author Posted May 8 Hello Nine, Of course, I agree with you about debugging myself. (I always try to do that too) But underneath that, I'm still not getting anywhere. Among other things, I found that the ID of my listviews doesn't start at 0, but at 3 But unfortunately I still can't get it to work. I have taken your first version and adapted it in many places, but no real success is achieved For testing, I used an extra variable ($idLV_start), so I can be sure I'm using the right id. The for next loop (starting on line 33) works if I keep it below 19 (so 20 listviews) and then also don't put more than 20 fields in each listview. Another peculiarity is the consolewrite on line 39. If I activate it, execution stops immediately. Perhaps you would be kind enough to take another look? expandcollapse popup#include <GUIConstants.au3> #include <GuiListView.au3> #include <WinAPISysWin.au3> Opt("MustDeclareVars", True) Global $mColor[], $bDragging, $tDragItem = DllStructCreate($tagNMHDR) Example() Func Example() Local $MainGui = GUICreate("Colored ListView", 1700, 600) local $idListview_secties[24]; local $left $left =5 for $i_listview_number= 0 to 23 $idListview_secties[$i_listview_number] = GUICtrlCreateListView("Number|Number", $left, 30, 60, 480) _GUICtrlListView_SetColumnWidth($idListview_secties[$i_listview_number], 0, 50) _GUICtrlListView_SetColumnWidth($idListview_secties[$i_listview_number], 1, 1000) $left=$left+65 ; ConsoleWrite($idListview_secties[$i_listview_number]&" ") next Local $idButton = GUICtrlCreateButton("Change", 5, 550, 100, 20) GUIRegisterMsg($WM_NOTIFY, WM_NOTIFY) GUIRegisterMsg($WM_LBUTTONUP, WM_LBUTTONUP) GUISetState() local $idLV_start=0 For $i_listview_number = 0 To 19; for $i_positie=0 to 20 GUICtrlCreateListViewItem($i_positie & '|' & "y" , $idListview_secties[$idLV_start]) next ConsoleWrite ($idLV_start&" "&$i_listview_number&" "&$i_positie&@CRLF) Local $aColor[ControlListView($MainGui, "", $idListview_secties[$idLV_start], "GetItemCount")][ControlListView($MainGui, "", $idListview_secties[$idLV_start], "GetSubItemCount")] ;ConsoleWrite ($idLV_start&" "&$i_listview_number&" "&$i_positie&@CRLF) $aColor[0][0] = 0xFFFF00; $mColor[$idListview_secties[$idLV_start]] = $aColor $idLV_start=$idLV_start+1 Next While True Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $idButton $aColor = $mColor[$idListview_secties[1]] $aColor[5][0] = 0xFF $mColor[$idListview_secties[1]] = $aColor _WinAPI_RedrawWindow(GUICtrlGetHandle($idListview_secties[1])) $aColor = $mColor[$idListview_secties[2]] $aColor[6][0] = 0xFF $mColor[$idListview_secties[2]] = $aColor _WinAPI_RedrawWindow(GUICtrlGetHandle($idListview_secties[2])) EndSwitch WEnd EndFunc ;==>Example Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) ; ConsoleWrite ($iMsg&" "&$wParam&" "&$lParam&@CRLF) Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam) If _WinAPI_GetClassName($tNMHDR.hWndFrom) <> "SysListView32" Then Return $GUI_RUNDEFMSG Switch $tNMHDR.Code Case $NM_CUSTOMDRAW Local $tCustDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam) Local $iDrawStage = $tCustDraw.dwDrawStage If $iDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW If $iDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW ; Paint item and subitem Local $iSubItem = $tCustDraw.iSubItem Local $iItem = $tCustDraw.dwItemSpec ; ConsoleWrite ($iItem&" "&$iSubItem&@CRLF) If ControlListView($hWnd, "", $tNMHDR.hWndFrom, "IsSelected", $iItem) Then Return $CDRF_DODEFAULT $tCustDraw.clrTextBk = ($mColor[$tCustDraw.IDFrom])[$iItem][$iSubItem] ? ($mColor[$tCustDraw.IDFrom])[$iItem][$iSubItem] : 0xFFFFFF Return $CDRF_NEWFONT Case $NM_DBLCLK Local $tItem = DllStructCreate($tagNMITEMACTIVATE, $lParam) ConsoleWrite("Double click for ListView : " & $tItem.IDFrom & " on item : " & $tItem.Index & " on subitem : " & $tItem.SubItem & @CRLF) Case $LVN_BEGINDRAG Local $tDrag = DllStructCreate($tagNMLISTVIEW, $lParam) $tDragItem.hWndFrom = $tDrag.hWndFrom $tDragItem.IDFrom = $tDrag.IDFrom $tDragItem.Code = $tDrag.Item $bDragging = True EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY Func WM_LBUTTONUP($hWnd, $iMsg, $wParam, $lParam) If Not $bDragging Then Return $GUI_RUNDEFMSG $bDragging = False Local $tPoint = _WinAPI_GetMousePos() Local $hPoint = _WinAPI_WindowFromPoint($tPoint) If Not $hPoint Then Return $GUI_RUNDEFMSG If _WinAPI_GetClassName($hPoint) <> "SysListView32" Then Return $GUI_RUNDEFMSG If $hPoint = $tDragItem.hWndFrom Then Return $GUI_RUNDEFMSG Local $aColorSrc = $mColor[$tDragItem.IDFrom] Local $idDest = _WinAPI_GetDlgCtrlID($hPoint) Local $aColorDest = $mColor[$idDest] If UBound($aColorSrc, 2) <> UBound($aColorDest, 2) Then Return $GUI_RUNDEFMSG _GUICtrlListView_CopyItems($tDragItem.hWndFrom, $hPoint, True) Local $nDest = UBound($aColorDest) + 1 ReDim $aColorDest[$nDest][UBound($aColorDest, 2)] For $i = 0 To UBound($aColorSrc, 2) - 1 $aColorDest[$nDest - 1][$i] = $aColorSrc[$tDragItem.Code][$i] Next _ArrayDelete($aColorSrc, $tDragItem.Code) $mColor[$tDragItem.IDFrom] = $aColorSrc $mColor[$idDest] = $aColorDest Return $GUI_RUNDEFMSG EndFunc ;==>WM_LBUTTONUP
albertmaathuis Posted May 9 Author Posted May 9 A few more additions to the above problem. Maybe there is a limit somewhere that I can't find after all. In the attached code, you can crash the program simply by naming an extra variable (see line 20) The crash then occurs if line 26 runs to 605, no crash if line 26 runs to 604 No extra variable? then always a crash if line 26 runs to 606. The code is stripped down as much as possible and all tests are described in the code. Anybody any ideas? expandcollapse popup#include <GUIConstants.au3> #include <GuiListView.au3> #include <WinAPISysWin.au3> Opt("MustDeclareVars", True) Global $mColor[],$bDragging,$tDragItem = DllStructCreate($tagNMHDR) ; Something strange is going on here. As soon as I split the global variable, I immediately get the error message ;Global $mColor[],$bDragging ;global $tDragItem = DllStructCreate($tagNMHDR) Example() Func Example() Local $hGUI = GUICreate("Colored ListView", 700, 800,600,10); Changing does not affect the error GUISetFont(6) ; local $test ;As soon as I activate this rule (local variable $test) then the error message occurs at 605 occurs (changing to 604 works again) Local $idListView1 = GUICtrlCreateListView("Number|Number|Number", 5, 5, 300, 400); Changing does not affect the error GUIRegisterMsg($WM_NOTIFY, WM_NOTIFY) GUISetState() For $i = 1 To 605;If this is changed to 606 the error message follows GUICtrlCreateListViewItem($i & '|' & $i & '|' & $i, $idListView1) Next Local $aColor[ControlListView($hGUI, "", $idListView1, "GetItemCount")][ControlListView($hGUI, "", $idListView1, "GetSubItemCount")] ; local $aColor[1000][3];Expanding the number of lines in this way also produces no effect; the error remains when 605 goes to 606. $aColor[2][0] = 0xFFAAFF;Removing this line gives no effect (except that no cell is colored) the error remains as 605 goes to 606. $mColor[$idListView1] = $aColor ; $mColor[3] = $aColor;The id of the listview=3, also this way the error remains if 605 goes to 606. While True Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd EndFunc ;==>Example Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) ConsoleWrite("hWnd= "&$hWnd&" "&"iMsg= "&$iMsg&" "&"wParam= "&$wParam&" "&"lParam= "&$lParam&" "&@CRLF) Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam) If _WinAPI_GetClassName($tNMHDR.hWndFrom) <> "SysListView32" Then Return $GUI_RUNDEFMSG Switch $tNMHDR.Code Case $NM_CUSTOMDRAW Local $tCustDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam) Local $iDrawStage = $tCustDraw.dwDrawStage If $iDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW If $iDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW ; Paint item and subitem Local $iSubItem = $tCustDraw.iSubItem Local $iItem = $tCustDraw.dwItemSpec ;ConsoleWrite("IItem= "&$iItem&" ") If ControlListView($hWnd, "", $tNMHDR.hWndFrom, "IsSelected", $iItem) Then Return $CDRF_DODEFAULT $tCustDraw.clrTextBk = ($mColor[$tCustDraw.IDFrom])[$iItem][$iSubItem] ? ($mColor[$tCustDraw.IDFrom])[$iItem][$iSubItem] : 0xFFFFFF Return $CDRF_NEWFONT Case $NM_DBLCLK Local $tItem = DllStructCreate($tagNMITEMACTIVATE, $lParam) ConsoleWrite("Double click for ListView : " & $tItem.IDFrom & " on item : " & $tItem.Index & " on subitem : " & $tItem.SubItem & @CRLF) Case $LVN_BEGINDRAG Local $tDrag = DllStructCreate($tagNMLISTVIEW, $lParam) $tDragItem.hWndFrom = $tDrag.hWndFrom $tDragItem.IDFrom = $tDrag.IDFrom $tDragItem.Code = $tDrag.Item $bDragging = True EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY
Solution pixelsearch Posted May 9 Solution Posted May 9 (edited) 1 hour ago, albertmaathuis said: Anybody any ideas? Ok, I'll finally post something in this thread, though we had a solution for 2 days ("we" = me and a helpful tester via PM, for confirmation on a different OS) But the sentence "Back to your issue, I will not give you the answer." refrained us for posting anything, to avoid creating new tensions. Just have a look at this post above, then 1) Change this line... For $i = 1 To 10 ...to For $i = 1 To 500 Now the script throws the error you reported : $tCustDraw.clrTextBk = ($mColor[$tCustDraw.IDFrom])[$iItem][$iSubItem] ? ($mColor[$tCustDraw.IDFrom])[$iItem][$iSubItem] : 0xFFFFFF $tCustDraw.clrTextBk = ($mColor[$tCustDraw.IDFrom])^ ERROR 2) Then move this block of 3 lines... GUIRegisterMsg($WM_NOTIFY, WM_NOTIFY) GUIRegisterMsg($WM_LBUTTONUP, WM_LBUTTONUP) GUISetState() ...and place it just before While True : GUIRegisterMsg($WM_NOTIFY, WM_NOTIFY) GUIRegisterMsg($WM_LBUTTONUP, WM_LBUTTONUP) GUISetState() While True ...now everything should work fine. It seems that after a few hundreds of list items added, then WM_NOTIFY is always triggered (the listview needs to be redrawn). So if you place the block of 3 lines too early, then the script will crash because the array $aColor is not defined (when map is encountered within the WM_NOTIFY function) Moving the 3 lines just before the main loop should fix it. Please tell us if this solution works for you. Edited May 9 by pixelsearch typo argumentum and ioa747 2 "I think you are searching a bug where there is no bug... don't listen to bad advice."
albertmaathuis Posted May 9 Author Posted May 9 Thank you very much, it works. I have put the version I will continue with in my project below. expandcollapse popup#include <GUIConstants.au3> #include <GuiListView.au3> #include <WinAPISysWin.au3> Opt("MustDeclareVars", True) Global $mColor[], $bDragging, $tDragItem = DllStructCreate($tagNMHDR) Example() Func Example() Local $MainGui = GUICreate("Colored ListView", 1700, 800) local $idListview_secties[24]; local $left $left =5 for $i_listview_number= 0 to 23 $idListview_secties[$i_listview_number] = GUICtrlCreateListView("Number|Number", $left, 30, 60, 480) _GUICtrlListView_SetColumnWidth($idListview_secties[$i_listview_number], 0, 50) _GUICtrlListView_SetColumnWidth($idListview_secties[$i_listview_number], 1, 1000) $left=$left+65 next Local $idButton = GUICtrlCreateButton("Change", 5, 550, 100, 20) global $idLV_start=0 For $i_listview_number = 2 To 25; for $i_positie=0 to 29 GUICtrlCreateListViewItem($i_positie & '|' & "y" , $idListview_secties[$idLV_start]) next Local $aColor[ControlListView($MainGui, "", $idListview_secties[$idLV_start], "GetItemCount")][ControlListView($MainGui, "", $idListview_secties[$idLV_start], "GetSubItemCount")] $aColor[0][0] = 0xFFFF00; $aColor[29][0] = 0xFFFF00; $mColor[$idListview_secties[$idLV_start]] = $aColor $idLV_start=$idLV_start+1 Next GUIRegisterMsg($WM_NOTIFY, WM_NOTIFY) GUIRegisterMsg($WM_LBUTTONUP, WM_LBUTTONUP) GUISetState() While True Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $idButton $aColor = $mColor[$idListview_secties[1]] $aColor[5][0] = 0xFF $mColor[$idListview_secties[1]] = $aColor _WinAPI_RedrawWindow(GUICtrlGetHandle($idListview_secties[1])) $aColor = $mColor[$idListview_secties[2]] $aColor[6][0] = 0xFF $mColor[$idListview_secties[2]] = $aColor _WinAPI_RedrawWindow(GUICtrlGetHandle($idListview_secties[2])) EndSwitch WEnd EndFunc ;==>Example Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam) If _WinAPI_GetClassName($tNMHDR.hWndFrom) <> "SysListView32" Then Return $GUI_RUNDEFMSG Switch $tNMHDR.Code Case $NM_CUSTOMDRAW Local $tCustDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam) Local $iDrawStage = $tCustDraw.dwDrawStage If $iDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW If $iDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW ; Paint item and subitem Local $iSubItem = $tCustDraw.iSubItem Local $iItem = $tCustDraw.dwItemSpec If ControlListView($hWnd, "", $tNMHDR.hWndFrom, "IsSelected", $iItem) Then Return $CDRF_DODEFAULT $tCustDraw.clrTextBk = ($mColor[$tCustDraw.IDFrom])[$iItem][$iSubItem] ? ($mColor[$tCustDraw.IDFrom])[$iItem][$iSubItem] : 0xFFFFFF Return $CDRF_NEWFONT Case $NM_DBLCLK Local $tItem = DllStructCreate($tagNMITEMACTIVATE, $lParam) ConsoleWrite("Double click for ListView : " & $tItem.IDFrom & " on item : " & $tItem.Index & " on subitem : " & $tItem.SubItem & @CRLF) Case $LVN_BEGINDRAG Local $tDrag = DllStructCreate($tagNMLISTVIEW, $lParam) $tDragItem.hWndFrom = $tDrag.hWndFrom $tDragItem.IDFrom = $tDrag.IDFrom $tDragItem.Code = $tDrag.Item $bDragging = True EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY Func WM_LBUTTONUP($hWnd, $iMsg, $wParam, $lParam) If Not $bDragging Then Return $GUI_RUNDEFMSG $bDragging = False Local $tPoint = _WinAPI_GetMousePos() Local $hPoint = _WinAPI_WindowFromPoint($tPoint) If Not $hPoint Then Return $GUI_RUNDEFMSG If _WinAPI_GetClassName($hPoint) <> "SysListView32" Then Return $GUI_RUNDEFMSG If $hPoint = $tDragItem.hWndFrom Then Return $GUI_RUNDEFMSG Local $aColorSrc = $mColor[$tDragItem.IDFrom] Local $idDest = _WinAPI_GetDlgCtrlID($hPoint) Local $aColorDest = $mColor[$idDest] If UBound($aColorSrc, 2) <> UBound($aColorDest, 2) Then Return $GUI_RUNDEFMSG _GUICtrlListView_CopyItems($tDragItem.hWndFrom, $hPoint, True) Local $nDest = UBound($aColorDest) + 1 ReDim $aColorDest[$nDest][UBound($aColorDest, 2)] For $i = 0 To UBound($aColorSrc, 2) - 1 $aColorDest[$nDest - 1][$i] = $aColorSrc[$tDragItem.Code][$i] Next _ArrayDelete($aColorSrc, $tDragItem.Code) $mColor[$tDragItem.IDFrom] = $aColorSrc $mColor[$idDest] = $aColorDest Return $GUI_RUNDEFMSG EndFunc ;==>WM_LBUTTONUP pixelsearch 1
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