Jump to content

When listview loses focus,the selected item,How to keep blue


Recommended Posts

When LISTVIEW loses focus,the selected item will turn gray.

How can I change It . Let it continue to stay blue

Do not gray

5aba436369b91_A1.jpg.f3c38b5351225a2208c532b4d64a756b.jpg

 

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

Example()

Func Example()
    Local $listview, $button, $item1, $item2, $item3, $msg

    GUICreate("LISTVIEW", 220, 250, 100, 200, -1, $WS_EX_ACCEPTFILES)

    $listview = GUICtrlCreateListView("NO1  |NO2|NO3  ", 10, 10, 200, 150);,$LVS_SORTDESCENDING)
    $button = GUICtrlCreateButton("BUTTON", 75, 170, 70, 20)
    $item1 = GUICtrlCreateListViewItem ("A1|A2|A3", $listview)
    $item2 = GUICtrlCreateListViewItem ("B1|B2|B3", $listview)
    $item3 = GUICtrlCreateListViewItem ("C1|C2|C3", $listview)
    $item4 = GUICtrlCreateListViewItem ("D1|D2|D3", $listview)
    $item5 = GUICtrlCreateListViewItem ("E1|E2|E3", $listview)
    GUICtrlCreateInput("", 20, 200, 150)
    GUISetState()


    Do
        $msg = GUIGetMsg()

        Select
            Case $msg = $button
                MsgBox(0, "", GUICtrlRead(GUICtrlRead($listview)), 2)
            Case $msg = $listview
                MsgBox(0, "", "" & GUICtrlGetState($listview), 2)
        EndSelect
    Until $msg = $GUI_EVENT_CLOSE
EndFunc   ;==>Example

 

Link to comment
Share on other sites

Never could figure out a clean way to do this, so used the following hack:

#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#include <WindowsConstants.au3>
#include <ColorConstants.au3>
#include <GuiListView.au3>
#include <MsgBoxConstants.au3>
Global $listview

Example()

Func Example()
    Local $button, $item1, $item2, $item3, $msg

    GUICreate("LISTVIEW", 220, 250, 100, 200, -1, $WS_EX_ACCEPTFILES)

    $listview = GUICtrlCreateListView("NO1  |NO2|NO3  ", 10, 10, 200, 150, $LVS_SINGLESEL, $LVS_EX_FULLROWSELECT)
    $button = GUICtrlCreateButton("BUTTON", 75, 170, 70, 20)
    $item1 = GUICtrlCreateListViewItem ("A1|A2|A3", $listview)
    $item2 = GUICtrlCreateListViewItem ("B1|B2|B3", $listview)
    $item3 = GUICtrlCreateListViewItem ("C1|C2|C3", $listview)
    $item4 = GUICtrlCreateListViewItem ("D1|D2|D3", $listview)
    $item5 = GUICtrlCreateListViewItem ("E1|E2|E3", $listview)
    GUICtrlCreateInput("", 20, 200, 150)
    GUISetState()

    GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

    Do
        $msg = GUIGetMsg()

        Select
            Case $msg = $button
                MsgBox(0, "", GUICtrlRead(GUICtrlRead($listview)), 2)
            Case $msg = $listview
                MsgBox(0, "", "" & GUICtrlGetState($listview), 2)
        EndSelect
    Until $msg = $GUI_EVENT_CLOSE
EndFunc   ;==>Example

Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $wParam
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView, $tInfo
    ; Local $tBuffer
    $hWndListView = $listview
    If Not IsHWnd($listview) Then $hWndListView = GUICtrlGetHandle($listview)

    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $iIDFrom
        Case $listview
            Switch $iCode
                Case $NM_CLICK ; Sent by a list-view control when the user clicks an item with the left mouse button
                    For $i = 0 To _GUICtrlListView_GetItemCount($listview)
                        _GUICtrlListView_SetItemDropHilited($listview, $i, False)
                    Next
                    $tInfo = DllStructCreate($tagNMITEMACTIVATE, $lParam)
                    _GUICtrlListView_SetItemDropHilited($listview, DllStructGetData($tInfo, "Index"))
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

 

