Six major mechanisms of MFC

Source: Internet
Author: User
Tags map class win32

I. Entrance function mechanism (program initiation mechanism)

Language Summary:

3.1 Constructing Theapp Object Cwinapp::cwinapp ()

1) Save the &theapp to the current program module status information

2) Save the &theapp to the current program thread state information

3) Afxgetapp/afxgetthread-back to &theapp

3.2 Program Flow (WinMain)

1) Get &theapp with Afxgetapp/afxgetthread

2) Invoking application class member virtual functions with &theapp

InitApplication (Initialize)

3) Invoking application class member virtual functions with &theapp

InitInstance (Create, display window)

4) Invoking application class member virtual functions with &theapp

Run (message loop)

4.1 Calling application class member virtual functions with &theapp

OnIdle (Idle processing)

4.2 Calling application class member virtual functions with &theapp

ExitInstance (Aftercare)

Pseudo code:

Afx_module_state aaa;//Current Program module status information

Afx_module_thread_state bbb;//Current Program thread state information

Constructing Theapp objects

Cwinapp::cwinapp (...)

{

afx_module_state* Pmodulestate=afxgetmodulestate ()

Get global variable &aaa

afx_module_thread_state* pthreadstate = pmodulestate->m_thread;

2

Get global variable &BBB

Pthreadstate->m_pcurrentwinthread = this;

Save &theapp to a member of the global variable BBB

Afxgetthread ()

{

afx_module_thread_state* pState = Afxgetmodulethreadstate ();

Get global variable &BBB

cwinthread* PThread = pstate->m_pcurrentwinthread;

Get &theapp

return pThread;

}

Pmodulestate->m_pcurrentwinapp = this;

Save &theapp to a member of the global variable AAA

AfxGetApp ()

{

Return Afxgetmodulestate ()->m_pcurrentwinapp;

}

}

****************************************

Experience is not the Theapp object guidance process.

WinMain (...)

{

Afxwinmain (...)

{

cwinthread* pThread = Afxgetthread ();

cwinapp* papp = AfxGetApp ();//The above two sentences get &theapp

Papp->initapplication ();

Call CWinApp class member virtual function (initialize) with Theapp object

Pthread->initinstance ();

Invoking a member virtual function of an application class with a Theapp object

Pthread->run ()

Invoking a member virtual function (message loop) of an application class with a Theapp object

{

Cwinthread::run ()//function internal this is &theapp

{

while (no message)

{

This->onidle (...); /Application class member virtual function (idle processing)

}

Do

{

If (GetMessage caught Wm_quit)

return ExitInstance ();

Application class member virtual function (aftercare)

3

}while (...)

}

}

}

}

Second, the window creation mechanism

Language Summary:

1 Loading Menus

2 Call CreateEx Register window class, create window

2.1 Calling PreCreateWindow to design and register the window class

Wndclass wndcls;

....

Wndcls.lpfnwndproc = DefWindowProc;

Finally call the Win32 API function registerclass Register a window class

2.2 Calling the Afxhookwindowcreate function

1) Save Pframe (your own New Frame class object address) to the current program

The thread information.

2) Use:: SetWindowsHookEx function to bury a hook in the program,

The type is WH_CBT.

2.3 Using the Win32 API function:: CreateWindowEx Create window, this function

Once the trigger hook handler function is executed

3 Hook handler function

3.1 Create your own new Frame class object address and window handle one-to-one

The binding relationship.

M_hwnd = hWnd-the window handle can be obtained by pframe

M_permanentmap[hwnd] = pframe

Pframe can be obtained by window handle

3.2 Using the Win32 API function:: SetWindowLong The window handler function more

Change to AfxWndProc (real window processing function)

Pseudo code:

_afxwndframeorview=== "AFXFRAMEORVIEW42SD"

Cmyframewnd *pframe = new Cmyframewnd;

Pframe->create (NULL, "mfccreate")//function internal this is pframe

