Jump to content

Listview doesn't redraw properly on top of label without $LVS_EX_FULLROWSELECT


Go to solution Solved by pixelsearch,

Recommended Posts

Hello,

Not sure where to put this.  May be a bug, or may be my misunderstanding.

I have a large applications with colored tabs, from @Melba23's example in 

With these colored tabs, there is a disabled background label over each Tab Item.  On one of my tabs ListViews was not redrawing properly.  I tracked it down to the ListView extended style requiring $LVS_EX_FULLROWSELECT, otherwise the label seems to get drawn on top.

See this example:

#include <GuiTab.au3>
#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#include <GuiListView.au3>
#include <EditConstants.au3>
#include <WindowsConstants.au3>
#include <GuiEdit.au3>

;- Extended flags require $LVS_EX_FULLROWSELECT to work
$BROKEN_EXTENDED_FLAGS = BitOr($LVS_EX_GRIDLINES, $LVS_EX_INFOTIP)
$WORKING_EXTENDED_FLAGS = BitOr($LVS_EX_GRIDLINES, $LVS_EX_INFOTIP, $LVS_EX_FULLROWSELECT)

$GUI_WIDTH = 600
$GUI_HEIGHT = 400

$GUI = GUICreate("ListView On Colored Tab Extended Styles Example", $GUI_WIDTH, $GUI_HEIGHT)
$GUI_TAB = GUICtrlCreateTab(0, 0, $GUI_WIDTH, $GUI_HEIGHT)

CreateColoredTab("Working")
CreateGUIItems($WORKING_EXTENDED_FLAGS)
CreateColoredTab("Broken")
CreateGUIItems($BROKEN_EXTENDED_FLAGS)

GUICtrlCreateTabItem("")
GUISetState()

While 1
    $msg = GUIGetMsg()
    If $msg = $GUI_EVENT_CLOSE Then
        Exit
    EndIf
WEnd

Func CreateColoredTab($title)
    GUICtrlCreateTabItem($title)
    Local $aTabPos = ControlGetPos($GUI, "", $GUI_TAB)
    Local $aTab_Rect = _GUICtrlTab_GetItemRect($GUI_TAB, -1)
    $bk_label = GUICtrlCreateLabel("", $aTabPos[0] + 2, $aTabPos[1] + $aTab_Rect[3] + 4, $aTabPos[2] - 6, $aTabPos[3] - $aTab_Rect[3] - 7)
    GUICtrlSetBkColor($bk_label, 0x555555)
    GUICtrlSetState($bk_label, $GUI_DISABLE)
EndFunc

Func CreateGUIItems($extended_flags)

    $__g_GUITFTPDirList = GUICtrlCreateListView("Directories", 2, 28, $GUI_WIDTH - 4, $GUI_HEIGHT - 32, Default, $extended_flags)

    ;- Make a bunch of random items
    For $i = 0 To 20 Step 1
        $string = ""
        For $c = 0 To 50 Step 1
            $string &= Chr(65 + $i)
        Next
        GUICtrlCreateListViewItem($i & "-" & $string, $__g_GUITFTPDirList)
    Next

EndFunc

You'll see two tabs, "Working" and "Broken".

Working draws properly:

image.png.9cdd2ab48c9c4bb86b0ca9af05688f4d.png

