Solved

Progress Dialog

Posted on 2003-10-23
19
534 Views
Last Modified: 2013-11-20
I have a progress dialog that monitors actions in a thread. The problem is that when it comes up...it takes over the program and allows nothing else to happen while it is monitoring the progress of my download. The UI locks up. The way I am updating the dialog is through messages posted by my worker thread to the main UI thread. Everytime my thread loops to get more data...it updates the dialog. Now I have done this the modeless way. How can I make it so that the user can just minimize this window and continue to do other things. Before I had the dialog..the file downloads were no problem...they were just in the background. Even if I put sleeps in the worker that posts the messages...still no control over the main UI. Can anyone help??
0
Comment
Question by:SGyves
  • 7
  • 6
  • 4
  • +2
19 Comments
 
LVL 48

Expert Comment

by:AlexFM
ID: 9612200
Dialog is modeless and UI is unavailable? Can you describe your problem with more details and show some code?
Creating the dialog, handling thread messages, closing the dialog.
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 9612634
You say you have the dialog modeless.  Just check again to make certain you don't start it with DoModal by mistake.
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 9612918
Maybe you require a function such as the following in your dialog

void CProgressDlg::PumpMessages()
{
    // Must call Create() before using the dialog
    ASSERT(m_hWnd!=NULL);

    MSG msg;
    // Handle dialog messages
    while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
      if(!IsDialogMessage(&msg))
      {
        TranslateMessage(&msg);
        DispatchMessage(&msg);  
      }
    }
}
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 9612980
IsDialogMessage is used for modeless dialogs.
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 9613237
SGyves is talking about modeless dialogs.  

from the help file
Although the IsDialogMessage function is intended for modeless dialog boxes, you can use it with any window that contains controls, enabling the windows to provide the same keyboard selection as is used in a dialog box.

Although the behaviour described looks as if it is a modal dialog hence my first post.  This message loop was just a wild thought, quick to try out,  as something seems to be crippling the normal message handling in his app.
0
 
LVL 23

Expert Comment

by:Roshan Davis
ID: 9613452
In your main UI class add a dialog member as *class member* like

CStatusDlg m_dlgStatus;

You can create the status dialog window at any time like this (but creation should be from the main thread, don't call dialog create function from thread, it will block the message loop of that dialog in a delay process)

if ( !IsWindow(m_dlgStatus.m_hWnd) )
{
      m_dlgStatus.Create(IDD_STATUS_DIALOG, this);
}

In the downloading thread, you would have the pointer of the UI main thread right?

for each status, Post a message to main window

PostMessage(pMain->m_hWnd, WM_USER+101,nPercentage,0);


BEGIN_MESSAGE_MAP(CYourMainWnd, CDialog)
      //{{AFX_MSG_MAP(CYourMainWnd)
      // classwizard added message maps
      //}}AFX_MSG_MAP
      ON_MESSGAE(WM_USER+101, OnProgress)
END_MESSAGE_MAP()

void CYourMainWnd::OnProgress(WPARAM wParam, LPARAM lParam)
{
      if ( !IsWindow(m_dlgStatus.m_hWnd) )
      {
            m_dlgStatus.Create(IDD_STATUS_DIALOG, this);
      }

      m_dlgStatus.SetProgress(wParam);      <---------- THIS IS YOUR FUNCTION IN YOUR DIALOG STATUS CLASS

      m_dlgStatus.ShowWindow(SW_SHOW);
      m_dlgStatus.SetForegroundWindow();
}


Rosh :)
0
 

Author Comment

by:SGyves
ID: 9614789
I have something else that is majorly wrong with my program. It looks like the dialog may not be working for another reason. Let me look further into it before anyone else tries to answer this question. Basically, I need to find some way of keeping track of my downloads. Right now...my program just spawns the thread and turns it loose with no way of knowing what it is doing. I have to figure some way of keeping track of all the downloads in the main document. If anyone ahs any ideas there....that would be great. But that is what I have to try to figure out for now.
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 9616069
Spawn one thread per download from your doc?  Or only start the second and subsequent downloads when the first is finished?
0
 

Author Comment

by:SGyves
ID: 9616841
I can have as many downloads as a user wants. All at the same time.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:SGyves
ID: 9616851
SO for every worker thread....there will be one progress dialog. Tha help at all?? Which is why I though that having the progress dialog inside the thread would have been okay.
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 9618287
You should do as I advised in the original thread:  
The progress dialog should not handle progress messages.  It should simply have a timer that checks the current download status, byte count, etc and updates the progrsss control during the timer handler.

-- Dan
0
 
LVL 48

Accepted Solution

by:
AlexFM earned 300 total points
ID: 9618847
Keep all created thread handles in the list or vector. Every worker thread posts user-defined message to main thread in some loop (progress) and just before finish. Main thread updates download information and removes worker thread handle from the list keeping it up-to-date. You need this list, for example, to stop all worker threads before exit or when user asks this.

Sample design:

struct THREAD_INFO
{
    HANDLE hThread;        // or CWinThread*
    int nProgress;             // 0-100
}

vector<THREAD_INFO*> m_RunningThreads;  // every started thread is added to it

User-defined message:
WM_PROGRESS_MESSAGE  
wParam - thread handle for seach in m_RunningThreads
lParam - progress indication. 100 - thread finished and may be removed from m_RunningThreads.
< 100 - update nProgress.

WM_PROGRESS_MESSAGE  is posted to main frame. If m_RunningThreads is not empty, there is some indication "Download in progress" (like icon in status bar). Double-click on such icon opens modal dialog with full list of download threads and their current state. Notice that dialog is modal: I beleive that modeless dialogs are evil and should be avoided.



0
 
LVL 48

Expert Comment

by:AlexFM
ID: 9618885
Correction: replace hThread with DWORD nThreadID in THREAD_INFO.
0
 

Author Comment

by:SGyves
ID: 9620250
Damn good idea for the download progress Alex...I still might like to make it modeless though...because so many people want to be doing something else...and monitoring thier downloads. I just need to figure out how I am going to make the dialog scrollable and be able to add a so called "download" object to the list. I think I would have to have a loop to cycle through all the download info and add a dialog item for each one. So it does create another problem for me. How to make a scrolling dialog and how to make individual "info panels" (precentage, meter, etc.) that can be added to the dialog. But I really like that idea.

Also thanks for the tips on tracking my threads.
0
 

Author Comment

by:SGyves
ID: 9620264
Basically...I would love to hear more about how to achieve the idea in your last paragraph...
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 9620324
Don't search for hard ways, use list control or list box.
0
 

Author Comment

by:SGyves
ID: 9620483
can a progrss control be a member of a list???
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 9622020
0
 

Author Comment

by:SGyves
ID: 9622581
Wow....far beyond cool. Thank you so much for this tip. I mean...why have a window for every download when you can have a list.   :)
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Introduction: Hints for the grid button.  Nested classes, templated collections.  Squash that darned bug! Continuing from the sixth article about sudoku.   Open the project in visual studio. First we will finish with the SUD_SETVALUE messa…
If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now