Solved

Basic Doc-View explanation

Posted on 2000-02-13
17
309 Views
Last Modified: 2013-11-20
Could someone explain the basic mechanics of the Document View architecture?
Is it true that the "View" is a GUI control/widget and a "Document" is a OO model?

Is it possible then, to associate a specific model object attribute e.g. customer1.name with a GUI static text control using document/view?  Or is that too fine grained?

thanks,
-Andy
0
Comment
Question by:abulka
  • 8
  • 5
  • 3
  • +1
17 Comments
 
LVL 30

Expert Comment

by:Zoppo
Comment Utility
Hi abulka,

This is from MSDN:

---------------------------------------------------------------------------------------------------------------------
The CDocument class provides the basic functionality for programmer-defined document classes. A document represents the unit of data that the user typically opens with the Open command on the File menu and saves with the Save command on the File menu.

The CView class provides the basic functionality for programmer-defined view classes. A view is attached to a document and acts as an intermediary between the document and the user: the view renders an image of the document on the screen and interprets user input as operations upon the document. The view also renders the image for both printing and print preview.
---------------------------------------------------------------------------------------------------------------------
(search MSDN index for 'MFC document/view architecture' and see related articles)

associating an object from the document to the view as you mentioned is only possible by setting the data in the view's OnInitialUpdate() and updating the data in the view's OnUpdate(). Direct association is difficult because a document can have multipe views.

hope that helps,

ZOPPO
0
 
LVL 1

Expert Comment

by:andymurd
Comment Utility
MSDN can be a bit wordy and technical - so here's an example. Think of a document which is a load of sales figures for lots of different salespersons. There are many different ways to view this info:

* A graph of the performance of each salesperson.
* A Table (like Access) which allows the data to be edited.
* A Report
etc

The document doesn't change but it has different views applied to it.

Similarly, if you wanted to store that sales figures in a database instead of a file, the same views could be applied to a different document class (if the coders weren't lazy and provided proper accessor functions).

If you've heard of the model/view/controller design pattern, document view is kind of like that.
0
 

Author Comment

by:abulka
Comment Utility
I am familiar with MVC, and other similar patterns.  So with Doc/View - assuming I have 3 'business objects' (3 customer objects) and I want to display them on a form.  What would be the basic steps?  Here is my guess:

1. Derive CCustomer from CDocument?
2. Derive a form from CView?
3. Register the form as an 'observer' of each customer object e.g.
  form1.attach( cust1 );
  form1.attach( cust2 );
  form1.attach( cust3 );
4. In the form1.OnUpdate ask
  if updateType = 'some type of interest'
      editgui1.text = cust1.name;
      editgui2.text = cust1.phone;
      editgui3.text = cust1.address;

I have taken some liberties with names and methods, and stand to be corrected.  I hope the gist of what I am doing is right though - is it?
0
 
LVL 30

Expert Comment

by:Zoppo
Comment Utility
Hi abulka,

this depends on what you wanna do:

seems that you wanna try to put multiple documents together with one view. This is not possible. You can only have multiple views for one document. So, I would suggest something like this:

- create a class for data you need to hold called CCustomer (you can derive this from CObject to give the class standard MFC serialization functionality)
- create a document class derived from CDocument, i.e. CCustomerDoc and there implement a container for CCustomer objects, i.e. a CArray or a CList or a CMap.
- override the documents Serialize() function and implement loading and saving of this CCustomer container.

Next steps depend on what type of view-design you like to have:

1. You can create a single formview for all customers, or
2. you can create a formview for one customer and some selection functionality (i.e. select customer with dialog or a split window with a list or a tree holding the customers)

BTW, at very first you'll have to decide if you app should be MDI or SDI. Think about this carefully. It's nearly impossible (or at least very hard) to re-design an SDI app as MDI or vice versa. Think about all the pros and contras for both.

hope this helps,

ZOPPO
0
 

Author Comment

by:abulka
Comment Utility
Ok - Zoppo - that's a most useful comment.  It seems you need to have one single 'document' object that aggregates all the business objects in the model.  Would that be a correct way of phrasing it?

And finally, could you say just a little more about the form side of things. e.g.

4. In the form1.OnUpdate ask
  if updateType = 'some type of interest'
      editgui1.text = cust1.name;
      editgui2.text = cust1.phone;
      editgui3.text = cust1.address;

(my above pseudo code is my current understanding of what goes on).  I would suspect that some notification happens (an event handler?) and that information (via a parameter?) is passed saying WHICH particular business object (and what aspect?) of it has changed.  Then it is up to the form code to decide what to do with it?  Is that the gist of it?
0
 
LVL 30

Expert Comment

by:Zoppo
Comment Utility
Now, I assume with 'form' you mean some dialog like input mask (with edit controls, buttons, combo boxes and so on...), so using a CFormView is best way to do this. For this do following:

When start creating your app in the last pane of the AppWizard you can select the base class of your application's view class. Select CFormView. Then AppWizard creates an empty dialog resource which will be used as template for the formview. There add the controls you need, give them senseful resource IDs and add member variables for the controls with ClassWizard (i.e. a CString m_CustomerName as member variable for the edit box you want to use for the customer's names).
So you can now simply set/get the edit box's text somehow like this:

// get text entered to edit box
UpdateData( TRUE );
// now the entered text is in m_CustomerName...

// set text to edit box
m_CustomerName = "NewCustomer";
UpdateData( FALSE );

You just have to take a little bit care because all controls which has a member variable attached are updated when UpdateData() is called, so no way to pass any hint which controls need update.

