MFC fifth Day

Source: Internet
Author: User

An MFC view
1, related issues
View window--a window of data that can be interactively manipulated by the user
MFC view class CView and its subclasses
2. The view window uses the frame window with the title bar, which is the parent window, and the view window does not have a title bar, which is a child window
2.1 derives the CView class from its own view class (CMyView) and needs to override a virtual function OnDraw
Create a view window in a wm_create message in a frame window

The WM_PAINT message is processed, OnDraw () does not execute
A frame window can contain multiple view windows, but only one is the active window, with focus. Mouse click to get focus.


Theapp
|->m_hmainwnd (Save frame class object address)
|->m_pviewactive (Save view class object address)

3. Command message processing. (WM_COMMAND)
Cframewnd::oncmdmsg Internal Code Execution order
1 using GetActiveView to get the address of the view class object, traverse the view class This spur list finds the processing of messages Pview->oncmdmsg
2. Use the implied this pointer (pframe) to call OnCmdMsg, traverse the Framework class this spur list find message processing
3. Use the Theapp object to call OnCmdMsg, traverse the application class This branch of the chain list to find message processing.
View--->frame--->app

Two. Runtime class information mechanism
1. The role of the runtime class information mechanism
During a program's run, you can determine the information about the class object's related classes and inherit derived relationships
1. Role
Class 2.1 must derive from CObject
2.2 Class internal must add declaration macro Declare_dynamic (Theclass)
2.3 Add implementation macros outside of class
Implement_dynamic (Theclass,baseclass)

CObject::IsKindOf




struct CRuntimeClass
{
Attributes
LPCSTR m_lpszclassname;//class Name
int m_nobjectsize; The size of the class sizeof
UINT M_wschema; Schema number of the loaded class//category version
cobject* (pascal* m_pfnCreateObject) (); NULL = abstract class
Dynamic creation mechanism use (run-time class information is null)
#ifdef _afxdll
cruntimeclass* (pascal* M_pfngetbaseclass) ();
#else
Cruntimeclass* M_pbaseclass; Xxxxx
#endif

Operations
cobject* CreateObject ();
BOOL isderivedfrom (const cruntimeclass* pbaseclass) const;

Implementation
void Store (carchive& ar) const;
Static cruntimeclass* PASCAL Load (carchive& ar, uint* pwschemanum);

CRuntimeClass objects linked together in simple list
Cruntimeclass* M_pnextclass; Linked list of registered classes//null
};




4 expanded Sections
Classcdog--Static variables hold the class name/size/version of the related information ....
Geyruntimeclass virtual function
Gets the static variable address (&classcdog) of the Cdog class (Gets the list header node)

Runtime_class (class name)-Gets the address of the static variable of the class indicated in parentheses



5 IsKindOf function Execution procedure
5.1 Gets the static variable address of the class to which the object belongs (&classcdog)
5.2 Take this static variable &classcdog and be judged by the type &classcobject to compare if the equivalence proves that the object belongs to the class
5.3 If unequal gets the static variable address of the parent class compared to the &classcobject cycle of the judged class, as long as there is an equality case certificate
Object belongs to this class
5.4 No equality case proves that the object does not belong to that class.

Three dynamic creation mechanisms
1. The role of dynamic creation mechanisms
Creates an object of a class without knowing the class name.
2. Use of dynamic creation
1. Class must derive from CObject
2. Add Declaration macro Declare_dyncreate (Theclass) inside class
3. Add implementation macro Implement_dyncreate (Theclass,baseclass) outside the class

Dynamically creating objects with Cruntimeclass::createobject
3. Macro expansion of the role of each part
3.1 Static variables are changed
Afx_comdat Const AFX_DATADEF CRuntimeClass cdog::classcdog = {
"Cdog",//
sizeof (class Cdog),
0xffff,cdog::createobject,//
Runtime_class (Canimal),//
Null
};
3.2 More than a static function CreateObject
New an object, the disease returns the object address.
4. Execution process
4.1 First get the static variable address of the Cdog class (&cdog::classcdog)
4.2 Use this function address to invoke the Cruntimeclass::createobject function
4.3 Call the fourth member of the Cdog::classcdog static variable inside this function (cdog::createobject)
4.4 In this function new is an object of the Cdog class and returns the object address.
Four. Segmentation of Windows
Window Segmentation related issues
1. The static split window is sliced when it is created, and you can slice multiple view windows up to 16*16
2. Dynamic segmentation Program in the course of operation, according to the user needs real-time slicing up to 2*2 multiple windows, but is a unified type of

