Jump to content

GUIListViewEx - BugFix Version 6 Apr 24


Melba23
 Share

Recommended Posts

  • Moderators

borsTiHD,

No idea I am afraid.

M23

Edit: But I have just reached out to someone who might....

Edited by Melba23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

borsTiHD, It's almost impossible just to point out the cause of the problem. But I'm pretty sure the problem can't be solved in GUIListViewEx.au3. You need to look for the problem in your own code.

So the problem is that $NM_CUSTOMDRAW notifications sent from the operating system to the header control do not work because the return values do not reach the parent control, ie. the listview control.

$CDDS_PREPAINT notifications are correctly sent from the operating system, but $CDRF_NOTIFYITEMDRAW return values do not reach the listview control. This means that the subsequent $CDDS_ITEMPREPAINT and $CDDS_ITEMPOSTPAINT are simply not generated by the operating system.

The consequence is that custom draw functionality does not work in the header control. Only the default functionality works. Ie. there are only default colors.

It's probably not just $NM_CUSTOMDRAW notifications that do not work, but all notifications. In the header control there is only default functionality with respect to the functionality that's controlled by notifications.

To figure out the cause of the problem you have to do some proper debugging. There are two easy methods you can use.

One is to copy code from your original script to a new blank script. Start by just copying the GUI itself, the listview and the GUIListViewEx.au3 functionality. When you run the script you should see a fully functional listview that also has colors in the header control. Then you copy features one at a time from the original script to the new one and test after each feature. When the header colors are missing, you know which feature is causing the problem. From there you can then try to solve the problem.

Another method is to make a copy of the original script, and then delete features one at a time and test after each deleted feature. When the colors appear in the header control, you have identified the problem.

Lars.

Link to comment
Share on other sites

  • 2 weeks later...

Hey you two, I found my problem.

Its because of one statement for AutoIt3Wrapper.

#AutoIt3Wrapper_UseX64=y

My original script is running in 64bit mode.

 

After I had deleted my project in the most necessary way (including the line above), the error was gone.

When I finally figured out that it was this one line, I took my whole project again and just commented out this line and everything worked.

I can also reproduce it with our old "demo".

#AutoIt3Wrapper_UseX64=y

#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>

#include "GUIListViewEx.au3"

Global $GUI_Listview[1][2], $iModulID = 0

$hGUI = GUICreate("Test", 800, 500)

;Listview
$GUI_Listview[$iModulID][0] = GUICtrlCreateListView("", 1, 1, 780, 90) ;,$LVS_SORTDESCENDING)

;Fügt der Listview Spaltennamen hinzu
_GUICtrlListView_AddColumn($GUI_Listview[$iModulID][0], "EndSZ A", 100)
_GUICtrlListView_AddColumn($GUI_Listview[$iModulID][0], "Port A", 50)
_GUICtrlListView_AddColumn($GUI_Listview[$iModulID][0], "LSZ", 35)
_GUICtrlListView_AddColumn($GUI_Listview[$iModulID][0], "OrdnNR", 60)
_GUICtrlListView_AddColumn($GUI_Listview[$iModulID][0], "Port B", 50)
_GUICtrlListView_AddColumn($GUI_Listview[$iModulID][0], "EndSZ B", 100)
_GUICtrlListView_AddColumn($GUI_Listview[$iModulID][0], "Betrieb", 60)
_GUICtrlListView_AddColumn($GUI_Listview[$iModulID][0], "Status", 50)
_GUICtrlListView_AddColumn($GUI_Listview[$iModulID][0], "Pegel", 70)

;Test Data
For $i = 1 To 2
    Local $sData = "Item: "&$i&"|1|2|3|4|5|6|7|8"
    GUICtrlCreateListViewItem($sData, $GUI_Listview[$iModulID][0])
Next
Local $aLV = _GUIListViewEx_ReadToArray($GUI_Listview[$iModulID][0], 0)