{

Load Menu

CreateEx (..., NULL:) Inside the function this is pframe

{

4

CREATESTRUCT cs;

Cs.lpszclass = null;//below will change

......

Cs.hinstance = AfxGetInstanceHandle ();

PreCreateWindow (CS)

{

Afxdeferregisterclass (...)

{

Wndclass wndcls;

....

Wndcls.lpfnwndproc = defwindowproc;//Bottom Change

_afxregisterwithicon (&wndcls, "AFXFRAMEORVIEW42SD")

{

&wndcls->lpszclassname = "AFXFRAMEORVIEW42SD";

AfxRegisterClass (&WNDCLS)

{

:: RegisterClass (&WNDCLS);

}

}

}

Cs.lpszclass = "AFXFRAMEORVIEW42SD";

}

Afxhookwindowcreate (pframe)//parameter for self new Frame class object address

{

_afx_thread_state* pthreadstate = _afxthreadstate.getdata ();

Get global variable &CCC (current program thread information)

:: SetWindowsHookEx (WH_CBT ...);

Bury a hook of type WH_CBT in the program

Pthreadstate->m_pwndinit = pframe;

Save your new Frame class object address pframe to a member of the CCC

}

:: CreateWindowEx (...); /This function once executed wm_create message appears

The hook is immediately hooked to the hook handler function.

}

}

*********************************************************

Hook handler function

_afxcbtfilterhook (... wParam.)

{

_afx_thread_state* pthreadstate = _afxthreadstate.getdata ();

Get global variable &CCC

cwnd* Pwndinit = pthreadstate->m_pwndinit;

Get Pframe===pwndinit from the CCC

HWND hwnd = (HWND) wparam;//get window Handle

5

Pwndinit->attach (HWND)//function internal this is Pframe===pwndinit

{

chandlemap* PMap = Afxmaphwnd (TRUE)

{

afx_module_thread_state* pState = Afxgetmodulethreadstate ();

Get global variable &BBB

Pstate->m_pmaphwnd = new Chandlemap (...);

Save the new map class object address in a member of BBB

Return pstate->m_pmaphwnd;

}

Pmap->setpermanent (m_hwnd = hWnd, pframe)

Inside the function this is PMAP (Map class object address)

{

M_permanentmap[hwnd] = pframe;

}

}

WNDPROC AfxWndProc = Afxgetafxwndproc ();

Get the address of the AFXWNDPROC function

:: SetWindowLong (HWnd, GWL_WNDPROC, (DWORD) afxwndproc);

Change the window handler function to AfxWndProc (real window processing function)

}

***************************************************

Take wm_create message as an example

AfxWndProc (...)

{

cwnd* pWnd = cwnd::fromhandlepermanent (hWnd)

{

chandlemap* PMap = Afxmaphwnd ()

{

afx_module_thread_state* pState = Afxgetmodulethreadstate ();

Get &BBB

Return pstate->m_pmaphwnd;

Returns the address of the mapped class object saved above

}

PWnd = (cwnd*) pmap->lookuppermanent (hWnd)

Inside the function this is PMAP (Map class object address)

{

return m_permanentmap[hwnd];//Get Pframe

}

}

Afxcallwndproc (PWnd ...) Pwnd===pframe of parameters

{

Pwnd->windowproc (...)

{

6

Go back to your code

}

}

}

Third, message mapping mechanism

Language Summary:

1 use of the message mapping mechanism

1) class must derive from the CCmdTarget class

2) The Declaration macro must be added within the class Declare_message_map ()

3) Implement macros must be added outside the class

Begin_message_map (Theclass, BaseClass)

End_message_map ()

Implementation of 2 message mapping mechanism

2.1 Data Structures

struct Afx_msgmap_entry (static array per element type)

{

UINT nmessage; Message ID

UINT NCode; Notification code

UINT NID; Command ID/control ID.

UINT Nlastid; Last control ID

UINT NSig; Types of Message handler functions

Afx_pmsg PFN; Address of the message handler function (pointer)

};

struct Afx_msgmap (static variable type)

{

Const afx_msgmap* pbasemap;//

Const afx_msgmap_entry* lpentries;//

};

2.2 Macro Expansion

See Code

2.3 Macro Expand the role of each part

_messageentries[]-static array

Each element holds a pointer to the message-handler function corresponding to the message ID

Messagemap-Static variables

Responsible for getting the parent class static variable address (link list)

The first address of the static array that is responsible for obtaining the corresponding class

Getmessagemap ()-Virtual function

Get the static variable address of this class (Get the link header node)

2.4 Execution of the message-mapping mechanism

7

1) Call Getmessagemap using the Framework class object (Pframe) to get the linked list

Head node (this class static variable address) Pmessagemap

2) Use the second member of Pmessagemap to get the static number of the corresponding class

Group header address, finding the message ID in the array corresponding to the handler function pointer

If 4 is found, if no execution 3 is found

3) Use the first member of Pmessagemap to get the parent class static variable address

If NULL, the end lookup, if not NULL, is performed 2

4) Use the sixth member of this array element found

(Message handler address) completes the processing of the message.

Classification of two MFC messages

