Modify

#4091 new Bug

Header painting dysfunctional when subclassed in ListView

Reported by: Nine Owned by:
Milestone: Component: AutoIt
Version: 3.3.18.0 Severity: None
Keywords: Cc:

Description

The following line is not executed properly when run in x64 while it works perfectly in x86.

If $tItem.Code <> $NM_CUSTOMDRAW Then Return $GUI_RUNDEFMSG

Here the full example. Toggle the useX64 to see difference.
This code was prepared by mlipok.

#AutoIt3Wrapper_UseX64=Y

; From Nine
#include <WindowsConstants.au3>
#include <ColorConstants.au3>
#include <GUIConstants.au3>
#include <GuiListView.au3>
#include <WinAPI.au3>

Opt("MustDeclareVars", True)

Example()

Func Example()
    GUICreate("Example")
    Local $idListview = GUICtrlCreateListView("", 10, 10, 350, 200, -1, BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_DOUBLEBUFFER))
    Local $idButton = GUICtrlCreateButton("Test", 10, 220, 70, 20)
    GUICtrlSendMsg($idListview, $LVM_GETHEADER, 0, 0)

    GUISetState(@SW_SHOW)
    GUIRegisterMsg($WM_NOTIFY, WM_NOTIFY)

    _GUICtrlListView_AddColumn($idListview, "Column 1", 100)
    _GUICtrlListView_AddItem($idListview, "Row 1: Col 1", 0)

    While True
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
            Case $idButton
                ConsoleWrite("Test button clicked" & @CRLF)
        EndSwitch
    WEnd
EndFunc   ;==>Example

Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $wParam
    Local Static $iCounter = 0

    $iCounter += 1
    Local $tItem = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam)
    ConsoleWrite("+ COUNTER = " & $iCounter & " >>> " & _WinAPI_GetClassName($tItem.hWndFrom) & @CRLF)

    ; I thought that for testing AutoIt x64 we do not need anything more but it is not true
    ; when the next line is commented, the COUNTER ends on 5 in x32  ..... but ends on 4 in x64
;~  Return $GUI_RUNDEFMSG

    #QUESTION = why COUNTER ends with 4 in x64 instead of doing the 5 processing as in x32 ?
    #NOTE =  I see that in x32 there is additionall step in the middle of processing ; + COUNTER = 3 >>> SysHeader32

    If _WinAPI_GetClassName($tItem.hWndFrom) <> "SysHeader32" Then Return $GUI_RUNDEFMSG ; we are focusing only on "SysHeader32"

    If $tItem.Code <> $NM_CUSTOMDRAW Then Return $GUI_RUNDEFMSG

    Local $tRect = DllStructCreate($tagRECT, DllStructGetPtr($tItem, "left"))
    Local $hBrush, $hPen

    If _WinAPI_GetClassName($tItem.hWndFrom) = "SysHeader32" Then
    ConsoleWrite("! 1st CheckPoint = " & @ScriptLineNumber & @CRLF)
        If $tItem.dwDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW
    ConsoleWrite("! 2nd CheckPoint = " & @ScriptLineNumber & @CRLF)

        If Not $tItem.dwItemSpec Then $tRect.left += 5
        $tRect.bottom -= 1
        $hPen = _WinAPI_CreatePen($PS_SOLID, 1, 0xA0A0A0)
        _WinAPI_SelectObject($tItem.hDC, $hPen)
        $hBrush = _WinAPI_CreateSolidBrush(0xFFCCDD)
        _WinAPI_SelectObject($tItem.hDC, $hBrush)
        _WinAPI_Rectangle($tItem.hDC, $tRect)
        _WinAPI_DeleteObject($hPen)
        _WinAPI_DeleteObject($hBrush)

        $tRect.Left += 5
        $tRect.Top += 3
        _WinAPI_SetTextColor($tItem.hDC, _WinAPI_SwitchColor($COLOR_BLACK))
        _WinAPI_SetBkMode($tItem.hDC, $TRANSPARENT)
        _WinAPI_DrawText($tItem.hDC, _GUICtrlHeader_GetItemText($tItem.hWndFrom, $tItem.dwItemSpec), $tRect, $DT_LEFT)

        Return $CDRF_SKIPDEFAULT
    EndIf
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Attachments (0)

Change History (1)

comment:1 by mLipok, on Apr 26, 2026 at 12:08:17 PM

My note
I think that WM_NOTIFY() function registered by GUIRegisterMsg() in x64 is not allways called.

Modify Ticket

Action
as new The ticket will remain with no owner.

Add Comment


E-mail address and name can be saved in the Preferences .
 
Note: See TracTickets for help on using tickets.