Is it possible to use TrackPopupMenu from a secondary thread? - multithreading

Is it possible to use TrackPopupMenu from a secondary thread? I'm trying to use it with TPM_NONOTIFY and TPM_RETURNCMD flags.
In our code, the call to TrackPopupMenu returns immediately without displaying the menu, indicating that the user cancelled the menu.
The same code, when called from the main/gui thread works fine.

You need to run this from the same thread that owns the window to which the menu is attached.
The threading rule in Windows is that windows have affinity to the thread that creates the window. Since TrackPopupMenu receives a window handle, you can assume that it must be called from that window's thread.
In practice on Windows (and all GUI frameworks that I have ever come across), everything related to the GUI should happen in the main thread.

Related

Do we have to use Synchronize if we want to make some changes in the VCL main thread?

Let's say that I want to simply change the caption of a Label when the program is in a child thread. I don't want use Synchronize. I really don't want to get the OS switch to another thread context to do this job. I know that I can't do this by just putting some lock(Semaphore or something) in my child thread. Can anyone tell me the reason why I can't use locks for that?
Thanks in advance :)
Do we have to use Synchronize if we want to make some changes in the VCL main thread?
Yes.
Well, code that accesses VCL objects has to execute on the main thread and Synchronize is the most commonly used way to achieve that. There is no way around that constraint.
David's answer is 100% correct. But I thought I'd shed a little more light...
Imagine this scenario: You have a VCL component with a number of properties which you want to update from a thread. You create a lock (such as a critical section) and any call in both your main VCL thread and additional thread you respect this lock whenever trying to access that object and its properties. However, since the VCL doesn't acknowledge the presence of other threads trying to use it, there may be something in the main thread which tries to access the same property that your thread is trying to access... at the same time. I'm not talking about your own code which might access this property, but something behind the VCL its self. There's no way that the VCL its self knows about your lock to acknowledge it.
Therefore, even the best locking mechanisms are not safe when working with anything in the main thread. Synchronize is an essential part of how multi-threading works, although there are a few alternatives such as feeding windows messages.
Scenario
Let's say you create a custom button component inherited from TButton. You create a thread behind this button and want to update the caption of the button from within this thread. You create a critical section lock to protect your control.
Let's also say that you have an action manager and this button is assigned to an action. The action manager is responsible for updating the caption of the button. While your thread and all your code respects the lock when accessing your button control, the action manager has no concept of this and tries to go ahead and update the caption anyway.

How can I create a second UI thread in Delphi with its own message processing loop?

I am working on a VCL (Delphi Win32) forms application platform with embedded scripting and would like to add debugging support. Scripting executes in the main VCL thread - scripts do direct UI manipulation and has some other legacy constraints keeping it in the UI thread.
The debugger UI needs to run in its own thread since the main UI thread will block on script breakpoints. It still needs to be in the same process for the thread-safe debugging component to work.
I tried to follow Blorgbeard's comment on https://stackoverflow.com/a/12505959/243144, but I am not sure if this is even possible with Delphi's VCL. (.NET creates a new ApplicationContext when passing a form to Application.Run) With the following Delphi, blocking of the main UI thread stops message processing on the second thread (and vice versa).
procedure TDebuggerThread.Execute;
begin
CoInitialize(nil);
FForm := TForm2.Create(nil);
FForm.Show;
Application.Run;
end;
Delphi forms are single-thread only. Any descendant of TControl, including TForm, must only be accessed from the main UI thread. Never call any TApplication method on anything but the main thread.
You're of course allowed to create other windows that are tied to different threads. You just can't use the VCL UI elements in those threads. Instead, you'll use CreateWindow to create the main window and any controls on it. You'll write a window procedure to handle any messages sent to those windows. You'll handle control-notification messages in the parent's window procedure rather than the child's.
One of the constraints of the VCL is that all interaction with GUI controls must be performed on the main thread. There's no way to circumvent that.
If you want to show debugger GUI in a separate thread, using VCL, your only option is to use an out-of-process solution. In other words, run your debugger in a different process, and use IPC to communicate between the two processes.

EndDialog can't be called in a thread?

I want to close a Modal Dialog when the thread ends. I know how to use PostMessage or SendMessage, but why can't I directly call the EndDialog member function? If I do, it causes an App exception.
EndDialog needs to be called from the thread that created the modal dialog box, specifically the dialog box procedure. It sounds like you want to call it from another thread. To close the dialog from another thread, you will need to post a message as that is supported across threads. The dialog can then respond to the message and close itself. The calling thread needs to wait for the dialog box to close before destroying the thread.
If you’re wondering why this is, well most of the USER API functions have thread affinity. They were originally implemented in this way and were not designed to support use across threads.

Breakpoint a multi thread application

