Finally, analyze the six key technologies of MFC (Part 1)
Finally, analyze the six key technologies of MFC: I don't think MFC reduces the burden of programmers. Although the purpose of MFC seems to make programmers don't have to know too much, they can make a window programming, but I am The MFC has been in a long time (because there is no book in detail the principle of MFC), there is no harvest. Maybe friends will say, how must I know the specific MFC? "Black Box" does not work? Isn't this the original intention of Microsoft? No! ! ! If so, I would rather never choose MFC! Before learning the computer, most of the things that I have learned from the art don't matter, and I have participated in the National Painting and Calligraphy Competition. The childhood hobby is to paint in a piece of paper! The MFC "Black Box" is like a huge abstract painting (abstract to you can't understand), it uses a pencil to draw a good line, then please fill the color. How can we endure the "black box" homework? We choose C , just because it is free, enough art, we can let go of fantasies here. So, we have to overcome MFC. Take great grandmother, although the MFC is trying to do, it may be unclear due to the limit of the space (I believe that many students have this experience). Here, I am a honesty, I want to share with you a famous MFC six key technologies. From where it started to talk? I feel that when I started to explore the MFC, I just talked about the best. Because I know, a programmer came over, I always forgot how I came over, I forgot what a student was most wanting to know. A small problem (can be explained in one or two words), the foot student is in the first half of the month, so I work hard to recall how it makes you suddenly open. Transfer entry: six key technologies for MFC include: the initialization process of the MFC program. Runtime Type Identification (RTTI). Dynamically created. Permanently saved. Message mapping. Message delivery. The initialization process of the MFC program 1. Design a simple full MFC program to generate a window. Of course, this can't make AppWizard to automatically generate us. We can write below Win32 Application Engineering: #include
Set the link MFC library, run, you can see one window.
From above, everyone can see the establishment of an MFC window, only two steps: First, from CWINApp to derive an application class (here is myApp), and then establish an application object (THEAPP), you can generate a self need Window (ie, what you need is created in InitInstance ()). Over the program, you will have an initInstance () function, create such an object (THEAPP), is a complete window program. This is the charm of "black box" homework! ! ! ! When we want to make Microsoft, we suddenly felt empty, we wanted to know what Microsoft did what we did, and what we need to do when we want to edit your own procedure, then it is afraid that the procedure above Inside, we have unclear place, such as, why there is a m_pmainwnd pointer variable, where is it come, where is it? I want to think about how wonderful things under DOS, what variables we need, declare what variables, what kind of function, what kind of function, or reference to the library ... But now what should we do? ! ! ! We can reverse thinking, MFC has to achieve this effect, how did it do? First of all, we must understand that VC is not a language, it is like a similar notebook editor when we learn C language (please forgive me for an ineffective metaphor), so we use C in VC. Language programming, C is the foundation (initiator always thinks that VC is a new language, one more complicated than C advanced complex language, sweat). Said so much, I want to use a simple words to summarize "MFC 'black box" is to help us insert' C code '. " Since the MFC black box helps us insert the code, then everyone thinks it will help us insert what code? Will he help us insert code for solving a secondary equation? Of course, it is actually inserted by each time you write the window program, the general code. I think about it, what is common? Each time we look up the Winmain () function, we must have a registration window, generate a window, message loop, callback function ... that is, every time you want, let them disappear from us, let MFC help write Enter! To know the MFC initialization process, you can of course track the executive. Teacher Sun has been tracking for a long time, I believe everyone is a little dizzy. I think that I am afraid that you understand the MFC code, it is easy to find the north. How can we find an exit in the maze of thousands of lines at all? We have to change a way, it is better to re-write a MFC library, hey! Don't laugh, be careful of your big teeth, I am not a mad (although the madman said that I am not mad). What we have to write is the simplest MFC class library, which is written in the MFC macro, theoretical thing. We want to simplify the simplified code to just run. Since our section, we write the initialization process of the MFC program, and we have an executable MFC program. The program is just two MFC classes, one is CWINAPP, the other is CFrameWnd. Of course, there are still many important MFC classes such as view classes, document classes, and more.
But the above programs can not be used, so it is temporarily eliminated (in short, it is simple). Ok, now I start writing the MFC class library ... Hey, there is a big problem in front of you, let everyone carry out the MFC hierarchy. God, how do you remember the fish net, but since we have to understand him, you have to know that it is derived from there. Considering that everyone is very hard, then we look at the father and son relationship of the above two classes (arrow representative derived): cobject-> ccmdtarget-> cwinthread-> cwinapp-> Overrind the initInstance () application class. COBJECT (同) -> ccmdtarget -> CWND-> CFrameWnd
After seeing the chart of the hierarchy, you can finally start writing the MFC class library. According to the above hierarchy, we can write the following six classes (for intuitive, save constructor and destructive function). / class cobiect {}; // MFC class base class. Class ccmdtarget: public cobject {}; -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------ CLASS CWINTHREAD: Public CCMDTARGET {}; class cwinapp: public cwinthread {}; -------------------------------------------------------------------------------------------------------------------- -------------------- Class CWnd: public ccmdtarget {}; class cframewnd: public cwnd {}; / Everyone thinks, in the above class, there should be what? Everyone will think that CWinapp class or its base class ccmdtarget should have a virtual function Virtual Bool InitInstance (), because there is a program's entry point, the place where the initialization program is natural. Some friends may say, anyway, INITINSTANCE () must be overloaded in the derived class, I am not defined in the ccmdtarget or CWINAPP class, leaving CWINAPP derived classes to increase this function can not. It may be a bit more far from this problem, but I want to believe that C friends should have no problem with the virtual function. In general, as a programmer knows that a function of the base class is used to be derived, it is convenient to be a virtual function. There are also many friends asking, why not automatically define all the functions of the base class as a virtual function, so that all functions are called derived classes, not defined. Basic class, don't write Virtual! In fact, many object-oriented languages are doing this. But define a virtual function to generate a virtual function table, to take up the system space, the more virtual functions, the larger the table, sometimes it is lost! Here is a few words, because everyone will experience this in the message map to be explained, well, this is called. Above we solved a problem, just write a Virtual Bool InitInstance () at CCMDTARGE. Everyone thinks again, we also want our MFC "hidden" more things: WinMain () function, design window, window registration, message loop, callback function ... We immediately thought that packaging wanted to encaps them. Everyone seems to feel invisible to encapsulation Winmain () is not easy, think Winmain () is a special function, many times it represents the start and end of a program. Therefore, when we write programs, we write procedures habits from WinMain (), to the right bracket return, and end the program. We have to think about it, there is something to get winmain () to do, many beginners, always feel the winmain () function of the big function, what function is as if it is necessary to actually run it. In fact, this understands very plane, or even mistakes.
We can write such a C program: #include
Everyone can see that I have not constructed a framework, but the program can run - a dialog box (if there is no Winmain "function program will report.). I have written like this or for intuitive, in fact, we only need to write two lines: #include
Therefore, WinMain () is simply written: int WinMain (Hinstance Hinst, Hinstance Hprevinstance, LPSTR LPCMDLINE, INT NCMDSHOW) {hinstance = hinst} Since the instance handle should wait until the program started to know, then we are used to create a window The Create () function must also perform in WinMain () [Because if WinMain () is completed, the program ends, the process is undo, of course, Create () is not possible to create a window] So, Run () (message loop) is put Do you do it there? As we all know, the message loop is the same code, but we don't try to put it outside the WinMain () function. So we are in the Winmain () function, we have to write Winmain (...) {... window objects below ...... Program class object executes message loop functions ...} For WinMain () Question, you have to summarize it, we can't package it into the CWINAPP class when we package it, but because of the invariance of WinMain (or regularity), MFC is fully capable of constructing CWinapp class objects. , Help us complete the line of code. Turned a big circle, we seem to return to the beginning of the SDK programming. But now we can now clearly know that the MFC and SDK are completely different, but the MFC is only available in the form of a class, and after packaging, we only need a few lines in the Winmain () function, you can Complete a window program. We also have learned how to encapsulate application classes (CFrameWnd) should be encapsulated. The two classes are designed to begin. For the sake of simplicity, we ignore the basic class and derived class writing. Maybe everyone will think that this is a very irresponsible approach, but I think this can be reduced and burden, and I have been in all kinds. Between wearing, better understanding (we are in key places). Also, I wrote all the code in the same file, so that everyone doesn't look so much, but this is the least advocated writing code method, don't learn! #include
Class cframewnd {hwnd hwnd; public: cframeWnd (); // can also call create () Virtual ~ cframeWnd (); int create (); // Class I pay attention to this function! Bool showWnd ();}; class cwinapp1 {public: cframeWnd * m_pmainwnd; // In the real MFC // it is a CWND pointer, but here does not write CWnd classes // only write it into a cframewnd pointer cwinapp1 * m_pcurrentwinapp; / / Point to the application object itself cwinapp1 (); Virtual ~ cwinapp1 (); virtual bool initInstance (); // MFC originally a function that must be overloaded, the most important function! ! ! ! Virtual Bool Run (); // Message Cycle}; cframeWnd :: CFrameWnd () {} cframeWnd :: ~ cframeWnd () {} int cFrameWnd :: create () // package creation window code {WNDCLASS WNDCLS; WNDCLS.Style = 0; wndcls.cbClsExtra = 0; wndcls.cbWndExtra = 0; wndcls.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); wndcls.hCursor = LoadCursor (NULL, IDC_CROSS); wndcls.hIcon = LoadIcon (NULL, IDC_ARROW); wndcls. Hinstance = Hinstance; wndcls.lpfnwndproc = defWindowProc; // Default window process function. // You can imagine a MFC universal window process. Wndcls.lpszclassname = "Window Class Name"; WNDCLS.LPSZMENUNAME = NULL; RegisterClass (& WNDCLS);
HWND = CREATEWINDOW ("Window Catenis Name", "Window Instance Title Name", WS_OVERLAPPEDWINDOW, 0, 0, 600, 400, NULL, NULL, HINSTANCE, NULL; RETURN 0;}
Bool CFrameWnd :: ShowWnd () // Displays Update Window {ShowWindow (HWND, SW_SHOWNORMAL); UpdateWindow (hwnd); Return 0;}
/ Cwinapp1 :: cwinapp1 () {m_pcurrentwinapp = this;} cwinapp1 :: ~ cwinapp1 () {} // The following is the initInstance () function, the MFC is rewritten for CWINAPP's derived class, / / here for easy understanding, put it Put it in the CWINAPP class! / / You only need to remember that the true MFC has changed this function in the derived class. Bool cwinapp1 :: initInstance () {m_pmainwnd = new cframewnd; m_pmainwnd-> create (); m_pmainwnd-> showWnd (); return 0;}
Bool cwinapp1 :: run () // Package message loop {msg msg; while (GetMessage (& MSG, NULL, 0)) {TranslateMessage (& MSG); DispatchMessage (& MSG);} return 0;} // Package message loop
CWINAPP1 THEAPP; // Application Object (Global)
int WINAPI WinMain (HINSTANCE hinst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {hInstance = hinst; CWinApp1 * pApp = theApp.m_pCurrentWinApp; // MFC write a true global function AfxGetApp, to obtain CWinApp pointer. PAPP-> InitInstance (); PAPP-> Run (); return 0;} The code is so long, actually just written three functions, one is CREATE () of the cframewnd class (), the second is the cwinapp class InitInstance () And Run (). In this particular statement, INITINSTANCE (), the real MFC, that is the need to construct the window according to its own window, rewrite this function yourself. You can see that after the above two classes are encapsulated, you can write a few lines of code in the entrance function WinMain, you can generate a window program. In the MFC, because the WinMain function is fixed as a few lines of code, the MFC can definitely help us complete (the expert of MFC is to help us complete the regular code), so we creating the MFC application, see WinMain function. Write here, one of the six key technologies of MFC: The initialization process of the MFC program (simulation) is almost finished. Looking back, I actually wrote more than 8,000 words. I thought that I didn't have to write so many words. Now I am fortunate that I don't put the document and optimistic. Otherwise, I don't know when I write. There are five key technologies that have not been written. Do I still write it? More than 8,000 words were written above, I was knocked in a word, and each example was hard to come out. It took more than ten hours, there may be more than the friends in the forum, ridicule! But I think it is worth it. I have always thought that VC has no enemy, only friends, look around, and finds less and less friends who are learning VC, and have not found a place to recruit VC programmers. When I was studying a college, I met a brother who made an art. I originally in the enemy (I used to have an art). The brother's artwork is very good, but he has never been a first prize in the school, and the reason for the award does not know how to appreciate his work. My appearance, he deeply realized: more friends, will be less than one point! Sometimes a friend who is learning VC is a hero (but I am not a hero, because I have a breakthrough in VC for many years), it is a distinguished person, everyone exchanges, correct your own mistakes, it is a blessing ... I am QQ: 14653353, E_MAIL: Liyi268@163.net (this is two men and two women sharing mailbox, may not necessarily have received, if you specify Mr. Xiao, pay attention to another matter) Welcome contact.