Page 1 of 1

[SOLVED] No notification of listicongadget header click, if it's inside PanelGadget

Posted: Fri May 05, 2023 2:09 pm
by Caronte3D
Until now I have used this code to sort the ListIconGadget lines clicking on her header, works nice, but my ListIconGadget is inside a PanelGadget and now not work anymore, Don't know since what version, but not work with the PB 6.02 beta 2-3.
To test it, un comment the 3 lines indicated afterOpenWindow.

EDIT: With the PB 6.01 LTS works nice (as expected).

Code: Select all

; English forum:
; Author: Unknown (updated for PB 4.00 by netmaestro)
; Date: 31. December 2002
; OS: Windows
; Demo: No

Structure PB_ListIconItem
  UserData.l
EndStructure

#LVM_SETEXTENDEDLISTVIEWSTYLE                      = #LVM_FIRST + 54
#LVM_GETEXTENDEDLISTVIEWSTYLE                      = #LVM_FIRST + 55
Global Buffer1.l, Buffer2.l, lvi.LV_ITEM, updown.l = 1, lastcol.l = 0
Buffer1                                            = AllocateMemory(128)
Buffer2                                            = AllocateMemory(128)

Procedure CompareFunc(*item1.PB_ListIconItem, *item2.PB_ListIconItem, lParamSort)
  result         = 0
  lvi\iSubItem   = lParamSort
  lvi\pszText    = Buffer1
  lvi\cchTextMax = 512
  lvi\Mask       = #LVIF_TEXT
  SendMessage_(GadgetID(0), #LVM_GETITEMTEXT, *item1\UserData, @lvi)
  lvi\pszText = Buffer2
  SendMessage_(GadgetID(0), #LVM_GETITEMTEXT, *item2\UserData, @lvi)
  Seeker1 = Buffer1
  Seeker2 = Buffer2
  done    = 0
  While done = 0
    char1  = Asc(UCase(Chr(PeekB(Seeker1))))
    char2  = Asc(UCase(Chr(PeekB(Seeker2))))
    result = (char1 - char2) * updown
    If result <> 0 Or (Seeker1 - Buffer1) > 511
      done = 1
    EndIf
    Seeker1 + 1
    Seeker2 + 1
  Wend
  ProcedureReturn result
EndProcedure

Procedure UpdatelParam()
  Protected i.l, lRecs.l
  lRecs = SendMessage_(GadgetID(0), #LVM_GETITEMCOUNT, 0, 0)
  For i = 0 To lRecs - 1
    SetGadgetItemData(GetDlgCtrlID_(GadgetID(0)), i, i)
  Next
EndProcedure


Procedure ColumnClickCallback(hwnd, msg, wParam, lParam)
  result = #PB_ProcessPureBasicEvents
  Select msg
    Case #WM_NOTIFY
      *msg.NMHDR = lParam
      If *msg\hwndFrom = GadgetID(0) And *msg\code = #LVN_COLUMNCLICK
        *pnmv.NM_LISTVIEW = lParam
        If lastcol <> *pnmv\iSubItem
          updown = 1
        EndIf
        SendMessage_(GadgetID(0), #LVM_SORTITEMS, *pnmv\iSubItem, @CompareFunc())
        UpdatelParam()
        UpdateWindow_(GadgetID(0))
        lastcol = *pnmv\iSubItem
        updown  = - updown
        Debug GetGadgetItemData(0, 0)
        Debug GetGadgetItemData(0, 1)
        Debug GetGadgetItemData(0, 2)
      EndIf
    Case #WM_SIZE
      If hwnd = WindowID(0) And IsIconic_(hwnd) = 0
        WindowWidth  = lParam & $FFFF
        WindowHeight = lParam >> 16
        ResizeGadget(0, 0, 0, WindowWidth, WindowHeight)
        result = 1
      EndIf
  EndSelect
  
  ProcedureReturn result
EndProcedure

If OpenWindow(0, 384, 288, 640, 480, "ListIconGadget sort example", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget)
  LVWidth  = WindowWidth(0)
  LVCWidth = Int(LVWidth / 4) - 1
  
;  PanelGadget(2,0,0,LVWidth,WindowHeight(0)) ; >>>>>>>>>  UNCOMMENT THIS 3 LINES AND YOU CAN'T SORT THE LISTICONGADGET COLUMNS
;  AddGadgetItem(2, -1, " INFO")              ; >>>>>>>>>  UNCOMMENT THIS 3 LINES AND YOU CAN'T SORT THE LISTICONGADGET COLUMNS
  
  ListIconGadget(0, 0, 0, LVWidth, WindowHeight(0), "Column 0", LVCWidth, #PB_ListIcon_GridLines | #PB_ListIcon_FullRowSelect)
  AddGadgetColumn(0, 1, "Column 1", LVCWidth)
  AddGadgetColumn(0, 2, "Column 2", LVCWidth)
  AddGadgetColumn(0, 3, "Column 3", LVCWidth)
  
;  CloseGadgetList()                          ; >>>>>>>>>  UNCOMMENT THIS 3 LINES AND YOU CAN'T SORT THE LISTICONGADGET COLUMNS
  
  AddGadgetItem(0, 0, "Aaa 1" + Chr(10) + "Bcc 3" + Chr(10) + "Cdd 2" + Chr(10) + "Eee 3" + Chr(10), 0)
  AddGadgetItem(0, 1, "Aab 2" + Chr(10) + "Bbc 2" + Chr(10) + "Ddd 3" + Chr(10) + "Dde 1" + Chr(10), 0)
  AddGadgetItem(0, 2, "Abb 3" + Chr(10) + "Baa 1" + Chr(10) + "Ccd 1" + Chr(10) + "Dee 2" + Chr(10), 0)
  SetGadgetItemData(0, 0, 0)
  SetGadgetItemData(0, 1, 1)
  SetGadgetItemData(0, 2, 2)
  UpdatelParam()
  SetWindowCallback(@ColumnClickCallback())
  
  Repeat
    EventID = WaitWindowEvent()
  Until EventID = #PB_Event_CloseWindow
EndIf

FreeMemory(Buffer1)
FreeMemory(Buffer2)
End

Re: No notification of listicongadget header click, if it's inside PanelGadget

Posted: Fri May 05, 2023 3:52 pm
by Fred
WM_NOTIFY is sent to the parent window, not to the root window. It was 'luckily' working before, but the bug has been fixed so you need to attach your callback to the panelgadget item (it also works properly on 64-bit):

Code: Select all

; English forum:
; Author: Unknown (updated for PB 4.00 by netmaestro)
; Date: 31. December 2002
; OS: Windows
; Demo: No

Structure PB_ListIconItem
  UserData.i
EndStructure

Global Buffer1, Buffer2, lvi.LV_ITEM, updown = 1, lastcol = 0
Buffer1                                            = AllocateMemory(1024)
Buffer2                                            = AllocateMemory(1024)

Global OldListViewCallback

Procedure CompareFunc(*item1.PB_ListIconItem, *item2.PB_ListIconItem, lParamSort)
  result         = 0
  lvi\iSubItem   = lParamSort
  lvi\pszText    = Buffer1
  lvi\cchTextMax = 512
  lvi\Mask       = #LVIF_TEXT
  SendMessage_(GadgetID(0), #LVM_GETITEMTEXT, *item1\UserData, @lvi)
  lvi\pszText = Buffer2
  SendMessage_(GadgetID(0), #LVM_GETITEMTEXT, *item2\UserData, @lvi)
  Seeker1 = Buffer1
  Seeker2 = Buffer2
  done    = 0
  While done = 0
    char1  = Asc(UCase(Chr(PeekB(Seeker1))))
    char2  = Asc(UCase(Chr(PeekB(Seeker2))))
    result = (char1 - char2) * updown
    If result <> 0 Or (Seeker1 - Buffer1) > 511
      done = 1
    EndIf
    Seeker1 + 1
    Seeker2 + 1
  Wend
  ProcedureReturn result
EndProcedure

Procedure UpdatelParam()
  Protected i, lRecs
  lRecs = SendMessage_(GadgetID(0), #LVM_GETITEMCOUNT, 0, 0)
  For i = 0 To lRecs - 1
    SetGadgetItemData(GetDlgCtrlID_(GadgetID(0)), i, i)
  Next
EndProcedure


Procedure ColumnClickCallback(hwnd, msg, wParam, lParam)
  
  Select msg
    Case #WM_NOTIFY
      *msg.NMHDR = lParam
      If *msg\hwndFrom = GadgetID(0) And *msg\code = #LVN_COLUMNCLICK
        *pnmv.NM_LISTVIEW = lParam
        If lastcol <> *pnmv\iSubItem
          updown = 1
        EndIf
        SendMessage_(GadgetID(0), #LVM_SORTITEMS, *pnmv\iSubItem, @CompareFunc())
        UpdatelParam()
        UpdateWindow_(GadgetID(0))
        lastcol = *pnmv\iSubItem
        updown  = - updown
        Debug GetGadgetItemData(0, 0)
        Debug GetGadgetItemData(0, 1)
        Debug GetGadgetItemData(0, 2)
      EndIf
    Case #WM_SIZE
      If hwnd = WindowID(0) And IsIconic_(hwnd) = 0
        WindowWidth  = lParam & $FFFF
        WindowHeight = lParam >> 16
        ResizeGadget(0, 0, 0, WindowWidth, WindowHeight)
        result = 1
      EndIf
  EndSelect
  
  ProcedureReturn CallWindowProc_(OldListViewCallback, hwnd, msg, wParam, lParam)
EndProcedure

If OpenWindow(0, 384, 288, 640, 480, "ListIconGadget sort example", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget)
  LVWidth  = WindowWidth(0)
  LVCWidth = Int(LVWidth / 4) - 1
  
  PanelGadget(2,0,0,LVWidth,WindowHeight(0)) ; >>>>>>>>>  UNCOMMENT THIS 3 LINES AND YOU CAN'T SORT THE LISTICONGADGET COLUMNS
  AddGadgetItem(2, -1, " INFO")              ; >>>>>>>>>  UNCOMMENT THIS 3 LINES AND YOU CAN'T SORT THE LISTICONGADGET COLUMNS
  
  ListIconGadget(0, 0, 0, LVWidth, WindowHeight(0), "Column 0", LVCWidth, #PB_ListIcon_GridLines | #PB_ListIcon_FullRowSelect)
  AddGadgetColumn(0, 1, "Column 1", LVCWidth)
  AddGadgetColumn(0, 2, "Column 2", LVCWidth)
  AddGadgetColumn(0, 3, "Column 3", LVCWidth)
  
  ; Get the Panel Item handle
  ;
  Item.TC_ITEM\mask = #TCIF_PARAM;
  SendMessage_(GadgetID(2), #TCM_GETITEM, 0, @Item)
  PanelItemHandle = Item\lParam
  
  ; Attach the callback to it
  OldListViewCallback = SetWindowLongPtr_(PanelItemHandle, #GWLP_WNDPROC, @ColumnClickCallback())
  
  CloseGadgetList()                          ; >>>>>>>>>  UNCOMMENT THIS 3 LINES AND YOU CAN'T SORT THE LISTICONGADGET COLUMNS
  
  AddGadgetItem(0, 0, "Aaa 1" + Chr(10) + "Bcc 3" + Chr(10) + "Cdd 2" + Chr(10) + "Eee 3" + Chr(10), 0)
  AddGadgetItem(0, 1, "Aab 2" + Chr(10) + "Bbc 2" + Chr(10) + "Ddd 3" + Chr(10) + "Dde 1" + Chr(10), 0)
  AddGadgetItem(0, 2, "Abb 3" + Chr(10) + "Baa 1" + Chr(10) + "Ccd 1" + Chr(10) + "Dee 2" + Chr(10), 0)
  SetGadgetItemData(0, 0, 0)
  SetGadgetItemData(0, 1, 1)
  SetGadgetItemData(0, 2, 2)
  UpdatelParam()
  
  
  Repeat
    EventID = WaitWindowEvent()
  Until EventID = #PB_Event_CloseWindow
EndIf

FreeMemory(Buffer1)
FreeMemory(Buffer2)
End

Re: No notification of listicongadget header click, if it's inside PanelGadget

Posted: Fri May 05, 2023 5:02 pm
by Caronte3D
Ok, but...
If I have several Panels I can repeat your example for everyone?
Also, until now I have a WindowCallback to process another things related to the main window, so I can use it too?
As you can notice, I don't understand to much about callbacks :D

EDIT: I answer my self :D Yes, I can keep my WindowCallback for other tasks.

Re: [SOLVED] No notification of listicongadget header click, if it's inside PanelGadget

Posted: Fri May 05, 2023 6:57 pm
by jacdelad
@Caronte3D: Maybe GetActiveGadget()?

Re: [SOLVED] No notification of listicongadget header click, if it's inside PanelGadget

Posted: Fri May 05, 2023 9:56 pm
by Caronte3D
I think no, but i will take a look