Edited by Subz
Link to comment
Share on other sites

Listviews, by design, work this way. The only way you could possibly get this to work is with an owner drawn listview. The standard listview can't work like this.

 

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

1 hour ago, Subz said:

Sorry you need to remove $LVS_SHOWSELALWAYS i.e.

$listview = GUICtrlCreateListView("NO1  |NO2|NO3  ", 10, 10, 200, 150, $LVS_SINGLESEL , $LVS_EX_FULLROWSELECT)

 

OK!!  it works very well

But it doesn't Work in multi-selection mode

After losing focus, only one item Keep blue

I still want to thank you for providing such good code

Link to comment
Share on other sites

This can be done by drawing selected back and fore colors with GDI functions in custom draw post paint stage:

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

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

Opt( "MustDeclareVars", 1 )

Global $idListView, $hListView

Example()

Func Example()
  GUICreate("Listview", 220, 250, 300, 200, -1, $WS_EX_ACCEPTFILES)

  $idListView = GUICtrlCreateListView("NO1  |NO2|NO3  ", 10, 10, 200, 150, $GUI_SS_DEFAULT_LISTVIEW-$LVS_SINGLESEL)
  GUICtrlCreateListViewItem ("A1|A2|A3", $idListView)
  GUICtrlCreateListViewItem ("B1|B2|B3", $idListView)
  GUICtrlCreateListViewItem ("C1|C2|C3", $idListView)
  GUICtrlCreateListViewItem ("D1|D2|D3", $idListView)
  GUICtrlCreateListViewItem ("E1|E2|E3", $idListView)
  $hListView = GUICtrlGetHandle( $idListView )

  Local $idButton = GUICtrlCreateButton("Button", 75, 170, 70, 20)
  GUICtrlCreateInput("", 20, 200, 150)

  GUISetState()
  GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

  While 1
    Switch GUIGetMsg()
      Case $idButton
        MsgBox(0, "", GUICtrlRead(GUICtrlRead($idListView)), 2)
      Case $idListView
        MsgBox(0, "", "" & GUICtrlGetState($idListView), 2)
      Case $GUI_EVENT_CLOSE
        ExitLoop
    EndSwitch
  WEnd
EndFunc

