Page 1 of 1

PB list in win32 enumeration callback?

Posted: Tue Jun 13, 2023 3:47 am
by Rinzwind
Any way to make this work without an extra container structure? Too bad it is not supported. It does compile, just errors out because it passes the value of the list element, instead of the list object itself (which PB does do in a normal procudure call).

Code: Select all

EnableExplicit

Structure Window
  Handle.i
  Title.s
EndStructure

Procedure EnumProc(hw, List lp.Window())
  If IsWindowVisible_(hw)
    AddElement(lp())
    lp()\Handle = hw
    ;...
  EndIf
  
  ProcedureReturn #True
EndProcedure


Procedure EnumProc2(hw, List *lp.Window())
  If IsWindowVisible_(hw)
    AddElement(*lp())
    Define *s.Window = AllocateStructure(Window)
    *s\Handle = hw
    ;...
    *lp() = *s
  EndIf
  
  ProcedureReturn #True
EndProcedure

NewList wlist.Window()
; Global w.Window
; w\Handle = 1
; w\Title = "Test"
; AddElement(wlist())
; wlist() = w

; EnumWindows_(@EnumProc(), wlist())

NewList *wlist.Window()
EnumProc2(GetDesktopWindow_(), *wlist()) ; works fine
EnumWindows_(@EnumProc2(), *wlist()) ; crashes because the list is not provided

Re: PB list in win32 enumeration callback?

Posted: Tue Jun 13, 2023 4:29 am
by jassing
maybe? (quick & dirty)

Code: Select all

EnableExplicit

Structure Window
  Handle.i
  Title.s{1024}
EndStructure

Procedure EnumProc(hw, List lp.Window())
  If IsWindowVisible_(hw)
    AddElement(lp())
    lp()\Handle = hw
    ;...
  EndIf
  
  ProcedureReturn #True
EndProcedure

Global NewList wlist()

Procedure EnumProc2(hw, nul)
  If IsWindowVisible_(hw)
    AddElement(wlist())
    Define *s.Window = AllocateMemory(SizeOf(Window))
    *s\Handle = hw
    ;...
    wlist() = *s
  EndIf
  
  ProcedureReturn #True
EndProcedure

; Global w.Window
; w\Handle = 1
; w\Title = "Test"
; AddElement(wlist())
; wlist() = w

; EnumWindows_(@EnumProc(), wlist())

EnumProc2(GetDesktopWindow_(), #NUL) ; works fine
EnumWindows_(@EnumProc2(), #NUL) ; crashes because the list is not provided

Define *p.window 
ForEach wlist()
  *p = wlist()
  Debug *p\Handle
  FreeMemory(*p)
Next
if you allocate memory for a structure, the structure should be a constant size; "field.s" is not constant; "field.s{100}" is.

Re: PB list in win32 enumeration callback?

Posted: Tue Jun 13, 2023 5:25 am
by Rinzwind
Yes, a global list works, but that makes it not usable in a generic way. You can't pass any list.

Re: PB list in win32 enumeration callback?

Posted: Tue Jun 13, 2023 1:04 pm
by Rinzwind
Found this

Code: Select all

EnableExplicit

Structure Window
  Handle.i
  Title.s
EndStructure

Procedure procGetPointer( *list )
	ProcedureReturn *list
EndProcedure

Prototype.i pGetWindowListPointer(List p.Window() )
Global GetWindowListPointer.pGetWindowListPointer = @procGetPointer()

Procedure EnumProc(hw, List lp.Window())
  If IsWindowVisible_(hw)
    Debug hw
    AddElement(lp())
    lp()\Handle = hw
    ;...
  EndIf
  
  ProcedureReturn #True
EndProcedure


Procedure EnumProc2(hw, List *lp.Window())

  If IsWindowVisible_(hw)
    Debug hw
    AddElement(*lp())
    Define *s.Window = AllocateStructure(Window)
    *s\Handle = hw
    ;...
    *lp() = *s
  EndIf
  
  ProcedureReturn #True
EndProcedure


NewList wlist.Window()
EnumWindows_(@EnumProc(), GetWindowListPointer(wlist()))
Debug ""
ForEach wlist()
  Debug wlist()\Handle
Next
Debug ""

; Global w.Window
; w\Handle = 1
; w\Title = "Test"
; AddElement(wlist())
; wlist() = w

; EnumWindows_(@EnumProc(), wlist())

NewList *wlist.Window()
;EnumProc2(GetDesktopWindow_(), *wlist()) ; works fine

EnumWindows_(@EnumProc2(), GetWindowListPointer(*wlist())) 
Debug ""

ForEach *wlist()
  Debug *wlist()\Handle
Next
It is close, but still needs a custom prototype for each kind of list... shows PB just misses the syntax to get an actual list/map address... (double @@ for lists? thank you Fred)