Use view summary on the Dialog Box and document

Source: Internet
Author: User
In MFC, cview and Its Derived classes will display and perform relevant operations well, for example, in the program
If our view class inherits cscrollview, we do not need to write any code.
With a rolling response mechanism, you can automatically determine the value based on the set rolling range and the actual window size.
Whether to display the scroll bar (horizontal or vertical), ceditview, cricheditview, etc.
Corresponding basic operations in different practical scopes.

Usually in a program, we need to process and display some data, and put the display part in the view.
We can ignore most of the window interaction details and focus on the data display.
.

This article is designed to handle the following situations: During data collection and analysis
More data. It is impossible to display it on the main interface of the program. We need a pop-up window to display,
It can be closed at any time, that is, such a window should be dynamically generated and the number is not fixed (this limit
To use the splitting view ). For these pop-up windows, we can write
A derived class, which is completely acceptable, but this requires you to process some column messages such as scrolling (I
I have met such requirements in a grayscale histogram of the displayed image and binary image projection.
At that time, I derived a class from cwnd to display data. Because the image is large, one-Screen Display
The display is incomplete, so we need to add a scroll bar to the window, which takes a lot of time to process these messages,
The code that actually displays data is rare ). Therefore, I have always wanted to use the MFC encapsulated very well.
Cview class and its derived class to display data. Because I mainly use cscrollview
Use it as a column to describe how to use a view.

The implementation based on the dialog box and SDI structure has different details, which must be separated:

 
1. If your program is a dialog box-based program (for example, a dialog generated using the MFC wizard)
Box program), then the thing is very simple:
First, insert a class in insert/new class, and select cscrollview as the base class.
Assume that your own view class is named cmyscrollview.
Oninitdialog in the dialog box (both the main interface dialog box and the new pop-up dialog box)
Add the following code:

Crect rectwndclient;
Getclientrect (& rectwndclient );

Cruntimeclass * pviewruntimeclass = runtime_class (cmyscrollview );

Cmyscrollview * pview = (cmyscrollview *) pviewruntimeclass-> Createobject ();
Pview-> Create (null, null, ws_visible | ws_child,
Rectwndclient,
This, 123, null );
Pview-> oninitialupdate ();

Note:
1) because the constructor of cview and Its Derived classes is a protected member, runtimeclass is used to construct
Object,
2) In the create function, the first parameter must have the ws_child attribute, indicating that the view is a subwindow.
3) The fourth parameter rectwndclient can be changed as needed, because you may only want to be in a certain area of the dialog box.
Create a view.
4) The fifth parameter indicates that the dialog box is used as the parent window of the view.
5) The sixth parameter is the view ID. You can specify an integer as needed.

An error occurs after oninitialupdate is created because the cscrollview class has a protected member.
M_nmapmode, which is set to 0 in the cscrollview constructor, as follows:
M_nmapmode = mm_none; // In the 115 row of viewscrl. cpp, mm_none is a macro and is defined as 0.

The cause of the error is as follows:
Generally, a window draws a customer area when responding to wm_paint. All views are derived from cview. Their wm_paint response functions are as follows:

Void cview: onpaint () // In viewcore. cpp row 176
{
// Standard paint routine
Cpaintdc DC (this );
Onpreparedc (& DC );
Ondraw (& DC );
}

It can be seen that the virtual function onpreparedc will be called before drawing, and this virtual function will be rewritten in cscroolview.
The start part is as follows:

Assert_valid (PDC );

# Ifdef _ debug
If (m_nmapmode = mm_none)
{
Trace0 ("Error: Must Call Setscrollsizes()Or Setscaletofitsize()");
Trace0 ("Before PaintingScroll view .");
Assert (false );
Return;
}
# Endif // _ debug

It can be seen that if m_nmapmode is 0 (it is set to 0 by default in the constructor), it will be wrong during program debugging.
Therefore, when oninitialupdate is called (Note: oninitialupdate is declared as a public member function of cview, but it is declared as protect when the oninitialupdate function of the derived class is generated in the MFC wizard, you can change it to public, call oninitialupdate to initialize your own view, or set m_nmapmode to the desired ing mode in the constructor) to initialize something, set the correct value of m_nmapmode. A typical value of m_nmapmode is mm_text (for details about the ing mode, refer to the relevant articles or books ).


The above describes how to create a view and call related functions in the dialog box. One thing to note is that if you add
If the maximize button is used, you may want to change the view when the dialog box is the largest, so you need to process
Wm_size message. You can adjust the View Size Based on the actual size of the current dialog box. In this way, you need the view pointer.
So your possible program should be like this.

// Declare a pointer to your view in the header file of the dialog box
Cmyscrollview * m_pview;
// Assign a null value to the pointer in the constructor
M_pview = NULL;

// Create a view in oninitdialog

Crect rectwndclient;
Getclientrect (& rectwndclient );
 
Cruntimeclass * pviewruntimeclass = runtime_class (cmyscrollview );
 
M_pview = (cmyscrollview *) pviewruntimeclass-> Createobject ();
M_pview-> Create (null, null, ws_visible | ws_child,
Rectwndclient,
This, 123, null );
M_pview-> oninitialupdat ();
// Change the view size in onsize
If (m_pview) // note that the view has not been created before the onsize is called for the first time, which is also required in the constructor
{// M_pview) reason for null
M_pview-> setwindowpos (null, 0, 0, CX, Cy, swp_nozorder );
}

 

