Please try the cross-platform code example below which detects the clicked header column and the clicked row. I have tested it successfully on these operating systems:CONVERT wrote:Freak's code works fine with PB 5.21, but it is Windows specific.
For Linux or Macintosh, I tried to see how to use BindEvent, but I did not find yet how to detect the column. It is not urgent, but I would like to use it in future versions of my application for Linux or Mac.
Thanks if you have any idea.
- Debian 7 x86 with Gnome 3
- Fedora 20 x86 with Gnome 3
- Kubuntu 13.10 x86 with KDE
- Linux Mint 16 x86 with Cinnamon
- Lubuntu 13.10 x86 with LXDE
- MacOS X 10.6.8 (Snow Leopard) with PB 5.21 x86 and x64 in ASCII and unicode mode
- MacOS X 10.9.2 (Mavericks)
- OpenSUSE 13.1 with KDE
- PCLinuxOS x86 with KDE
- PearOS 8 x86 with a heavily modified Gnome 3
- Ubuntu 10.04 LTS x86 with Gnome 2
- Ubuntu 12.04 LTS x64 with KDE
- Ubuntu 12.04 LTS x64 with Unity
- Ubuntu 12.04 LTS x64 with Enlightenment
- Windows XP SP3 x86
- Windows 7 SP1 x64
- Xubuntu 13.10 x86 with Xfce
Code: Select all
EnableExplicit
Structure CallbackEntry
  WindowID.I
  ListIconID.I
  DefaultCallback.I
