Application MFC Development Advanced Application Qianding Tsinghua University Heat Technology (Beijing, 100084) Distinguished: First, use C / C and VC and VB comparison II, MFC programming review three, use single document - multi-view structure four, use DDE service five Using 3D Control 6. Use custom message. Seven. Use the MFC application without a text-seeking-optic structure 8. Artificial optimization of the MFC application [Summary]: Tools currently developing applications under Windows, there are many, but C / C As a very mature and efficient development language, it is still widely used in the development of large complex projects. In order to reduce the development burden, improve development efficiency, all popular C provide class libraries, this article is to explore some of the issues required to develop some questions needed to use the MFC class library in the Visual C environment to develop advanced programs. The method of using the MFC development single document multi-view application and DDE application is discussed. First, using C / C With the increasing generals of the Windows series operating system, traditional DOS programming gradually turned to Windows has become an inevitable trend. There are many tools for developing applications under Windows, typically, such as BorlandC , Visual C , Visual Baisic, and Delphi, and more. Each development tool has its own characteristics. Generally speaking, users can choose a specific development language based on their usage habits and development projects. Visual Basic is a Software Summate innovation product, which changes people to develop Windows programs, which use interactive visualization, so that every process of developing Windows programs has an intuitive image feedback, Thereby accelerating the entire development process. Visual Basic makes the Windows programmaker no longer only depend on complex SDK programming, making it easy to develop Windows programs, can be said that users learn and use VB to develop Windows applications for the shortest time. The Visual Basic version has evolved, and it has been developed to 5.0. In version 4.0, since the object-oriented programming concept is fully used, it has the version under Windows 3.1 and Windows 95, thus making it developing complex programs gradually enhanced. VB5.0 discards Windows 3.x users, can only be used in 32-bit Windows, it is reported that this version absorbs the successful strategy of Delphi, introduces the Native Code compiler, so that the program executes Accelerated, overcoming the previous version due to the implementation of the P-CODE code, the running speed is slow, according to Microsoft's statement, the version of the app obtained after the local code compiled in some cases has been improved. 10 ~ 20 times, execution speed can be founded with the application written by Visual C , while the application development speed is a strong term VB, so Visual Basic 5.0 is very competitive. At present, Visual Basic is very widely used to develop a variety of Windows programs such as database front-end applications and multimedia applications. However, in the author's view, there is also a certain shortcoming of using VB: 1. Visual Basic comes from the Basic language, although the Microsoft continues to increase, but still lacks a very flexible data type and programming strategy, so Developing some of the complex data structures that must have trouble, such as linked lists, diagrams, and binary trees, etc.
Since the development work is no longer dominated in the development of China, it is not based on the interface, but in the algorithm design and underlying hardware and software, this will increase the post-work volume of the VB development project, in order to meet the project requirements, often needs Turn to C / C to develop some dedicated dynamic connection libraries to solve problems. 2. Visual Basic runs slow, foregoing, although the execution file is small, but it needs to be explained at runtime, and its operation must have a corresponding VBRun.dll and the VBX or OCX used. stand by. For floating-point operation dense or loop nesting, VB does not take special optimization, so performing speed is far less expensive to develop from C / C and Fortran. VB 5.0 Although this defect is greatly made by introducing a local code compiler, since it can only work on a 32-bit Windows environment, it is still not resolved on the 16-bit Windows speed problem. Although the trend of current turning to 32 windows is very strong, there is still many users who are still working on 16-bit Windows due to many reasons such as hardware restrictions or habits. In the United States in the United States, 96 users who use 16 Windows users still exceed users who use 32-bit Windows users, any person who performs system software design should take care of these users who still use 16 Windows. 3. VB cannot flexibly use system resources. Those familiar with Windows programming know that if you want to access hardware or write an application for valid access to the system, it is very difficult, but the VB programmer is disappointed, the API function is used in C language And assembly language, is prepared for C, if you want to use these thousand API functions in VB, especially if designers don't understand C language is particularly difficult. Due to the complexity of the API function, it is not provided for the convenience of VB programming, so it is necessary to use a very thick book to express it in the VB to call the API function. VB programmers can find a lot of books from books. It can be said that any VB programmers have developed to a certain stage of dealing with many API functions. In addition, since VB does not support port operation, if you want to write a similar data acquisition, a program that needs to be interactive with hardware is required, it needs to be saved in the C / C language. 4. Visual Basic project distribution and management difficulties, the reason is that the operation of the VB application cannot be separated from the VB's running library and the controls used, so if the developer wants to distribute VB applications to the user so must bring VB The runtulent library and the control used, and to ensure proper installation, this leads to even a very simple application also requires a large number of other related support library programs, for VB 4.0 and higher, due to a large number of OLE controls ( It is called OCX in VB), which is more complicated. Delphi software is a proud of international Borland, which is also highly respected. Like VB, it is entirely an interactive visual development platform that supports the development of Client / Server applications, its latest version 2.0 You can develop applications for Windows 3.x, Windows 95, and Windows NT. Delphi development speed is also very fast, compared with VB, because there is a local code compiler, therefore the execution speed it produces is greatly accelerated. Delphi software is a very competitive software that adopts object-oriented Object Pascal language, supports hardware operations and API calls.
However, due to the programming language used for Pascal, this language is not very popular. Many programming staff are completely unfamiliar with this language, so greatly limiting the use of the software, if Bailan can develop RAD development from Delphi software The mechanism is introduced into its Borland C , it may form a very successful product (current version has been launched, namely C Builder, I Note). VB and Delphi introduced visual development methods There is also a common disadvantage that the compatibility between the various versions. Generally speaking, applications developed by these visualization development tools will not encounter too much difficulty when transplanted into the high version, but once the direction of transplantation is difficult, sometimes it is impossible. The C / C language does not have this limitability. The mutual transplant between each version is not difficult. The high version to transplant the low version is generally only necessary to rebuild the project document. In summary, according to the author's point of view, if you want to develop a large complex application preferred or C / C , especially under 16-bit Windows. Although this will increase the previous work, it will gradually appreciate its superiority and development efficiency in the middle and later periods of the project, and its flexible and efficient execution code is suitable for occasions that have high synergy between speeds and applications. Pure Windows SDK to develop a Windows program is a daunting project. It is worthy of a variety of popular C / C development tools to provide library development frameworks to simplify the entire development process and lose its inherent flexible and efficient. Different, different development languages are different, such as the OWL (Object Windows Library) and Visual C provided by Borland C , which encapsulates a lot of WindowsAPI and Windows. The development element makes the development task simplifies. There are two kinds of libraries have their own advantages. According to the author's information, the application execution code written by MFC is smaller, the execution speed is faster, which is probably because the software developers are By developing the Windows operating system Microsoft, now MFC is gradually become a class library development standard under Windows, which is being supported by more and more other C / C compilation tools, such as Watcom C . The AppWizard, ClassWizard, and AppStudio provided by Visual C can be greatly improved in terms of Visual C . The author has accumulated some of the experience of MFC's experience now. It is now proposed to give you a reference. I hope to help the majority of peers, especially those who are still committed to 16-bit Windows programming. This article uses the Visual C 1.51 compiler, but its method is equally applicable to other VC versions, including Visual C 4.x. Second, the MFC programming reviews the use of MFC development Windows programs that can significantly increase the development speed and efficiency is mainly because MFC encapsulates a large number of Windows SDK functions and typical Windows applications in the class level. In this way, users only need less. Programming can realize its own development tasks. If the AppWizard, ClassWizard and AppStudio tools provided by Visual C on the MFC are then greatly accelerated. The MFC provides a large number of base-based servants, common, such as CWINAPP, CFrameWnd, CMDIFrameWnd classes, cmdichildwnd classes, CView classes, CDC classes, and cDocument classes, and more. A separate application can be generated by sending a user's own class from these base classes, and then overloading a special number of functions.
It can be said that it is very convenient to write a Windows application using the MFC, although its learning process is not simple, but its flexible and efficacy is enough to make any Windows program developers working hard. If the user has not used the MFC, then the user can learn the powerful functionality of MFC through the reference book listed in the appendix. The application generated by the MFC application framework uses a standardized structure, thus making the transplant on different platforms using MFC, in fact, there is a difference between the 16-bit and 32-bit versions of the MFC. The standardized structure provided by the MFC is prepared by many experts and analyzes the research. In general, it can meet the requirements of the vast majority of users, but sometimes users can modify their default style by overloading some functions. Style, such as custom application charts and gray backgrounds, etc. In the documentation structure provided by the MFC, the link between documents, depending, and resources is implemented by defining document templates, such as: m_psimuteemplate = new cmultidoCtemplate (idR_SImutype, Runtime_Class (csimudoc), Runtime_Class (CMYCHILD), // deerived MDI Child frameUntime_class (csimuView)); the first IdR_SIMUTYPE includes resources such as the viewport's menu, accelerator keys, and charts. If the user uses AppWizard to generate the basic framework, then it also produces a default icon, If the user is not satisfied with the default icon (actually user satisfied by the default icon), only need to delete the default icon, then edit or directly introduce a new icon, only need to use and deleted when the icon is stored. The same ID can be replaced. People who are familiar with Windows program have known that in Windows can enhance the visual effect of the application by using a gray background, some people are called, gray is an eternal color of the graphical interface. The background of the application generated by the MFC is over white. If the user wants to change into gray or other colors, you need to use separate processing, a lot of ways to solve, such as a gray brush in the onpaint () event in each viewport Artificial fill background, but this is not the best way. The author discovered the best way to use the AFXREGIsterWndClass () function to register a new window class using a gray background, which requires the precreateWindow () function to achieve this, as shown in the following program code: BOOL CSIMUVIEW :: PrecreateWindow CREATESTRUCT & cs) {HBRUSH hbkbrush = CreateSolidBrush (RGB (192,192,192)); // create a gray background brush LPCSTR lpMyOwnClass = AfxRegisterWndClass (CS_HREDRAW | CS_VREDRAW | CS_OWNDC, 0, hbkbrush); // register a new class cs.lpszClass = lpMyOwnClass; // Modify the default style Return True;} This method is the fastest, and most economical. At the same time, you can also define any window style, such as window size, cursor style, etc. in the precreateWindow () function. Third, using a single document-multi-view structure If the user has used MFC to program, it will find that it is very convenient to use the AppWizard based MFC whether to write SDI (single document interface) or write MDI (multi-document interface) is very convenient. MDI applications currently use more common, people's familiar Microsoft's Office Series and Visual Series products are typical multi-document applications. This multi-document interface has a multi-window characteristics, so people can use multiple sub-windings in a program to view viewing of different data.
If the user wants to achieve different visualizations for the same data between the MDI windows, it is a more troublesome thing. Fortunately, the documentation provided by the MFC is greatly simplified. The document-optic structure is easily achieved by separating the data from the user to the data observation, that is, multiple viewports for the same data, if the data in a viewport changes, then other relevant viewports will also There is changed to reflect the changes in the data. SDI and MDI These Windows Standard Application Frames do not always meet the needs of users. For the author's work, there is a special application known as a single document, English can be abbreviated as SDMV. Applications through SDMV We can use document classes to manage all data from the application, while you need to use multiple windows to visualize these data, such as rod, trend graphs, and parameter lists, so that users can observe from different angles. data. Although MDI has a multi-window characteristics, it is a multi-document, ie, in the case of a viewport corresponding to a document, the viewport document constitutes a sub-window. The data between each sub-window is independent, and if you need to keep the data synchronous update, special techniques are needed, and this approach is expensive and laborious. Through the practice of the author, the above SDMV structure can be achieved by appropriately transforming the MDI window application by appropriately transforming the MDI window application. The so-called SDMV application is still an MDI application, just in the program, we can only generate a document class in the program. This document is created when the first viewport is created, paying attention, it does not need to limit the respective views. The creation of the mouth is successive. Since then, the inherent characteristics of the MDI window are different. All newly created sub-windows no longer create independent documents, but directly connect the new viewport directly to existing document objects, which makes it a single document. Structure, all related data is stored in the document object. Once the data in the text gear changes, all relevant viewports can be notified by the UpdateAllViews () function, and each viewport can change the data in onupdate (). This response mechanism is shown below: Figure 1 Document - View Structure Data Update Mechanism Due to MDI Essentially, it is not necessary to solve some problems when actual application is actually applied. 1. Window Title Problem window The title should not be a problem. By default, the MDI window determines the window title by the corresponding string provided by the resource ID provided in the Document Template. However, for SDMV applications, since each vision is essentially corresponding to the same text, each viewport has the same title, but it has only increased a data to indicate that this is the first session. If the specific window name is specified in each viewport, the window title generated by the different viewports started to create a document is different. This name affects the subsequent viewport. In order to make different types of views such as rod graphics and curve viewports have different titles, this requires a certain technical process.
According to the author's exploitation, you can use the following steps: First, a child window class is derived from the standard MDI sub-window base class cmdichildwnd, and then add a CMYCHILD, then add a CString type variable in its member variable to store the current Window Title: CString Wintitle; then assigns the above variables by getting the parent window pointer during different viewport creation, the program fragment is as follows: pchild = (cmychild *) getParent (); pchild-> wintitle = " Rod display window "; Finally, in the CMYCHILD derived class overloaded the onupdateframeTeitle () function in the cmdichildwnd base class to force the personalization of the window title, this function is not in the various types of library manuals and online help, but There is indeed such a function with the protection attribute to implement an update operation of the window title, which can find the implementation of the function from the source code of the MFC class library. Overloaded version of the source code as follows: void CMyChild :: OnUpdateFrameTitle (BOOL bAddToTitle) {// update our parent window firstGetMDIFrame () -> OnUpdateFrameTitle (bAddToTitle); if ((GetStyle () & FWS_ADDTOTITLE) == 0) return; / ! / leave child window alone CDocument * pDocument = GetActiveDocument (); if (! bAddToTitle && pDocument = NULL) {char szOld [256]; GetWindowText (szOld, sizeof (szOld)); char szText [256]; lstrcpy (szText, Wintitle); // modified by author! if (m_nwindow> 0) WSPrintf (Sztext lstrlen (sztext), ":% d", m_nwindow); // set title ife, but don't remove completionif (lstrcmp (sztext Szold! = 0) SetwindowText (Sztext);}} 2, how to create an SDMV application How to create an SDMV application is more troublesome, and below is specifically described below. This example assumes that the user needs two viewports in the form of the rod diagram and the curve. It is assumed that the user has derived and implements these two classes, respectively correspond to the CMYCHART and CMYTRACEVIEW.
1) Add the following variables and function prototypes for the application class (class from CWINAPP): cmultidoCtemplate * m_pmytraceTemplate; cmultidockstance * m_pmychartTemplate; int exitInstance (); 2) Delete pairs in the INITINSTANCE function function of the application class and OpenFileNew AddDocTemplate function call () statements, and add the following code: m_pMyTraceTemplate = new CMultiDocTemplate (IDR_MYTRACEVIEW, RUNTIME_CLASS (CSimuDoc), RUNTIME_CLASS (CMyChild), // Derived MDI child frameRUNTIME_CLASS (CMyTraceView)); m_pMyChartTemplate = new CMultiDocTemplate (IDR_MYCHART, RUNTIME_CLASS (CSimuDoc), RUNTIME_CLASS (CMyChild), // Derived MDI child frameRUNTIME_CLASS (CMyChart)); 3) implement the ExitInstance () function, in which the two auxiliary delete templates used: int CTestApp :: ExitInstance () {if (m_pMyChartTemplate Delete M_PMYCHARTTEMPLATE; if (M_PMYTRACETEMPLATE) DELETE M_PMYTRACETEMPLATE; RETURN TRUE;} 4) Remove New and Open items in the File menu in the menu resource, join the New Chart View and NewTrace View, implement the corresponding menu commands: void CMainFrame :: OnNewMychart () {// TODO: Add your command handler code hereOnNewView (((CSimuApp *) AfxGetApp ()) -> m_pMyChartTemplate);} void CMainFrame :: OnNewMyTrace () {// TODO: Add your command handler Code HereonnewView (((((( CSimuApp *) AfxGetApp ()) -> m_pMyTraceTemplate);} in the following implementation OnNewView: BOOL CMainFrame :: OnNewView (CMultiDocTemplate * pDocTemplate) {CMDIChildWnd * pActiveChild = MDIGetActive (); CDocument * pDocument; if (pActiveChild == NULL | | (pDocument = pActiveChild-> GetActiveDocument ()) == NULL) {TRACE0 ( "Now New the specify view / n"); ASSERT (pDocTemplate = NULL); ASSERT (pDocTemplate-> IsKindOf (RUNTIME_CLASS (CDocTemplate)!)) ; pDocTemplate-> OpenDocumentFile (NULL); return TRUE;} // otherwise we have a new frame to the same document CMultiDocTemplate * pTemplate = pDocTemplate;! ASSERT_VALID (pTemplate); CFrameWnd * pFrame = pTemplate->
CreateNewFrame (pDocument, pActiveChild); if (pFrame == NULL) {TRACE0 ( "Warning: failed to create new frame / n"); return FALSE; // command failed} pTemplate-> InitialUpdateFrame (pFrame, pDocument); return TRUE } OnnewView is the core composition of the entire SDMV application. Its task is to create a new specified type of viewport, which first determines if there is an activity viewport, whether the document has been created, and there is an activity viewport in the event. Existent, if there is no existence, create a new activity viewport with the specified document template, otherwise only the viewport is created, and it is connected to the existing document object. By the above steps, the SDMV application can be implemented, and the onupdateAllViews () function and viewport of the document object can be used in its subsequent application. Fourth, using DDE service Windows 3.x is a minute multitasking environment, in which multiple applications can be executed concurrently. In order to share data and resources between multiple tasks implemented, Windows provides several mechanisms, mainly by clipboard and dynamic data exchange (Dynamic Data Exchange). The former is a very convenient tool for data exchanges that users need to participate directly, but if you want data exchange being automatically performed, you must rely on DDE technology. Techniques to write DDE applications have also developed several generations, from the initial message-based DDE to DDEML (Dynamic Data Exchange Management Library), and now popular OLE technology. The development of DDE technology makes program developers write DDE applications more concise. From the perspective of development trends, OLE-based data exchange is the best, which is especially in line with customers - server mechanisms in the field of software. In order to adapt to the needs of multi-platform and Internet, Microsoft has developed ActiveX technology on the basis of OLE. However, it is not to ignore that the traditional DDE data exchange also has its own application space, and the use is still extensive. At Windows 3.x, OLE-based remote data exchange is still immature, but network-based dynamic data exchange under WFW (Windows for Workgroup) is mature, and it is also very common. About DDE Application Development and NetDDe Applications Can see Appendix 7.1, processing of callback functions Since the DDEML mechanism requires a callback function, the key to use DDEML is to solve the use of callback functions in the MFC programming system. The callback function (Callback function) is a large number of system services for Windows. By it, the programmer can install the device driver and message filtering system to control the effective use of Windows. Many programmers have found that writing callback functions using MFC or other C applications is very troublesome, and the root cause is that the callback function is based on C-programmed Windows SDK technology. It is not for C , and the programmer can direct a C function. As a callback function, if you try to use the C member function as a callback function, it will not pass it even compile. By querying the information, its error is that the ordinary C member function is implied with a transfer function as a parameter, that is, "this" pointer, C to achieve the program function to access C by passing a pointer to its own pointer Data members. This can also be understood why multiple instances of the C class can share member functions but have different data members.
Due to the role of the THIS pointer, it will make the function parameters matches the number of the function parameters because the hidden THIS pointer is installed, resulting in the number of callback functions to fail. The key to solving this problem is to do not let the THIS pointer work, by using the following two typical techniques, can solve the problems encountered in C to use the callback function. This method has versatility and is suitable for any C . 1. Do not use the member function, directly use the normal C function, in order to implement the member variables of the class in the C function, you can use the Friends Operator (Friend), and the C function will be described as the class friend of the class in C . can. This processing mechanism is the same as the callback function in normal C programming. 2. Use a static member function, static member functions do not use the THIS pointer as an implied parameters, which can be used as a callback function. The static member function has two features: one, can be used without class; second, only access to static member variables and static member functions, and cannot access non-static member variables and non-static member functions. Since the purpose of using class member functions in C is the purpose of the callback function to access all member variables and member functions, if this will not be practical. The solution is also very simple, just use a static class pointer as a class member, initialize the static pointer when creating, such as pTHIS = this, then pass the static pointer in the callback function to access all member variables and member functions . This method of processing is applicable to only one class instance, because multiple class instances share static classes and static member functions, which causes static pointers to point to the final created class instance. To avoid this, you can use a parameter of the callback function to deliver the THIS pointer to implement data member sharing. This method is slightly troublesome, here is not described again. 2. Use DDEML in the MFC for a typical MFC application, the main frame window (CMAINFRAME) only one instance, so the static member function can be used as the callback function to implement the DDE mechanism.
The specific code snippet is as follows: (1) Declare the following static members in the CMAINFRAME class: static cMAINFRAME * PTHIS; Static DWord IDinst; Static HDDedata Callback Export Ddecallback (Uint, Uint, HCONV, HSZ, HSZ, HDDATA, DWORD, DWORD); (2) the class creation code (the OnCreate ()) as follows Description: pThis = this; lpDdeCallback = MakeProcInstance ((FARPROC) DdeCallback, hInstance); if (DdeInitialize (& idInst, (pFNCALLBACK) lpDdeCallback, CBF_FAIL_EXECUTES | CBF_SKIP_REGISTRATIONS | CBF_SKIP_UNREGISTRATIONS , 0L)) {AFXMessageBox ("Unable to initialize DDE service", "error"); DestroyWindow ();} (3) The callback function is implemented as follows: HDDedata FAR Pascal_export CMAINFRAME :: DDECALLBACK (uint itype, uint IFMT, HCONV HCONV, HSZ HSZ1, HSZ HSZ2, HDDedata HData, DWORD DWDATA1, DWORD DWDATA2 {Char Szbuffer [16]; INT I; Switch (ITYPE) {CASE xtyp_connect: // HSZ1 = TOPIV, HSZ2 = ServicesRN (HDDATA) TRUE; // True ; case XTYP_ADVSTART: // hsz1 = topic, hsz2 = itemcase XTYP_REQUEST: case XTYP_ADVREQ: case XTYP_POKE: // hsz1 = Topic, hsz2 = item, hData = datacase XTYP_ADVSTOP: return NULL;}} 3, to avoid a conflict if the variable type MFC The application uses DDEML services directly, then the MFC application will encounter variable type HSZ repeat definition errors when compiling. After tracking discovery, the error lies in the definition of DDeml.h to HSZ: declare_handle32 (HSZ); in Afxext.h (introduced by stdafx.h), HSZ is described below: TypeDef BPSTR FAR * HSZ; / / Long handle to a string two definitions one is 32-bit integers, one is a Basic string pointer, of course, the compiler cannot do a variable type conversion error. In fact, the HSZ declared as a Basic string pointer primarily used VBX control in the MFC application.
To correct this error, you must guarantee that you do not use DDEML and VBX support in the same code module, by separating the code of DDEML and VBX, and in the module using DDEML code, you can solve the following compiler macros. The above questions: #define no_vbx_support 5. Using 3D control without doubt, 3D control can significantly improve the interface friendliness of Windows applications, currently, many popular Windows applications use 3D control, typical, such as Microsoft Office Series Software, and, in Windows 95 and Windows NT 4.0, 3D control is directly supplied as part of the operating system, which means that software running on it does not require any special processing, with a 3D interface effect, but Unfortunately, in Windows 3.x, in addition to the command button control, the remaining control, such as editing box, list box, check box, etc. in addition to the command button, etc., if you want to use 3D control, program Designers must make certain changes in their own procedures, considering the popularity of the current 3D effect, this effort is worth it. In order to support 3D effect, Microsoft provides a dynamic connection library specifically for 3D control, CTL3D.DLL, but there is no discussion of 3D control in its Visual C , and Visualc does not directly support 3D encoding, Because it does not include the header files necessary to use 3D control. However, this does not mean that 3D control cannot be used in Visual C , but users need to obtain technical support from other places. Since the use of a dynamic connection library mechanism, the 3D header file and CTL3D.DLL input library are available in any other language. The author is used by the CTL3D.H and CTL3D.LIB provided in Borland's Borland C . There are also many ways to use 3D control in C / C , here, for the saving space, only discussing the topics related to this article, how to use 3D control when programming with MFC. 3D using the dialog controls in all the MFC may follow the following steps: 1 and Ctl3dAutosubclass function calls Ctl3dRegister CWinApp :: InitInstance function:. Ctl3dRegister (AfxGetInstanceHandle ()); Ctl3dAutoSubclass (AfxGetInstanceHandle ()); worth mentioning that, There is a function called setDialogbkcolor in AppWizard's application framework. This function is set to gray the background color of all dialogs. This function can be removed from the 3D interface. . Since CTL3D reads all system colors when initialization, the MFC application can call the CTL3DColorChange function in the WM_SYSCOLORCHANGE message in order to enable the application to correctly reflect the changes in the system color. 2. Call the CTL3 DunRegister function in the ExitInstance function in the CWINAPP class of the MFC application to facilitate the correct management of the CTL3D library. 3. Add CTL3D.LIB (you can use import.exe) in the project file of the MFC application.
The mechanism of automatic subclass using the above CTL3D can greatly simplify the use of 3D control, if this does not satisfy your requirements, then you must separately depending on the self-tax type of OnInitDialog () you need to use the 3D control. Class, typical code snippet shows: BOOL CMYDIALOG :: OnNInitDialog () {CTL3DSUBCLASSDLGEX (m_hwnd, ctl3d_all); Return True;} Top Talk above, using 3D effects in the dialog, if users want to be in non-dialog box Use 3D control, typically use in the FormView export class, you can make appropriate modifications in the onInitialUpdate function of the export class, depending on whether you use 3D control automated subclassics. If you use the auto subclassification method mentioned earlier, you only need to call the ctl3dsubclassdlg function in the corresponding OnInitialUpdate function, as shown below: void cmyview :: onInitialUpdate () {ctl3dsubclassdlg (m_hwnd, ctl3d_all);} Otherwise, Then you need to modify the following: void cmyview :: OnInitialUpdate () {CTL3DSUBCLASSDLGEX (M_HWND, CTL3D_ALL);} 6. Using Custom Messages 1, MFC message mapping mechanism Windows is a typical message-driven operating system, the program is running For the response of various messages, these messages are very wide, including common messages such as WM_Close, WM_Paint, WM_CREATE, WM_PAINT, WM_CREATE, and WM_TIMER, including user menu selection, keyboard acceleration keys, and toolbars and dialogs Buttons, etc. If the application works with other programs, the source of the message also includes messages sent by other applications, serial ports, and parallel ports, and the like. In summary, the development of the Windows program is to achieve various functions of the program around the reasonable response and implementation of many messages. People who use C language to develop Windows programs know that the Switch statement needs to be arranged in the Windows program window callback function to respond to a large number of messages, and due to the interruption of the message, the transmission between the information responses will pass in a large number of information. Global variables or static data is implemented. Both of the two class libraries, OWL and MFCs, provide message mapping mechanisms to accelerate development speed, and users only need to define the processing function of the corresponding message according to the specified definition, as for the actual calls provided by the class library itself. Or use virtual functions, or use message mapping macro. In order to save the memory, the MFC does not use the virtual function mechanism, but macro uses macro to map specific messages to the response member function in the derived class. This mechanism not only applies to 140 messages of Windows themselves, but also apply to menu command messages and button control messages. The message mapping mechanism provided by the MFC is very powerful, which allows the message to be controlled at each level of the class, and is not simple to limit the message generator itself. When the application receives a window command, the MFC will look for the corresponding message control function as follows: SDI App MDI App Victor Vision Document Document SDI Main Framework MDI Subfro Frame Application MDI Main Framework Application Most Applications Most Apply to Each Order Usually There is only one specific command control function, and this command control function only belongs to a particular class, but if there is multiple command control functions to the same message in the application, then only the priority command control function will Call. In order to simplify the processing of common commands, the MFC provides and implements the entry of many message mappings in the base class, such as print commands, print preview commands, exit commands, and online help commands, so in the derived class inherited all the bases. The message mapping function in the class can greatly simplify programming.
If we want to implement control of the message in its derived class, we must add the corresponding control functions and mapping portals in the derived class. 2, using your own message deeper program design, people often find that the messages that only depend on the menu and command buttons are not enough, often because the logical structure of the program and the data between the data between different viewports need to be used Some custom messages, such a special need can be implemented by schedule a message response function at the respective level. For example, if we want to notify all data output viewports in a specific time interval to re-achieve new data, it is necessary to rely on the menu command and button command to achieve insure enough, and the ideal solution is to use the timer event to perform a specific calculation operation, the operation is completed. The SendMessage is used to send its own specific message, and only the message will return to the main controller for the next time calculation when this message is processed. By schedule the response to the message to acquire the latest computing data after the document hierarchy, the display of all relevant viewport update data is notified. The viewport can realize the update display of specific data by overloading the onupdate () member function. If the user can skilled using the sendMessage () function and postmessage () function, it is not difficult to send a custom message, usually there are two options, one is to send a WM_COMMAND message, pass the WordWParam parameters of the message to pass the user's command ID, Example As follows: sendMessage (WM_COMMAND, IDC_GETDATA, 0); // MFC main frame sends and arrange message mapping inlets at the document hierarchy: ON_COMMAND (IDC_GETDATA, ONGETDATA) Simultaneously implements an OnGetData () function in the document class: void csimudoc :: ONGETITA ( {Trace ("now in Simudoc, from ONGETDATA / N"); UpdateAllViews (NULL);} Note that the message map in the upper message requires users to manually join, the ClassWizard provided by Visual C does not complete this job for users. The reason for the Using the PostMessage function is not using the PostMessage function, it is only the characteristics of the sendMessage function, ie it only returns to the send message to get appropriate processing, which helps program control. Another way to send custom messages is to send a command ID directly, using ON_MESSAGE in the control level, pay attention to the message mapping entry, pay attention to the prototype of the command control function in this time according to the rules of the Windows itself, the following: AFX_MSG long oncaculationon " WPARAM WPARAM, LPARAM LPARAM; relatively, this mechanism is not as simple as the above mechanism, and will not be described again. 7. Use the MFC application document that does not have a text-seeking-optic structure-optimistic function, which can be suitable for most applications, but sometimes we only need very simple programs, in order to reduce the final executable file size and Improve the running speed, we don't have to use a text-on-view structure, typically a simple SDI application and dialog-based applications. 1. Simple SDI Application At this time, you can only use CWINAPP and CFRAMEWND. Since the CWINAPP class encapsulates the WinMain function and the message processing loop, any programs that use the MFC can not be separated from the class.
In fact, using the CWINAPP class is very simple, mainly to derive a user's own application class, such as CMYApp, then only need to overload the cwinApp class InitInstance () function: BOOL CMYAPP :: InitInstance () {m_pmainwnd = new cMAINFRAME (); askERT (m_pmainwnd! = null); // error checking onlym_pmainwnd-> showwindow (m_ncmdshow); m_pmainwnd-> UpdateWindow (); return true;} As for the main frame class required, you can use the ClassWizard utility to generate, the class The header file and the implementation code can be placed together with the header file of the CMYAPP class. Note that this is here, because the use of ClassWizard needs to have the corresponding CLW file existence, and there is no corresponding CLW file when collecting code, so it cannot be used directly, the solution is to enter the App Studio utility after using ClassWizard, at which time the system Will find that there is no corresponding CLW file, the system will prompt you to rebuild the CLW file and pop up the corresponding dialog, then you don't need to select any file directly to select the OK button, so that the system will generate an empty CLW file for you, so You can use the ClassWizard utility. In order to combine CWINAPP and CFrameWnd's derived class, you can create a window to create a window in the constructor of the CFrameWnd derived class. Typical code is as follows: CMainFrame :: CMainFrame () {Create (NULL, "DDE Client Application", WS_OVERLAPPEDWINDOW, rectDefault, NULL, MAKEINTRESOURCE (IDR_MAINFRAME));} ClassWizard using the utility generates correlation class code, other implementations all classes And maintenance is the same as the code generated by the AppWizard utility. 2. Dialog-based programs Some applications that are primarily used for data input and output, etc., there is no need to change window size, typically, such as various online registration procedures, these use dialogs as the main interface of the application, is sufficient, Moreover, developing such applications has convenient and fast, the code is also relatively short, and if the control needs to be used directly, it is particularly troublesome. Use AppWizard in Visual C 4.x to directly generate dialog-based applications. There is no such function in Visual 1.x, so such applications require programmers to implement themselves. In fact, the use of MFC-based applications is very simple, and only two MFC classes are used as base classes, which are CWINAPP classes and CDIALOG classes.
The main interface used by the dialog box can also use the AppStudio to edit the dialog interface, then use ClassWizard to generate the corresponding code frame, then modify the CMYAPP class declaration, add a member variable m_mydlg of the dialog class, and finally modify the CMYAPP class InitInstance. The function is as follows: BOOL CMYApp :: InitInstance () {m_mydlg.domodal (); return true;} 8. Artificial optimization of the MFC application Using C / C to write a Windows program is flexible and efficient, fast, Visual C compiler The optimization of itself is quite good, but this does not mean not need proper artificial optimization. In order to improve the speed of the program, the programmer can work hard from the following aspects: 1) Reduce unnecessary repeat display, Windows The GDI operation is relatively slow, so we should control the display and updates of the entire viewport as much as possible, and if the data does not change before and after, do not re-perform the GDI graphics operation of the viewport, especially for the background diagram Do not re-painted when it is displayed, do not refresh the entire window. 2) Do not update the screen operation when the viewport is extremely minimized, there is no need to continue the viewport update when the window is extremely small, which can significantly increase the speed. In this way, it is necessary to capture the above information at the child window (the viewport cannot capture the class information), and then perform the corresponding operation in the viewport. As shown below: First add the following block to the sub-window class: void cmychild :: OnsensCommand (uint nid, lparam lparam) {cmdichildwnd :: oversysCommand (NID, LPARAM); if (NID == sc_minimize) {redrawflag = 0; ElseredRawflag = 1;} Remnounced in the viewport update as follows: Void CMYCHART :: OnUpdate (CView * psenter, lparam lhint, cobject * phint) {if (pchild-> redrawflag) {INVALIDATERECT (& R, FALSE) Trace ("now in cmychart :: onupdate / n");}} As for the upstal PCHild pointer to get in the routine created by the viewport: pchild = (cmychild *) getParent (); 3) Using permanent resources In the viewport of GDI output frequent GDI output, as often used in monitoring software, display and album display, etc., you should consider establishing frequently used brushes and brushes at class levels, which avoids frequent piles. Create and delete the GDI object in the middle, thereby increasing the speed. 4) Use the own device description handle to have its own display device handle by specifying the WM_OWNDC style when creating a viewport, which consumes more memory, a DC accounts for about 800 bytes of memory, but this is avoided Create and reasonably initialize these duplicate operations each time GDI operation. In particular, it is especially important to customize the coordinate system and the viewport using special fonts. It is not advisable to reduce speed in order to save a little memory today in 16M machine. 5) Optimize compile time Specify / G3 Options and / FPIX87 Options / G3 options will force the compiler to use the 386 processor's processing code, use the embedded coprocessor instruction for frequent floating procedures that frequent floating point operations. Although these two compilation switches have improved the requirements for the user model, the 386 has been gradually eliminated, and the 486 market has shrunk substantially, and the 586 market is increasingly popular today, the above problems are no longer a problem.