What happens if I breakpoint a multi thread application.
does it stop all the threads, just the one that is break pointed or does the whole program just crash ?
If it is possible would I want to stop just one thread or would this mess up my application ?
If I cannot break point a multi tread application what are the debug techniques available to me ?
JAVA: As far as personal experience goes, you can debug multi-threaded applications by stopping all threads or individual threads. It would most likely depend on what IDE you are using, and what application you are connecting to, but for me its:
Eclipse connecting in debug mode to a Tomcat server running in jpda
Place a breakpoint in the code, go to Eclipse's debug perspective (sometimes it pauses but doesn't switch perspective)
In the breakpoints window, you will see a list of breakpoints. Each one you can right-click and set properties on... if you want to stop all threads on one breakpoint, hit the Suspend VM radio button. If you only want to stop a single thread, click suspend thread.
I'm not sure you're able at this point to select which thread you want to pause if using the single thread stop option. In Suspend VM, you can look at the Debug pane and see your thread... scroll down and you can jump between the threads (Daemon thread 10 vs Daemon thread 9, something like that)
It stops all threads.
It is not normally possible to just stop one thread. For more information on debugging threads with GDB see this part of the manual.
Since you didn't tag your question with a specific language/platform, I'll give a Java-related answer.
In most IDEs you can set properties on your breakpoints, specifically conditional properties. So, if you know the name of your thread, you can do something like this:
"ThreadName".equals(Thread.currentThread().getName())
...and all other threads utilising the same class (where you set the breakpoint) will carry on unhindered.

Multiple UI threads on the same window

I don't want multiple windows, each with its own UI thread, nor events raised on a single UI thread, not background workers and notifications, none of that Invoke, BeginInvoke stuff either.
I'm interested in a platform that allows multiple threads to update the same window in a safe manner. Something like first thread creates three buttons, the second thread another five, and they both can access them,change their properties and delete them without any unwanted consequences.
I want safe multi-threaded access to the UI without Invoking, a platform where the UI objects can be accessed directly from any thread without raising errors like "The object can only be accessed from the thread that created it". To let me do the synchronizing if I have to, not prevent me from cross-tread accessing the UI in a direct manner.
I'm gonna get down voted but ... Go Go Gadget Soapbox.
Multi threaded GUI are not possible in the general case. It has been attempted time and time again and it never comes out well. It is not a coincidence that all of the major windowing frameworks follow the single threaded ui model. They weren't copying each other, it's just that the constraints of the problem lead them to the same answer. Many people smarter than you or i have tried to solve this.
It might be possible to implement a multi-thread ui for a particular project. I'm only saying that it can't be done in the general case. That means it's unlikely you'll find a framework to do what you want.
The gist of the problem is this. Envision the gui components as a chain (in reality it's more like a tree, but a chain is simple to describe). The button connects to the frame, connects to the box, connects to the window. There are two source of events for a gui the system/OS and the user. The system/OS event originate at the bottom of the chain (the windowing system), the user event originate at the top of the chain (the button). Both of these events must move through the gui chain. If two threads are pushing these events simultaneously they must be mutex protected. However, there is no known algorithm for concurrently traversing a double linked list in both directions. It is prone to dead lock. GUI experts tried and tried to figure out ways to get around the deadlocking problem, and eventually arrived at the solution we use today called Model/View/Controller, aka one thread runs the UI.
You could make a thread-safe Producer/Consumer queue of delegates.
Any thread that wants to update a UI component would create a delegate encapsulating the operations to be performed, and add it to the queue.
The UI thread (assuming all components were created on the same thread) would then periodically pull an item from the queue, and execute the delegate.
I don't believe a platform like that exists per se
There is nothing stopping you from saying taking .Net and creating all new controls which are thread safe and can work like that(or maybe just the subset of what you need) which shouldn't be an extremely large job(though definitely no small job) because you can just derive from the base controls and override any thread-unsafe methods or properties.
The real question though is why? It would definitely be slower because of all the locking. Say your in one thread that is doing something with the UI, well it has to lock the window it's working on else it could be changed without it knowing by the other thread. So with all the locking, you will spend most of your drawing time and such waiting on locks and (expensive) context switches from threads. You could maybe make it async, but that just doesn't seem safe(and probably isn't) because controls that you supposedly just created may or may not exist and would be about like
Panel p=new Panel();
Button b=new Button();
WaitForControlsCreated(); //waits until the current control queue is cleared
p.Controls.Add(b);
which is probably just as slow..
So the real question here is why? The only "good" way of doing it is just having an invoke abstracted away so that it appears you can add controls from a non-UI thread.
I think you are misunderstanding how threads really work and what it takes to actually make an object thread safe
Accept that any code updating the GUI has to be on the GUI thread.
Learn to use BeginInvoke().
On Windows, Window handles have thread affinity. This is a limitation of the Window manager. It's a bad idea to have multiple threads accessing the same window on Windows.
I'm surprised to see these answers.
Only the higher level language frameworks like C# have thread restrictions on GUI elements.
Windows, at the SDK layer, is 100% application controlled and there are no restrictions on threads except at insignificant nitty gritty level. For example if multiple threads want to write to a window, you need to lock on a mutex, get the device context, draw, then release the context, then unlock the mutex. Getting and releasing a device context for a moment of drawing needs to be on the same thread... but those are typically within 10 lines of code from each other.
There isn't even a dedicated thread that windows messages come down on, whatever thread calls "DispatchMessage()" is the thread the WINPROC will be called on.
Another minor thread restriction is that you can only "PeekMessage" or "GetMessage" a window that was created on the current thread. But really this is very minor, and how many message pumps do you need anyway.
Drawing is completely disconnected from threads in Windows, just mutex your DC's for drawing. You can draw anytime, from anywhere, not just on a WM_PAINT message.
BeOS / Haiku OS
Based on my guessing of your requirement, you want a single Windows Form and having ways to execute certain routines asynchronously (like multi-threading), yes?
Typically (for the case of .NET WinForms) Control.Invoke / Control.BeginInvoke is used to a certain effect what I think you want.
Here's an interesting article which might help: http://www.yoda.arachsys.com/csharp/threads/winforms.shtml

Resources