Jump to content

Protect ListView subitem color


Spiff59
 Share

Recommended Posts

I'm popping up a second gui on top of a large ListView, one that has individual cells colored via customdraw. When I delete the temporary GUI, the colors beneath have reverted to the default, black. Tried a forum search, tried playing with some styles and extended styles. Is there a way to protect the colors beneath so I won't have to repeatedly recreate the main listview?

Thanks.

Link to comment
Share on other sites

  • 3 weeks later...

I'd about given up on this one.

Ok, took 40 mins to chop 1000 lines down to a working 100.

No more databases, files, subscripts, images, buttons, timers, etc.

This example is similar to what I was experiencing when I made this post.

In that state, the text/bg color of cells gets trashed by the sub-GUI.

Uncommenting the SW_LOCK and SW_UNLOCK statements in this example is what I'm running now.

Now, dragging the second GUI around is ugly, but the colors are at least restored after it's closed (the users dont drag the popup anyway).

Typically, my listview will be fully populated, so you'll need to drag the popup GUI around to see how it effects text color.

Double-click "CLICK ME" to launch the second GUI.

I made a couple comments on interesting (confusing) areas in the code.

Am sure there's a style or two that would make things prettier, or a patch to my WM_NOTIFY code?

Thanks much.

#include <GuiConstants.au3>
#include <GuiListView.au3>
#include <WindowsConstants.au3>
Global $hListItem[2]
Global $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView, $tInfo, $aHit
Global $iColor, $iColorBk

$Main_GUI = GuiCreate("test", 924, 604, 60, 20)
$hListView = GuiCtrlCreateListView("", 10, 44, 904, 535, -1, BitOR($LVS_ICON, $LVS_EX_GRIDLINES, $LVS_EX_DOUBLEBUFFER, $LVS_EX_TWOCLICKACTIVATE))
$hListView = GUICtrlGetHandle($hListView) ; necessary for _SubItemHitTest
_GUICtrlListView_AddColumn($hListView, " ", 20)
_GUICtrlListView_AddColumn($hListView, "TIME", 40, 1)
_GUICtrlListView_AddColumn($hListView, "PROVIDER ", 70)
_GUICtrlListView_AddColumn($hListView, "CHART # ", 70)
_GUICtrlListView_AddColumn($hListView, "PATIENT NAME ", 155)
_GUICtrlListView_AddColumn($hListView, "NOTE ", 158)
_GUICtrlListView_AddColumn($hListView, "RESOURCE", 72)
_GUICtrlListView_AddColumn($hListView, "STATUS ", 74)
_GUICtrlListView_AddColumn($hListView, "CLAIM(S) ", 80)
_GUICtrlListView_AddColumn($hListView, "LEDGER", 72)
_GUICtrlListView_AddColumn($hListView, "DICTATION", 72)

$Status_Message = GUICtrlCreateLabel("", 20, 582, 180, 20)
GUISetState()
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

;_GUICtrlListView_BeginUpdate($hListView)
$hListItem[1] = _GUICtrlListView_AddItem($hListView, " ")
_GUICtrlListView_AddSubItem($hListView, 0, "11:30", 1)
_GUICtrlListView_AddSubItem($hListView, 0, "XYZZY", 2)
_GUICtrlListView_AddSubItem($hListView, 0, "PLUGH", 3)
_GUICtrlListView_AddSubItem($hListView, 0, "DOE, JOHN", 4)
_GUICtrlListView_AddSubItem($hListView, 0, "PLOVER", 5)
_GUICtrlListView_AddSubItem($hListView, 0, "FOOBAR", 6)
_GUICtrlListView_AddSubItem($hListView, 0, "CLICK ME", 7)
_GUICtrlListView_AddSubItem($hListView, 0, "12345", 8)
_GUICtrlListView_AddSubItem($hListView, 0, "01-01-2009", 9)
_GUICtrlListView_AddSubItem($hListView, 0, "01-31-2009", 10)    
;_GUICtrlListView_EndUpdate($hListView)

;-----------------------------------------------------------------------------------------------------------
While 1
    $msg = GUIGetMsg()  
    Switch $msg
        Case -3 ; $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
Wend
Exit

