gadget state/text not updated with multiselect listicon

Just starting out? Need help? Post your questions and find answers here.
nsstudios
Enthusiast
Enthusiast
Posts: 274
Joined: Wed Aug 28, 2019 1:01 pm
Location: Serbia
Contact:

gadget state/text not updated with multiselect listicon

Post by nsstudios »

Hi,

After getting a report from a client that they're getting weird behavior when using home key to jump to the top of multiselect listicon, I made a test in which I noticed that holding control along with home//end/page up/page down/up arrow/down arrow, the gadget state and gadget text do not update.
I could not reproduce the same behavior with home, but sending the test program to the client, they could verify that they also get the same behavior with just home as we both get with control+home.
Is this perhaps a bug?
The only way I've found to "fix" it is to switch to the regular mode instead of the multiselect mode, which does then make it impossible to select multiple items, of course.
Here's a demo that has two listicons, one has multiselect enabled, another one doesn't.
The title gets updated with the currently focused gadget's state and text.

Code: Select all

OpenWindow(0, #PB_Ignore, #PB_Ignore, #PB_Ignore, #PB_Ignore, "test", #PB_Window_ScreenCentered|#PB_Window_Maximize)
ListIconGadget(0, 0, 0, 100, 100, "", 10, #PB_ListIcon_MultiSelect)
ListIconGadget(1, 200, 0, 100, 100, "", 10)
TextGadget(2, 0, 200, 100, 5, "multiselect")
TextGadget(3, 200, 200, 100, 5, "normal")
For i=0 To 100
AddGadgetItem(0, -1, ""+i)
AddGadgetItem(1, -1, ""+i)
Next

Repeat
e=WaitWindowEvent(1)
If GetActiveGadget()>=0
state=GetGadgetState(GetActiveGadget())
text$=GetGadgetText(GetActiveGadget())
If state<>oldstate
oldstate=state
SetWindowTitle(0, ""+state+", "+text$)
EndIf
EndIf
Until e=#PB_Event_CloseWindow
Thanks.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4636
Joined: Sun Apr 12, 2009 6:27 am

Re: gadget state/text not updated with multiselect listicon

Post by RASHAD »

Just tested Windows API ListView and got the same results as you mentioned
I think it is not a bug
Egypt my love
nsstudios
Enthusiast
Enthusiast
Posts: 274
Joined: Wed Aug 28, 2019 1:01 pm
Location: Serbia
Contact:

Re: gadget state/text not updated with multiselect listicon

Post by nsstudios »

Thanks Rashad for the reply and clarification.
Is there perhaps a reliable way of getting the currently selected item?
Preferably cross-platform, but I don't even know if other platforms act the same way (haven't had time to test).
User avatar
Paul
PureBasic Expert
PureBasic Expert
Posts: 1243
Joined: Fri Apr 25, 2003 4:34 pm
Location: Canada
Contact:

Re: gadget state/text not updated with multiselect listicon

Post by Paul »

If you are selecting multiple items, shouldn't you then be checking for the multiple items?

Code: Select all

OpenWindow(0, 0, 0, 300, 400, "test", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
ListIconGadget(0, 0, 0, 300, 400, "My List", 200, #PB_ListIcon_MultiSelect)

For i=0 To 100
  AddGadgetItem(0, -1, ""+i)
Next

Repeat
e=WaitWindowEvent()
Select e
  Case #PB_Event_Gadget 
    Select EventGadget()
      Case 0
        If EventType()=#PB_EventType_Change
          id$=""
          For tmp=0 To 100
            If GetGadgetItemState(0,tmp)
              id$+GetGadgetItemText(0,tmp)+" "
            EndIf            
          Next
          Debug id$
        EndIf        
        
    EndSelect  
    
EndSelect

Until e=#PB_Event_CloseWindow
Image Image
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4636
Joined: Sun Apr 12, 2009 6:27 am

Re: gadget state/text not updated with multiselect listicon

Post by RASHAD »

For Windows
Shardik can adapt it for Linux & Mac

Code: Select all

OpenWindow(0, #PB_Ignore, #PB_Ignore, #PB_Ignore, #PB_Ignore, "test", #PB_Window_ScreenCentered|#PB_Window_Maximize)

ListIconGadget(0, 0, 0, 100, 100, "", 10, #PB_ListIcon_MultiSelect)
ListIconGadget(1, 200, 0, 100, 100, "", 10)
TextGadget(2, 0, 200, 100, 5, "multiselect")
TextGadget(3, 200, 200, 100, 5, "normal")
For i=0 To 100
AddGadgetItem(0, -1, ""+i)
AddGadgetItem(1, -1, ""+i)
Next

Repeat
e=WaitWindowEvent(1)
If GetActiveGadget()>=0
  If GetAsyncKeyState_(#VK_CONTROL) <> 0
    keybd_event_(#VK_CONTROL,0,#KEYEVENTF_KEYUP,0)
  EndIf
state=GetGadgetState(GetActiveGadget())
text$=GetGadgetText(GetActiveGadget())
If state<>oldstate
oldstate=state
SetWindowTitle(0, ""+state+", "+text$)
EndIf
EndIf
Until e=#PB_Event_CloseWindow
Egypt my love
nsstudios
Enthusiast
Enthusiast
Posts: 274
Joined: Wed Aug 28, 2019 1:01 pm
Location: Serbia
Contact:

Re: gadget state/text not updated with multiselect listicon

Post by nsstudios »

@Paul, I wasn't trying to get the selected item, but the currently focused item in the list.
@Rashad, Wow, thanks! That works.
I'd still love to find a proper way to do it without messing with the keyboard...
breeze4me
Enthusiast
Enthusiast
Posts: 511
Joined: Thu Mar 09, 2006 9:24 am
Location: S. Kor

Re: gadget state/text not updated with multiselect listicon

Post by breeze4me »

nsstudios wrote:...... I'd still love to find a proper way to do it without messing with the keyboard...
This may be the more proper way you want.

Code: Select all

Procedure WindowCallback(hWnd, Message, wParam, lParam)
  Result = #PB_ProcessPureBasicEvents
  
  If Message = #WM_NOTIFY
    *lvn.NMLISTVIEW = lParam
    
    If *lvn\hdr\hwndFrom = GadgetID(0) And *lvn\hdr\code = #LVN_ITEMCHANGED
      
      If *lvn\iItem <> GetGadgetState(0) And *lvn\uNewState = #LVIS_FOCUSED And *lvn\uOldState = 0
      ;If *lvn\uNewState = #LVIS_FOCUSED And *lvn\uOldState = 0
        
        Debug "-------------------------"
        Debug *lvn\iItem
        Debug *lvn\uOldState
        Debug *lvn\uNewState
        Debug "-------------------------"
        
        ;SetGadgetItemState(0, *lvn\iItem, #PB_ListIcon_Selected)
        SetGadgetState(0, *lvn\iItem)
      EndIf
      
    EndIf
  EndIf
  
  ProcedureReturn Result
EndProcedure


OpenWindow(0, #PB_Ignore, #PB_Ignore, 600, 500, "test", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
ListIconGadget(0, 0, 0, 100, 100, "", 50, #PB_ListIcon_MultiSelect)
ListIconGadget(1, 200, 0, 100, 100, "", 50)
TextGadget(2, 0, 200, 100, 5, "multiselect")
TextGadget(3, 200, 200, 100, 5, "normal")

SetWindowCallback(@WindowCallback())

For i=0 To 100
  AddGadgetItem(0, -1, ""+i)
  AddGadgetItem(1, -1, ""+i)
Next

Repeat
  e=WaitWindowEvent(1)
  If GetActiveGadget()>=0
    state=GetGadgetState(GetActiveGadget())
    text$=GetGadgetText(GetActiveGadget())
    
    If state<>oldstate
      oldstate=state
      SetWindowTitle(0, ""+state+", "+text$)
    EndIf
  EndIf
  
Until e=#PB_Event_CloseWindow
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4636
Joined: Sun Apr 12, 2009 6:27 am

Re: gadget state/text not updated with multiselect listicon

Post by RASHAD »

@breeze4me
If the first item is selected within a combination of other keys and click Ctrl+Home nothing will happened (No Update)

As per MSDN recommendations

Code: Select all

Procedure.i SendKey (key.a)
   Protected send.Input
   
  send\type = #INPUT_KEYBOARD
  send\ki\wVk = key 
  send\ki\dwFlags = #KEYEVENTF_KEYUP
   
  ProcedureReturn SendInput_(1, @send, SizeOf(Input))
EndProcedure


OpenWindow(0, #PB_Ignore, #PB_Ignore, #PB_Ignore, #PB_Ignore, "test", #PB_Window_ScreenCentered|#PB_Window_Maximize)

ListIconGadget(0, 0, 0, 100, 100, "", 10, #PB_ListIcon_MultiSelect)
ListIconGadget(1, 200, 0, 100, 100, "", 10)
TextGadget(2, 0, 200, 100, 5, "multiselect")
TextGadget(3, 200, 200, 100, 5, "normal")
For i=0 To 100
AddGadgetItem(0, -1, ""+i)
AddGadgetItem(1, -1, ""+i)
Next

Repeat
e=WaitWindowEvent(1)
If GetActiveGadget()>=0
  If GetAsyncKeyState_(#VK_CONTROL) <> 0
    SendKey(#VK_CONTROL)
  EndIf
state=GetGadgetState(GetActiveGadget())
text$=GetGadgetText(GetActiveGadget())
If state<>oldstate
oldstate=state
SetWindowTitle(0, ""+state+", "+text$)
EndIf
EndIf
Until e=#PB_Event_CloseWindow
Egypt my love
nsstudios
Enthusiast
Enthusiast
Posts: 274
Joined: Wed Aug 28, 2019 1:01 pm
Location: Serbia
Contact:

Re: gadget state/text not updated with multiselect listicon

Post by nsstudios »

@Breeze4me, thanks for another example, however the callback somehow results in the list losing its multiselectability.
I guess I'll just have to resort to a non-multiselect listicon instead and worry about selecting later.
Maybe I can do it manually.
breeze4me
Enthusiast
Enthusiast
Posts: 511
Joined: Thu Mar 09, 2006 9:24 am
Location: S. Kor

Re: gadget state/text not updated with multiselect listicon

Post by breeze4me »

The following code shows how to ignore the control key down when certain keys are pressed, but it doesn't ignore Ctrl + click combination.

Code: Select all

Global OldWndProc

Structure ByteArray
  b.b[256]
EndStructure

Procedure WindowCallback(hWnd, Message, wParam, lParam)
  Protected keys.ByteArray
  
  If Message = #WM_KEYDOWN
    
    Select wParam
      Case #VK_UP, #VK_DOWN, #VK_PRIOR, #VK_NEXT, #VK_HOME, #VK_END
        
        If GetKeyState_(#VK_CONTROL) & $8000
          
          If GetKeyboardState_(@keys)
            keys\b[#VK_CONTROL] & $7F
            SetKeyboardState_(@keys)
          EndIf
          
        EndIf
        
    EndSelect
    
  EndIf
  
  ProcedureReturn CallWindowProc_(OldWndProc, hWnd, Message, wParam, lParam)
EndProcedure

OpenWindow(0, #PB_Ignore, #PB_Ignore, 600, 500, "test", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
ListIconGadget(0, 0, 0, 100, 400, "", 50, #PB_ListIcon_MultiSelect)
ListIconGadget(1, 200, 0, 100, 100, "", 50)

OldWndProc = SetWindowLongPtr_(GadgetID(0), #GWLP_WNDPROC, @WindowCallback())

For i=0 To 100
  AddGadgetItem(0, -1, ""+i)
  AddGadgetItem(1, -1, ""+i)
Next

Repeat
  e=WaitWindowEvent(1)
  If GetActiveGadget()>=0
    state=GetGadgetState(GetActiveGadget())
    text$=GetGadgetText(GetActiveGadget())
    
    If state<>oldstate
      oldstate=state
      SetWindowTitle(0, ""+state+", "+text$)
    EndIf
  EndIf
Until e=#PB_Event_CloseWindow
Post Reply