Click here to Skip to main content
15,884,298 members
Please Sign up or sign in to vote.
2.00/5 (1 vote)
See more:
This is my first real attempt at using MFC so I apologize for any basic mistakes I'm making or any gaps in knowledge that I may have regarding the subject.

I constructed a pretty basic program that can take the contents and all the files in a directory and copy and paste the contents to a different directory of my choice. I have a CString type member class wizard value variable called m_percent. This variable is supposed to keep track of the percentage of the files copied so far and display the number as each file transfers.

I have a class that has a function which accepts m_percent by reference so that the changes to m_percent within this function can be used to update the progress percentage.

The problem i'm having is I'm unable to call UpdateData(FALSE) from within the class I've constructed so that I can immediately update the percentage and as a result am unable to update my DLG visually at each recursion of copying effectively making my percentage upkeep worthless as I can't update it visually until after the 100% mark.

Is there a better way than UpdateData to visually update what m_percent actually is as I increment it? How can I properly make this work?

Thanks

Psuedocode:

C++
Void dir_backup::make_backup(CString &m_percent, unsigned long max_size)
{
 
for(all files that exist)
{
  Copy a file;

  size_copied = copied_file.size();

  double temp = ((double)size_copied/(double)max_size)*100;

  m_percent.Format("%.2f",temp); //Percent is now modified because I passed it by    reference so now I want to visually change it

  This is where I tried to call CWnd::UpdateData(FALSE) but cant so I need an                alternative
}
}
Posted
Updated 9-Jan-13 4:24am
v2
Comments
Sergey Alexandrovich Kryukov 9-Jan-13 10:08am    
Almost nothing is clear. The problem looks very simple, only you need to provide some code sample ("Improve question", above) and explain properly referring to the code.
It's absolutely unclear why can't you call some function of a class. And what is "withing the class"? Just class, or instance?
And, do yourself a favor, don't even think about using a timer as "Solution 1" suggests; this is totally wrong.
—SA
willempipi 9-Jan-13 10:11am    
SA, learn some people skills please...
Daniele Rota Nodari 9-Jan-13 10:57am    
You tell that you cannot call CWnd::UpdateData(FALSE)...
What is the reason you are telling that? Some compiler error? Or simply it seems not working?
Is dir_backup the CWnd (or CDialog, or derived one) object or some other class?
Parwarrior7 11-Jan-13 11:19am    
At the end of the day I actually was able to come up a very simple solution using a combination of a Timer and a Pass by reference call so sorry I wasn't able to accept the initial solution as it's no longer here :(.

The User interface will not be updated during a long process in the same thread.

You need to create a work thread in which you will do the file copy; and from that thread you can notify the main thread (your user interface) to update the percent value.

One other suggestion, if you only want to copy files, would be to use ShFileOperation[^] (with options FO_COPY )and use its own progress dialog (FOF_SIMPLEPROGRESS).
 
Share this answer
 
I think you have two problems:


  1. How to update a progress control
  2. Ensure that the update is executed (not blocked)


Updating such progress controls is usually performed by posting user defined messages from the worker code to the dialog:

C++
// Your app header file
#define WM_APP_PERCENT_PROGRESS (WM_APP + 0)

// Your dialog header file
class CMyDialog : CDialog
{
    ...
    LRESULT OnUpdateProgress(WPARAM wParam, LPARAM lParam);
    ...
};


// Your dialog source file
BEGIN_MESSAGE_MAP(CMyDialog, CDialog)
    ...
    ON_MESSAGE(WM_APP_PERCENT_PROGRESS, OnUpdateProgress)
END_MESSAGE_MAP()

CMyDialog::OnUpdateProgress(WPARAM wParam, LPARAM lParam)
{
    unsigned long size_copied = static_cast<unsigned long>(wParam);
    unsigned long max_size = static_cast<unsigned long>(lParam);
    m_percent.Format(_T("%.2f %%"),
        ((double)size_copied/(double)max_size)*100.);
    UpdateData(FALSE);
    return 0:
}

// From within your dir_backup class post the update message
// You must know the dialogs CWnd / HWND
::PostMessage(hWndDialog, WM_APP_PERCENT_PROGRESS, (WPARAM)size_copied, (LPARAM)max_size);


Solving the second problem is more complicated. If your copy code is executed from within the same thread as your dialog, the message processing of your dialog is blocked until copying has been finished. To solve this, the copying must be executed from within another thread. An example for such a worker thread would be too much code for a short answer. However, you may find lot of examples here at CodeProject and in the web.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900