How to kill XtAppMainLoop (Motif)? - c++

I want to use XmCreate{Error|Warning|Info}Dialog to display some message in screen in my SDL based application before its main window is open and any program data is available. I want the dialog to open, print the intended message, and when the user clicks on the OK button, the dialog plus the top widget I had to create for it should be closed/removed. Now afaik XtAppMainLoop will loop and process top widget messages (a window?) until the user closes it. I want to close it when the dialog returns though. How can I do that?

After hours and hours of googling and reading I have found out that you can use XtAppSetExitFlag (XtAppContext).

It's easy, in the XtAppContext that is returned from XtAppMainLoop, just do p->exit_flag = 1;.
It's also common for applications to simply include their own main loop and do whatever they want. All XtAppMainLoop does is call XtAppNextEvent(app, &event) and then XtDispatchEvent(&event).

Related

C++ Modal dialog box continuing adding texts

I have dialog box and in it, it has OK and Cancel buttons then it also has a ListBox to display text in two columns. I would like to continue adding text into the ListBox after the dialog box is shown. How can I do that? Because after I call DoModal() to show the dialog box, the code does not continue to execute. Or should I create two threads (one is display dialog box while another thread continues adding text to dialog box)?
Make your dialog 'pull' the data it needs, maybe polling the data source with window messages every second, or every 100ms or so. Or, if you go the 'two threads' route (the better but more complicated option), have your data source post a window message to your dialog when there is new data, and then have the dialog fetch the data it needs. The reason for this is that it's much easier to use the existing CDialog infrastructure to get a window that behaves like an actual dialog, compared to building a modal window that acts like a dialog but isn't really.
If you do go the two threads route, your division of labor should be: one thread that does all the UI work (including showing the dialog), and one that 'generates' data and lets the UI know when there is new data. So the worker thread should not do anything related to the UI, nor call any methods on the dialog directly - you can't access windows from several threads. The only cross-thread window communication should happen through window message (i.e., use ::SendMessage()). So certainly don't do something like myDialog->m_theList.AddString("blah") from another thread, or something like it.
Showing a dialog box modally halts further execution until you close the box. Instead of showing it modal, show it normal but make it always on top so you can continue executing the code after the call to DoModal(). Alternatively, populate the box with all the info it will need before you call DoModal().
If you decide to take the "two threads" approach you will discover that the controls on MFC dialogs should not be updated or accessed from a thread other than the one that created the dialog. Even if you have pointers to these controls available in another thread it is not thread-safe to access them. This rule applies whether or not the dialog is modal.
Instead, your second thread would need to PostMessage or SendMessage to the dialog window, so the updates occur on the thread that created the dialog (most likely the main UI thread of the application).

Programmatically clicking toolbar button in parent of modal window

I have an application that hooks into another application via an API. My application launches a modal window which prevents keypresses to reach the parent as one would expect.
However due to limitations in the API I need to click one of the parents toolbar buttons from time to time (yes it's a kludge).
I wonder if this is possible while still having the modal window of my application active? Is it perhaps possible to send the required command directly into the parent command queue?
Clicking the button programmatically with no modal window should not be a problem, one could go by this link for example: http://forums.codeguru.com/showthread.php?307633-How-to-run-a-very-long-SQL-statement. But I would prefer not having to close my window each time I have to click the button.
Although the fifth answer is what I find interesting as I'm thinking this could make it possible to send the command without having to close my modal window first. Also it feels an ever so small bit less ugly.
First of all, when a modal dialog is shown, it runs its own message pump. So any attempt to fake input messages will land in the modal dialog message pump. Which is no good to you. So, you'd have to send a message rather than fake input.
However, when a modal dialog is shown, its owning windows are disabled. Which means that these windows will not respond to any messages you send. So I guess that means that you could:
Enable the owning top-level window that you hosts the toolbar in question.
Send the message to the toolbar button.
Disable the owning window again.
Not the prettiest way to go about things, but you did ask!

MFC dialog close issues

Good day!
I have an MFC dialog with progress.
Dialog automatically closes after reaching 100% using PostMessageW(WM_CLOSE).
The problem is, when, during progress, I'm moving dialog over the screen, dialog is not closing and WM_CLOSE message is ignored. Any suggestions? Thanks.
For a modal dialog you shouldn't really need to use a WM_CLOSE message.
Normally you'd use the OK or Cancel button events to close it, call the EndDialog method from functional code or just return when your processing is complete (assuming that its the process run as soon as the dialog is initialised). You can set your return value at the same time e.g. EndDialog(2);.
Either way the dialog will close once th current message handler returns, so there could well be a delay, in closure but it shouldn't be much.
Is the activity behind progress bar done in a separate thread? It look like to be the case otherwise when you drag the dialog the progress bar would have froze until you release the dialog than it would have resumed. This means you might have to look into inter thread communication, how the message is being posted to the dialog HWND.
It might have to do with the dialog being in freeze (no activity) state while you are dragging it which seems to be normal windows behavior. If that is the case you could use signals/CEvent to tell the dialog to close down.

Create two windows in one application?

It might be a simple question, but I don't know where to start the search for the answer. How do I create two individual windows interface in one application using native winapi? Do I put two CreateWindow() functions using same HINSTANCE? What if I want a login screen windows and the content page such that login screen comes first, and after I press the button, the login screen is destroyed, and the content page appears. How do I do such trick?
I was thinking of using DestroyWindow and then CreateWindow inside the button click message. However, this would mean the main while loop (for translate/dispatch msg) in WinMain will exit its loop and cause the whole program to exit. Another way is to pre-create it in WinMain, but how would I notify the WinMain if the button was clicked and enter the second loop instead of exiting the program?
You're over-thinking it. To create two windows, call CreateWindow twice. It's just that simple.
Calling DestroyWindow does not cause your program to exit its message pump. Calling PostQuitMessage is what does that. So don't do that.
When the button is clicked, destroy the one window and create the other. There are no tricks. The message pump delivers messages to all windows (unless you're doing it wrong by explicitly requesting messages for one window, but you shouldn't do that).

FindWindowEx not able to find window handle

I am trying to find the handle to a dialog as soon as it opens.
Now as soon as dialog is opened I try to call FindWindowEx for that dialog in a separate thread but it returns NULL.
I then put some sleep before calling FindWindowEx. It works some time after putting sleep.
It looks like FindWindowEx is getting called before even dialog is created and sleep is helping to create the dialog and hence some times it work.
Now I have put some random value in sleep. And it doesnot look a good approach since it can fail anytime.
Is there any full proof approach so that I may get handle every time via FindWindowEx without making thread to sleep.
If the dialog you are looking for is your dialog -- that is, you control the code -- then you can send a message from your dialog to your watching app that says, "Oh, hi there!"
If the dialog is not yours, and you don't want to spin, you can create a Windows hook on the WM_CREATE message.
A very straightforward solution would be to call FindWindowEx repeatedly in a loop.
HWND h = NULL;
while (1) {
h = FindWindowEx(...);
if (h) {
break;
}
Sleep(100);
}
That's not bullet-proof - it's an infinite loop if the dialog nevers opens, or is closed too quickly (although that's unlikely). To catch both cases, let the main thread (which creates and runs the dialog) maintain a simple bool property that the worker thread queries to find out whether there's still a dialog around.