1 Windows Standard Example: keyboard/mouse/timer ....

On_wm_xxx

2 Custom Messages

#define Wm_mymessage Wm_user+n

On_message

3 command Message (WM_COMMAND)

On_command

On_command_range (start ID, termination ID, processing function)

Pseudo code:

Take the WM_CREATE message as an example (think about the point Wm_command/wm_paint)

AfxWndProc (...)

{

cwnd* pWnd = cwnd::fromhandlepermanent (hWnd);

Gets the Frame class object address (Pframe===pwnd) bound together with HWND

Afxcallwndproc (pWnd.) Parameter Pwnd===pframe

{

Pwnd->windowproc (...) Inside the function this is Pframe===pwnd

{

Onwndmsg (...) Inside the function this is Pframe===pwnd

{

Const afx_msgmap* PMESSAGEMAP = Getmessagemap ();

Get the Link header node (this class static variable address)

afx_msgmap_entry* Lpentry;

for (; Pmessagemap! = null;//Traversal list find something

Pmessagemap = Pmessagemap->pbasemap)

{

Lpentry = Afxfindmessageentry

(Pmessagemap->lpentries,message ...);

if (lpentry! = NULL)

{

Goto Ldispatch;

}

}

Ldispatch:

8

Union Messagemapfunctions MMF;

MMF.PFN = lpentry->pfn;//Get &oncreate

int nSig = LPENTRY->NSIG;//AFXSIG_LWL

Switch (NSIG)

{

Case AFXSIG_LWL:

LResult = (THIS->*MMF.PFN_LWL) (WParam, LParam);

Break

.....

}

}

}

}

}

Iv. Runtime class information (CRuntimeClass)

1 run-time class information mechanism function

The program can get information about the object related classes during the execution.

(whether the object belongs to this class)

2 run-time class information mechanism usage

Class 2.1 must derive from CObject

Declare macros must be added within class 2.2 declare_dynamic

Implementation macro must be added outside of class 2.3 implement_dynamic

CObject::IsKindOf-You can tell if an object belongs to a class

3 implementation of runtime class information mechanism

3.1 Data structures

struct CRuntimeClass (static variable type)

{

LPCSTR m_lpszclassname;//class Name

int m_nobjectsize; Class size sizeof

UINT M_wschema; Version 0XFFFF of the class

cobject* (pascal* m_pfnCreateObject) ();

The dynamic creation mechanism is used, and the runtime class information mechanism is NULL

Cruntimeclass* M_pbaseclass;

Parent static variable address (for connecting linked list)

Cruntimeclass* m_pnextclass;//is null

};

3.2 Macro-Expanded Code

See Code

3.3 Macro Expand the role of each part

9

Classcdog-Static variables

To save information about a class such as: Class size/name/version.

Getruntimeclass ()-Virtual function

Gets the address of the static variable of this class (the linked list head node)

3.4 The execution process of IsKindOf function

Use this class of objects Yellowdog call virtual functions Getruntimeclass get

Static variable address of this class (linked table head node)

Use this type of static variable address to match the target if the equivalence proof object

belongs to the class, if not equal to the loop comparison

As long as there is an equal proof object belonging to the class during the cycle comparison, the loop

The end is not equal. proves that the object does not belong to this class

**************

Runtime_class (Theclass)-The static variable address of the class inside the parentheses

(&theclass::classtheclass)

Pseudo code:

No

V. Dynamic creation (essentially the new object)

Usually programmatically, programmers use system classes to create objects, calling member functions to complete

Related functions. With dynamic creation, the system's code can create a programmer-defined class of

object, in other words, the underlying code can create objects of the upper class.

Language Summary:

2 use

Creates a class object without knowing the name of the class.

2 use

Class 2.1 must derive from the CObject class

Declare macros must be added within class 2.2 declare_dyncreate

Implementation macro must be added outside of class 2.3 implement_dyncreate

Cruntimeclass::createobject-Dynamically creating class objects

3 implementation

3.1 Difference (and runtime class information mechanism comparison)

Classcdog-Static variables

The fourth member is no longer null and the address of a static function is saved

The difference between functions

One more static function CreateObject

3.2 Effects

CreateObject ()-Static function

New an object of the Cdog class and returns the object address

Classcdog-Static variables

Save the address of the newly added static function CreateObject in the fourth

10

Members of

Getruntimeclass ()-Virtual function

Gets the static variable address of this class (Cdog) (The Chain header node)

3.3 Cruntimeclass::createobject Execution Process

1) Use the fourth member of this class of static variables (Classcdog)