Then you can implement a OnUpdate() function for the view which gets passed a pointer to a view(pSender), a LPARAM(lHint) and a pointer to a CObject(pHint). The LPARAM can be used to pass control values to the function, the COpbject pointer can be used to pass data to the function. This function is called for every view (except the view passed as pSender if pSender not zero) when CDocument::UpdateAllViews() is called. So you can implement it somehow like this:

#define UPD_HINT_GET_VALUES 1
#define UPD_HINT_SET_VALUES 2

CMyView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
 CMyDoc* pDoc = GetDocument();
 if ( lHint & UPD_HINT_GET_VALUES )
 {
  UpdateData( TRUE );
  // here you can set the data in the document with the entered data of the form view
 }

 if ( lHint & UPD_HINT_SET_VALUES )
 {
  // here you can set the form view's data with the data of the document
  UpdateData( FALSE );
 }
}

now, the only thing you'll have to do when i.e. selecting a new customer is something like:

CMainFrame::OnSelectNewCustomer()
{
 CView* pView = GetActiveView(); // this is for SDI, for MDI you'll have first to get the active view's child frame with MDIGetActive()
 CMyDoc* pMyDoc = (CMyDoc*)pView->GetDocument();

 // first update the data eventually entered for the previous customer
 pView->OnUpdate( NULL, UPD_HINT_GET_VALUES, NULL );

 // next set new values to the view(s)
 pMyDoc->UpdateAllViews( NULL, UPD_HINT_SET_VALUES, NULL );
}


Any further stuff (especially the messages you need to handle) strongly depends on how you design you application. Some messages need to be handled completely different for SDI and MDI. Further you'll need any possibility to select a customer from the documents customer list, i.e. simply through a combo box in the form view or even more complex through a list(or tree) view in an extra pane of a splitted window (somehow like explorer window).

ok, that's nearly all I can say without more info.

hope my description sounds meaningful,

ZOPPO
0
 

Author Comment

by:abulka
Comment Utility
Adjusted points from 50 to 75
0
 

Author Comment

by:abulka
Comment Utility
That's great - just the sort of stuff I wanted to know.  I'll accept your last answer.  Just one more thing... (I've bumped the points a little higher)

I've heard an argument to say that its sometimes useful to introduce a class that sits in between the view and the doc.  This intermediate class inherits from view, rather than a form having to inherit from view.  The intermediate class would encapsulate and manage the view behaviour.  Its sort of like an adaptor or mediator.  It saves you from having to have the form inherit from view and keeps the form clean.  What do you think of this idea?  Especially the sentence:
  "DV users often avoid sub-classing GUI controls by introducing an adapter class which inherits from the ‘view’ class."

Also, have you heard of the DocManager class in this framework?  I don't know what it does...  Could this DocManager class be doing anything like the mediation/adaptor role described above.  Or is the DocManager class just an aggregate/ manager for document objects?

thanks for any thoughts.
0
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 
LVL 30

Expert Comment

by:Zoppo
Comment Utility
Hmm, I'm not sure if I really understand what this 'adaptor'-class should do ... would be good if you could explain this with a little pseudo code. BTW, I think it's mostly a good idea to implement a clean interface class for related classes.

CDocManager is just a kind of interface class used by the CWinApp class to handle document templates and default document-dependant functionality

ZOPPO
0
 

Author Comment

by:abulka
Comment Utility
Adjusted points from 75 to 80
0
 

Author Comment

by:abulka
Comment Utility
(sorry for the delay in my repsonding to this thread...)

The CandyCustomAdaptor adapter class would implement the 'view' interface and forward things onto a regular form.

This would alleviate the need for the visual form to know about doc/view or having to inherit/implement view.

So what I am basically asking is: is this a common/useful/workable technique?  Some doc/view programmer friend of mine reckons he does it.
0
 
LVL 3

Expert Comment

by:darinw
Comment Utility
This question has been undeleted.  The points for this question were originally 80 but have been reduced to 0
0
 
LVL 3

Expert Comment

by:darinw
Comment Utility
Adjusted points from 0 to 80
0
 
LVL 3

Expert Comment

by:darinw
Comment Utility
Restoring question.

darinw
Customer Service
0
 

Author Comment

by:abulka
Comment Utility
zoppo - could you comment on my last comment so that I can award your points and close this thread?  thanks for your patience on the slow progress on this one.
-Andy
0
 
LVL 30

Accepted Solution

by:
Zoppo earned 80 total points
Comment Utility
Now, to your last comment I only can say that it is always a good and useful style (and especially good for maintenance) to implement anything as modular as possible, and since I do not see any disadvantage of this technique I would recommend it.

I myself must say that I use a nearly similar way for implementing GUI in my companie's application (it's some CAD-like GUI): I created a view derived from CScrollView, added message handlers for all needed messages, created two new classes CDrawHelper (implements primitve drawing functionality) and CPosHelper (implements functions for the view to use in the message handlers for dynamic position/movement/modification of objects). These two helper classes are implemented as a dll, so later re-use in other applications should be possible with little work. The view itself doesn't know anything about objects and their drawing/handling.

ZOPPO
0
 

Author Comment

by:abulka
Comment Utility
Answer accepted
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: Dynamic window placements and drawing on a form, simple usage of windows registry as a storage place for information. Continuing from the first article about sudoku.  There we have designed the application and put a lot of user int…
Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
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.
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…

728 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

9 Experts available now in Live!

Get 1:1 Help Now