Page 1 of 1

[windows] EnumWindows and use of TreeGadget sample

Posted: Wed Aug 28, 2002 3:51 pm
by BackupUser
Code updated for 5.20+

Restored from previous forum. Originally posted by fweil.

From Beginners section discussion I place this snippet here (also available soon on ressource site).

Any feedback will be welcome.

Krgds

Code: Select all

;======================================================
;
; EnumWindows TreeView
; F.Weil 20020828
;
; Two linked lists are used for both parent windows and children objects
;
; Each list is updated using a callback Enum procedure
;
; The Tree gadget is build when opening the program's main window
; then you have just to click the items / nodes and surf.
;
; This program has a resizing feature linking the tree gadget size to the main window.
;
; I choosed to put all handle, text and class name information in a single label in the
; tree gadget for each item, so that no more action is necessary except looking labels.
;
; I also tried a List icon gadget version of this program but this tree gadget version is
; really simple and convenient for any further feature to add later.
;
; Feel free to modify update this code sample for any use in the PureBasic community.
;

Structure FindWindowData
  hFW.l ; variable to store a handle
  sFW.s ; variable to store a Window name
  cFW.s ; variable to store a window class name
EndStructure

Global NewList FindWindow.FindWindowData()
Global NewList FindChild.FindWindowData()

Procedure.l EnumChildProc(hChild, lParam)
  ChildName.s = Space(255)
  ChildClass.s = Space(255)
  If GetWindowText_(hChild, ChildName, 255)
  Else
    SendMessage_(hChild, #WM_GETTEXT, 500, ChildName)
  EndIf
  If GetClassName_(hChild, ChildClass, 255)
    AddElement(FindChild())
    FindChild()\hFW = hChild
    FindChild()\sFW = ChildName
    FindChild()\cFW = ChildClass
  EndIf
  ProcedureReturn 1
EndProcedure

Procedure.l EnumWindowsProc(hFind, lParam)
  WindowName.s = Space(255)
  WindowClass.s = Space(255)
  If GetWindowText_(hFind, WindowName, 255)
    Result = GetClassName_(hFind, WindowClass, 255)
    AddElement(FindWindow())
    FindWindow()\hFW = hFind
    FindWindow()\sFW = WindowName
    FindWindow()\cFW = WindowClass
  EndIf
  ProcedureReturn 1
EndProcedure

;
; Main starts here
;

WEvent.l
WindowXSize.l
WindowYSize.l
Quit.l

Quit = #False
WindowXSize = 320
WindowYSize = 240

If OpenWindow(0, 200, 200, WindowXSize, WindowYSize, "MyWindow", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_TitleBar)
  
  TreeGadget(100, 0, 0, WindowXSize, WindowYSize, #PB_Tree_AlwaysShowSelection)
  If EnumWindows_(@EnumWindowsProc(), 0)
    ResetList(FindWindow())
    While NextElement(FindWindow())
      AddGadgetItem(100, -1, FindWindow()\sFW + " - " + FindWindow()\cFW + " - " + Str(FindWindow()\hFW))
      ClearList(FindChild())
      If EnumChildWindows_(FindWindow()\hFW, @EnumChildProc(), 0)
        
        ResetList(FindChild())
        While NextElement(FindChild())
          AddGadgetItem(100, -1, FindChild()\sFW + " - " + FindChild()\cFW + " - " + Str(FindChild()\hFW))
        Wend
        
      EndIf
    Wend
  EndIf
  
  Repeat
    WEvent = WaitWindowEvent()
    Select WEvent
      Case #PB_Event_CloseWindow
        Quit = #True
      Default
    EndSelect
    
    If WindowXSize <> WindowWidth(0) Or WindowYSize <> WindowHeight(0)
      WindowXSize = WindowWidth(0)
      WindowYSize = WindowHeight(0)
      ResizeGadget(100, 0, 0, WindowXSize, WindowYSize)
    EndIf
    
  Until Quit
  
EndIf

End
;======================================================
Francois Weil
14, rue Douer
F64100 Bayonne

Posted: Wed Aug 28, 2002 4:11 pm
by BackupUser
Restored from previous forum. Originally posted by Rings.

crashes here (win2000)

Its a long way to the top if you wanna .....CodeGuru

Posted: Wed Aug 28, 2002 4:37 pm
by BackupUser
Restored from previous forum. Originally posted by fweil.

I have a W2K with a PureBasic 3.30 no user lib ...

Sorry but it works fine on mine.

Would you like to check until where it works ?

Rgrds

Francois Weil
14, rue Douer
F64100 Bayonne

Posted: Wed Aug 28, 2002 5:07 pm
by BackupUser
Restored from previous forum. Originally posted by fred.

Works perfectly on WinXP. Nice work !

Fred - AlphaSND

Posted: Wed Aug 28, 2002 6:19 pm
by BackupUser
Restored from previous forum. Originally posted by Paul.

Don't feel bad Rings... it crashes on my Win2K box as well :(

This is the line that Crashes it:
If EnumChildWindows_(FindWindow()\hFW, @EnumChildProc(), 0)

...which of course traces back to EnumChildProc()
...which contains:
If GetWindowText_(hChild, ChildName, 255)
Else
SendMessage_(hChild, #WM_GETTEXT, 500, ChildName)
EndIf

Notice the 500? when only 255 has been reserved :)

Change 500 to 255 and no more crash.

Posted: Wed Aug 28, 2002 6:32 pm
by BackupUser
Restored from previous forum. Originally posted by MrVainSCL.

Here it will crash too ;(

PIII450, 256MB Ram, 6GB HD, RivaTNT, DirectX8.1, SB AWE64, Win2000 + all Updates...

greetz
MrVainSCL! aka Thorsten

Posted: Wed Aug 28, 2002 6:33 pm
by BackupUser
Restored from previous forum. Originally posted by Franco.

It works very fine with W2k-Sp3 (@work) - even with:
SendMessage_(hChild, #WM_GETTEXT, 500, ChildName)

Nice job Francois :)

Have a nice day...
Franco

Sometimes you have to go a lonely way to accomplish genius things.

Posted: Wed Aug 28, 2002 7:18 pm
by BackupUser
Restored from previous forum. Originally posted by Paul.
Originally posted by Franco

It works very fine with W2k-Sp3 (@work) - even with:
SendMessage_(hChild, #WM_GETTEXT, 500, ChildName)
Obviously you don't have any names long enough to overflow the 255 limit that has been set by Space(255).

This is a good example of how a mistake in coding can cause bad effects on one system but not on another. Be careful people :)

Posted: Thu Aug 29, 2002 7:12 am
by BackupUser
Restored from previous forum. Originally posted by fweil.

Thanks all for comments and feedback.

I did not notice the 500 - 255 mistake and could not imagine its effect !

I also continued in doing some other interesting tests using the EnumWindow with 0 first value in one hand and EnumChildWindows with GetDesktopWindow in the other hand ... and result are close but not exactly the same. By the way some more children components appear when using EnumChildWindows with GetDesktopWindow as far as I can see.

There is something I don't understand but it seems that such callback procedures used in this context may have complex behaviour.

Rgrds

Francois Weil
14, rue Douer
F64100 Bayonne