;-----------------------------------------------------------------------------------------------------------
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg, $iwParam
    $hWndListView = $hListView
    If Not IsHWnd($hListView) Then $hWndListView = GUICtrlGetHandle($hListView)
    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")

    Switch $hWndFrom
        Case $hWndListView
            Switch $iCode
                Case $LVN_ENDSCROLL
                    $tNMHDR = DllStructCreate("hwnd hWnd;uint cID;int code", $ilParam)
                    $hLV = HWnd(DllStructGetData($tNMHDR, "hWnd"))
                    _WinAPI_InvalidateRect($hLV)
                Case $NM_DBLCLK 
                    $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
                    $aHit = _GUICtrlListView_SubItemHitTest($hListView)
                    If $aHit[0] < 0 Then Return $GUI_RUNDEFMSG
                    Switch $aHit[1]
                        Case 7
                            Child_GUI($aHit[0])
                    EndSwitch
                Case $NM_CUSTOMDRAW
                    Local $tCustDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $ilParam)
                    Local $iDrawStage = DllStructGetData($tCustDraw, "dwDrawStage")
                    If $iDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW
                    If $iDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW
                    Local $iItem = DllStructGetData($tCustDraw, "dwItemSpec")
                    Local $iSubItem = DllStructGetData($tCustDraw, "iSubItem")
                    
                    If $iSubItem Then
                        $iColor = 0x000000
                        $iColorBk = 0xFFFFFF 
                        Switch $iSubItem
                            Case 4 
                                $iColor = 0xFFFFFF 
                                $iColorBk = 8421376
                            Case 6 
                                $iColor = 0x0080FF
                            Case 7 
                                $iColor = 0x888888
                            Case 8 
                                $iColor = 0x228B22
                            Case 9 
                                $iColor = 0xFF0000
                            Case 10
                                $iColor = 0x0000FF
                        EndSwitch
                        DllStructSetData($tCustDraw, "clrTextBk", $iColorBk)
                        DllStructSetData($tCustDraw, "clrText", $iColor)
                    EndIf
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc

;-----------------------------------------------------------------------------------------------------------
Func Child_GUI($y)
;   GUISetState(@SW_LOCK, $Main_GUI) ; uncommented changes behaviour
    $APPTSTAT_GUI = GUICreate("", 230, 180, 560, 140)
    GUISetState(@SW_SHOW, $APPTSTAT_GUI)
    While 1
        $msg2 = GUIGetMsg()
        Switch $msg2
            Case $GUI_EVENT_CLOSE
                ExitLoop
        EndSwitch
        Sleep(50) ; why is this necessary? otherwise crashes
    Wend
    GUIDelete($APPTSTAT_GUI)
    GUISetState(@SW_RESTORE, $Main_GUI)
;   GUISetState(@SW_UNLOCK, $Main_GUI); uncommented changes behaviour
EndFunc

typos

Edited by Spiff59
Link to comment
Share on other sites

Something like this

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

Global $hListItem[2]
Global $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView, $tInfo, $aHit
Global $iColor, $iColorBk, $fChildGui = False

$Main_GUI = GuiCreate("test", 924, 604, 60, 20)
$hListView = GuiCtrlCreateListView("", 10, 44, 904, 535, -1, BitOR($LVS_ICON, $LVS_EX_GRIDLINES, $LVS_EX_DOUBLEBUFFER, $LVS_EX_TWOCLICKACTIVATE))
$hListView = GUICtrlGetHandle($hListView) ; necessary for _SubItemHitTest
_GUICtrlListView_AddColumn($hListView, " ", 20)
_GUICtrlListView_AddColumn($hListView, "TIME", 40, 1)
_GUICtrlListView_AddColumn($hListView, "PROVIDER ", 70)
_GUICtrlListView_AddColumn($hListView, "CHART # ", 70)
_GUICtrlListView_AddColumn($hListView, "PATIENT NAME ", 155)
_GUICtrlListView_AddColumn($hListView, "NOTE ", 158)
_GUICtrlListView_AddColumn($hListView, "RESOURCE", 72)
_GUICtrlListView_AddColumn($hListView, "STATUS ", 74)
_GUICtrlListView_AddColumn($hListView, "CLAIM(S) ", 80)
_GUICtrlListView_AddColumn($hListView, "LEDGER", 72)
_GUICtrlListView_AddColumn($hListView, "DICTATION", 72)

$Status_Message = GUICtrlCreateLabel("", 20, 582, 180, 20)
GUISetState()
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