Func WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam )
  Static $hDC, $iItem, $hBrush = DllCall( "gdi32.dll", "handle", "CreateSolidBrush", "int", _WinAPI_GetSysColor( $COLOR_HIGHLIGHT ) )[0] ; Selected back color, _WinAPI_CreateSolidBrush
  Static $tRect = DllStructCreate( $tagRECT ), $pRect = DllStructGetPtr( $tRect ), $tLVitem = DllStructCreate( $tagLVITEM ), $pLVitem = DllStructGetPtr( $tLVitem ), $tBuffer = DllStructCreate( "wchar Text[4096]" ), $pBuffer = DllStructGetPtr( $tBuffer )
  Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
  Switch HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    Case $hListView
      Switch DllStructGetData($tNMHDR, "Code")
        Case $NM_CUSTOMDRAW
          Local $tNMLVCUSTOMDRAW = DllStructCreate( $tagNMLVCUSTOMDRAW, $lParam )
          Switch DllStructGetData( $tNMLVCUSTOMDRAW, "dwDrawStage" )
            Case $CDDS_PREPAINT                              ; Before the paint cycle begins
              $hDC = DllStructGetData( $tNMLVCUSTOMDRAW, "hdc" )                              ; Device context
              DllCall( "gdi32.dll", "int", "SetBkMode", "handle", $hDC, "int", $TRANSPARENT ) ; Transparent background, _WinAPI_SetBkMode
              Return $CDRF_NOTIFYITEMDRAW                    ; Notify the parent window before an item is painted

            Case $CDDS_ITEMPREPAINT                          ; Before an item is painted
              $iItem = DllStructGetData( $tNMLVCUSTOMDRAW, "dwItemSpec" ) ; Item index
              If GUICtrlSendMsg( $idListView, $LVM_GETITEMSTATE, $iItem, $LVIS_SELECTED ) Then _ ; Selected item?
                Return $CDRF_NOTIFYPOSTPAINT                 ; Custom drawing of selected items
              Return $CDRF_NEWFONT                           ; Default drawing of other items

            Case $CDDS_ITEMPOSTPAINT                         ; After an item has been painted
              DllCall( "gdi32.dll", "int", "SetTextColor", "handle", $hDC, "int",  0xFFFFFF ) ; Selected fore color, white, _WinAPI_SetTextColor
              ; For each subitem
              For $iSubItem = 0 To 2
                ; Subitem rectangle
                DllStructSetData( $tRect, "Top", $iSubItem )
                DllStructSetData( $tRect, "Left", $LVIR_LABEL )
                GUICtrlSendMsg( $idListView, $LVM_GETSUBITEMRECT, $iItem, $pRect )
                DllStructSetData( $tRect, "Left", DllStructGetData( $tRect, "Left" ) )

                ; Selected back color
                DllCall( "user32.dll", "int", "FillRect", "handle", $hDC, "struct*", $tRect, "handle", $hBrush ) ; _WinAPI_FillRect

                ; Left and top margin of subitem text
                DllStructSetData( $tRect, "Left", DllStructGetData( $tRect, "Left" ) + ( $iSubItem ? 6 : 2 ) )
                DllStructSetData( $tRect, "Top", DllStructGetData( $tRect, "Top" ) + 2 )

                ; Extract subitem text from listview
                DllStructSetData( $tLVitem, "Mask", $LVIF_TEXT )
                DllStructSetData( $tLVitem, "SubItem", $iSubItem )
                DllStructSetData( $tLVitem, "Text", $pBuffer )
                DllStructSetData( $tLVitem, "TextMax", 4096 )
                GUICtrlSendMsg( $idListView, $LVM_GETITEMTEXTW, $iItem, $pLVitem )

                ; Draw subitem text with selected fore color and selected text font (through the device context, $hDC)
                DllCall( "user32.dll", "int", "DrawTextW", "handle", $hDC, "wstr", DllStructGetData( $tBuffer, "Text" ), "int", -1, "struct*", $tRect, "uint", $DT_WORD_ELLIPSIS ) ; _WinAPI_DrawText
              Next
              Return $CDRF_NEWFONT                           ; $CDRF_NEWFONT must be returned after changing font or colors
          EndSwitch
      EndSwitch
  EndSwitch
  #forceref $hWnd, $iMsg, $wParam
EndFunc

 

Link to comment
Share on other sites

17 hours ago, LarsJ said:

This can be done by drawing selected back and fore colors with GDI functions in custom draw post paint stage:

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

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

Opt( "MustDeclareVars", 1 )

Global $idListView, $hListView

Example()

Func Example()
  GUICreate("Listview", 220, 250, 300, 200, -1, $WS_EX_ACCEPTFILES)

  $idListView = GUICtrlCreateListView("NO1  |NO2|NO3  ", 10, 10, 200, 150, $GUI_SS_DEFAULT_LISTVIEW-$LVS_SINGLESEL)
  GUICtrlCreateListViewItem ("A1|A2|A3", $idListView)
  GUICtrlCreateListViewItem ("B1|B2|B3", $idListView)
  GUICtrlCreateListViewItem ("C1|C2|C3", $idListView)
  GUICtrlCreateListViewItem ("D1|D2|D3", $idListView)
  GUICtrlCreateListViewItem ("E1|E2|E3", $idListView)
  $hListView = GUICtrlGetHandle( $idListView )

  Local $idButton = GUICtrlCreateButton("Button", 75, 170, 70, 20)
  GUICtrlCreateInput("", 20, 200, 150)

  GUISetState()
  GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

  While 1
    Switch GUIGetMsg()
      Case $idButton
        MsgBox(0, "", GUICtrlRead(GUICtrlRead($idListView)), 2)
      Case $idListView
        MsgBox(0, "", "" & GUICtrlGetState($idListView), 2)
      Case $GUI_EVENT_CLOSE
        ExitLoop
    EndSwitch
  WEnd
