Problem with WindowsListMBS.WindowText

I’m having some trouble getting WindowsListMBS.WindowText to work in a DesktopWindows Thread on Windows 11. I haven’t tested Windows 10. The problem is that when I use WindowsListMBS.WindowText(i) in a Thread my code freezes. Just hangs with no error message. But the same code placed directly into a Windows Opening event works just fine.

I tried it from a fresh new Project to make sure something else in my code wasn’t causing the problem.

Here’s some code: I’ll include the whole test program. If you uncomment the line tTitle = w.WindowText(i), everything hangs

This code is for a custom windows taskbar. I’m using the WindowListMBS in a thread to keep track of my open windows.

#tag WindowCode
	#tag Event
		Sub Opening()
		  'Thread1.Start
		  
		  Var w as new WindowsListMBS
		  Var tPID As Integer = 0
		  Var tClassN As String = ""
		  Var tTitle As String = ""
		  Var i As Integer = 0
		  
		  
		  Do Until i = w.WindowCount - 1
		    
		    if w.WindowText(i).IndexOf("Xojo") > -1 Then
		      tPid = w.WindowProcessID(i)
		      tClassN = w.WindowClassName(i)
		      tTitle = w.WindowText(i)
		    End If
		    i = i + 1
		  Loop
		  
		  label2.text = tPid.ToString + " | " + tClassN + " | " + tTitle + " | " + i.ToString
		End Sub
	#tag EndEvent


#tag EndWindowCode

#tag Events Thread1
	#tag Event
		Sub Run()
		  Var w as new WindowsListMBS
		  Var tPID As Integer = 0
		  Var tClassN As String = ""
		  Var tTitle As String = ""
		  Var i As Integer = 0
		  
		  Do Until i = w.WindowCount - 1
		    
		    tPid = w.WindowProcessID(i)
		    tClassN = w.WindowClassName(i)
			'*** This is the problem code.  Uncomment this and everything hangs ***
		    'tTitle = w.WindowText(i)
		    i = i + 1
		    
		  Loop
		  
		  me.AddUserInterfaceUpdate("tPid":tPid,"tClassN":tClassN,"tTitle":tTitle,"i":i) '
		  
		End Sub
	#tag EndEvent
	#tag Event
		Sub UserInterfaceUpdate(data() as Dictionary)
		  For Each update As Dictionary In data 
		    
		    if update.Value("tTitle").StringValue.IndexOf("Xojo") > -1 Then
		      
		      Label1.Text = update.Value("i").StringValue + " | " + update.Value("tPID").StringValue + " | " + update.Value("tClassN").StringValue + " | " + update.Value("tTitle").StringValue
		      
		    End IF
		    
		  Next
		End Sub
	#tag EndEvent
#tag EndEvents

My guess is that w.WindowText is not thread safe. The limitation could be the OS rather than Christian’s plugin so you might have to use a timer instead of a thread.

Unfortunately, with this code in a timer my program gets bogged down every time the timer fires. I do have a console app setup as a background daemon that updates data that I can access. So, I have options. I just thought it might be better to try a Thread. I’m trying a worker now. i’m guessing it’ll be the same thing.

One thing I’ll point out, if I change tTitle = w.WindowText(i) to tTitle = w.WindowText(0) it doesn’t freeze! It returns whatever window text was at index 0 for everything.

I suggest you ping Christian a message asking him to investigate the issue.

Could you check if the window thread/process is your own?

because querying title will probably send a message to the window and if it’s your own window, you may not get an answer since you are in that function asking for it.

Just skip some windows like your own application windows.

1 Like

That would make sense, because I just figured out the index is failing when it hits 70. Class name for 70 is Default IME. I’ll have to figure out if that’s me. But I think you got it. Thanks!

Ok, in the WindowListMBS Class there’s the method CurrentProcessID. And where my code is freezing is when the thread’s processID is the same as my Current ProcessID. So that’s it. Easy to get around. “if w.WindowProcessID(Doi) <> w.CurrentProcessID”. Thanks for the help.

1 Like

Great, so we got a solution and I may add a note to documentation for next update.

1 Like