; ListView UDF >> Initiate ListView
$GUI_Listview[$iModulID][1] = _GUIListViewEx_Init($GUI_Listview[$iModulID][0], $aLV, 0, 0, False, 16 + 32 + 64 + 128)

; ListView UDF >> If colours used then this function must be run BEFORE GUISetState
_GUIListViewEx_MsgRegister()

; Set required colours for ListView elements - (Normal text, Normal field, Selected text, Selected field)
;Local $aSelCol[4] = [$GUIBKCOLOR_FONT_TEXT, $GUIBKCOLOR_MAIN_SECOND, $GUIBKCOLOR_MAIN_SECOND, $GUIBKCOLOR_FONT_TEXT]
Local $aSelCol[4] = ["0x999b9d", "0x303443", "0x303443", "0x999b9d"]
_GUIListViewEx_SetDefColours($GUI_Listview[$iModulID][1], $aSelCol)


; Set header data
;Local $sHeaderColor = $GUIBKCOLOR_FONT_TEXT&";"&$GUIBKCOLOR_MAIN_SECOND
Local $sHeaderColor = "0x999b9d;0x303443"
Local $aHdrData[][] = [["Tom", "Dick", "Harry", "Fred", "Fred", "Fred", "Fred", "Fred", "Fred"], _              ; As colour is enabled, these will replace original titles
                            [$sHeaderColor, $sHeaderColor, $sHeaderColor, $sHeaderColor, $sHeaderColor, $sHeaderColor, $sHeaderColor, $sHeaderColor, $sHeaderColor], _
                            ["", "", "", "", "", "", "", "", ""], _
                            [0,0,0,0,0,0,0,0,0]]
Local $sTest = _GUIListViewEx_LoadHdrData($GUI_Listview[$iModulID][1], $aHdrData)


GUISetState()

While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch

WEnd

 

I'm just at the point of finding out. If the bug has been handled before, I'm sorry, I didn't see that.

Still the question, am I making a mistake here? Or is your UDF 64bit capable? Is there anything I can do to change it or deal with the bug in a different way?

Link to comment
Share on other sites

  • Moderators

borsTiHD,

Well done - excellent detective work. Now looking into it.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Long time no been here  :)

Back in 2015 I used this udf to make sortable list boxes for an inhouse app.

As these things go, the app has been in use since that time, loved but untouched.  Recently however, we have had to migrate to a new server farm and for "reasons" the code needs a recompile.

Unfortunately the new guilistviewex.au3 no longer works in the clever list view sorting department.  In other words I click on the column headers and nothing happens.

What I have tried:

  • Reviewed the GUIListViewEx_Init statement
  • Reviewed the GUIListViewEx_MsgRegister statement
  • Reviewed the GUIListViewEx_SetActive statement
  • Added a GUIListViewEx_EventMonitor into the script loop

I have checked the @extended return from GUIListViewEx_EventMonitor and it returns nothing when clicking the column headers.  It does return a 9 when I click on a row so I know the listbox is active.

What else can I check to see why this sorting is not working?  I have spent all day on this and cannot think what else it could be.

Thanks in advance for any help

 

Link to comment
Share on other sites

  • Moderators

Clark,

Are you running this under x64 using the #AutoIt3Wrapper_UseX64=y directive? If so, it would seem that, as with the header colouring problem reported just above, something has changed recently in Windows which has messed up the header code. No doubt a struct needs reworking - my brain is bleeding as I type. As luck would have it, I have just managed to find some free time and, real life permitting, hope to look into the problem over this weekend.

M23

Edit: I have just been running test scripts under x86 and x64 both with and without the directive and I can sort the columns on header click (if enabled) without problem. Unless you can provide a reproducer script which shows the problem I am afraid there is little more I can do.

Edited by Melba23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

  • Moderators

borsTiHD,

I can reproduce the problem - so it is not just you! It seems to me that the UDF is not returning a valid Device Context handle for the Header when used in x64 mode - but at the moment I have no idea why this happens. I will keep plugging away at the problem.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

