Notifications
Clear all

[Closed] collecting windows

How do I collect all open dotnet windows? There isn’t a findwindows command

9 Replies

that’s a way:


  fn getOpenedForms level:0 =
  (
  	type = "System.Windows.Forms.Form"
  	fromHwnd = (dotnetclass "Control").FromHandle
  	for hwnd in windows.getchildrenhwnd level where (c = fromHwnd (dotnetobject "System.IntPtr" hwnd[1])) != undefined collect 
  	(
  		t = c.GetType()
  		if (t.FullName == type or t.BaseType.FullName == type) and c.TopLevel then c else dontcollect
  	)
  )
  
1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

my bad… we don’t need to check the ‘top level’.
the windows.getchildrenhwnd collects only top-level windows.

Denis, your way is obviously the only way that can easily solve the problem that I had with “OwnedForms”. Now i can control all “slave” forms opened with “main” form.
Thanks for that.

Perhaps this is unrelated to the topic, but i add here a recursive fn for collecting all controls of dotnet form (including nested ctrls) in order. This is useful when you need to dispose all controls, remove all events, set lifetime control etc.

--example
  form = dotnetobject "form" ; form.name ="form"
  lbl1 = dotnetobject "Label" ; lbl1.name ="lbl1"
  lbl2 = dotnetobject "Label" ; lbl2.name ="lbl2"
  lbl3 = dotnetobject "Label" ; lbl3.name ="lbl3"
  lbl4 = dotnetobject "Label" ; lbl4.name ="lbl4"
  tb1 = dotnetobject "textbox" ; tb1.name ="tb1"
  tb2 = dotnetobject "textbox" ; tb2.name ="tb2"
  pnl1 = dotnetobject "panel" ; pnl1.name ="pnl1"
  pnl2 = dotnetobject "panel" ; pnl2.name ="pnl2"
  lbl1.Controls.AddRange #(tb1)
  lbl2.Controls.AddRange #(tb2)
  pnl1.Controls.AddRange #(lbl2,lbl4)
  lbl3.Controls.AddRange #(pnl2)
  form.Controls.AddRange #(lbl1,pnl1,lbl3)
 
  --function for collecting controls names
  ctrlArr = #()
  fn getnames dnCtrl &ctrlArr revert:true =
  (
  	for i in 0 to dnCtrl.Controls.count-1 do 
  	(
  		dnCtrlChild = dnCtrl.Controls.Item[i]
  		if revert then insertItem dnCtrlChild.name ctrlArr 1 else append ctrlArr dnCtrlChild.name
  		if dnCtrlChild.HasChildren do (getnames dnCtrlChild &ctrlArr)
  	)
  )
  getnames form &ctrlArr
  ctrlArr
 lo1

Great code. Avoids all the pitfalls.

3 Replies
(@denist)
Joined: 11 months ago

Posts: 0

the code is not perfect. to cover all cases we have to use user32.

 lo1
(@lo1)
Joined: 11 months ago

Posts: 0

Which cases are not covered?

(@denist)
Joined: 11 months ago

Posts: 0

some .net forms might be owned by not .net top level dialog. using only the windows structure we can’t resolve this situation.

technically the .net has to care about all these.

 lo1

This is true only when the HWND you pass is 0.