I believe I am in the right forum.
My project involves an exe and few dll. The dll does the work of reading the drive. Now while dll is reading the files, I want to be able to create a progress bar in the exe to display how long it is going to take for the dll to finish its work. I do realise that the dll can't access the exe resource, so I have an existing callback functions to access some of the exe functions. All I need is some direction as to how to proceed this task. Also, the dll has no idea how long it will take to finish reading the files, so this information also needs to come from the dll to the exe progress bar.
Would appreciate anyone shedding light in this project.
Thanks
Anderson.
I take it that you're coding the exe as well as the dlls?
If possible, I would have the exe display the progress information with the dll feeding back where it's gotten to via your callback mechanism. I mean, have the exe do all the feedback GUI work.
For this to work with the standard MFC controls, you'll need to avoid blocking the GUI thread. Is the file processing already being done on a worker thread?
The exe and the dll are already in place. Now the task is to add the progress control to the project because some of the dlls (according to the user's query to browse through the entire disk or particular folder to read files)takes hours to display the list. The project does not include any thread at the moment.
So should I include a multi-threaded function here, one for the dll to do what it is doing now and another for the user-interface(in the exe) to update the progress bar? Can't these be done with the thread? I have not worked on thread before , so any thoughts is welcome.
Thanks
A
Well, the main UI thread should be able to not only update the progress bar, but redraw the main windows as required (e.g. if it was covered and upcovered).
It is also possible to create a second GUI thread to handle the progress bar while the main thread is off doing processing, but this would leave the main window without a thread to look after it. And the one time we were forced to do this, when adding a progress dialog to tortuous legacy code, I learnt how much harder extra GUI threads are than normal ones (not esp hard, but a good bit more work than the actual progress dialog).
I would create a UI-less worker thread to do the file processing and have it notify the main app of its progress using the message loop mechanism. Your DLL will still need to use a callback function, but that should itself use PostMessage to inform the main thread what's up. Etc.
Thanks again. Can you direct me to any specific link or any example I can follow as I am new to coding threads.
I have already created the callback functions from the dll to the exe with the increment number and the maximum position number for the progressbar. So every time the dll reads a file/files, it sends the message and update the progress bar in the exe. Just making some progress......
HI Again,
I need some help with my coding and would appreciate any input.
My program has a dialog box button which the user click to make the get the background task going. I have included a new dialog box with progress bar and text.
In the inital dialog box onbutton clicked event
<code>
MyDialog::ButtonClicked(){
m_progressbardialog.DoModal(); //this is added newly to bring in the //progress bar
mydll.ReadFilesFromDirectory();
}
Progress bar class
OnInitDialog()
I have set the range
set the position etc
</code>
Now the program goes to the progress bar class and starts the thread but the actual program never hit the mydll.ReadFilesFromDirectory() function.
I do realise that the program is stuck in the new thread and not sure what I am doing wrong.
I realised I have got the idea of multi-threading completly wrong and had rewritten my code. I have added the threading code in the dialog to call dll function rather than for the user-interface(progress bar).
Though the EndDialog(true) is hit, the progressbar does not close by itself. And it throws the debug assertion failed error message. I believe I can sort that out. My question here is if a user clicks on cancel button in the progressbar, how do i send the message to the dll to stop what it is doing? Is there where the WM_USER come into picture?
THanks
Thanks for the link Lodger. Will try to adapt some of the things mentioned. My idea is not to add any addition to the UI , but to let the UI know that the progress of the dll's work. Is that not possible?
THe exe is a subclass of CHtmlView. Yes it is frame/view approach.There are several dll in my project. The dlls are loaded(afxloadlibrary) at the start of the dialog and when the user chooses an option, the particular dll's function (readfiles..) is called. I hope it makes sense.
Never was keen on doing work on thread, well....I have to cross this hurdle one day or other.
The best way to inform your UI that your worker thread's progress is to use PostMessage to send your UI thread a custom Windows message. You can then catch this message in your main message loop and update your UI accordingly. Your milage may vary with the multi-DLL architecture of your project but I suspect the principles are the same. The link in my previous post explains how to do this with MFC.
I've used this method in the past (when I used to work in windows land) and it works a treat. It may be worth creating a small standalone sample application with a worker thread first then adapt it to work with your project. I'd post some sample code but I work in Mac land nowadays and don't have any to hand, sorry.
Thanks for the reply. I kind of understood what is need now. I followed what is mentioned in this link and was quite useful. http://vcfaq.mvps.org/mfc/12.htm
Now my dll will do a callback function and the actual function will postMessage with the dialog handler.
dll.cpp
/*I am sending the max value as well as we know the maxvalue only when it's done */
mycallback.UpdateProgressControl(int incrementno, int maxvalue)
callback.cpp
UpdateProgressControl(int incrementno, int maxvalue){
//I haven't figured out how to send an int/uint via wparam
PostMessage(m_progBar.m_hwnd, Progress_Message, wparam, Lparam)
}
progbar.cpp
ON_MESSAGE(Progress_Message, OnWorkerMessage)
LRESULT OnWorkerMessage(WPARAM wParam, LPARAM lParam)
{ /*here i am supposed to check the current value of the progressbar to the value I got. But at the moment I am just checking if it's working by increasing the progressbar value*/
m_progBarCtrl.SetPos(500);
return 0;
}
#define Progress_Message WM_USER+1 //in stdafx.h
I have defined the value of the Progress_Message in the stdafx.h as this used in two separate classes(callback and progbar.cpp which is in the exe project).
I have put a breakpoint in the callback and progbar class, but it never hits the progbar breakpoint. When I check the value of m_progbar in the callback.cpp it is 0x000000....Can some one tell me what I am doing wrong?
THanks a lot for all your help.
This seems to work the first time (the OnMessage break point in the progressbar class is hit though the progressbar value remains at the same place), but the second time it does not go to the progressbar class.
I solved the problem by sending the dialog handle from the main thread to the worker thread, so the worker thread knows what dialog I am talking about. This has resolved lot of debug assertion as well.
Now I am working on how to close the dialog and send the message to the workthread.
Thanks.
I am still a little unclear about what you are doing.
Note that
- the worker thread should not be using any of MFC's GUI classes.
- when you need another thread to process a message, you need to use PostMessage (as Lodger mentioned) not SendMessage. Or PostThreadMessage().