I've tested the header color example as 64 bit code on both Windows 7 and Windows 10. In both cases, it fails. There are no colors in the header.

Then I've made a much smaller example that only contains header colors:

#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7

#AutoIt3Wrapper_UseX64=y

Opt( "MustDeclareVars", 1 )

#include <GUIConstants.au3>
#include <GuiListView.au3>

Global $hHeader, $aHdrTexts[8]

Example()

Func Example()
  ; Create GUI
  GUICreate( "ListView Header Colors - GUIRegisterMsg", 840, 420 )

  ; Create ListView
  Local $idListView = GUICtrlCreateListView( "", 10, 10, 820, 400 )
  _GUICtrlListView_SetExtendedListViewStyle ( $idListView, $LVS_EX_FULLROWSELECT )

  ; Add columns to ListView
  For $i = 0 To 7
    _GUICtrlListView_AddColumn( $idListView, "Column " & $i, 99 )
    $aHdrTexts[$i] = "Column " & $i
  Next

  ; Fill ListView
  For $i = 0 To 99
    GUICtrlCreateListViewItem( $i & "/0|" & $i & "/1|" & $i & "/2|" & $i & "/3|" & _
                               $i & "/4|" & $i & "/5|" & $i & "/6|" & $i & "/7|", $idListView )
  Next

  ; Header control
  $hHeader = _GUICtrlListView_GetHeader( $idListView )

  ; Register WM_NOTIFY message handler
  GUIRegisterMsg( 0x004E, "WM_NOTIFY" ) ; 0x004E = $WM_NOTIFY

  ; Show GUI
  GUISetState( @SW_SHOW )

  ; Message loop
  While 1
    Switch GUIGetMsg()
      Case $GUI_EVENT_CLOSE
        ExitLoop
    EndSwitch
  WEnd

  ; Cleanup
  GUIDelete()
EndFunc

; WM_NOTIFY message handler
Func WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam )
  Local Static $hHdrBrush = _WinAPI_CreateSolidBrush( 0xCCFFFF ) ; Yellow, BGR
  Local $tNMHDR = DllStructCreate( $tagNMHDR, $lParam ), $hWndFrom = HWnd( DllStructGetData( $tNMHDR, "hWndFrom" ) ), $iCode = DllStructGetData( $tNMHDR, "Code" )

  Switch $hWndFrom
    Case $hHeader
      Switch $iCode
        Case $NM_CUSTOMDRAW
          Local $tNMCustomDraw = DllStructCreate( $tagNMLVCUSTOMDRAW, $lParam )
          Local $dwDrawStage = DllStructGetData( $tNMCustomDraw, "dwDrawStage" )
          Switch $dwDrawStage              ; Holds a value that specifies the drawing stage
            Case $CDDS_PREPAINT            ; Before the paint cycle begins
              ConsoleWrite( "CDDS_PREPAINT" & @CRLF )
              Return $CDRF_NOTIFYITEMDRAW  ; Notify parent window of any item related drawing operations

            Case $CDDS_ITEMPREPAINT        ; Before an item is drawn: Default painting (frames and background)
              ConsoleWrite( "CDDS_ITEMPREPAINT" & @CRLF )
              Return $CDRF_NOTIFYPOSTPAINT ; Notify parent window of any post item related drawing operations

            Case $CDDS_ITEMPOSTPAINT       ; After an item is drawn: Custom painting (item texts)
              ConsoleWrite( "CDDS_ITEMPOSTPAINT" & @CRLF )
              Local $iIndex = DllStructGetData( $tNMCustomDraw, "dwItemSpec" ) ; Item index
              Local $hDC = DllStructGetData( $tNMCustomDraw, "hdc" )           ; Device context
              _WinAPI_SetBkMode( $hDC, $TRANSPARENT )                          ; Transparent background
              Local $tRECT = DllStructCreate( $tagRECT )
              DllStructSetData( $tRECT, 1, DllStructGetData( $tNMCustomDraw, 6 ) + 1 )
              DllStructSetData( $tRECT, 2, DllStructGetData( $tNMCustomDraw, 7 ) + 1 )
              DllStructSetData( $tRECT, 3, DllStructGetData( $tNMCustomDraw, 8 ) - 2 )
              DllStructSetData( $tRECT, 4, DllStructGetData( $tNMCustomDraw, 9 ) - 2 )
              _WinAPI_FillRect( $hDC, $tRECT, $hHdrBrush )                     ; Background color
              DllStructSetData( $tNMCustomDraw, "Left",   DllStructGetData( $tNMCustomDraw, "Left" )  + 4 ) ; Left margin
              DllStructSetData( $tNMCustomDraw, "Right",  DllStructGetData( $tNMCustomDraw, "Right" ) - 4 ) ; Right margin
              DllCall( "user32.dll", "int", "DrawTextW", "handle", $hDC, "wstr", $aHdrTexts[$iIndex], "int", StringLen( $aHdrTexts[$iIndex] ), "struct*", DllStructGetPtr( $tNMCustomDraw, "Left" ), "uint", $DT_LEFT+$DT_SINGLELINE+$DT_VCENTER ) ; _WinAPI_DrawText
              Return $CDRF_NEWFONT         ; $CDRF_NEWFONT must be returned after changing font or colors
          EndSwitch
      EndSwitch
  EndSwitch

  Return $GUI_RUNDEFMSG
  #forceref $hWnd, $iMsg, $wParam