Cspiltterwnd-The parent class is CWnd, a frame class CFrameWnd mouth font

Static slicing
overriding virtual functions CFrameWnd::OnCreateClient
Defining a CSplitterWnd class object inside a function
To create a frame window using an object call Csplitterwnd::createstatic
Call Csplitterwnd::createview to add a view window to each section


*****************************************************************
Run-time class information pseudo-code
Yellowdog.iskindof (Runtime_class (Cdog) {//function internal this pointer is &yellowdog, parameter &cobject::classcobject
cruntimeclass* pclassthis = Getruntimeclass ();//Get the link list header node
Return Pclassthis->isderivedfrom (PClass); {//pclass Tail node
Inside the function The this pointer is a pclassthis-linked header node ==&cdog::classcdog
Const cruntimeclass* Pclassthis = this; This==&cdog::classcdog
while (Pclassthis!-null) {
if (Pclass==&cobject::classcdog) {
return TRUE;
}
pclassthis=pclassthis->m_pbaseclass;
}
return FALSE;
}
}



***************************************************************
Dynamic creation mechanism
Runtime_class (Cdog)->createobject () {//this==&cdog::classcdog
Pobject= (*pfncreateobject) (); {
Return new Cdog;//new An object and returns the address.
}
}








*************************************************
BOOL cruntimeclass::isderivedfrom (const cruntimeclass* pbaseclass) const
{
ASSERT (This! = NULL);
ASSERT (afxisvalidaddress (this, sizeof (CRuntimeClass), FALSE));
ASSERT (Pbaseclass! = NULL);
ASSERT (afxisvalidaddress (pbaseclass, sizeof (CRuntimeClass), FALSE));

Simple SI case
Const cruntimeclass* Pclassthis = this;
while (pclassthis! = NULL)
{
if (pclassthis = = Pbaseclass)
return TRUE;
#ifdef _afxdll
Pclassthis = (*pclassthis->m_pfngetbaseclass) ();
#else
Pclassthis = pclassthis->m_pbaseclass;
#endif
}
return FALSE; Walked to the top, no match
}



BOOL cobject::iskindof (const cruntimeclass* pClass) const
{
ASSERT (This! = NULL);
It better is in valid memory, at least for CObject size
ASSERT (afxisvalidaddress (this, sizeof (CObject)));

Simple SI case
cruntimeclass* pclassthis = Getruntimeclass (); Yellowdog->getruntimeclass (); Returns the head node.
Return Pclassthis->isderivedfrom (PClass);
}



This process is consistent with wm_create
Onwndmsg () {
OnCommand () {
UINT NID = LoWord (WParam); Gets the ID of the clicked menu item
...
ONCMDMSG (NID ...) {
cview* PView = GetActiveView () {;//this==pframe gets the view with focus
return m_pviewactive;
}
Pview->oncmdmsg (NID, NCode, Pextra, phandlerinfo) {;//function internal pointer is PView

}
}
}
}


BOOL cwnd::onwndmsg (UINT message, WPARAM WPARAM, LPARAM LPARAM, lresult* pResult)
{
LRESULT LRESULT = 0;

Special case for commands
if (message = = WM_COMMAND)
{//Menu hangs on frame window
if (OnCommand (WParam, LParam))//this==pframe
{
LResult = 1;
Goto Lreturntrue;
}
return FALSE;
}
.....
}


void Cview::onpaint ()
{
Standard Paint Routine
CPAINTDC DC (this);
OnPrepareDC (&DC);
OnDraw (&DC); The parent class calls
}


cview* Cframewnd::getactiveview () const
{
ASSERT (m_pviewactive = = NULL | |
M_pviewactive->iskindof (Runtime_class (CView)));
return m_pviewactive;
}

Cmyview::ondraw (CDC * 0x0018fa98 {cpaintdc hwnd=0x00060190}) line 16
Cview::onpaint () line 185
cwnd::onwndmsg (unsigned int, unsigned int 0, long 0, long * 0x0018fc08) line 1836
Cwnd::windowproc (unsigned int, unsigned int 0, long 0) line 1596 + bytes
Afxcallwndproc (CWnd * 0x028d1680 {CMyView hwnd=0x00060190}, hwnd__ * 0x00060190, unsigned int, unsigned int 0, long 0) Line 215 + bytes
AfxWndProc (hwnd__ * 0x00060190, unsigned int, unsigned int 0, long 0) line 379
user32! 760162FA ()
user32! 76017316 ()
user32! 76016de8 ()
user32! 76016e44 ()
ntdll! 776F011A ()
Cwnd::updatewindow () line 118 + bytes
Cmywinapp::initinstance () Line 62
Afxwinmain (hinstance__ * 0x00400000, hinstance__ * 0x00000000, char * 0x006f588e, int 1) line + one bytes
WinMain (hinstance__ * 0x00400000, hinstance__ * 0x00000000, char * 0x006f588e, int 1) Line 30
WinMainCRTStartup () line 198 + bytes
kernel32! 767B33CA ()
ntdll! 77719ed2 ()
ntdll! 77719ea



cobject* Cruntimeclass::createobject ()
{
if (m_pfnCreateObject = = NULL)//this->
{
TRACE (_t ("error:trying to create object which are not")
_t ("Declare_dyncreate \nor declare_serial:%hs.\n"),
m_lpszClassName);
return NULL;
}

cobject* pobject = NULL;
TRY
{
Pobject = (*m_pfncreateobject) ();
}
End_try

return pobject;

}


Macro expansion

#ifdef _afxdll#define declare_dynamic (class_name) protected:static cruntimeclass* PASCAL _getbaseclass (); public:static Const AFX_DATA CRuntimeClass class# #class_name; Virtual cruntimeclass* getruntimeclass () const; #define _DECLARE_DYNAMIC (class_name) protected:static cruntimeclass* PASCAL _getbaseclass (); Public:static afx_data CRuntimeClass class# #class_name; Virtual cruntimeclass* getruntimeclass () const; #else # define DECLARE_DYNAMIC (class_name) public:static const afx_data CRuntimeClass class# #class_name; Virtual cruntimeclass* getruntimeclass () const; #define _DECLARE_DYNAMIC (class_name) public:static afx_data cruntimeclass class# #class_name; Virtual cruntimeclass* getruntimeclass () const; #endifstruct cruntimeclass{//attributeslpcstr m_lpszclassname;int m_nobjectsize; UINT M_wschema; Schema number of the loaded classcobject* (pascal* m_pfncreateobject) (); NULL = abstract Class#ifdef _afxdllcruntimeclass* (pascal* m_pfngetbaseclass); #elseCRuntimeClass * M_PBASECL#endif//operationscobject* CreateObject (); BOOL isderivedfrom (const cruntimeclass* pbaseclass) const;//implementationvoid Store (carchive& ar) const;static cruntimeclass* PASCAL Load (carchive& ar, uint* pwschemanum);//CRuntimeClass objects linked together in simple Listcru       Ntimeclass* M_pnextclass; Linked list of registered classes}; #ifdef _afxdll#define implement_runtimeclass (class_name, Base_class_name, Wschema , pfnnew) cruntimeclass* PASCAL Class_name::_getbaseclass () {return runtime_class (base_class_name);} Afx_comdat Const AFX_DATADEF CRuntimeClass class_name::class# #class_name = {#class_name, sizeof (class class_name), Wschema, Pfnnew, &class_name::_getbaseclass, NULL}; cruntimeclass* Class_name::getruntimeclass () const {return runtime_class (class_name);} #define _implement_ RuntimeClass (Class_name, Base_class_name, Wschema, pfnnew) cruntimeclass* PASCAL Class_name::_getbaseclass () {return Runtime_class (Base_class_name); } afx_comdat afx_datadef CrunTimeclass class_name::class# #class_name = {#class_name, sizeof (class class_name), Wschema, Pfnnew, &class_name::_ Getbaseclass, NULL}; cruntimeclass* Class_name::getruntimeclass () const {return runtime_class (class_name);} #elseAFX_COMDAT Const AFX_ Datadef CRuntimeClass class_name::class# #class_name = {#class_name, sizeof (class class_name), Wschema, Pfnnew, runtime_ CLASS (Base_class_name), NULL}; cruntimeclass* Class_name::getruntimeclass () const {return runtime_class (class_name);} #define _implement_ RuntimeClass (Class_name, Base_class_name, Wschema, pfnnew) afx_datadef CRuntimeClass class_name::class# #class_name = { #class_name, sizeof (class class_name), Wschema, Pfnnew, Runtime_class (Base_class_name), NULL}; cruntimeclass* Class_name::getruntimeclass () const {return runtime_class (class_name);} \

#define DECLARE_DYNCREATE (class_name) declare_dynamic (class_name) Static cobject* PASCAL CreateObject ();p rotected: Static cruntimeclass* PASCAL _getbaseclass (); Public:static afx_data CRuntimeClass class# #class_name; Virtual cruntimeclass* getruntimeclass () const; #ifdef _afxdll#define declare_dynamic (class_name) protected:static cruntimeclass* PASCAL _getbaseclass (); public:static Const AFX_DATA CRuntimeClass class# #class_name; Virtual cruntimeclass* getruntimeclass () const; #define _DECLARE_DYNAMIC (class_name) protected:static cruntimeclass* PASCAL _getbaseclass (); Public:static afx_data CRuntimeClass class# #class_name; Virtual cruntimeclass* getruntimeclass () const; #else # define IMPLEMENT_DYNCREATE (Class_name, base_class_name) cobject* PASCAL class_name::createobject () {return new class_name; } implement_runtimeclass (Class_name, Base_class_name, 0xFFFF, class_name::createobject) #ifdef _afxdll#define Implement_runtimeclass (Class_name, Base_class_name, Wschema, pfnnew) Cruntimeclass* PASCAL Class_name::_getbaseclass () {return runtime_class (base_class_name);} Afx_comdat Const AFX_DATADEF CRuntimeClass class_name::class# #class_name = {#class_name, sizeof (class class_name), Wschema, Pfnnew, &class_name::_getbaseclass, NULL}; cruntimeclass* Class_name::getruntimeclass () const {return runtime_class (class_name);} #define _implement_ RuntimeClass (Class_name, Base_class_name, Wschema, pfnnew) cruntimeclass* PASCAL Class_name::_getbaseclass () {return Runtime_class (Base_class_name); } afx_comdat afx_datadef CRuntimeClass class_name::class# #class_name = {#class_name, sizeof (class class_name), Wschema, Pfnnew, &class_name::_getbaseclass, NULL}; cruntimeclass* Class_name::getruntimeclass () const {return runtime_class (class_name);} #else # define Implement_ RuntimeClass (Class_name, Base_class_name, Wschema, pfnnew) afx_comdat const afx_datadef CRuntimeClass class_name:: class# #class_name = {#class_name, sizeof (class class_name), Wschema, Pfnnew, Runtime_clasS (Base_class_name), NULL}; cruntimeclass* Class_name::getruntimeclass () const {return runtime_class (class_name);} #define _implement_ RuntimeClass (Class_name, Base_class_name, Wschema, pfnnew) afx_datadef CRuntimeClass class_name::class# #class_name = { #class_name, sizeof (class class_name), Wschema, Pfnnew, Runtime_class (Base_class_name), NULL}; cruntimeclass* Class_name::getruntimeclass () const {return runtime_class (class_name);} #endif ********************** cobject* Cruntimeclass::createobject () {if (m_pfnCreateObject = = NULL) {TRACE (_t ("Error:trying to create object Which is not ") _t (" Declare_dyncreate \nor declare_serial:%hs.\n "), m_lpszclassname); return NULL;} cobject* pobject = NULL; Try{pobject = (*m_pfncreateobject) ();} End_tryreturn Pobject;}


MFC fifth Day

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.