// Note that we use the new method above [specifically when pviewruntimeclass-> Createobject ()] to generate
Cmyscrollview object. Our program does not call the delete statement. Will this cause memory leakage?

The answer is no: The Window accepts the last message wm_ncdestroy. In onncdestroy (), cview calls the virtual function postncdestory.
Both our class and cscrolview did not override postncdestory, so he called the postncdestory function of cview and called it in this function.
Delete this; cview deletes itself, so there will be no memory leakage.

2. Use cview in the dialog box in the SDI (Single Document) Program

Create a view in the pop-up dialog box of SDI. If you use method 1 above, as long as you do not click the view, there will be no problem (this requirement
I'm afraid no one can accept it. ^_^ ).
Let's analyze the cause first. Click the mouse on the view to execute the following functions:

Int cview: onmouseactivate (cwnd * p0000topwnd, uint nhittest, uint message)
{
Int nresult = cwnd: onmouseactivate (psf-topwnd, nhittest, message );
If (nresult = ma_noactivate | nresult = ma_noactivateandeat)
Return nresult; // frame does not want to activate

Cframewnd * pparentframe = getparentframe (); // here *********** ()
If (pparentframe! = NULL)
{
// Eat it if this will cause Activation
Assert (pparentframe = psf-topwnd
| Pdesktopwnd-> ischild (pparentframe); // here, ******** (B)

// Omitted
......
}
Return nresult;
}

The above A and B are the problems we found. The last error is in B, but the cause is.
When it is a dialog box program, such as the first 1, the returned pparentframe value is 0, and B's assertions are not executed, so there will be no errors.
However, in the above SDI case, the pparentframe returned by a is the main framework window of the application, and the psf-topwnd is the dialog box window where the view is located,
We analyzed the code of B and found that pparentframe = psf-topwnd is invalid at this time. And pparentframe (this is the main window)
It is not a subwindow of p0000topwnd (in the dialog box at this time), so assert is false and produces an error.

Looking at the above Code, we still cannot decide how to use cscrollview.

However, observing the implementation of getparentframe at a opens the door to hope for us:

Getparentframe is inherited from cwnd

Cframewnd * cwnd: getparentframe () const
{
If (getsafehwnd () = NULL) // No window attached
Return NULL;

Assert_valid (this );

Cwnd * pparentwnd = getparent (); // start with one parent up
While (pparentwnd! = NULL)
{
If (pparentwnd-> isframewnd ())
Return (cframewnd *) pparentwnd;
Pparentwnd = pparentwnd-> getparent ();
}
Return NULL;
}

After analyzing this code, it is found that his purpose is to roll back in the window of his ancestor until a window of the framewnd type is found, and then the pointer of the window object is returned (if not, return NULL). Such a window exists in SDI (the main frame window is !).
We know from the previous analysis that p0000topwnd is a dialog box window, and it must not be a framework window. Therefore, the first part of the assertion cannot meet the requirements of only the next one, psf-topwnd-> ischild (pparentframe). As mentioned earlier, the main framework cannot be a subwindow of the dialog box. Therefore, if psf-topwnd-> ischild (pparentframe) meets the requirements, that is, a cframewnd window is a subwindow of the dialog box and a parent window of the view (because getparentframe is traced from the view ), therefore, we can embed a cframewnd or a derived class object in the dialog box and view. Since cframewnd itself does not require any operation, we do not need to derive a cmyframewnd of our own, and cframewnd is used directly. Therefore, the possible code is as follows:

Crect rectwndclient;
Getclientrect (& rectwndclient );

Cframewnd * pframe = new cframewnd ();
Pframe-> Create (null, null, ws_visible | ws_child, rectwndclient, this );

Cruntimeclass * pviewclass = runtime_class (cmyscrollview );

Cmyscrollview * pview = (cmyscrollview *) pviewclass-> Createobject ();
Pview-> Create (null, null, ws_visible | ws_child,
Rectwndclient,
(Pframe, 123 );
Pview-> oninitialupdate ();

To dynamically change the view size with the size of the dialog box, you can use pframe and pview as members of the dialog box.
Some of my own operations are as follows:

// Declare a pointer to your view in the header file of the dialog box
Cframewnd * m_pframe;
Cmyscrollview * m_pview;

// Assign a null value to the pointer in the constructor
M_pframe = NULL;
M_pview = NULL;

// Create a view in oninitdialog

Crect rectwndclient;
Getclientrect (& rectwndclient );

M_pframe = new cframewnd ();
M_pframe-> Create (null, null, ws_visible | ws_child, rectwndclient, this );
 
Cruntimeclass * pviewclass = runtime_class (cmyscrollview );

M_pview = (cmyscrollview *) pviewclass-> Createobject ();
 
M_pview-> Create (null, null, ws_visible | ws_child,
Rectwndclient,
M_pframe, 123 );
M_pview-> oninitialupdate ();

// Change the view size in onsize

// Note that the view has not been created before the first onsize call, which is also required in the constructor
// M_pframe, m_pview causes null

If (m_pframe & m_pview)
{
M_pframe-> setwindowpos (null, 0, 0, CX, Cy, swp_nozorder );
M_pview-> setwindowpos (null, 0, 0, CX, Cy, swp_nozorder );
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.