EndFunc

Func WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam )
  Static $hDC, $iItem, $hBrush = DllCall( "gdi32.dll", "handle", "CreateSolidBrush", "int", _WinAPI_GetSysColor( $COLOR_HIGHLIGHT ) )[0] ; Selected back color, _WinAPI_CreateSolidBrush
  Static $tRect = DllStructCreate( $tagRECT ), $pRect = DllStructGetPtr( $tRect ), $tLVitem = DllStructCreate( $tagLVITEM ), $pLVitem = DllStructGetPtr( $tLVitem ), $tBuffer = DllStructCreate( "wchar Text[4096]" ), $pBuffer = DllStructGetPtr( $tBuffer )
  Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
  Switch HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    Case $hListView
      Switch DllStructGetData($tNMHDR, "Code")
        Case $NM_CUSTOMDRAW
          Local $tNMLVCUSTOMDRAW = DllStructCreate( $tagNMLVCUSTOMDRAW, $lParam )
          Switch DllStructGetData( $tNMLVCUSTOMDRAW, "dwDrawStage" )
            Case $CDDS_PREPAINT                              ; Before the paint cycle begins
              $hDC = DllStructGetData( $tNMLVCUSTOMDRAW, "hdc" )                              ; Device context
              DllCall( "gdi32.dll", "int", "SetBkMode", "handle", $hDC, "int", $TRANSPARENT ) ; Transparent background, _WinAPI_SetBkMode
              Return $CDRF_NOTIFYITEMDRAW                    ; Notify the parent window before an item is painted

            Case $CDDS_ITEMPREPAINT                          ; Before an item is painted
              $iItem = DllStructGetData( $tNMLVCUSTOMDRAW, "dwItemSpec" ) ; Item index
              If GUICtrlSendMsg( $idListView, $LVM_GETITEMSTATE, $iItem, $LVIS_SELECTED ) Then _ ; Selected item?
                Return $CDRF_NOTIFYPOSTPAINT                 ; Custom drawing of selected items
              Return $CDRF_NEWFONT                           ; Default drawing of other items

            Case $CDDS_ITEMPOSTPAINT                         ; After an item has been painted
              DllCall( "gdi32.dll", "int", "SetTextColor", "handle", $hDC, "int",  0xFFFFFF ) ; Selected fore color, white, _WinAPI_SetTextColor
              ; For each subitem
              For $iSubItem = 0 To 2
                ; Subitem rectangle
                DllStructSetData( $tRect, "Top", $iSubItem )
                DllStructSetData( $tRect, "Left", $LVIR_LABEL )
                GUICtrlSendMsg( $idListView, $LVM_GETSUBITEMRECT, $iItem, $pRect )
                DllStructSetData( $tRect, "Left", DllStructGetData( $tRect, "Left" ) )

                ; Selected back color
                DllCall( "user32.dll", "int", "FillRect", "handle", $hDC, "struct*", $tRect, "handle", $hBrush ) ; _WinAPI_FillRect

                ; Left and top margin of subitem text
                DllStructSetData( $tRect, "Left", DllStructGetData( $tRect, "Left" ) + ( $iSubItem ? 6 : 2 ) )
                DllStructSetData( $tRect, "Top", DllStructGetData( $tRect, "Top" ) + 2 )

                ; Extract subitem text from listview
                DllStructSetData( $tLVitem, "Mask", $LVIF_TEXT )
                DllStructSetData( $tLVitem, "SubItem", $iSubItem )
                DllStructSetData( $tLVitem, "Text", $pBuffer )
                DllStructSetData( $tLVitem, "TextMax", 4096 )
                GUICtrlSendMsg( $idListView, $LVM_GETITEMTEXTW, $iItem, $pLVitem )

                ; Draw subitem text with selected fore color and selected text font (through the device context, $hDC)
                DllCall( "user32.dll", "int", "DrawTextW", "handle", $hDC, "wstr", DllStructGetData( $tBuffer, "Text" ), "int", -1, "struct*", $tRect, "uint", $DT_WORD_ELLIPSIS ) ; _WinAPI_DrawText
              Next
              Return $CDRF_NEWFONT                           ; $CDRF_NEWFONT must be returned after changing font or colors
          EndSwitch
      EndSwitch
  EndSwitch
  #forceref $hWnd, $iMsg, $wParam
