Is there an example of doing this for a dialog application? The only examples I can find are for MIDI applications.
Main Topics
Browse All TopicsI have a dialog based application in c++ 2008. I have a dialog that takes some time loading data, so I created a child dialog that displays a single static text control with the text "Loading Data" displayed when the parent form opens. When the data is loaded, the parent form hides the child dialog ( m_child.ShowWindow(0) ).
There is a picture control on the child dialog that displays an animated gif. The problem is that the animation won't start until after the loading of the data is complete. I'm thinking I need to have this dialog running in another thread, but don't know how to accomplish this.
Any help or suggestions appreciated.
This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.
Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.
If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.
Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.
Access the answers to your technology questions today.
30-day free trial. Register in 60 seconds.
Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Try it out and discover for yourself.
30-day free trial. Register in 60 seconds.
Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.
If you want to put a dialog in the thread, just create the thread and in the thread function write:
CMyDialog* pDlg = new CMyDialog;
pDlg->DoModal();
delete pDlg;
Of course, you can use pDlg->Create() and pDlg->ShowWindow(SW_SHOWNOR
That's all. And maybe this is a mistake.
I'd propose to make one function that will load all data. For the beginning, call this function from OnInitDialog or whenever it is now. This function ONLY loads the data and does not interact with GUI.
Next step will just to create the thread and move the code from this loading function to this thread.
When the data will be loaded, in the end of the thread function post a message to the GUI. GUI, when receives this message, shows the images or whatever it is.
DanRollins "Simple Multithreading in Visual C++":
"M
I like Win32 API: CreateThread. It is just trivial
DWORD WINAPI ThreadFunc(LPVOID pParam)
{
CParentClass* pWnd = (CParentClass*)pParam;
CMyDialog* pDlg = new CMyDialog;
//bla-bla
pWnd->PostMessage(THREAD_FI
return 0;
}
Somewhere in the app:
CreateThread(..., ThreadFunc, this,...);
BTW, UI thread, communication thread, listening thread,... these are only names.
If there is a GUI window created and handled in a thread function, probably, this thread can be named as an UI thread.
Actually, UI thread, I think, is the main application thread (the first one created in the process), because the main application window is in this thread.
According to both articles, he is recommending to stay away from threads unless absolutely necessary. OK, I'll buy that. I tried using your example of the api thread, but I'm not understanding something. Is this declared in the parent dialog or the child dialog?
Is there a way I can do this with a timer? It seems like a simple proposition, but I'm just not understanding. Let me try again here and you can show me where I'm going wrong.
1. I have a main dialog, a child dialog, and a "splash" dialog for the child dialog.
2. The child form is created on the OnInitDialog method of the main dialog and it's set to be hidden ( ShowWindow(0) ).
3. When it's time to show the child dialog, from a button event, I set m_childDialog.ShowWindow(1
4. The main dialog calls a method of the child dialog to load its data which, in turn, is loaded into a group of controls on the child dialog.
5. THE PROBLEM: The "splash" dialog has an animated gif image, but the animation doesn't work until the method that is retrieving the data and loading the child dialog is complete, after which I will close, or hide, the splash dialog.
I may be approaching this completely wrong, so if you have a better method please let me know. But I would like to have the animation run while the data is being loaded and the child dialog controls are being populated.
Ok. As you said - it is almost right.
Almost any application has a similar structure.
I proposed you a standard way:
1. Create main dialog
2. From OnInitDialog create the splash dialog with a timer for the animation.
3. From OnInitDialog create the thread loading the data.
4. When the thread finished to load it posts a message to the main dialog.
5. When the main dialog receives this message from the thread, the main dialog closes the thread handle and create the child dialog
6. The child dialog shows the loaded data.
When you create the child dialog invisible - you are wastng the time and resources - you don't know if the data will be loaded correctly or not. So better to wait till you will know what's going with data loading.
Also you are wasting the CPU time - instead of the loading the data as fast as possible, it creates a dialog.
So if to load the data takes longer than a second put the loading into the thread - the GUI will response all the time and will not stuck.
You can pass the pointer to the main dialog to the thread function. So from the thread you can send notifications to the main dialog.
The thread function should be declared as a static function in the main dialog or somewhere else without any class. I'd make it in the main dialog class:
static DWORD WINAPI Loading(LPVOID pParam);
if you will use CreateThread Win32 API.
You will need to add few messages to your application. For example, WM_LOADED. Maybe WM_LOADING_PROGRESS?
The main dialog will handle this message. In MFC ON_MESSAGE(WM_LOADED, OnLoaded) and so on.
Of course, you can solve the task without the thread, but this way will be more complicated and, probably, depends on the data you loading.
Ok, so just to be clear, I create the child dialog when the main dialog starts up. It's not doing anything but sitting there doing nothing. Data for that form won't be loaded until much later in the program.
Since the child method to load the data is being called from the parent, is that where I put the thread call? or do I put it in the child dialog itself and have it called from the method to load the data?
If this is a static call, do I place it at the top of the .cpp file just below the #include statements, or do I need to create another non-class file for it?
:)
we are posting in the same time.
I wanted to say, that I'm going to agree with your design, but I don't like the idea to put the child dialog into the thread.
The thread function can be in the beginning of the cpp-file. Like you said. But it will be better if it will be the static member-function of the main dialog.
so:
1. Child dialog is not in the thread
2. Thread function is a static member-function of the main dialog
ahhh...ok. :)
Well, the method I need to call is in the child dialog. So how would I reference that method to call in the thread?
earlier you provided this:
DWORD WINAPI ThreadFunc(LPVOID pParam)
{
CParentClass* pWnd = (CParentClass*)pParam;
CMyDialog* pDlg = new CMyDialog;
//bla-bla
pWnd->PostMessage(THREAD_FI
return 0;
}
so would I replace //bla-bla with pDlg->LoadData()?
and would I reference the parent form, where this function lives, with "this"?
if you need an explanation:
1. Child dialog is a GUI interacting with the user and controlled by the main dialog (the child is a modaless dialog). If it will be in the thread, you will have a problem even with the message handling.
2. If the thread function is a static member of the main dialog class, it will have access to all members of the main dialog. The thread function should receive this pointer as a parameter and the first line in the thread function should be:
CMainDialog* pThis = (CMainDialog*)pParam;
I definately agree that the dialog itself should not run in a separate thread. You'll have nothing but headaches.
The key issue seems to be lack of animation in the animated GIF. How are you showing the animated GIF? Are you using a webbrowser control?
Also, please talk a bit more about the process that "loads the data" Do you have a data-bound grid control that accesses a remote database? Are you acquiring data from a web page? What sort of delays are we talking about here?
The animated gif is loaded into a static picture control, same as a bitmap.
The controls on the child dialog are mostly combo box controls; they are populated by a rather long xml string, it takes about 3 seconds to download, parse, and load the controls. The xml is delivered from a request to the host. This is host is not a web server.
The CMyDialog* pDlg = new CMyDialog; line was there only because that was what you had posted earlier, I just did a copy/paste.
There are no web controls in play here, only mfc CDialog classes.
The original question was how to put a dialog into a thread. So I answered.
Then, I want to think so, we made a great deal - we designed a multi-thread MFC application where all GUI is in the main thread and the data loading is in a separate thread. Again, the thread will load data and notify its owner that the data was loaded (or not loaded) and nothing more. In the GUI part of the application the user will see an animation. It's just nice.
Between us, 3 seconds is not a big deal. Many applications need much more time to initialize their data. But, if the main idea of this EE thread is to design a multi-threaded app - we did it.
For PAQ searchers:
Here's an article that implements an MFC dialog running on a secondary a U/I thread:
Create a Dialog in its Own Thread
http://www.experts-exchang
Business Accounts
Answer for Membership
by: AndyAinscowPosted on 2009-10-18 at 10:47:59ID: 25600660
Have the other dialog in a UI based thread (not a worker thread).