Broken does not draw properly (I've clicked items here so they are drawn):

image.png.b85ea6a7f74373d86a842f813b08de1d.png

I've read the documentation for GUICtrlCreateListView as well as the Style Tables and can't seem to find this requirement anywhere.

Figured I'd post it here as an FYI, and seeing if I missed something in the help.  May be better as a bug report if this is unexpected.

 Thanks!

 

Link to comment
Share on other sites

I tested with $TCS_OWNERDRAWFIXED on the tab control.  Although I am getting better results than using a disabled colored label, I still have issues with the use of $LVS_EX_FULLROWSELECT.  I think it could be possible to find a workaround in WM_NOTIFY, but in all cases, I believe there is a bug somewhere.  I suggest you fill a bug tracker with your code.

Good luck.

Link to comment
Share on other sites

Looks like the the closing of the tab structure is set wrong. Should be called in the CreateColoredTab() function. See code.

 

#include <GuiTab.au3>
#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#include <GuiListView.au3>
#include <EditConstants.au3>
#include <WindowsConstants.au3>
#include <GuiEdit.au3>

;- Extended flags require $LVS_EX_FULLROWSELECT to work
$BROKEN_EXTENDED_FLAGS = BitOr($LVS_EX_GRIDLINES, $LVS_EX_INFOTIP)
$WORKING_EXTENDED_FLAGS = BitOr($LVS_EX_GRIDLINES, $LVS_EX_INFOTIP, $LVS_EX_FULLROWSELECT)

$GUI_WIDTH = 600
$GUI_HEIGHT = 400

$GUI = GUICreate("ListView On Colored Tab Extended Styles Example", $GUI_WIDTH, $GUI_HEIGHT)
$GUI_TAB = GUICtrlCreateTab(0, 0, $GUI_WIDTH, $GUI_HEIGHT)

CreateColoredTab("Working")
CreateGUIItems($WORKING_EXTENDED_FLAGS)
CreateColoredTab("Broken")
CreateGUIItems($BROKEN_EXTENDED_FLAGS)


;~ GUICtrlCreateTabItem("") ;end tabitem definition in wrong place


GUISetState()

While 1
    $msg = GUIGetMsg()
    If $msg = $GUI_EVENT_CLOSE Then
        Exit
    EndIf
WEnd

Func CreateColoredTab($title)
    GUICtrlCreateTabItem($title)
    Local $aTabPos = ControlGetPos($GUI, "", $GUI_TAB)
    Local $aTab_Rect = _GUICtrlTab_GetItemRect($GUI_TAB, -1)
    $bk_label = GUICtrlCreateLabel("", $aTabPos[0] + 2, $aTabPos[1] + $aTab_Rect[3] + 4, $aTabPos[2] - 6, $aTabPos[3] - $aTab_Rect[3] - 7)
    GUICtrlSetBkColor($bk_label, 0x555555)
    GUICtrlSetState($bk_label, $GUI_DISABLE)



    GUICtrlCreateTabItem("") ;end tabitem definition



EndFunc

Func CreateGUIItems($extended_flags)

    $__g_GUITFTPDirList = GUICtrlCreateListView("Directories", 2, 28, $GUI_WIDTH - 4, $GUI_HEIGHT - 32, Default, $extended_flags)

    ;- Make a bunch of random items
    For $i = 0 To 20 Step 1
        $string = ""
        For $c = 0 To 50 Step 1
            $string &= Chr(65 + $i)
        Next
        GUICtrlCreateListViewItem($i & "-" & $string, $__g_GUITFTPDirList)
    Next

EndFunc

 

Edited by AndrewG
Link to comment
Share on other sites

Does not work for me, try removing  $LVS_EX_FULLROWSELECT, then nothing works anymore (at least for me).  And it does not make much sense to end tab definition after each tab...

edit : after a few more tests with my own code, it now works perfectly if I don't use $LVS_EX_FULLROWSELECT at all. Funny and strange...

Edited by Nine
Link to comment
Share on other sites

  • Solution

It should work if you set the extended styles after the listview creation :

; $__g_GUITFTPDirList = GUICtrlCreateListView("Directories", 2, 28, $GUI_WIDTH - 4, $GUI_HEIGHT - 32, Default, $extended_flags)
    ; $__g_GUITFTPDirList = GUICtrlCreateListView("Directories|Files", 2, 28, $GUI_WIDTH - 4, $GUI_HEIGHT - 32, -1, $extended_flags)

    $__g_GUITFTPDirList = GUICtrlCreateListView("Directories|Files", 2, 28, $GUI_WIDTH - 4, $GUI_HEIGHT - 32)
    _GUICtrlListView_SetExtendedListViewStyle($__g_GUITFTPDirList, $extended_flags)

 

Link to comment
Share on other sites

  • Moderators

pixelsearch,

As so often - good spot!

DStark,

It is always recommended to use _GUICtrlListView_SetExtendedListViewStyle rather than setting the extended style parameter when creating the ListView. MS, in their wisdom, made some of the extended ListView styles the same value as some of the extended GUI styles and Windows will interpret the value as the latter when used at creation time.

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

Sadly it does not work for my code.  It made it even worst.  Maybe I am missing something ?

Here the code that is working :

#include <WinAPIGdiDC.au3>
#include <GuiConstants.au3>
#include <WindowsConstants.au3>
#include <GuiTab.au3>
#include <WinAPIGdiDC.au3>
#include <GuiListView.au3>

Opt("MustDeclareVars", True)

Global Const $ODT_TAB = 101
Global Const $ODS_SELECTED = 1
Global Const $ODA_DRAWENTIRE = 1
Global Const $tagDRAWITEMSTRUCT = "uint cType;uint cID;uint itmID;uint itmAction;uint itmState;hwnd hItm;hwnd hDC;dword itmRect[4];dword itmData"

Global $hDCTab

Main()

Func Main()
  Local $hGUI = GUICreate("Draw Tabs", 300, 200)
  Local $idTab = GUICtrlCreateTab(10, 10, 280, 180, $TCS_OWNERDRAWFIXED)
  $hDCTab = _WinAPI_GetDC(GUICtrlGetHandle($idTab))

  Local $TabItem_1 = GUICtrlCreateTabItem("TabItem 1")
  CreateGUIItems("A")
  Local $TabItem_2 = GUICtrlCreateTabItem("TabItem 2")

  CreateGUIItems("B")
  GUICtrlCreateTabItem("")

  GUISetState()
  GUIRegisterMsg($WM_DRAWITEM, "WM_DRAWITEM")

  _GUICtrlTab_SetCurSel($idTab, 1)
  _GUICtrlTab_SetCurSel($idTab, 0)

  Do
  Until GUIGetMsg() = $GUI_EVENT_CLOSE
EndFunc   ;==>Main

Func WM_DRAWITEM($hWnd, $Msg, $wParam, $lParam)
  Local $tDrawItem = DllStructCreate($tagDRAWITEMSTRUCT, $lParam)
  If $tDrawItem.cType <> $ODT_TAB Then Return $GUI_RUNDEFMSG

  Local $itmID = DllStructGetData($tDrawItem, "itmID")
  Local $itmAction = DllStructGetData($tDrawItem, "itmAction")
  Local $hDC = DllStructGetData($tDrawItem, "hDC")

  If $itmAction <> $ODA_DRAWENTIRE Then Return $GUI_RUNDEFMSG
  Local $iTextColor, $itmText, $iBrushColor, $tRect
  Switch $itmID
    Case 0
      $iBrushColor = 0x11AADD
    Case 1
      $iBrushColor = 0xEEBB99
  EndSwitch

  _WinAPI_SetBkMode($hDC, 1)
  Local $iBrush = _WinAPI_CreateSolidBrush($iBrushColor)
  $tRect = DllStructCreate($tagRect, DllStructGetPtr($tDrawItem, "itmRect"))
  _WinAPI_FillRect($hDC, $tRect, $iBrush)

  Local $tBuffer = DllStructCreate("char[256]")
  DllStructSetData($tBuffer, 1, "Item" & $itmID)
  $itmText = DllStructGetData($tBuffer, 1)

  DllStructSetData($tDrawItem, "itmRect", DllStructGetData($tDrawItem, "itmRect", 1) + 10, 1)
  DllStructSetData($tDrawItem, "itmRect", DllStructGetData($tDrawItem, "itmRect", 2) + 5, 2)

  _WinAPI_DrawText($hDC, $itmText, $tRect, $DT_LEFT)
  $tRect = DllStructCreate($tagRect)
  $tRect.left = 2
  $tRect.top = 22
  $tRect.right = 278
  $tRect.bottom = 178

  _WinAPI_FillRect($hDCTab, $tRect, $iBrush)
  _WinAPI_DeleteObject($iBrush)

  Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_DRAWITEM

Func CreateGUIItems($sPrefix)
  Local $idListView = GUICtrlCreateListView("Directories", 15, 35, 170, 150, Default, BitOR($LVS_EX_GRIDLINES, $LVS_EX_INFOTIP))
  ;_GUICtrlListView_SetExtendedListViewStyle($idListView, BitOR($LVS_EX_GRIDLINES, $LVS_EX_INFOTIP, $LVS_EX_FULLROWSELECT))
  Local $sString
  For $i = 0 To 5
    $sString = ""
    For $c = 0 To 10 Step 1
      $sString &= Chr(65 + $i)
    Next
    GUICtrlCreateListViewItem($sPrefix & $i & "-" & $sString, $idListView)
  Next
EndFunc   ;==>CreateGUIItems

 

Link to comment
Share on other sites

@Nine maybe this ?

Func CreateGUIItems($sPrefix)
  ; Works
  ; Local $idListView = GUICtrlCreateListView("Directories", 15, 35, 170, 150, Default, BitOR($LVS_EX_GRIDLINES, $LVS_EX_INFOTIP))
  ; Local $idListView = GUICtrlCreateListView("Directories|Files", 15, 35, 170, 150, -1, BitOR($LVS_EX_GRIDLINES, $LVS_EX_INFOTIP))

  ; Doesn't work
  ; Local $idListView = GUICtrlCreateListView("Directories|Files", 15, 35, 170, 150, -1, BitOR($LVS_EX_GRIDLINES, $LVS_EX_INFOTIP, $LVS_EX_FULLROWSELECT))

  ; Works
  Local $iExStyle = ($sPrefix = "A") _
    ? BitOr($LVS_EX_GRIDLINES, $LVS_EX_INFOTIP, $LVS_EX_FULLROWSELECT) _
    : BitOr($LVS_EX_GRIDLINES, $LVS_EX_INFOTIP)
  Local $idListView = GUICtrlCreateListView("Directories|Files", 15, 35, 170, 150, -1, 0)
  _GUICtrlListView_SetExtendedListViewStyle($idListView, $iExStyle)  
  
  ...

 

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...