EndFunc

It fails the same way.

 

Then I've replaced the GUIRegisterMsg technique with the Subclassing technique:

#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7

#AutoIt3Wrapper_UseX64=y

Opt( "MustDeclareVars", 1 )

#include <GUIConstants.au3>
#include <GuiListView.au3>

Global $hHeader, $aHdrTexts[8]

Example()

Func Example()
  ; Create GUI
  GUICreate( "ListView Header Colors - Subclassing", 840, 420 )

  ; Create ListView
  Local $idListView = GUICtrlCreateListView( "", 10, 10, 820, 400 )
  _GUICtrlListView_SetExtendedListViewStyle ( $idListView, $LVS_EX_FULLROWSELECT )
  Local $hListView = GUICtrlGetHandle( $idListView )

  ; Add columns to ListView
  For $i = 0 To 7
    _GUICtrlListView_AddColumn( $idListView, "Column " & $i, 99 )
    $aHdrTexts[$i] = "Column " & $i
  Next

  ; Fill ListView
  For $i = 0 To 99
    GUICtrlCreateListViewItem( $i & "/0|" & $i & "/1|" & $i & "/2|" & $i & "/3|" & _
                               $i & "/4|" & $i & "/5|" & $i & "/6|" & $i & "/7|", $idListView )
  Next

  ; Header control
  $hHeader = _GUICtrlListView_GetHeader( $idListView )

  ; Register ListView WM_NOTIFY message handler
  Local $pLV_WM_NOTIFY = DllCallbackGetPtr( DllCallbackRegister( "LV_WM_NOTIFY", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr" ) )
  DllCall( "comctl32.dll", "bool", "SetWindowSubclass", "hwnd", $hListView, "ptr", $pLV_WM_NOTIFY, "uint_ptr", 0, "dword_ptr", 0 ) ; $iSubclassId = 0, $pData = 0
  ;_WinAPI_SetWindowSubclass( $hListView, $pLV_WM_NOTIFY, 0, 0 ) ; $iSubclassId = 0, $pData = 0

  ; Show GUI
  GUISetState( @SW_SHOW )

  ; Message loop
  While 1
    Switch GUIGetMsg()
      Case $GUI_EVENT_CLOSE
        ExitLoop
    EndSwitch
  WEnd

  ; Cleanup
  DllCall( "comctl32.dll", "bool", "RemoveWindowSubclass", "hwnd", $hListView, "ptr", $pLV_WM_NOTIFY, "uint_ptr", 0 ) ; $iSubclassId = 0
  ;_WinAPI_RemoveWindowSubclass( $hListView, $pLV_WM_NOTIFY, 0 ) ; $iSubclassId = 0
  GUIDelete()
EndFunc

; ListView WM_NOTIFY message handler
Func LV_WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam, $iSubclassId, $pData )
  If $iMsg <> 0x004E Then Return DllCall( "comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam )[0] ; 0x004E = $WM_NOTIFY

  Local Static $hHdrBrush = _WinAPI_CreateSolidBrush( 0xCCFFFF ) ; Yellow, BGR
  Local $tNMHDR = DllStructCreate( $tagNMHDR, $lParam ), $hWndFrom = HWnd( DllStructGetData( $tNMHDR, "hWndFrom" ) ), $iCode = DllStructGetData( $tNMHDR, "Code" )

  Switch $hWndFrom
    Case $hHeader
      Switch $iCode
        Case $NM_CUSTOMDRAW
          Local $tNMCustomDraw = DllStructCreate( $tagNMLVCUSTOMDRAW, $lParam )
          Local $dwDrawStage = DllStructGetData( $tNMCustomDraw, "dwDrawStage" )
          Switch $dwDrawStage              ; Holds a value that specifies the drawing stage
            Case $CDDS_PREPAINT            ; Before the paint cycle begins
              ConsoleWrite( "CDDS_PREPAINT" & @CRLF )
              Return $CDRF_NOTIFYITEMDRAW  ; Notify parent window of any item related drawing operations

            Case $CDDS_ITEMPREPAINT        ; Before an item is drawn: Default painting (frames and background)
              ConsoleWrite( "CDDS_ITEMPREPAINT" & @CRLF )
              Return $CDRF_NOTIFYPOSTPAINT ; Notify parent window of any post item related drawing operations

            Case $CDDS_ITEMPOSTPAINT       ; After an item is drawn: Custom painting (item texts)
              ConsoleWrite( "CDDS_ITEMPOSTPAINT" & @CRLF )
              Local $iIndex = DllStructGetData( $tNMCustomDraw, "dwItemSpec" ) ; Item index
              Local $hDC = DllStructGetData( $tNMCustomDraw, "hdc" )           ; Device context
              _WinAPI_SetBkMode( $hDC, $TRANSPARENT )                          ; Transparent background
              Local $tRECT = DllStructCreate( $tagRECT )
              DllStructSetData( $tRECT, 1, DllStructGetData( $tNMCustomDraw, 6 ) + 1 )
              DllStructSetData( $tRECT, 2, DllStructGetData( $tNMCustomDraw, 7 ) + 1 )
              DllStructSetData( $tRECT, 3, DllStructGetData( $tNMCustomDraw, 8 ) - 2 )
              DllStructSetData( $tRECT, 4, DllStructGetData( $tNMCustomDraw, 9 ) - 2 )
              _WinAPI_FillRect( $hDC, $tRECT, $hHdrBrush )                     ; Background color
              DllStructSetData( $tNMCustomDraw, "Left",   DllStructGetData( $tNMCustomDraw, "Left" )  + 4 ) ; Left margin
              DllStructSetData( $tNMCustomDraw, "Right",  DllStructGetData( $tNMCustomDraw, "Right" ) - 4 ) ; Right margin
              DllCall( "user32.dll", "int", "DrawTextW", "handle", $hDC, "wstr", $aHdrTexts[$iIndex], "int", StringLen( $aHdrTexts[$iIndex] ), "struct*", DllStructGetPtr( $tNMCustomDraw, "Left" ), "uint", $DT_LEFT+$DT_SINGLELINE+$DT_VCENTER ) ; _WinAPI_DrawText
              Return $CDRF_NEWFONT         ; $CDRF_NEWFONT must be returned after changing font or colors
          EndSwitch
      EndSwitch
  EndSwitch

  ; Call next function in subclass chain
  Return DllCall( "comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam )[0]
  #forceref $iSubclassId, $pData
EndFunc

Here the code works in all 4 situations: Windows 7/10, 32/64 bit.

 

In the GUIRegisterMsg example, only CDDS_PREPAINT notifications are displayed in SciTE console. The problem seems to be that the CDRF_NOTIFYITEMDRAW return values are not received by the operating system. Therefore, the operating system does not generate CDDS_ITEMPREPAINT or CDDS_ITEMPOSTPAINT notifications and the header items are not colored.

Because the Subclassing example works, it excludes errors in the $tagNMLVCUSTOMDRAW structure.

It seems like there is an error in the internal AutoIt code associated with the GUIRegisterMsg function when the code is run as 64 bit code. The return values from the WM_NOTIFY message handler are not properly forwarded to the operating system. The error seems also to be related to the fact that the header control is a second level child in relation to the GUI. Colors does work for a listview control which is a first level child.

Solution: Implement the WM_NOTIFY message handler in GUIListViewEx.au3 using the Subclassing technique. This is not necessarily completely trivial. In my example above, it looks easy. But this is also a very small example.

Lars.

Link to comment
Share on other sites

On 3/8/2019 at 4:53 PM, Melba23 said:

Edit: I have just been running test scripts under x86 and x64 both with and without the directive and I can sort the columns on header click (if enabled) without problem. Unless you can provide a reproducer script which shows the problem I am afraid there is little more I can do.

Thanks for looking at this Melba

 

I have hacked away all my original code and inserted some fake data into the array and the problem still exists.  Clearly PICNIC (Problem In Chair, Not In Computer).   I would appreciate your guidance when you have the time.   I have left all the includes in there in case there is some conflict somewhere.

 

 

listboxtest.au3

Link to comment
Share on other sites

  • Moderators

Clark,

The problem is at you are not reinitialising the ListView when you change the data - as explained in the "Beginner's Guide" which is within the main UDF zip you downloaded:

Quote

Closure and Reloading:

 If you delete the ListView, then it is recommended to use _GUIListViewEx_Close to free the memory used by the UDF.

 If you wish to reload the ListView with new data, you will need to clear the current content using _GUICtrlListView_DeleteAllItems, close it within the UDF using _GUIListViewEx_Close, reload the ListView with the new data and then reinitialise it using _GUIListViewEx_Init. Otherwise the UDF will become confused about the current content and errors will certainly occur.

In this particular case the UDF thinks the ListView is still empty after the data is loaded and so there is nothing to sort. See this amended script (look for the <<<<<<<<< lines):

#cs ----------------------------------------------------------------------------

 AutoIt Version: 3.3.6.1
 Author:         Clark Lawton

 Script Function:
    Delta Dashboard

#ce ----------------------------------------------------------------------------
;#include <ButtonConstants.au3>
;#include <Date.au3>
;#include <DateTimeConstants.au3>
;#include <EditConstants.au3>
;#include <Excel.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
;#include <StaticConstants.au3>
;#include <TabConstants.au3>
;#include <WindowsConstants.au3>
;#include <ListViewConstants.au3>
#include <array.au3>
;#include <File.au3>
;#include <GuiListView.au3>
;#include "EzMySql.au3"
#include <Array.au3>
;#include <WinAPIEx.au3>
#include "GuiListViewEx.au3" ; Custom sortable listview library

Opt("GUICloseOnESC", 1)

#Region Environment and variable definitions
    Global $sSQL, $iRval, $jRval, $error, $lvItems, $iCntr = 0, $maxItems = 0
    Global $lvItems[1000], $sSelect, $ID, $pos1, $r_[10], $temp, $iLV_Index, $oExcel, $tvi
    Global $lvMain ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#EndRegion Environment and variable definitions

;_WinAPI_Wow64EnableWow64FsRedirection(False)

#Region ### START GUI section ### Form=
    $Form1 = GUICreate("Delta Dashboard", 606, 485, 500, 241, BitOR($WS_MINIMIZEBOX, $WS_MAXIMIZEBOX))
    $lvMain = GUICtrlCreateListView("ID|Name                      |Status                |System Impacted    |Last updated by|When    ", 0, 0, 605, 250, $LVS_SORTDESCENDING)
    _GUICtrlListView_SetColumnWidth($lvMain, 1, 250)
    _GUICtrlListView_SetColumnWidth($lvMain, 4, $LVSCW_AUTOSIZE_USEHEADER)
    $iLV_Index = _GUIListViewEx_Init($lvMain, $lvItems, 0, 0, False, 1 + 8)
    _GUIListViewEx_MsgRegister()
    _GUIListViewEx_SetActive($iLV_Index)
    $ActGroup1 = GUICtrlCreateGroup("Filter by", 25, 260, 555, 95)
    $r_[1] = GUICtrlCreateRadio("Populate", 70, 285)
    GUICtrlCreateGroup("", -99, -99, 1, 1)
    $ActGroup2 = GUICtrlCreateGroup("Actions", 25, 360, 555, 50)
    GUICtrlSetTip(-1, "Print the selected RFC")
    $btnExit = GUICtrlCreateButton(" Exit", 390, 375, 80, 25)
    GUICtrlSetImage(-1, "shell32.dll", 329, 0)
    GUICtrlCreateGroup("", -99, -99, 1, 1)
    GUISetState(@SW_SHOW)
#EndRegion ### START GUI section ### Form=

;msgbox(0,"Start up:","Select a filter to load data")
$message = "Select a filter to load data"
SplashTextOn("Start up", $message, 300, 100, 630, 350, 32, "")
Sleep(1500)
SplashOff()

#Region ### START Main Loop ###
    While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
            Case $r_[1]
                _do_action(16)                                     ; Awaiting EA Review
            Case $GUI_EVENT_CLOSE
                Exit
            Case $btnExit
                Exit
        EndSwitch
        $vRet = _GUIListViewEx_EventMonitor()
        If @error Then
            MsgBox($MB_SYSTEMMODAL, "Error", "Event error: " & @error)
        EndIf
        If @extended > 0 Then
            MsgBox(1, "Start up:", "action  is " & @extended)
        EndIf
    WEnd
#EndRegion ### START Main Loop ###

#Region ### START First Level Functions ###
    Func _do_action($action)
        ; $action=1: Populate All
        Local $iCntr
        _clear_lv()

        ; Remove existing ListView data from the UDF
        _GUIListViewEx_Close($iLV_Index); <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

        $lvItems[1] = "123|The first description|Open|Gaming|Mark|12/12/2012"
        $lvItems[2] = "456|The second description|Closed|Audit|Bill|12/12/2012"
        $lvItems[3] = "789|The third description|Paused|Treasury|Bruce|12/12/2012"
        $lvItems[4] = "234|The fourth description|Incomplete|Finance|Gordon|12/12/2012"
        For $iCntr = 1 To 4
            GUICtrlCreateListViewItem($lvItems[$iCntr], $lvMain)
        Next

        ; Read new ListView data into an array
        Local $aLVArray = _GUIListViewEx_ReadToArray($lvMain); <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        ; Reinitialise the UDF with the new ListView data
        $iLV_Index = _GUIListViewEx_Init($lvMain, $aLVArray, 0, 0, False, 1 + 8); <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<


    EndFunc   ;==>_do_action
#EndRegion ### START First Level Functions ###

#Region ### Start Second Level Functions ###
    Func _clear_lv()
        Local $iCntr
        If $maxItems > 0 Then
            For $iCntr = 1 To $maxItems
                GUICtrlDelete($lvItems[$iCntr])
            Next
        EndIf
    EndFunc   ;==>_clear_lv
#EndRegion ### Start Second Level Functions ###

I am unsure if this is the reason why your main code failed when you say it had previously worked - the requirement to initialise  the UDF with the actual data in the ListView is a fundamental requirement for the UDF to function and if you were not previously doing so I do not understand why the code worked at all!

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Thanks Melba

My bad for not rereading the doco.

I can't explain why the original code works with the old version of the udf, but it does.  I just did a search through the code and ReadToArray nor ListViewEx_Close appear anywhere in the code, yet it sorts those columns just fine.

You have made a really useful udf.

Thanks again

 

Clark

 

Link to comment
Share on other sites

  • Moderators

Clark,

Looking back through the old versions of the UDF it seems that it used to use the default _GUICtrlListView_SimpleSort to do the sorting but adding colour to the mix meant that this was no longer possible and so I changed the UDF to sort its internal array and then rewrite the ListView. Hence your old script could well have worked - another mystery solved!

Glad you find the UDF useful.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Oh boi... looks like it's too complicated to implement?

I don't want to steal all your free time either.

I'm really glad you guys were checking it out.

Anyway, I think your UDF is awesome and I will stay with it whether you get it done or not. :)

 

Thank you two so much.

Link to comment
Share on other sites

  • Moderators

borsTiHD,

I am afraid that you are correct - I have been looking at the problem and, to be frank, I am not prepared to spend the amount of time it would take to rewrite basically the whole UDF just so that user-defined headers can be used in x64. Sorry about that, but as LarsJ so neatly put it - the problem is not "completely trivial" in any sense.

So I am simply going to announce that the user-defined header functions do not function under x64 due to an AutoIt limitation. After all, you can still compile any script to x86 and get them to work.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

  • 1 month later...

Melba23,

I like your UDF a lot - it is very useful to me 😁

I encounter a small issue, maybe you can help me out...

If I use a column with auto-drop-down, like to type any other text which is _not_ in the drop down list and press enter the input will be discarded (= blank list view item). If I repeat it works...

Here is a reproducer (- please use "Col-3" to test):

#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include "GUIListViewEx.au3"


Local $hGUI = GUICreate("TEST", 500, 500)
Local $cLV = GUICtrlCreateListView("Col-0|Col-1|Col-2|Col-3", 10, 10, 420, 260, BitOR($LVS_SINGLESEL, $LVS_SHOWSELALWAYS))


_GUICtrlListView_SetExtendedListViewStyle($cLV, $LVS_EX_FULLROWSELECT)
For $i = 0 To 3
    _GUICtrlListView_SetColumnWidth($cLV, $i, 100)
Next


Global $aLVArray[6][4]
For $i = 0 To 5
    $sData = $i & "-0"
    $aLVArray[$i][0] = $sData
    For $j = 1 To 3
        $sData &= "|" & $j
        $aLVArray[$i][$j] = "" & $j
    Next
    GUICtrlCreateListViewItem($sData, $cLV)
Next


$iLVIndex = _GUIListViewEx_Init($cLV, $aLVArray)
_GUIListViewEx_SetEditStatus($iLVIndex, 3, 2, "||1|2|3|4|5|6", 2)
_GUIListViewEx_MsgRegister()
GUISetState()


While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
    _GUIListViewEx_EventMonitor()
WEnd

I guess it has something to do with the auto-complete behavior...

Any change to work around to store the input at the fist time?

Edited by supersonic
Link to comment
Share on other sites

  • Moderators

supersonic,

I see the same thing - looking into why it happens.

M23

Edit: I can see what is happening. The first time the combo is closed by the {ENTER} key after a manual input the UDF cannot read the edit, although it will quite happily read the manually inserted text up until that point. On subsequent attempts to enter manual text it appears that the UDF can read the edit after the {ENTER} key is pressed and so everything works correctly. I have no idea why the combo behaves like this - I am investigating further and will report if I find anything.

Edit 2: Part of the problem seems to be linked to the presence of an existing combo element appearing as the default input in the editbox - if I set the editbox to be blank when the combo is opened everything appears to work as expected.

Edit 3: That appears to be the solution - only display a default element when the combo is read-only. Can you please try this Beta code and see if it works for you: GUIListViewEx_Combo.au3

Edited by Melba23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

  • Melba23 changed the title to GUIListViewEx - BugFix Version 6 Apr 24

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
 Share

  • Recently Browsing   1 member

×
×
  • Create New...