;_GUICtrlListView_BeginUpdate($hListView)
$hListItem[1] = _GUICtrlListView_AddItem($hListView, " ")
_GUICtrlListView_AddSubItem($hListView, 0, "11:30", 1)
_GUICtrlListView_AddSubItem($hListView, 0, "XYZZY", 2)
_GUICtrlListView_AddSubItem($hListView, 0, "PLUGH", 3)
_GUICtrlListView_AddSubItem($hListView, 0, "DOE, JOHN", 4)
_GUICtrlListView_AddSubItem($hListView, 0, "PLOVER", 5)
_GUICtrlListView_AddSubItem($hListView, 0, "FOOBAR", 6)
_GUICtrlListView_AddSubItem($hListView, 0, "CLICK ME", 7)
_GUICtrlListView_AddSubItem($hListView, 0, "12345", 8)
_GUICtrlListView_AddSubItem($hListView, 0, "01-01-2009", 9)
_GUICtrlListView_AddSubItem($hListView, 0, "01-31-2009", 10)   
;_GUICtrlListView_EndUpdate($hListView)

;-----------------------------------------------------------------------------------------------------------
While 1
    $msg = GUIGetMsg() 
    Switch $msg
        Case -3 ; $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
    If $fChildGui Then
        Child_GUI($aHit[0])
        $fChildGui = False
    EndIf
Wend
Exit

;-----------------------------------------------------------------------------------------------------------
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg, $iwParam
    $hWndListView = $hListView
    If Not IsHWnd($hListView) Then $hWndListView = GUICtrlGetHandle($hListView)
    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")

    Switch $hWndFrom
        Case $hWndListView
            Switch $iCode
                Case $LVN_ENDSCROLL
                    $tNMHDR = DllStructCreate("hwnd hWnd;uint cID;int code", $ilParam)
                    $hLV = HWnd(DllStructGetData($tNMHDR, "hWnd"))
                    _WinAPI_InvalidateRect($hLV)
                Case $NM_DBLCLK
                    $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
                    $aHit = _GUICtrlListView_SubItemHitTest($hListView)
                    If $aHit[0] < 0 Then Return $GUI_RUNDEFMSG
                    Switch $aHit[1]
                        Case 7
                            $fChildGui = True
                            ;Child_GUI($aHit[0])
                    EndSwitch
                Case $NM_CUSTOMDRAW
                    Local $tCustDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $ilParam)
                    Local $iDrawStage = DllStructGetData($tCustDraw, "dwDrawStage")
                    If $iDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW
                    If $iDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW
                    Local $iItem = DllStructGetData($tCustDraw, "dwItemSpec")
                    Local $iSubItem = DllStructGetData($tCustDraw, "iSubItem")
                   
                    If $iSubItem Then
                        $iColor = 0x000000
                        $iColorBk = 0xFFFFFF
                        Switch $iSubItem
                            Case 4
                                $iColor = 0xFFFFFF
                                $iColorBk = 8421376
                            Case 6
                                $iColor = 0x0080FF
                            Case 7
                                $iColor = 0x888888
                            Case 8
                                $iColor = 0x228B22
                            Case 9
                                $iColor = 0xFF0000
                            Case 10
                                $iColor = 0x0000FF
                        EndSwitch
                        DllStructSetData($tCustDraw, "clrTextBk", $iColorBk)
                        DllStructSetData($tCustDraw, "clrText", $iColor)
                    EndIf
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc

;-----------------------------------------------------------------------------------------------------------
Func Child_GUI($y)
;   GUISetState(@SW_LOCK, $Main_GUI) ; uncommented changes behaviour
    $APPTSTAT_GUI = GUICreate("", 230, 180, 560, 140)
    GUISetState(@SW_SHOW, $APPTSTAT_GUI)
    While 1
        $msg2 = GUIGetMsg()
        Switch $msg2
            Case $GUI_EVENT_CLOSE
                ExitLoop
        EndSwitch
        Sleep(50) ; why is this necessary? otherwise crashes
    Wend
    GUIDelete($APPTSTAT_GUI)
    GUISetState(@SW_RESTORE, $Main_GUI)
;   GUISetState(@SW_UNLOCK, $Main_GUI); uncommented changes behaviour
EndFunc

Link to comment
Share on other sites

Very nice!

Makes complete sense...

I was launching my second GUI from within the middle of the WM_NOTIFY function.

Apparently not good timing for creating new controls :P

So, instead, flip a flag, let WM_NOTIFY finish it's mystical stuff, and then launch the second GUI outside of WM_NOTIFY.

The weird Sleep(50) is no longer required and SW_LOCK and SW_UNLOCK are no longer needed either (although I'll park a SW_DISABLE/ENABLE on the main GUI to keep users from trying to perform tricks prior to closing the child GUI).

Thank you very much, Gentlemen.

Edit: typo (as always, vey (sic) first word this time!)

Edited by Spiff59
Link to comment
Share on other sites

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   0 members

    • No registered users viewing this page.
×
×
  • Create New...