// Keywords: // Face object programming, superclass, subclass, superclassing // mfc, cWnd :: subclasswindow // General control, cmnctrl //// Topic: // Via CWnd :: SubclassWindow function Analysis, talk about the implementation of superclassics in MFC ////// background // I met Mahongxi (Grilled chicken wings) in 2002-201 (color tou) a post on 9CBS // introduced MFC The summary concept of the form, the following is a summary of my personal postback /// / log // Modification: PANR 2002-12-15 13:30 layout, transfer to 9CBS Document Center // Modify: PANR 2002-12-15 13:30 erword // Original: PANR 2002-12-13 12:00 /// About "document center" // In that post, see NJTU_SHIYL (Yujing) mentioned the document center, / / I have been thinking about where the document center is? // Later, I came here again, I came here with my wings, so this article is a sympathy is my first // I'm estimated that I am looking to the place ... ////
1: Summary Overview After the form example in the MFC is supercolar, the system provides two capability: 1. We call the member function to call the member function directly to change the relevant form handle. Corresponding form 2. The message transmitted to the relevant form handle will first pass the message map of the form instance.
I will give an example to explain: For example, I wrote a class called CSUPEREDIT (parent class as CEDIT), in this class, I declare void onchar (uint nchar, uint nrepcnt, uint nflags); and add it in the message loop ON_WM_CHAR now I now declare CSUPEREDIT M_EDIT in dialog CPROG1DLG; then add the following code in CPROG1DLG: ONINITDIALOG, complete "super category": hwnd hwndcontrol = :: getdlgitem (pParent-> m_hwnd, IDC_EDit1); m_edit.subclassWindow (HWNDControl);
Thus the supercarbying process: When we call m_edit.setWindowText ("
2: Overview of supercuro-realization All secrets are in CWnd :: SubclassWindow, let's check what it did, the following is a function body (in wincore.cpp file): BOOL CWND :: SubclassWindow HWND HWND) {if (! Attach (hwnd)) Return False;
// allow any other subsclassing to occur propclasswindow ();
// now hook into the AFX WndProc WNDPROC * lplpfn = GetSuperWndProcAddr (); WNDPROC oldWndProc = (WNDPROC) :: SetWindowLong (hWnd, GWL_WNDPROC, (DWORD) AfxGetAfxWndProc ()); ASSERT (! OldWndProc = (WNDPROC) AfxGetAfxWndProc ()) Combine True;} Combine Note It is not difficult to think of PresubClassWindow is a non-functional function, so we can learn about CWnd :: attach and :: afxgetafxWndproc in both CWnd :: attach and :: afxgetafxWndProc Corresponding to the implementation of the function 1, "We call the member function to call the member function directly change the corresponding form" :: AFXGetAfxWndProc function corresponds to function 2, ie "system pass to related forms The message of the handle will pass the message mapping of the form instance "
Three: The function of the function 1 CWnd :: Attach's function body is as follows (in wincore.cpp file): BOOL CWND :: attach (hwnd hwndnew) {if (hwndnew == null) Return False;
ChandleMap * pmap = AFXMAPHWND (TRUE); // Create Map if not exist
Assert (pmap! = Null); pmap-> setpermanent (m_hwnd = hwndnew, this); return true;} The most critical is m_hwnd = hwndnew (friends who have come into contact with Windows API know all form operation functions It's all called the form handle as a call parameter. Obviously, as long as I save the form's handle, then I can specify a form in the system, and then operate it for the form. The idea is this simple. We now see CWnd (Don't forget that Csuperedit is inherited from CWnd, CSUPEREDIT is CSUPEREDIT) Save the handle of IDC_EDIT1 in the Attach function in the member variable m_hwnd, then implement the function 1, nature is not there In
As for the Chandlemap :: setPermanent function, it is used to extend the use of the handle, and is independent of "superclasses", not discuss here, and the specific implementation can refer to WinHand_.h file
Four: Function 2 Implementation 4: The GWL_WndProc property of the form handle is in the previous discussion, I said that Function 2 is related to: AFXGetAfxWndProc, the implementation of this function is like this (also in WinCore.cpp file : WndProc AFXAPI AFXGETAFXWNDPROC () {# iFDef_AFXDLL Return AFXGETModuLestate () -> m_pfnafxwndproc; #ELSE Return & AfxWndProc; #ENDIF}
This refers to the call to AFXGETModuleState () -> m_pfnafxWndProc; otherwise return the address of the AFXWndProc function. Thus in the general executable of CWnd :: SubClassWindow for function 2 can be simplified as a line :: setWindowlong (HWND, GWL_WNDPROC, (DWORD & AFXWNDPROC); the function of this function is to put the GWL_WndProc property of the form handle HWND Set to the address of the AFXWndProc, then the problem that is urgently needed is: What is the GWL_WndProc property of the form handle? In fact, I don't have to say, everyone guess (because we are discussing the form of the form, and I have been saying AFXWndProc is a function), its role is to specify the processing function of the form message to be more accurate to this property. The description is as follows: For all messages sent to the form, the Windows operating system will call the function specified by the form handle's GWL_WndProc property of the message handle.
Four points: Transfer to the MFC environment (this section refers to Houjie Teacher "20,000 miles" in the "Two Military Mills" in the "Message Mapping and Command Pass") in the "Two Map and Command Pass") The function 2 can be expressed as: AFXWndProc How does the function find a message written for the CSUPEREDIT class? Or from the body of the function LRESULT CALLBACK AfxWndProc (HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam) {// special message which identifies the window as using AfxWndProc if (nMsg == WM_QUERYAFXWNDPROC) return 1;
// All Other Messages Route Through Message Map CWND * PWND = CWND :: fromHandlePermanent (HWND); Return AfxCallWndProc (PWND, HWND, NMSG, WPARAM, LPARAM);
As listed above :: AfxWndProc's entire function is only four lines, obviously it is only wrapped :: AfxCallWndProc function, just pack the hwnd parameter into PWND, then turn :: AfxCallWndProc. :: AFXCallWndProc This function is really doing something, but in which the message is delivered to the direct relationship: LRESULT AFXAPI AFXCallWndProc (CWND * PWND, HWND HWND, UINT NMSG, WPARAM WPARAM = 0, lparam lparam = 0) {...
// delegate to Object's WINDOWPROC LRESULT = PWND-> WINDOWPROC (NMSG, WPARAM, LPARAM);
... Return LRESULT;
Now we have seen the relay of the two functions of: AfxWndProc / :: AFXCallWndProc, the message is passed to the MFC environment. Further discussion can focus all your eyes to Lresult CWnd :: WindowProc (Uint Message, WPARAM WPARAM, LPARAM LPARAM);
Four points: Summary We see the transfer: In order to achieve different function calls, OOP (face-to-object programming) itself provides many methods such as inheritance and virtual functions. MFC is a language facing object now Csupers is inherited from CEDIT, CEDIT inherits from CWND, we must make program calls CSUPEREDIT :: OnChar also has no technical difficulty. For example, you can write a virtual function Virtual void cWnd :: onchar (uint nchar, uint nrepcnt, uint nflags); in CWnd :: windowproc, then I only overload CSUPEREDIT :: OnChar The function, the program naturally calls my write function.
Microsoft has made some optimization work in order to reduce the volume of the program file. It does not use the Virtual modifier to modify all functions, but to register "the message and corresponding response functions to be responded" in a message_map (called message, message Map. In the AFXMSG_.h file, the ON_WM_CHAR macro definition is {wm_char, 0, 0, ... & onchar}, its role is to put the onchar function of WM_CHAR and the current class (now csuperedit), fill a registration form for message mapping Since there is a registration form for "message mapping", the algorithm and code that "calls CSUPEREDIT :: onchar" when accepting WM_CHAR messages, it is estimated that you can implement it within two hours, I will not Here, as for the relevant code in the MFC, please refer to the book "in-depth shallow" book.