EndStructure
NewList CallbackEntry.CallbackEntry()
CompilerSelect #PB_Compiler_OS
  CompilerCase #PB_OS_Linux ; ------------------------------------------------
    ProcedureC ColumnHeaderClickCallback(*Column, ListIconData.I)
      Shared CallbackEntry()
      ForEach CallbackEntry()
        If ListIconData >> 16 = CallbackEntry()\ListIconID
          Break
        EndIf
      Next
      PostEvent(#PB_Event_Gadget, CallbackEntry()\WindowID,
        CallbackEntry()\ListIconID, #PB_EventType_LeftClick,
        (ListIconData & $FFFF) + 1)
    EndProcedure
    Procedure SetGadgetCallback(WindowID.I, ListIconID.I)
      Shared CallbackEntry()
      Protected Column.I
      Protected ColumnCount.I
      Protected ColumnIndex.I
      Protected *ListStore.GtkListStore
      AddElement(CallbackEntry())
      CallbackEntry()\WindowID = WindowID
      CallbackEntry()\ListIconID = ListIconID
      gtk_tree_view_set_headers_clickable_(GadgetID(ListIconID), #True)
      *ListStore = gtk_tree_view_get_model_(GadgetID(ListIconID))
      ColumnCount = (*ListStore\n_columns - 3) / 3
      For ColumnIndex = 0 To ColumnCount - 1
        Column = gtk_tree_view_get_column_(GadgetID(CallbackEntry()\ListIconID),
          ColumnIndex)
        If Column
          g_signal_connect_data_(Column, "clicked",
            @ColumnHeaderClickCallback(), ListIconID << 16 | ColumnIndex, 0, 0)
        EndIf
      Next ColumnIndex
    EndProcedure
  CompilerCase #PB_OS_MacOS ; ------------------------------------------------
    ImportC ""
      sel_registerName(MethodName.S)
      class_addMethod(Class.I, Selector.I, Implementation.I, Types.S)
    EndImport
    Procedure.S ConvertToUTF8(String.S)
      Protected UTF8String.S = Space(StringByteLength(String))
      PokeS(@UTF8String, String, -1, #PB_UTF8)
      ProcedureReturn UTF8String
    EndProcedure
   
    ProcedureC ColumnHeaderClickCallback(Object.I, Selector.I, TableView.I,
      TableColumn.I)
      Shared CallbackEntry()
      Protected ClickedHeaderColumn.I
 
      ForEach CallbackEntry()
        If TableView = GadgetID(CallbackEntry()\ListIconID)
          Break
        EndIf
      Next
    
      ClickedHeaderColumn = Val(PeekS(CocoaMessage(0,
        CocoaMessage(0, TableColumn, "identifier"),
        "UTF8String"), -1, #PB_UTF8))
      PostEvent(#PB_Event_Gadget, CallbackEntry()\WindowID,
        CallbackEntry()\ListIconID, #PB_EventType_LeftClick,
        ClickedHeaderColumn + 1)
    EndProcedure
   
    Procedure SetGadgetCallback(WindowID.I, ListIconID.I)
      Shared CallbackEntry()
     
      Protected AppDelegate.I
      Protected DelegateClass.I
      Protected Selector.I = sel_registerName(ConvertToUTF8("tableView:didClickTableColumn:"))
      Protected Types.S = ConvertToUTF8("v@:@@")
      AddElement(CallbackEntry())
      CallbackEntry()\WindowID = WindowID
      CallbackEntry()\ListIconID = ListIconID
      AppDelegate = CocoaMessage(0,
        CocoaMessage(0, 0, "NSApplication sharedApplication"), "delegate")
      DelegateClass = CocoaMessage(0, AppDelegate, "class")
      class_addMethod(DelegateClass, Selector, @ColumnHeaderClickCallback(),
        Types)
      CocoaMessage(0, GadgetID(CallbackEntry()\ListIconID),
        "setDelegate:", AppDelegate)
    EndProcedure
  CompilerCase #PB_OS_Windows ; ----------------------------------------------
    Procedure ColumnHeaderClickCallback(WindowHandle.I, Msg.I, WParam.I,
      LParam.I)
      Shared CallbackEntry()
      Protected Result.I
      Protected *Header.HD_NOTIFY
      ForEach CallbackEntry()
        If WindowHandle = GadgetID(CallbackEntry()\ListIconID)
          Break
        EndIf
      Next
      Result = CallWindowProc_(CallbackEntry()\DefaultCallback, WindowHandle,
        Msg, WParam, LParam)
      If Msg = #WM_NOTIFY
        *Header = LParam
        If *Header\hdr\code = #HDN_ITEMCLICK
          PostEvent(#PB_Event_Gadget, CallbackEntry()\WindowID,
            CallbackEntry()\ListIconID, #PB_EventType_LeftClick,
            *Header\iItem + 1)
        EndIf
      EndIf
      ProcedureReturn Result
    EndProcedure
    Procedure SetGadgetCallback(WindowID.I, ListIconID.I)
      Shared CallbackEntry()
      AddElement(CallbackEntry())
      CallbackEntry()\WindowID = WindowID
      CallbackEntry()\ListIconID = ListIconID
      CallbackEntry()\DefaultCallback = SetWindowLongPtr_(GadgetID(CallbackEntry()\ListIconID),
        #GWL_WNDPROC, @ColumnHeaderClickCallback())
    EndProcedure ; -----------------------------------------------------------
CompilerEndSelect
OpenWindow(0, 200, 100, 450, 150, "Detect left click on header cell")
ListIconGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20, "Name",
  110, #PB_ListIcon_FullRowSelect)
AddGadgetColumn(0, 1, "Address", 300)
AddGadgetItem(0, -1, "Harry Rannit" + #LF$ +
  "12 Parliament Way, Battle Street, By the Bay")
AddGadgetItem(0, -1, "Ginger Brokeit"+ #LF$ +
  "130 PureBasic Road, BigTown, CodeCity")
AddGadgetItem(0, -1, "Didi Foundit"+ #LF$ +
  "321 Logo Drive, Mouse House, Downtown")
SetGadgetCallback(0, 0)
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 0 And EventType() = #PB_EventType_LeftClick
        If EventData()
          Debug "Left click on header of column " + Str(EventData() - 1)
        Else
          Debug "Left click on row " + Str(GetGadgetState(0))
        EndIf
      EndIf
  EndSelect
ForEver