2) Save new Add static function in call member (Cdog::createobject)

Completes the creation of the object (this function internally new a Cdog class of

Object and returns the object address)

Pseudo code:

Dynamic creation mechanism

cobject* Pobject=runtime_class (Cdog)->createobject () {

Inside the function The this pointer is &classcdog---the node of the linked header

cobject* pobject = NULL;

Pobject = (*m_pfncreateobject) ()//call a static variable fourth member

--->cdog::createobject

{

return new Cdog;

}

VI. serialization of objects

Serialization of two

The benefits of introducing the CArchive class: 1 You can set the buffer size for file read and write

2 Read and write various basic data types, no type conversions are required.

1 Concepts

Writes data to a file as a binary stream or read from a file.

2 use

2.1 Open or create a new file

CFile::Open

2.2 File read/write

2.2.1 Defining CArchive objects

2.2.2 Specific data read and write

Carchive::operator >> "read"

Carchive::operator << "Write"

2.2.3 Closing CArchive objects

Carchive::close

2.3 Closing files

CFile::Close

Serialization of three objects (sixth mechanism of MFC)

1 Concepts

11

Serialized object-The class information for the object and the object's member variable as a binary stream

The process of writing to a file in sequential mode.

(Runtime class information is required for serialization)

Deserialize object-Reads the class information from the file, creates the object, and then reads the file

Initializes the process of the newly created object by a member variable in the

(Dynamic creation is a sine qua non for serialization)

2 use

2.1 Defining classes that support serialization

2.1.1 Derived from the CObject class

2.1.2 Adding a serialized declaration macro and Implementation macro

2.1.3 overrides the virtual function serilize (), in the function that completes the data member of the class.

Serialization of

2.2 Read and Write objects

The arguments passed in to read and write objects are the addresses of objects, steps and read-write basic types

The same data.

3 principle-Pseudo-code

3.1 Expanding the structure of a macro

struct AFX_CLASSINIT

{

constructor function

Afx_classinit (cruntimeclass* pnewclass)

{

Afxclassinit (Pnewclass);

{

afx_module_state* pModuleState = Afxgetmodulestate ();

Afxlockglobals (crit_runtimeclasslist);

Saves the current run-time class information to the application's m_classlist linked list

Pmodulestate->m_classlist.addhead (Pnewclass);

Afxunlockglobals (crit_runtimeclasslist);

}

}

};

_init_cstudent is a global structure variable, and the type is a struct-body

Afx_classinit. Before entering the _tmain () function, the current class's

Run-time class information is saved to the M_classlist linked list of module state information

3.2 The process of writing to an object

Ar. WriteObject (POB);

{

Get run-time class information for the current class

cruntimeclass* pclassref = Pob->getruntimeclass ();

Writes information about the class of an object to a file

WriteClass (PCLASSREF);

{

12

Pclassref->store (*this);

{

Class name length

Word Nlen = (word) Lstrlena (m_lpszclassname);

Write version, class name length to file

Ar << (WORD) M_wschema << Nlen;

Write a class name to a file

Ar. Write (m_lpszClassName, nlen*sizeof (char));

}

}

Because of the virtual function mechanism, call the Cstudent::serialize () function,

Writes member variables of a class to a file sequentially

((cobject*) pOb)->serialize (*this);

{

CObject::Serialize (AR);

if (AR. IsStoring ())

{

ar<<m_strname<<m_nage;

}

...

}

}

3.3 The process of reading an object

Ar. ReadObject (Runtime_class (cstudent));

{

Get run-time class information for the current class

ReadClass (pclassrefrequested, &nschema, &obtag);

{

Cruntimeclass::load (*this, &nschema);

{

Ar >> wtemp;

Ar >> nlen;

Ar. Read (Szclassname, nlen*sizeof (char));

Szclassname[nlen] = ' + ';

Looping through the name of a class in a linked list to get runtime class information

for (PClass = pmodulestate->m_classlist; PClass! = NULL;

PClass = Pclass->m_pnextclass)

{

if (Lstrcmpa (szclassname, pclass->m_lpszclassname) = = 0)

{

Afxunlockglobals (crit_runtimeclasslist);

return pClass;

}

}

13

}

}

Creating objects Dynamically

POb = Pclassref->createobject ();

Initializes a new object using a member of a class read from a file

Pob->serialize (*this);

{

CObject::Serialize (AR);

{

...

Else

{

ar>>m_strname>>m_nage;

}

}

}

}


This article from the "Do not know the day" blog, declined to reprint!

Six major mechanisms of MFC

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.