Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations wOOdy-Soft on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Refresh a view

Status
Not open for further replies.

Elliott3

Programmer
Sep 5, 2002
347
CA
I have an SDI application with one main view and I have dynamically created controls on this view(information comes from a database) all other windows that open are dialogs...
Each dialog is created modal and when they are destroyed and focus is moved back to the main view, the information in the view needs to be refreshed...really, I guess, what I need to do is recreate the view but I'm not sure how to go about this...
Can anyone help me out?
CES
 
Your view should automatically receive an OnDraw() message to redraw itself when a window covering it is dismissed. You need to check that you are actually drawing something in your OnDraw() function. If you don't have a OnDraw() function for some strange reason, you need to override it. See the CWnd Class Members in MSDN (CView is derived from CWnd) for full details of using the OnDraw() function.
However, I find it hard to understand how you can possibly lose your OnDraw() function without purposely deleting it??
 
I checked the OnDraw() function and it doesn't seem to be triggered when the focus is returned to the view...it only seems to be triggered at startup...
Also, the controls that I am dynamically creating are created in the OnUpdate...
Any other suggestions?
Thanks..
CES
 
I recall reading the very same problem in these posts a while ago - you may want to do a search.

Failing everything else, I would be tempted to copy your custom code from the class, delete the class and start again with a fresh copy.
 
Do you know the things I would have to do to delete the view and then recreate it and put it back within the document...I'm pretty foggy on that?
Thanks..
CES
 
I suppose it depends on how far along in your project you are. You would need to go through your entire project and copy all your own code from the MFC generated code. Create a whole new project and place your code back in the relevant places. I suspect you have accidentally deleted some VC++ generated code from your project which is causing the problem.

The other alternative is for you to create a new project using the same settings as your previous project. Then compare the header files/cpp files on the new one to your existing one to see what areas are missing, etc.
 
Well, say for example you create an SDI using the appwizard and included a database view...
say for argument sake the database has one table and displays information from the table at startup...
now say that you add a CDialog to the project and it is shown when you select it from the menu...on this dialog, you can edit records from the database...when you click 'Ok' the dialog is unloaded and focus has returned to the view...
so how do you update the information displayed in the view according to the changes you just made to the database through the dialog?
thanks for patience
CES
 
When, for example, you dismiss a dialog that is covering another window, only the part of the bottom window that was obscured by the dialog will be updated. In your case, you need to force the entire view to be updated to reflect the changes made by the user in the dialog that has just been dismissed.

I suppose there's a couple of ways of doing this. You could force a re-draw of the main view by calling the OnDraw() function directly. You could implement the CWnd::Invalidate() function. Or, you could perhaps use the view's CWnd::UpdateWindow() function. There's also the CWnd::RedrawWindow() function.

I suggest you not only read up on these functions in MSDN but also get yourself familiarized with the update region principles.

Here's how I would force an update to a view once a modal dialog has been dismissed:

Code:
// The function in your view.cpp that creates
// the dialog
Code:
void CSomeView::SomeFunction()
{
Code:
// Show the dialog
Code:
CSomeDialog*  myDlg = new CSomeDialog;
   myDlg->DoModal();
   delete myDlg;
Code:
// Dismiss the dialog coz we're
   // done with it now

   //Now force an update of the entire view
Code:
::Invalidate(FALSE);
}
 
Thanks for all the suggestions...I'm going to do some reading up up what you have suggested...
Thanks again for all your time!!
CES
 
Thanks for all your time!
Just wanted to say that CDocument::UpdateAllViews(NULL) works great! I just added a CDocument global variable initialized it at startup with GetActiveDocument() and now I can update the main view as each of the child CDialogs is unloaded.
CES
 
That's great! As you get more and more into using VC++ you'll eventually want to try and eliminate using global variables because it kind of defeats the whole purpose of using the object-oriented model. Essentially, your classes should be self-sufficient and look after themselves and their own internal workings, etc. - occassionally, you may want to share items/objects etc between your classes instead of using globals.

However, for the time being, as you're learning you should use whatever you feel comfortable with at first. If it means using globals, then feel free to use them until you feel ready to discover the other alternatives that C++ has to offer. Personally, if I'm in a rush to accomplish something, sometimes the quickest and easiest way of doing it is to use a global!! However, if I take the time to work my way around using them, my code appears much neater and my classes become entirely self-sufficient - which is, of course, the whole purpose of using classes in the first place!! :)
 
I know how to do that now but will probably be more comfortable doing so once I complete this of course...I guess I forgot the importance of not usings globals(im quit new to programming)...I hoped you would mention if it was ok but not the best idea...I was also wondering about pointers...I've added CRecordset objects to my CDialog classes as regular objects instead of pointers...being that I am not passing the data around, is this ok...any insight?
Thanks again and again!
CES
 
If you're passing objects around from function to function, you may want to read up on references rather than pointers. A lot of the newer MFC classes now use references instead of pointers - they are a LOT easier to use and understand, especially for newer programmers.

In essence a reference is like an 'alias' of an object. You can pass a reference of an object/variable into a function and perform changes on it:

void SomeClass::SomeFunction()
{
int myInt = 7;

ChangeValue(myInt);

// value of myInt is now 12

// If we hadn't used a reference, myInt would still
// have the original value

}

void SomeClass::ChangeValue(int& intRef)
{
intRef += 5;
}

You will notice the ampersand "&" after the type declaration on ChangeValue()'s parameter. This means that the parameter is a reference to an int rather than an int. Therefore, any changes you make to the int in the function ChangeValue() are made to the original int in the calling function.
You can achieve the same by using pointers but it is not only harder to understand pointers, it also means that, for your custom objects, you usually have to have a copy constructor and overloaded assignment operator.
If you hadn't declared the parameter as a reference and simply left it as an int, the value in SomeFunction() would still be 7 for the int after it called ChangeValue()


All this being said, you do still need to learn about pointers because they are the heart and soul of C/C++ programming!! :-(

Going back to what I was saying earlier about C++ and object-oriented programming and classes being responsible for their own actions, etc. You should try and design your classes so they are 'self-contained' - that way, you can use the same code over and over again in any future programs without having to mess around with global variables and chopping and changing bits around to suit the new project.

As an example, I have just placed a 'TIP' message in this forum with a link to class library I have just written that extracts files from your application onto the user's hard disk at run time. The thread title is:

"Storing/extracting files from application's resources"

This is a classic example of how you can write a useful class which can simply be 'plugged' into any project. There's no need to worry about declaring global variables or anything like that, usually a class such as this will take variables/objects as parameters to perform the necessary work on them or perform useful stuff.

Using the OOP model saves programmers time and therefore money because they are using re-usable code and over again in their projects. I have made this library downloadable so that it will save programmers such as yourself the trouble of hard-coding the stuff yourself when you need a function that performs a particular utility. In other words, if the code is tried and tested and works, you don't need to tear your hair out trying to rewrite it and reinvent the wheel!
 
Thank you for all your time...really appreciated!
CES
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top