EndFunc

 

Thank you for your reply
It solved my problem
Thank you for your help

Edited by kklee69
Link to comment
Share on other sites

  • Moderators

@kklee69 in the future please just hit reply rather than quoting every single response. We know what we said (we were there when we said it), and it pads the thread unnecessarily.

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Link to comment
Share on other sites

Just wanted to add Multi-Selection mode method using my method above, I had to use it this week in a script so thought I'd share the code.

#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#include <WindowsConstants.au3>
#include <ColorConstants.au3>
#include <GuiListView.au3>
#include <MsgBoxConstants.au3>

Global $listview

Example()

Func Example()
    Local $button, $item1, $item2, $item3, $msg

    GUICreate("LISTVIEW", 220, 250, 100, 200, -1, $WS_EX_ACCEPTFILES)

    $listview = GUICtrlCreateListView("NO1  |NO2|NO3  ", 10, 10, 200, 150)
    $button = GUICtrlCreateButton("BUTTON", 75, 170, 70, 20)
    $item1 = GUICtrlCreateListViewItem ("A1|A2|A3", $listview)
    $item2 = GUICtrlCreateListViewItem ("B1|B2|B3", $listview)
    $item3 = GUICtrlCreateListViewItem ("C1|C2|C3", $listview)
    $item4 = GUICtrlCreateListViewItem ("D1|D2|D3", $listview)
    $item5 = GUICtrlCreateListViewItem ("E1|E2|E3", $listview)
    GUICtrlCreateInput("", 20, 200, 150)
    GUISetState()

    GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

    Do
        $msg = GUIGetMsg()

        Select
            Case $msg = $button
                MsgBox(0, "", GUICtrlRead(GUICtrlRead($listview)), 2)
            Case $msg = $listview
                MsgBox(0, "", "" & GUICtrlGetState($listview), 2)
        EndSelect
    Until $msg = $GUI_EVENT_CLOSE
EndFunc   ;==>Example

Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $wParam
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView, $tInfo
    ; Local $tBuffer
    $hWndListView = $listview
    If Not IsHWnd($listview) Then $hWndListView = GUICtrlGetHandle($listview)

    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $iIDFrom
        Case $listview
            Switch $iCode
                    Case $LVN_ITEMCHANGED ; An item has changed
                    $tInfo = DllStructCreate($tagNMLISTVIEW, $lParam)
                    _GUICtrlListView_SetItemSelected($listview, DllStructGetData($tInfo, "Item"), False, False)
                Case $NM_CLICK ; Sent by a list-view control when the user clicks an item with the left mouse button
                    $tInfo = DllStructCreate($tagNMITEMACTIVATE, $lParam)
                    If _GUICtrlListView_GetItemDropHilited($listview, DllStructGetData($tInfo, "Index")) = True Then
                        _GUICtrlListView_SetItemDropHilited($listview, DllStructGetData($tInfo, "Index"), False)
                    Else
                        _GUICtrlListView_SetItemDropHilited($listview, DllStructGetData($tInfo, "Index"), True)
                    EndIf
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

 

Link to comment
Share on other sites

  • 4 years later...

Hi,

I'm working on the same thing.

In the example, is it possible to turn off the highlighted row using the button rather than going through WM_NOTIFY

I went another direction.  Thanks.

Edited by l4tran
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

×
×
  • Create New...