Page 1 of 2

ListIconGadget - Callback procedure to detect column header

Posted: Wed May 21, 2003 12:10 pm
by Mike
Hi,
after searching and reading a lot of staff in the forums I would like to setup two questions, as I'm still learning to use PB in the right way. My question is related to the ListIconGadget which I'm using as a "FlexGrid" to display a small snapshot out of a sqlite-database.

Currently I'm searching to find a solution for...

a) How can I setup a Callback procedure that can regognize, which column header was clicked by a user in the ListIconGadget ?

b) How can I determine, which row was selected by the user (click by the user somewhere in the Gadget) ?

Does anybody know, if that is possible and maybe could share the code with the community ?

THANKS !!!
Michael

Posted: Wed May 21, 2003 12:38 pm
by freak
Did you allready read this topic?
viewtopic.php?t=6085&highlight=flexgrid

To set up a Callback, use the SetWindowCallback() command. Have a look
at the help of this command, to see how the procedure must look like.
PB has only one callback procedure, but it will receive all events, so also
the ones from the ListIconGadget.

Timo

Posted: Wed May 21, 2003 12:57 pm
by Mike
Hi Timo,

thanks and yes...I've read that post before, but unfortunately it's not solving my problems. :(

(I'm also familiar how to setup the callback, but the problem is really,
how to determine the 'right events' for a+b.)

Regards,
Mike

Posted: Wed May 21, 2003 1:08 pm
by gnozal
I think you get the selected line with GetGadgetState(#ListIconGadget).
I don't know how to get the selected column either, sorry :(

Posted: Wed May 21, 2003 1:39 pm
by freak
Here is a example that shows how it's done:

Code: Select all

#ListIcon = 1

Procedure Callback(Window.l, Message.l, wParam.l, lParam.l)
  result = #PB_ProcessPureBasicEvents
  
  Select Message
  
    Case #WM_NOTIFY        ; these events are send as notification messages
      *pnmh.NMHDR = lParam  ; lParam points to a structure with more info
      
      If *pnmh\hwndFrom = GadgetID(#ListIcon) ; see if it is the right gadget
      
        Select *pnmh\code  ; code contains actual message
        
          Case #LVN_COLUMNCLICK ; user clicked on the Header of a column
            *pnmv.NMLISTVIEW = lParam ; another info structure
            
            Column.l = *pnmv\iSubItem ; clicked column
            
            MessageRequester("Column Header Click","Clicked on Column "+Str(Column),0)
            
          Case #NM_CLICK  ; user clicked in the ListView
            *lpnmitem.NMITEMACTIVATE = lParam
            
            Row.l = *lpnmitem\iItem
            Column.l = *lpnmitem\iSubItem
            
            MessageRequester("Listview Click","Row: "+Str(Row)+" Column: "+Str(Column), 0)
            
            ; there is also
            ; #NM_DBLCLK  - doublecklick
            ; #NM_RCLICK  - right button
            ; #NM_RDBLCLK - right doubleclick
            ; they work the same as #NM_CLICK
          
        
        EndSelect 
      
      EndIf 
  
  EndSelect
  
  ProcedureReturn result
EndProcedure

If OpenWindow(0,0,0,400,400,#PB_Window_Screencentered|#PB_Window_SystemMenu, "Listicon test...")
  If CreateGadgetList(WindowID())
  
    ListIconGadget(#ListIcon, 10, 10, 380, 380, "Column0", 100,#PB_ListIcon_FullRowSelect)
    ; Fullrowselect must be set, because otherwiese only the first
    ; column will be clickable
    
    AddGadgetColumn(#ListIcon, 1, "Column1", 100)
    AddGadgetColumn(#ListIcon, 1, "Column2", 100)
    
    AddGadgetItem(#ListIcon, 0, "Row0"+Chr(10)+"XXX"+Chr(10)+"XXX")
    AddGadgetItem(#ListIcon, 1, "Row1"+Chr(10)+"XXX"+Chr(10)+"XXX")
    AddGadgetItem(#ListIcon, 2, "Row2"+Chr(10)+"XXX"+Chr(10)+"XXX")
    AddGadgetItem(#ListIcon, 3, "Row3"+Chr(10)+"XXX"+Chr(10)+"XXX")

    SetWindowCallback(@Callback())
  
    Repeat
    Until WaitWindowEvent() = #PB_EventCloseWindow

  EndIf
EndIf

End
Hope that helps, if not just ask...

Timo

Posted: Wed May 21, 2003 2:26 pm
by Mike
Timo,

GREAT...(that's what I'm looking for)....but could you please so kind to add the needed structures ?

I'm getting some compiler messages (*lpnmitem.NMITEMACTIVATE = lParam) Structure not found NMITEMACTIVATE

Thanks,
Mike

Posted: Wed May 21, 2003 2:42 pm
by gnozal
Nice examples, thanks.
Would be a lot easier if there were purebasic events rather than doing it with API stuff (Purebasic 4.0 ? :wink:)

Posted: Wed May 21, 2003 5:04 pm
by Mike
All,

I was able to find the missing Structures by use of the MSDN and want to share it with use....copy this structures into the code and then it works perfect... :wink:

Structure NMLISTVIEW
hdr.NMHDR
iItem.l
iSubItem.l
uNewState.l
uOldState.l
uChanged.l
ptAction.POINT
lParam.l
EndStructure

Structure NMITEMACTIVATE
hdr.NMHDR
iItem.l
iSubItem.l
uNewState.l
uOldState.l
uChanged.l
ptAction.POINT
lParam.l
uKeyFlags.l
EndStructure

Again Thanks to Timo providing the Code
Mike

Posted: Wed May 21, 2003 5:14 pm
by freak
Sorry about the Structures.

These were missing in PB's structure declarations, and I just added them
recently, that's why I allready have them predefined, and you don't :wink:

With PB 3.70, they will all be there.

Timo

Posted: Thu May 22, 2003 12:55 am
by Fangbeast

second collumn should be 2 :):)

Code: Select all

    AddGadgetColumn(#ListIcon, 2, "Column2", 100)

This is probably a better idea for positioning items rather than absolute reference.

Code: Select all

    AddGadgetItem(#ListIcon, -1, "Row0"+Chr(10)+"XXX"+Chr(10)+"XXX")

sorry to be a pain

Posted: Thu May 22, 2003 9:35 am
by freak
Image

Damn Copy&Paste Errors! :wink:

Posted: Thu May 22, 2003 7:57 pm
by Mike
Hi,

the code works fine in my application now, but I'm still looking for some funny staff. :lol:

Does anybody knows, what should to be added to the code to determine the x,y, width and height (or x2,y2) of the selected cell ?

Thanks (I'm happy having decided to work with PB and this team !)
Mike

Posted: Thu May 22, 2003 8:35 pm
by El_Choni
In the ListGadget callback (NOT in the window callback!):

Code: Select all

    Case #WM_LBUTTONDOWN
        pInfo.LVHITTESTINFO
        pInfo\pt\x = lParam&$FFFF
        pInfo\pt\y = lParam>>16
        SendMessage_(hWnd, #LVM_SUBITEMHITTEST, 0, pInfo)
        rc.RECT
        rc\top = pInfo\iSubItem
        rc\left = #LVIR_BOUNDS
        SendMessage_(hWnd, #LVM_GETSUBITEMRECT, pInfo\iItem, rc)
        ; now rc holds coords relative to ListGadget topleft corner

Posted: Fri May 23, 2003 2:04 pm
by Mike
Hi El,

I don't get it run, do you have maybe a little bid more complete example ?

Thanks,
Mike

Posted: Fri May 23, 2003 4:32 pm
by El_Choni
Hadn't checked Freak's code, much better for this example. Here it is, reporting subitem x and y pixel coords:

Code: Select all

#ListIcon = 1 
#LVM_GETSUBITEMRECT = #LVM_FIRST+56

Structure NMLISTVIEW 
  hdr.NMHDR 
  iItem.l 
  iSubItem.l 
  uNewState.l 
  uOldState.l 
  uChanged.l 
  ptAction.POINT 
  lParam.l 
EndStructure 

Structure NMITEMACTIVATE 
  hdr.NMHDR 
  iItem.l 
  iSubItem.l 
  uNewState.l 
  uOldState.l 
  uChanged.l 
  ptAction.POINT 
  lParam.l 
  uKeyFlags.l 
EndStructure 
                       
Procedure Callback(Window.l, Message.l, wParam.l, lParam.l) 
  result = #PB_ProcessPureBasicEvents 
  Select Message 
    Case #WM_NOTIFY        ; these events are send as notification messages 
      *pnmh.NMHDR = lParam  ; lParam points to a structure with more info
      If *pnmh\hwndFrom = GadgetID(#ListIcon) ; see if it is the right gadget 
        Select *pnmh\code  ; code contains actual message 
          Case #LVN_COLUMNCLICK ; user clicked on the Header of a column 
            *pnmv.NMLISTVIEW = lParam ; another info structure 
            Column.l = *pnmv\iSubItem ; clicked column 
            MessageRequester("Column Header Click","Clicked on Column"+Str(Column),0) 
          Case #NM_CLICK  ; user clicked in the ListView 
            *lpnmitem.NMITEMACTIVATE = lParam 
            Row.l = *lpnmitem\iItem 
            Column.l = *lpnmitem\iSubItem 
            ; there is also 
            ; #NM_DBLCLK  - doublecklick 
            ; #NM_RCLICK  - right button 
            ; #NM_RDBLCLK - right doubleclick 
            ; they work the same as #NM_CLICK 
            rc.RECT 
            rc\top = Column 
            rc\left = #LVIR_BOUNDS 
            SendMessage_(*pnmh\hwndFrom, #LVM_GETSUBITEMRECT, Row, rc) 
            ; now rc holds coords relative to ListGadget topleft corner 
            MessageRequester("Listview Click","Row: "+Str(Row)+" Column: "+Str(Column)+Chr(10)+"Item left: "+Str(rc\left)+" Item top: "+Str(rc\top-1), 0) 
        EndSelect 
      EndIf 
  EndSelect 
  ProcedureReturn result 
EndProcedure 

If OpenWindow(0,0,0,400,400,#PB_Window_Screencentered|#PB_Window_SystemMenu, "Listicon test...") 
  If CreateGadgetList(WindowID()) 
    ListIconGadget(#ListIcon, 10, 10, 380, 380, "Column0",100,#PB_ListIcon_FullRowSelect) 
    ; Fullrowselect must be set, because otherwiese only the first 
    ; column will be clickable 
    AddGadgetColumn(#ListIcon, 1, "Column1", 100) 
    AddGadgetColumn(#ListIcon, 1, "Column2", 100) 
    AddGadgetItem(#ListIcon, 0, "Row0"+Chr(10)+"XXX"+Chr(10)+"XXX") 
    AddGadgetItem(#ListIcon, 1, "Row1"+Chr(10)+"XXX"+Chr(10)+"XXX") 
    AddGadgetItem(#ListIcon, 2, "Row2"+Chr(10)+"XXX"+Chr(10)+"XXX") 
    AddGadgetItem(#ListIcon, 3, "Row3"+Chr(10)+"XXX"+Chr(10)+"XXX") 
    SetWindowCallback(@Callback()) 
    Repeat 
    Until WaitWindowEvent() = #PB_EventCloseWindow 
  EndIf 
EndIf 
End