Visual C MFC is in the article (recommended) (very long, no patience) Part 1: MFC Introduction
Visual C is more than just a compiler. It is a comprehensive application development environment, using it you are
Develop a professional Windows application with C with object-oriented properties. In order to make full use of these
Features, you must understand the C programming language. Master C , you must master the Microsoft Basic Class Bank (MFC)
Hierarchy. This hierarchy contains the user interface part in the Windows API and makes you easily
Establish a Windows application in an object. This hierarchy applies to all versions of Windows and each other
compatible. The code created with MFC is fully portable.
This tutorial will introduce you to the basic concepts and terms of the MFC and the design method of event driver. In this section, you will lose
Enter, compile and run a simple MFC program. These code will be explained in detail in the next section. The third part discusses M
FC control and how to customize them. The fourth section describes the message mapping and you will process the MFC event.
What is MFC?
How should you start with a Windows application?
A good start is from the design user interface. First, you have to decide what kind of user can use the program and come as needed.
Set the corresponding user interface object. Windows user interface has some standard control, such as buttons, menus, scroll bars,
List, etc., which is very familiar with those Windows users.
To remember, as a programmer must choose a set of controls and decide how to arrange them on the screen. Traditionally, you need
To do the sketch of the user interface on the paper until you are satisfied with each element. This is some relatively small project,
And the early prototype phase of some major projects is ok.
The next step is to implement the code. When establishing an application for any Windows platform, both programmers have two options: C
Or C . Use C, programmers write code on the Windows Application Interface (API). Boundary
The surface is composed of hundreds of C functions, which are introduced in the Windows API reference manual. For Windows
NT, API is called "WIN32 API" to distinguish between 16-bit APIs used for Windows 3.1.
Microsoft also provides a C library, which is located on any Windows API to make programmers' work easier.
. It is the Microsoft Basic Class Library (MFC), the main advantage of this library is efficient. It reduces a large number of builds WIND
The code must be written when the OWS program is written. At the same time, it also provides all the advantages of general C programming, such as inheritance and packaging.
. The MFC is portable, for example, code written under Windows 3.1 can be easily ported to Windows NT or WIN
DOWS 95. Therefore, the MFC is worth recommending to develop a Windows application method, in this tutorial from beginning to end
It is MFC.
When using the MFC, the code you have written is used to establish the necessary user interface control and customize its appearance. At the same time, you have to write code used to respond to user operations. For example, if a user clicks on a button, you should have a code to respond. This is the event-driven code, which constitutes all applications. Once the application is correctly responding to all allowed controls, its task is also completed.
You can see that when Windows programming is used by MFC, it is a relatively easy process. The purpose of this tutorial is to compare how to quickly establish a professional-grade application technology. The Visual C application development program is particularly suitable for using MFC (also using MFC, translator's note), so learning MFC and Visual C can enhance your development program.
Windows vocabulary
The vocabulary to be used in Windows user interfaces and software development is basic and unique. For new contacts
Users, review several definitions below to make our discussion easier.
Windows applications use several standard controls:
l Static text tag
l button
l list box
l Combination box (a more advanced list box)
l radio button
l Check button
l Edit box (single line and multi-line)
l scroll bar
You can build these controls via code or "resource editor", you can establish dialogs and these controls in the resource editor
system. In this tutorial, we will use the code to build them.
Windows supports several types of application windows. A typical application should be active in "Frame Window"
. A frame window is a full-featured main window, and the user can change the size, minimize, maximize, and so on. Windows
Two types of dialogs are also supported: mode and non-Mode dialog. Once the pattern dialog box appears on the screen, only when it
When exiting, the rest of the application can respond. When the Mode dialog box appears on the screen, the rest of the program can also respond, it is like floating above. The simplest Windows application is using a single document interface (SDI), with only one frame window. Windows watch, PIF editor, notepad, etc. are examples of SDI applications. Windows also provides an organizational form called multi-document interface that can be used for more complex applications. The MDI system allows users to view multiple documents at the same time. For example, a text editor can allow users to simultaneously open multiple text files. When using MDI, the application has a main window that has some sub-windows in the main window, each containing their own documents. In the MDI framework, the main window has a main menu, which is valid for the top window in the main frame. Each sub-window can be reduced to the icon or expand, and the MDI main window can also become an icon on the desktop. The MDI interface may give you a second desktop feel, it has a great help to the management and delete the chaotic window.
You have established a application that uses its own control, menu structure, and dialog. Application
The good depends on how you choose and organize these interface objects. The resource editor in Visual C allows you to build and customize these interface objects.
Event driver software and vocabulary
All windows-based GUIs contain the same basic elements, their operational methods are the same. On the screen, the user sees a set of windows, each window contains control, icons, objects, and some elements that handle mouse and keyboard. From a user point of view, the interface objects of each system are the same: buttons, scroll bars, icons, dialogs, and drop-down menus, and more. Although these interface elements may be somewhat different, these interface objects have the same way. For example, scroll bars may be somewhat different for Windows, Mac and Motif, but their role is complete. From programmers From a perspective, these systems are conceptually similar, although they may have great differences. In order to establish a GUI program, the first step in the programmer should put all the required user interface controls on the window. For example, if The programmer should establish a simple program from the transition from Celsius, and the user interface selected by the programmer is completed and displayed on the screen. In this simple program, the programmer may need the user in one Enter the temperature value in the edit edit box, display the conversion result in an inabled editable edit box, and let the user can click on a button labeled "exit" to exit the application. Because it is the user to operate the application, So the program must respond. The response depends on the user using the mouse or keyboard in different controls. Each user interface object on the screen is different. For example, if the user clicks the exit button, The button must update the screen and highlight itself. Then the program must respond to exit. The mode used by Windows is similar. In a typical application, you will create a main window and place some user interface control. These controls are often referred to as a sub-window - they are like some smaller and more special sub-windows in the main window. As a programmer, you should call to send information to send these controls, send you information to you The code responds to the user's operation.
If you have never done an event driver design, all of these may be very strange to you. However, the event driver design is easy to understand. Specific details may differ from different systems, but its basic concept is similar. In an event-driven interface, the application draws several interface objects on the screen, such as buttons, text areas, and menus. Applications typically respond to the user's operation through a code called an event cycle. Users can use the mouse or keyboard to operate the object on the screen. For example, the user clicks a button with a mouse. Clicking with a mouse is called an event. The event drive system defines the user's actions such as the mouse, and the keyboard operation is defined as an event, and the system operation is also defined as an event.
In a relatively low-level programming method, if you write a WindowsAPI application directly with C, the amount of code is very big, because the details you have to take care of it too much. For example, you use some type of structure to receive clicked mouse events. The code in your event loop will view different domains in the structure to determine which user interface is subject to influence, and then the corresponding operation is completed. Applications become big when there are many objects on the screen. Just simply? Which object is clicked and what you need to do for it needs to spend a lot. Fortunately, you can program in a relatively advanced approach, which is using MFC. In MFC, almost all low-level details are handed over. If you put a user interface object on the screen, you only need two lines of code to create it. If the user clicks on a button, the button will complete all the necessary operations, from the update screen to the pre-process function in your program. This function contains a code that makes a corresponding operation of the button. MFC handles all the details: You build buttons and tell it specific handle, when it is pressed, it calls the corresponding function.
The fourth part describes how to use a message mapping to handle events.
example
It is best to understand the structure and style of a typical MFC program to enter a small program, then compile and run it. The following program is a simple "Hello World" program. This is very familiar with many C programmers, let's take a look at how to use the MFC method. If you see such a program for the first time, it may be more difficult to understand. This doesn't matter, we will introduce it in detail later. Now you can build, compile and run it in the Visual C environment. //Hello.cpp
#include
// Describe the application class
Class ChelloApp: Public CWINAPP
{
PUBLIC:
Virtual Bool InitInstance ();
}
// Establish an instance of the application class
ChelloApp HelloApp;
/ / Describe the main window class
Class Chellowindow: Public CFrameWnd
{
CSTATIC * CS;
PUBLIC:
CHELLOWINDOW ();
}
/ / Whenever the application is called for the first time execution, the initialization function is called
Bool chelloApp :: InitInstance ()
{
m_pmainwnd = new chellowindow ();
m_pmainwnd-> showwindow (m_ncmdshow);
m_pmainwnd-> UpdateWindow ();
Return True;
}
// Window constructor
Chellowindow :: chellowindow ()
{
// Create the window itself
Create (NULL,
"Hello World!",
WS_OVERLAPPEDWINDOW,
CRECT (0,0,200,200));
// Establish a static label
CS = new cstatic ();
CS-> CREATE ("Hello World",
WS_CHILD | WS_VISIBLE | SS_CENTER,
CRECT (50, 80, 150, 150),
THIS);
}
The above program is implemented by c, you have to need a few pages of code. This simple example did three things. First, it established an application object. Each MFC program you have written has a single program object that processes the initial details of MFC and Windows. Second, the application establishes a window to be used as the main window of the application. Finally, a static text tag is established in the application's window, which contains several words of "Hello World". In the second part we will study this process carefully to understand its structure. Start VC , if you just install it, you will see an empty window with the toolbar on the screen. If VC has been used on the machine, the displayed window may be somewhat different because VC will re-open items and files when you exit after the last use. What we need is that it is not installed as any project and code. If the program is started, the pop-up dialog indicates that some files cannot be opened, you can click "NO". Select the "Close All" option in the Win Dow menu to close all windows. Select "Close" option in the "File" menu to close other windows. Now you are in the beginning. If you installed VC , the first time you run, the screen should look like this:
If you don't want to see the "InfoViewer Topic" window in the future, you can turn it off with the button. If you need it later, you can also click the "Home" button on the toolbar to open the window. Everything is everything is normal. As you can see, the top is a menu and several toolbar. The left window is displayed online help, you can double-click on a title to browse its content. The content of online help is very rich. What should I do now? What you have to do is entering the above program, then cheap and run it. Before you start, check at least 5MB of remaining space on your hard drive. Establish project and compile code
In order to compile the code in Visual C , you have to build a project. In order to build a small program, it is possible to have a small subject, but in any actual program, the concept of the project is very useful. A project mainly stores the following three different types of information:
1. It can remember to create all source program code files required for executables. In this simple example. File Hello.cpp is the only source file, but in a large application, in order to facilitate management and maintenance, you can have many different source files. The project maintains a list of these different files and compiles them when you want to create the next new executable.
2. It remembers the compiler and connector options for your application. For example, it remembers which library connects to the executive, and whether you preparatively translate the header file and so on.
3. It will remember the type of item you want to build: a console application, or a window application, and more. If you have already understood project files, it will be easy to understand the role of project files generated by the machine. Now let's build a simple project and use it to compile hello.cpp.
To do this, first select the "New" option from the "File" menu. In the "Projects" tab, add "Win32 Application". Enter a suitable path name or click the "Browse" button to select one in the "Location" field. In "Project Name" into "Hello" as the project name. At this time you will see "Hello" will also appear in the "location" domain. Click the "OK" button. Visual C will create a new directory called Hello and put all items file hello .opt, hello.ncb, hello.dsp, and hello.dsw in this directory. If you quit, you can reopen the project later, you can choose Hello.dsw. Now, three tags appear on the left side of the screen. The InfoView tag is still in, and there is a new ClassView and FileView tags. The ClassView tab will list all the classes in your program, and the FileView tab gives a list of files in the project. You can now enter the code of the program. Select the "New" option in the "File" menu to create an editing window. In the dialog box that appears, select the "Files" tab and "text file". The Visual C intelligent editor will appear, you can use it to enter the above program code. When you enter a code, you will find that the editor will automatically turn different types of text into different colors, such as comments, keyword strings, etc. color. If you want to change its color or turn the color function, select the "Options" option in the Tools menu, then select the "Format" tab and "Sou RCE Windows" option to modify. After entering the code, select the "Save" option in the "File" menu to save. In the newly established directory of Visual C , the Hello.cpp file is stored. Now select "Add to Project" option in the "Project" menu, then select "Files ...". You will see a dialog for you to choose the file you want to add. In this example, select the Hello.cpp file. On the left side of the screen, click the FileView tab and double-click the icon marked with Hello. You will see files named hello.cpp. Click the ClassView tab and double-click the folder icon, you will see all the classes in the program. At any time, you can use FileView to delete the project file, you just click on the file, then press the Delete key on the keyboard. At this point you have to tell the project to use the MFC library. If you ignore this step, the project will be wrong when the project is connected, and the error message is unable to help you. Select "Settings" of the "Project" menu. Select the "General" tab in the dialog that appears. In the "Microsoft Foundation Classes" combo box, select "Use MFC in A Shared DLL". Then close the dialog box.
We have established project files and adjusted settings, you can now prepare to compile the Hello.cpp program. In the "Build" menu, you will find three different compilation options:
1. Compile hello.cpp (only when the window containing hello.cpp is active) 2. Build Hello.exe
3. Rebuild All
The first option is just the main file and forms their target files. This option cannot complete the connection task, so it is only useful to quickly compile some source files to check the error. The second option compiles all the source files modified after the last compiled, and connects to the formation executable. The third option To recompile and connect all source files. We can choose "Build Hello.exe" to compile and connect code. Visual C will establish a new child directory named "debug" and put hello.exe in this directory. The files of the subdirectory can be generated, so you can delete them any.
If you find a compilation error, double-click the error message in the output window. At this time, the editor will take you to the wrong location. Check if your code has a problem, if you have, you will modify it. If you see a large number of connection errors, you may not be right in the project type specified in the Establishment Project dialog. You can delete the subdirectories where the project is located, then re-press the steps above.
To perform the program, you can choose the "EXECUTE Hello.exe" option in the "Build" menu. You can see your first MFC program - a window with "Hello World" appears. The window itself has: title bar, size zoom area, maximum and minimum buttons, and more. On the window, there is a "Hello World". Please note that the program is complete. You can move the window, zoom window, minimize, and so on. You only use a very little code to complete a complete Window application. This is the advantage of using the MFC. All detail issues have MFC to handle.
in conclusion
In this lecture, you have successfully compiled and implemented your first MFC program. You will use similar steps to build applications. You can establish a separate directory for each project, or create a separate project file, then add or delete different source files. In the next lecture, we will carefully study the program, you will understand its structure more complete.
Part II: A simple MFC program
In this will, we will study the MFC app mentioned in a place in order to understand its structure and conceptual framework. We will introduce the MFC first, then describe how to use MFC to create an application.
MFC introduction
MFC is a big, extended C class hierarchy, which makes it easier to develop Windows applications. MFC is compatible throughout the Windows family, that is, whether Windows3.x, Windows95 is still Windows NT, and the MFC used is compatible. Whenever the new Windows version occurs, the MFC will be modified to make the old compiler and code work in a new system. The MFC also returns to the extension, adding new features, making it easier to build applications.
In contrast to traditionally accessing the Windows API, the advantage of using MFC and C is that the MFC already contains and compresses all standard "model file" code, which is required for all WINDOWS programs written in C. Therefore, the program written in MFC is much smaller than the program written in C language. In addition, the performance of the program written by the MFC has no loss. If necessary, you can also call the standard C function directly because MFC does not modify the basic structure of the Windows program.
The biggest advantage of using MFC is that it has made all the most difficult things. The MFC contains thousands of rows of correct, optimized, and powerful Windows code. Many member functions you call have completed the work you might hard. From this, MFC greatly accelerates your program development speed. MFC is very large. For example, approximately 200 different classes are included in version 4.0. Fortunately, you don't need to use all functions in a typical program. In fact, you may only need to use different categories in more than 10 MFCs to create a very beautiful program. This hierarchy can be divided into several different types:
l Application framework
l graphically drawn drawing
l file service
L abnormal processing
l Structure - List, Array and Map
l Internet service
l ole 2
l database
l General class
In this tutorial, we will focus on visual objects. The following list gives some classes:
l COBJECT
l ccmdtarget
l cwinthread
l cwinapp
l CWnd
l cframewnd
l CDIALOG
l CVIEW
l cstatic
l cbutton
l Clistbox
l CCOMBOBOX
l Cedit
l cscrollbar
In the list above, there are a few things to pay attention to. First, most of the classes in the MFC are inherited from the base class COBJECT. This class contains data members and member functions that most of the MFC classes. Second, it is the simplicity of the list. The CWINAPP class is to use in your establishment of the application, and only once in any program. The CWND class brings together all common features, dialogs, and control in Windows. The CFRAMEWND class is inherited from CWND and implements a standard framework application. CDIALOG can handle two types of dialogs that have two types and models, respectively. CVIEW is used to allow users to access documents via windows. Finally, Windows supports six control types: Static text box, editable text box, buttons, scroll bars, list boxes, and combo boxes (an extension list box). Once you understand these, you can better understand the MFC. Other classes in the MFC implements other features such as memory management, document control, and more.
In order to establish an MFC application, you must use these classes directly, and usually you need to inherit new classes from these classes. In inherited classes, you can create new member functions, which can be more applicable to your own needs. You have seen this inheritance process in the simple example of the first lecture, and will be described in detail below. ChelloApp and Chellowindow are inherited from existing MFC classes.
Design a program
Before discussing the code itself, we need some workers to briefly describe the process of designed in the following MFC. For example, if you want to compose a program to display "Hello World" information to the user. This is of course very simple, but still needs some consideration. "Hello World" application first needs to create a window on the screen to display "Hello World". Then you need to put "Hello World" on the window. We need but an object to complete this task:
1. An application object used to initialize the application and hung it on Windows. Application object processing
All low-level events.
2. A window object comes as a main window.
3. A static text object used to display "Hello World".
Each program created by MFC will contain two objects. The third object is for the application. Each application defines its own group of user interface objects to display the output of the application and collect input information for the application. Once you have completed the interface design, and decide to implement the control required to implement the interface, you need to write The code is to create these controls on the screen. You will also write code to handle information generated by users to operate these controls. In the "Hello World" application, there is only one control. It is used to output "Hello World". Complex programs may require hundreds of controls in their main windows and dialogs. It should be noted that there are two different methods in the application to establish user control. What is introduced here is to establish control with a C code method. However, in a relatively large application, this method is not feasible. Therefore, the control is established in the usual case of the graphic editor of the resource file. This method is much easier. Understand the code of "Hello World"
The code for "Hello World" program you have entered, compiled and running in the previous lecture is listed below. The addition line number is for convenience of discussion. Let's take a line to study it, you will better understand the way MFC builds the application. If you haven't compiled and run the code yet, you should do it on the way.
1 //Hello.cpp
2 #include
3 // Declare the Application Class
4 Class ChelloApp: Public CWINAPP
5 {
6 public:
7 Virtual Bool InitInstance ();
8 };
9 // Create an Instance of the Application Class
10 cheloApp helloapp;
11 // Declare The Main Window Class
12 Class Chellowindow: Public CFrameWnd
13 {
14 cstatic * cs;
15 public:
16 chellowindow ();
17};
18 // The InitInstance Function IS Called Each
19 // Time The Application First Execute.
20 Bool ChelloApp :: InitInstance ()
twenty one {
22 m_pmainwnd = new chellowindow ();
23 m_pmainwnd-> showwindow (m_ncmdshow);
24 m_pmainwnd-> UpdateWindow ();
25 return true;
26}
27 // The constructor for the window class
28 chellowindow :: chellowindow ()
29 {
30 // Create the window itself
31 CREATE (NULL,
32 "Hello World!",
33 WS_OVERLAPPEDWINDOW,
34 CRECT (0,0,200,200));
35 // CREATE A Static Label
36 cs = new cStatic ();
37 CS-> CREATE ("Hello World",
38 WS_CHILD | WS_VISIBLE | SS_CENTER,
39 CRECT (50, 80, 150, 150), 40 this);
41}
You look at the code above to get a whole impression. The procedure consists of six small parts, and every part is a very important role. First, the program contains the header file AFXWIN.H (line 2). The header file contains all types, classes, functions, and variables used in the MFC. It also includes other headers such as Windows API libraries. Articles 3 to 8 Row from the standard application class CWINAPP description of the MFC inherits new application class chelloApp. This new class is to overload the InitInstance member function in CWINAPP. InitInstance is an overloaded function to be called when an application starts execution. In Chain 10, an application is explained as a global variable. This example is important because it will affect the execution of the program. The establishment of the global variable will perform the default constructor of the CWINAPP class when the application is loaded into memory and start execution. This constructor automatically calls the initInstance function defined in the 18 to 26 row. In 11 to 17, the Chellowindow class is inherited from the CFrameWnd class in the MFC. Chellowindow is a window as an application on the screen. Establish a new class to implement constructor, destructuring functions, and data members. The 18th to 26 lines implements the initInstance function. This function generates an example of a CHELLOWINDOW class, thus executing the constructor of the category 27 to 41 lines. It also puts a new window on the screen. Section 27 to 41 implements the constructor of the window. This constructor is actually a window, and then establishes a static text control.
It should be noted that there is no main or winmain function in the program, and there is no event loop. However, we know that it also handles events from the previous lecture. Windows can maximize or minimize, mobile windows, and more. All of these operations are hidden in the primary application class CWINAPP, and we don't have to worry about its event, it is automated, which is invisible in the MFC.
In the next section, the part of the program will be described in detail. You may not be able to fully understand very well: But you'd better finish it to get the first impression. In the next lecture, some special examples will be introduced, and the combination of each fragment will help you better understand.
Program object
Each application established with MFC includes a single application object inherited from a CWINAPP class. This pair must be explained to a global (line 10) and can only appear once in your program. Objects inherited from CWINAPP classes are mainly to process the application's initialization, while also processing the application main event loop. CWINAPP classes have several data members and several member functions. In the above program, we only overload a virtual function in CWINAPP initInstance.
The purpose of the application object is to initialize and control your program. Because Windows allows multiple instances of the same application to be executed at the same time, the MFC divides the initialization process into two parts and uses two functions initApplication and InitInstance to process it. Here, we only use an initInstance function because our procedure is very simple. A new example will be called when the application is called. The code of the 3rd to 8th line has established a class called ChelloApp, which is inherited from cwinapp. It contains a new InitInstance function, which is overloaded from the existing functions existing in CWINAPP: 3 // Declare the Application Class
4 Class ChelloApp: Public CWINAPP
5 {
6 public:
7 Virtual Bool InitInstance ();
8 };
In the overloaded InitInstance function, the 18th to 26 lines, the program uses ChelloApp's data member m_pmainwnd to create and display the window: 18 // The InitInstance Function is Called Each
19 // Time The Application First Execute.
20 Bool ChelloApp :: InitInstance ()
twenty one {
22 m_pmainwnd = new chellowindow ();
23 m_pmainwnd-> showwindow (m_ncmdshow);
24 m_pmainwnd-> UpdateWindow ();
25 return true;
26}
The InitInstance function returns true indicates that the initialization has successfully completed. If false returns, it indicates that the application will terminate immediately. In the next section we will see the detailed process of the window initialization. When the application object is established at the 10th line, its data member (inherited from CWINAPP) will automatically initialize. For example, m_pszappname, m_lpcmdline, and m_ncmdshow include appropriate initialization values. You can see the MFC's help file to get more detailed information. We will use one of these variables.
Window object
The MFC defines two types of windows: 1) Frame window, which is a full-featured window, can change the size, minimize, maximize, etc.; 2) dialog window, it cannot change the size. The frame window is a typical primary application window. In the following code, inheriting a new class chellowindow from the cframewnd:
11 // Declare The Main Window Class
12 Class Chellowindow: Public CFrameWnd
13 {
14 cstatic * cs;
15 public:
16 chellowindow ();
17};
It includes a new constructor, and there is a data member that is the unique user interface control used in the program. Each application you create will have a unique set of controls in the main window. Therefore, inheritance classes will have an overloaded constructor to create all the controls needed by the main window. In a typical case, this class will contain a destructor to delete them when the window is closed. We did not use the destructor here. In the fourth lecture, we will see that the inheritance window will also explain a message processing function to handle the messages generated by the user event.
Typically, an application will have a primary application window. Therefore, the CHELLOAPP application class defines a named m_pmainwnd member variable to point to the main window. In order to establish the main window of the program, the InitInstance function (line 18 to 26) has established a checkowindow case and uses m_pmainwnd to point to a new window. Our Chellowindow object is established on line 22:
18 // The InitInstance Function IS Called Each
19 // Time The Application First Execute.
20 Bool ChelloApp :: InitInstance ()
twenty one {
22 m_pmainwnd = new chellowindow ();
23 m_pmainwnd-> showwindow (m_ncmdshow);
24 m_pmainwnd-> UpdateWindow ();
25 return true;
26}
It is not enough to create a simple frame window. Also make sure the window can appear correctly on the screen. First, the code must call the window's showWindow function to appear on the screen (line 23). Second, the program must use the UpdateWindow function to make sure that each of the controls and outputs in the window can appear on the screen (line 24). You may be strange, the showWindow and UpdateWindow functions are defined. For example, if you want to view to understand them, you might want to see the CFraMewnd definition section in the MFC's help file. However, these member functions are not included in the cframewnd. CframeWnd is inherited from the CWND class. You can view the CWnd in the MFC document and you will find that it contains more than 200 different member functions. Obviously, you can't grasp these functions in a few minutes, but you can master a few of them, such as ShowWindow and UpdateWindow. Now let's take a few minutes to see the CWnd :: ShowWindow function in the MFC help file. To do this, you ke with the Search button in the help file and enter "showwindow". After you found it, you will notice that ShowWindow has only one parameter, you can set different parameter values. We set it into the data member variable M_ncmdshow (line 23) of ChelloApp in our program. The m_ncmdshow variable is used to initialize the application started window display mode. For example, the user may launch an application in the Program Manager, and can tell the Program Properties dialog to tell the Manager application to maintain a minimize state when starting. The m_ncmdshow variable will be set to sw_showminimized, and the application is started in the form of an icon, that is, after the program is started, it is an icon representing the program. M_ncmdshow variables are a way to communicate with the application. If you like, you can use different m_ncmdshow values to test the effect of ShowWindow. But to recompile the program to see the effect. Chapter 22 is the initialization window. It assigns memory to call the New function. At this point, the program calls the CHELLOWINDOW constructor when executed. This constructor is called when the case is assigned each time the case is assigned. In the interior of the window constructor, the window must establish itself. It is implemented by calling the CREATE member function of CFrameWnd (31st line):
27 // The constructor for the window class
28 chellowindow :: chellowindow ()
29 {
30 // Create the window itself
31 CREATE (NULL,
32 "Hello World!",
33 WS_OVERLAPPEDWINDOW,
34 CRECT (0,0,200,200));
The establishment function transmits four parameters. By viewing the MFC document, you can learn about different types. NULL parameters represent the use of default class names. The second parameter is a title that appears on the window title bar. The third parameter is the type attribute of the window. This program uses normal, overwritable types of windows. Type properties will be described in detail in the next lecture. The fourth parameter indicates that the window should be placed on the screen and the upper left corner (0,0), the initialization size is 200 × 200 pixels. If you use RectDefault, Windows will automatically place the window and size for you. Because our program is too simple, it only creates a static text control in the window. See Sections 35 to 40. The following will be described in detail below.
Static text control
When the program is inherited from the CFRAMEWNDOD class (lines 11 to 17), a member type CSTATIC and its constructor are described. As seen in the previous, the chellowindow constructor mainly do two things. The first is to establish a window of the application by calling the Create function (line 31). Then allocate and establish controls that belong to the window. In our program, only one control is used. Building an object in the MFC will always take two steps. The first is to allocate memory for the class, and then call the constructor to initialize the variable. Next, call the CREATE function to actually create an object on the screen. Code uses these two steps allocation, constructs and creates a static text object (36-40): 27 // The constructor for the window class
28 chellowindow :: chellowindow ()
29 {
30 // Create the window itself
31 CREATE (NULL,
32 "Hello World!",
33 WS_OVERLAPPEDWINDOW,
34 CRECT (0,0,200,200));
35 // CREATE A Static Label
36 cs = new cStatic ();
37 CS-> CREATE ("Hello World",
38 WS_CHILD | WS_VISIBLE | SS_CENTER,
39 CRECT (50, 80, 150, 150),
40 THIS);
41}
The CSTATIC constructor is called when it is assigned, and then the CREATE function is called to establish a window of the CSTATIC control. The parameters used by the Create function are similar to the parameters used by the window establishment function (line 31). The first parameter specifies the text content to be displayed in the control. The second parameter specifies the type attribute. Type properties will be described in detail in the next lecture. The sub-window type (the window displayed in another window), and it is visible, and the display position of the text is in place. The third parameter determines the size and position of the control. The fourth parameter represents the parent window of the sub-window. A static control has been established, which will appear on the application window and display the specified text.
in conclusion
For the first time, you may not be very familiar with some troubles. But don't worry. From a programmer's point of view, the main job of the entire program is to establish CSTATIC control (36 to 40 rows). In the next lecture, we introduce you to the meaning of 36 to 40 lines of code, and you can see several options for custom CSTATIC control.
Part III: MFC style
Control is a user interface object used to establish a Windows application user interface. Most of the Windows applications and dialogs you have seen are intended by some controls to implement the program function. In order to establish a valid application, you must fully understand how to use it reasonably in a Windows application. There are six basic controls: CSTATIC, CB Utton, Cedit, Clist, CCOMBOX and CSCROLLBAR. In addition, Windows95 adds 15 enhanced control. What you need to understand is what control can do. How should you control its appearance and behavior and how to make control respond to user events. Just master these, plus the menu and dialog box, you can build any Windows applications you imagined. You can use the program code in this tutorial to build control, or use the test editor to create through the resource? When?, The dialog editor is more convenient, it is especially useful for it has been basically mastering.
The simplest control is CSTATIC, which is used to display static text. CSTATIC classes do not have any data members, which only have a small number of member functions: constructor, create function (used to get and set icons on static control), and so on. It does not respond to user events. Because of its simplicity, it is best to use it as the beginning of the WINDOWS control. In this lecture, we start from CSTATIC to see how to modify and customize control. In the next lecture, we will learn CButton and CScrollbar classes to understand the concept of event processing. Once you understand and master all control extremes, you can build a complete application.
Foundation
The CSTATIC class in the MFC is used to display static text information. These information can be used as pure information (eg, an error message displayed in the information dialog), or as a small label or the like. In the Windows Application File Open dialog, you will find six such labels. CSTATIC control has several other display formats. You can make it a rectangle, a border or icon, or the like by modifying the label style. CSTATIC control always appears as a sub-window. Typically, its parent window is an application's main window or dialog. As mentioned above, you can build a static control with two lines of code:
CSTATIC * CS;
...
CS = new cstatic ();
CS-> CREATE ("Hello World",
WS_CHILD | WS_VISIBLE | SS_CENTER,
CRECT (50, 80, 150, 150),
THIS);
These two lines of code are typical MFC to build all control code. Calling New to assign memory for the CSTATIC class, and then call the structure of the class. The constructor is the initialization function used to complete the class. The CREATE function establishes control and put it on the screen.
The Create function has five parameters:
LPSZText: Specifies the text to display.
RECT: The location, size, and shape of the text area.
PParentWnd: Specifies the parent window that CSTATIC control. This control will appear in its parent window, and its location is relative
The user area of its parent window is concerned.
NID: integer value indicates the identifier of the control.
DWStyle: The most important parameter. It controls the appearance and behavior of control.
CSTATIC style
All controls have various display styles. The style is determined by the DWStyle parameter passed to its DWStyle parameter when establishing a CREATE function. For CSTATIC Effective Style Description: Style from CWND inheritance:
l must be made by WS_CHILD CSTATIC.
l WS_Visible indicates that the control should be visible to the user.
l WS_DISABLED indicates that the control refuses to accept user events.
l WS_BORDER controlled text area with a border.
CSTATIC inherent style:
l SS_BLACKFRAME This control area is displayed in a rectangular boundary. Colors are the same as the window frame.
l SS_BLACKRECT? This control is displayed in a filling rectangle. Colors are the same as the current window frame.
l Ss_center text.
l SS_GRAYFRAME Control is displayed in a rectangular border. The color is the same as the current desktop.
l SS_GRAYRECT This control is displayed in a fill rectangle. The color is the same as the current desktop.
l SS_ICON control is displayed in the form of an icon. Text as the name of the icon in the resource file. The RECT parameter only controls the location.
l SS_LEFT text is left. Text can be wrapped around.
l SS_LEFTNOWORDWRAP text is left. Excess text is tailored.
l SS_NOPREFIX indicates that "&" characters in the string do not represent an acceleration prefix.
l SS_RIGHT text is displayed. Text can be wrapped around.
l SS_SIMPLE is only simple to display a line of text. Any CTLColor information is ignored by its parent window.
l SS_USERITEM user definition item.
l SS_WHITEFRAME Control is displayed in a rectangular border. The color is the same as the current window background.
l SS_WHITERECT control is displayed in a fill rectangle. The color is the same as the current window background. Among these constants, the "SS" (Static style) can only be used for CSTATIC control. The constant indicates that the "WS" (Window Style) can be applied to all windows, which are defined in the CWND object. There are still a lot of "WS" style constants in CWnd. You can find them in the CWnd :: Create function in the MFC document. The above four are only used for CSTATIC objects.
The CSTATIC object is at least two styles: WS_CHILD and WS_VISIBLE. This control must be established as a sub-window of another window. If WS_Visible is not used, the established control is invisible. WS_DISABLED controls the response of the label to the event because the CSTATIC does not receive a keyboard or mouse event, so it is redundant. All other style options are optional, which controls the appearance of the label. Use these controls in the cstatic :: Create function, you can control the display on the screen on the screen.
CSTATIC text appearance
The lower code is helpful for understanding CSTATIC. It is similar to the code introduced in the previous lecture, but modifies the establishment of CSTATIC.
//static1.cpp
#include
// Declare the Application Class
Class Ctestapp: Public CWINAPP
{
PUBLIC:
Virtual Bool InitInstance ();
}
// Create an Instance of the Application Class
CTestApp TestApp;
// Declare the main window class
Class CtestWindow: Public CFrameWnd
{
CSTATIC * CS;
PUBLIC:
CTestWindow ();
}
// the initInstance function is caled
// ONCE WHEN THE Application First Executes
Bool ctestapp :: initInstance ()
{
m_pmainwnd = new ctestwindow ();
m_pmainwnd-> showwindow (m_ncmdshow);
m_pmainwnd-> UpdateWindow ();
Return True;
}
// the constructor for the window class
CTestWindow :: ctestwindow ()
{
CRECT R;
// Create the window itself
Create (NULL,
"CSTATIC TESTS",
WS_OVERLAPPEDWINDOW,
CRECT (0,0,200,200));
// Get the size of the client rectangle
GetClientRect (& r);
R.INFLATERECT (-20, -20);
// Create a static label
CS = new cstatic ();
CS-> CREATE ("Hello World",
WS_CHILD | WS_VISIBLE | WS_BORDER | SS_CENTER,
R,
THIS);
}
Below is the window constructor plus the line number:
CTestWindow :: ctestwindow ()
{
CRECT R;
// Create the window itself
1 CREATE (NULL,
"CSTATIC TESTS",
WS_OVERLAPPEDWINDOW, CRECT (0,0,200,200));
// Get the size of the client rectangle
2 getClientRect (& r);
3 R.INFLATERECT (-20, -20);
// Create a static label
4 cs = new cStatic ();
5 CS-> Create ("Hello World",
WS_CHILD | WS_VISIBLE | WS_BORDER | SS_CENTER,
R,
THIS);
}
First call the CTestWindow :: Create function in clicking 1 line. It is the Create function of the cframewnd object because C TestWindow inherits its behavior from CFrameWnd. So the code in the first line specifies that the window size should be 200 × 200 pixels, and the upper left corner of the window is initialized at the 0,0 position of the screen. Constant RectDefault can be replaced with CRECT parameters. On the second line, call CTestWindow :: getClientRect, pass the & R parameter to it. The GetClientRect function is inherited from the CWND class. Variable R is CRECT type, and in the beginning of the function is described as partial variables. It may be two problems when this code is understood. 1) What is the getClientRect function? 2) What is the CRECT variable? 2) What is the CRECT variable?
Let us answer the first question first. When you view the CWnd :: getClientRect function in the MFC document, you will find it to return a CRECT type that contains the user area rectangle of the specified window. It saves the address & r of the parameters & r. This address points to the location of CRECT. The CRECT type is defined in the MFC. It is very convenient to use it to handle rectangles. If you look at the following MFC documents, will you define more than 30 member functions and operators of the rectangle. In our case, we have to display "Hello World" in the middle of the window. Therefore, we use getClientRect to get the rectangular coordinates of the user area. Crect:: Inflatrect is called in line 3, while also increasing or reducing the size of the rectangle (see CRECT :: DeflateRect). Here we decrease 20 pixels each side of the rectangle. If this is not this, the boundaries around the label will exceed the window frame. In fact, CSTATIC is established in lines 4 and 5. Styles properties are centered and have borders. The size and position are determined by the CRECT parameter R.
By modifying different style properties, you can understand different forms of CSTATIC. For example, the following code contains modifications to the CTESTWINDOW constructor, and the resulting control has a displacement:
CTestWindow :: ctestwindow ()
{
CRECT R;
// Create the window itself
Create (NULL,
"CSTATIC TESTS",
WS_OVERLAPPEDWINDOW,
CRECT (0,0,200,200));
// Get the size of the client rectangle
GetClientRect (& r);
R.INFLATERECT (-20, -20);
// Create a static label
CS = new cstatic ();
CS-> Create ("Now Is The Time for All Good Men TO /
Come to the aid of their country,
WS_CHILD | WS_VISIBLE | WS_BORDER | SS_CENTER,
R,
THIS);
}
The above code has no difference between the text displayed. You can see if you run the code, CSTATIC has wrapped around the text in the specified area, and there is no hide. If the border rectangle is too small to contain all text rows, the text will be cut to accommodate. You can see this feature of the CSTATIC if you reduce the size of the rectangle or increase the string length. In all the code we see, style ss_center is used in Chinese. CSTATIC also allows left alignment or right alignment. The left alignment is used to replace the SS_Center property with SS_LEFT. Similarly, right or right is to replace it with SS_RIGHT. The SS_LEFTNOWORDWRAP property is used to close the text round. It will force the use of left alignment properties. CSTATIC's rectangular display mode
CSTATIC also supports two different rectangular display modes: fill rectangles and frames. It is usually used in these two modes to bring together a set of controls. For example, you can put black background frame windows as a set of edit boxes. You can choose six different styles:
SS_BLACKFRAME, SS_BLACKRECT, SS_GRAYFRAME, SS_GRAYRECT, SS_WHITEFRAME, and SS_WHITERECT. RECT forms a filled rectangle, while the frame consists of one side. The color logo, such as SS_WHITERECT indicates that its color is the same as the color of the window background. Although the default value of this color is white, you can use the control panel to change, at this time, the color of the rectangle may not be white.
When a rectangle or frame properties are specified, the text string of CSTATIC will be ignored. Typical situations are transmitted. You can test these features.
Font
You can use the CFont class to change the CSTATIC's font. The CFont class in the MFC holds a single instance of a special Windows font. For example, an instance of the CFont class may save 18 points of Times fonts, while the other may save 10 points Courier fonts. You can call the setFont function to modify the font. The following code gives how to implement fonts.
CTestWindow :: ctestwindow ()
{
CRECT R;
// Create the window itself
Create (NULL,
"CSTATIC TESTS",
WS_OVERLAPPEDWINDOW,
CRECT (0,0,200,200));
// Get the size of the client rectangle
GetClientRect (& r);
R.INFLATERECT (-20, -20);
// Create a static label
CS = new cstatic ();
CS-> CREATE ("Hello World",
WS_CHILD | WS_VISIBLE | WS_BORDER | SS_CENTER,
R,
THIS);
// Create a new 36 Point Arial Font
Font = new cfont;
FONT-> CREATEFONT (36, 0, 0, 0, 700, 0, 0, 0,
ANSI_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,
DEFAULT_PITCH | FF_DONTCARE,
"arial");
// cause the lael to use the new font
CS-> setFont (font);
}
The above code begins with the creation window and cStatic. Then create a CFont type object. The font variable should be "cfont * font" as a data member of CTESTWINDOW. The cfont :: CreateFont function has 15 parameters, but only three are most common. For example, 36 specifies the font size of the point unit, 700 specifies the density of the font (400 is normal "normal", 700 is the black "bold", the value of the value is 1 to 1000. Fw_normal and fw_bold meanings actually Is the same), "arial" is the name of the font used. Windows usually has five TRUE TYPE fonts (Arial, Courier New, Symbol, Times New Roman, and Wingdings), you can make sure that there will be this font on any machine. If you use the font that you don't know, CFont will choose the default font, just as you can see in this tutorial. To learn more about the CFont class, see the MFC documentation. In the API online help file, there is a good overview of the font. Find "Fonts and Text Overview".
The setFont function is inherited from CWND. It is used to set the font of the window, in our program is a CSTATIC sub-window. You may have to ask: "How do I know which functions in CWnd can be used for CSTATIC?" You can only learn in practice. Take some time to look at all functions of CWND. You will have something to gain and you will find which functions can be used to customize control. We select other SET functions in the CWND class in the election.
in conclusion
In this tutorial, we surveted a lot of different characteristics in CSTATIC. For the SET function inherited from CWND, we will put it in the next lecture because it is more appropriate.
View the functions in the Microsoft document
In Visual C 5.x, it is very simple to find more unfamiliar functions. All MFC, SDK, Windows API, and C / C standard library functions are inherited to the same help system. If you can't determine where the function you want, you can use the Search option in the Help menu to find. All related functions will be listed.
Compile multiple executables
In this tutorial, there are several examples. There are two ways to compile and run them. The first way is to put each program in your own directory, and then establish a project for each program. Using this technology, you can compile each program separately, and you can use them simultaneously or independently. The disadvantage of this method is that there is a relatively large disk space. The second method is to establish a directory for all procedures. You can a project file. To compile each program, you can edit the project and change the source file. When you recompile the project, the new executor is the source file you choose. This method can reduce disk space.
Part IV: Message Mapping
Any user interface object in the application is placed with two controlable features: 1) Its appearance, 2) It responds to the act of events. In the previous talk, you have learned CSTATIC control and how to use style properties to customize the appearance of the user interface object. These concepts can be used in all different control classes in the MFC. In this lecture, we will introduce CButton control to understand message mapping and simple event processing. Then there is also an example of a slightly complex point using CScrollBar control.
Comprehension message mapping
In the second lecture, the MFC program does not include the main function or time cycle. All event processing is processed in the background as part of CWINAPP. Because they are hidden, we need a way to tell the invisible time loop to advertise our application. This requires a mechanism called a message mapping. Message mapping identifies an event of interest and then calls a function to respond to these events.
For example, if you want to write a program, you want to quit the application when the user is marked with the "exit" button. In the program, you write code to create buttons: You indicate how the button will act. Then, establish a message mapping when the user clicks the button is created for its parent window, which is trying to pass the message to his parent window. In order to establish a message of the parent window, you have to establish a mechanism for intercepting a message map and use the message of the button. When a specified button event occurs, the message mapping requests the MFC to call a specified function. In this case, click Exit button to be interested in events. Then you put the code of the exiting application in the specified function. Other work is made by MFC. When the program is executed, the user will highlight it when the user clicks the "Exit" button. The MFC then automatically invokes the corresponding function and the program will terminate. You only use fewer lines of code you respond to user events. CButton class
The CSTATIC control discussed in the previous lecture is the only connection to the user time. All other controls in Windows can respond to user events. First, when the user processes them, they automatically update their appearance (for example, when the user clicks the button, the button will highlight itself to give the user a feedback). Second, each different control must send information to your code to enable the program to respond to the needs of the user. For example, when a button is clicked, the button will send a command message. If you write code to receive messages, your code can respond to user events. In order to understand this process, we start from CButton control. The following code illustrates the process of establishing a button:
// Button1.cpp
#include
#define idb_button 100
// Declare the Application Class
Class CbuttonApp: Public CWINAPP
{
PUBLIC:
Virtual Bool InitInstance ();
}
// Create an Instance of the Application Class
CButtonApp ButtonApp;
// Declare the main window class
Class CButtonWindow: Public CFrameWnd
{
CButton * Button;
PUBLIC:
CButtonWindow ();
}
// the initInstance function is caled overce
// when the application first executes
Bool cbuttonapp :: initInstance ()
{
m_pmainwnd = new cbuttonWindow ();
m_pmainwnd-> showwindow (m_ncmdshow);
m_pmainwnd-> UpdateWindow ();
Return True;
}
// the constructor for the window class
CButtonWindow :: CbuttonWindow ()
{
CRECT R;
// Create the window itself
Create (NULL,
"CButton Tests",
WS_OVERLAPPEDWINDOW,
CRECT (0,0,200,200));
// Get the size of the client rectangle
GetClientRect (& r);
R.INFLATERECT (-20, -20);
// Create a button
Button = new cbutton ();
Button-> Create ("Push ME",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, R,
this,
IDB_BUTTON);
}
The above code is almost the same as the code described in the previous. The Create function of the CButton class has a total of 5 parameters. The top four were the same as CS Tatic. The fifth parameter is the resource ID of the button. The resource ID is the unique integer value used to identify the button in the message map. The constant value idb_button has been defined at the top of the program. "IDB_" is optional, but the constant ID is used to indicate the button. Its value is 100, because the value within 100 is preserved for the system. You can use any value greater than 99. The stylic properties allowed by the CButton class are different from the CSTATIC class. 11 different "bs") constants are defined. The full "BS" constant list can be found with the search command and select "Button Style". Here we need to use the BS_Pushbutton style, which means that we want a normal button mode to display the button. We also use two familiar "WS" properties: WS_CHILD and WS_VISIBLE. We will introduce some other styles later. When you run the code, you will notice the button to respond to user events. It is highlighted. In addition, it didn't do anything because we haven't teach it to do it. We need to write a message mapping to make the button to make some interesting things.
Establish a message mapping
The following code contains a message mapping, contains a function of new processing clicking on the button (a speaker when the user clicks the button). It is just a simple expansion of the previous code:
// Button2.cpp
#include
#define idb_button 100
// Declare the Application Class
Class CbuttonApp: Public CWINAPP
{
PUBLIC:
Virtual Bool InitInstance ();
}
// Create an Instance of the Application Class
CButtonApp ButtonApp;
// Declare the main window class
Class CButtonWindow: Public CFrameWnd
{
CButton * Button;
PUBLIC:
CButtonWindow ();
AFX_MSG Void Handlebutton ();
Declare_message_map ()
}
// the message handler function
Void CButtonWindow :: HandleButton ()
{
MessageBeep (-1);
}
// the message map
Begin_Message_Map (CButtonWindow, CFrameWnd)
ON_BN_CLICKED (IDB_Button, Handlebutton)
END_MESSAGE_MAP ()
// the initInstance function is caled overce
// when the application first executes
Bool cbuttonapp :: initInstance ()
{
m_pmainwnd = new cbuttonWindow ();
m_pmainwnd-> showwindow (m_ncmdshow);
m_pmainwnd-> UpdateWindow ();
Return True;
}
// the constructor for the window class
CButtonWindow :: CbuttonWindow ()
{
CRECT R;
// Create the window itself
Create (NULL,
"CButton Tests", WS_OVERLAPPEDWINDOW,
CRECT (0,0,200,200));
// Get the size of the client rectangle
GetClientRect (& r);
R.INFLATERECT (-20, -20);
// Create a button
Button = new cbutton ();
Button-> Create ("Push ME",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
R,
this,
IDB_BUTTON);
}
Mainly revised three aspects:
1. Class of CButtonWindow now contains a new member function and a new macro indicating message mapping. The HANDL EBUTTON function is a normal C function that determines the message processing function via the AFX_MSG tag. This function requires some special constraints, for example, it must be a VOID type and it cannot receive any parameters. The DECLARE_MESSAGE_MAP macro establishes a message mapping. Functions and macros must be public type.
2. The HandleButton function is established as a member function in the same way. In this function, we call the MessageBeep function in the Windows API.
3. Use macro to establish a message mapping. In the code, you can see the Begin_Message_Map macro accepts two parameters. The first name specified by the class map is used. The second is the base class. Then the ON_BN_CLICKED macro accepts the two parameter control ID and the function called when the ID sends a command message. Finally, the message mapping ends with End_Message_map. When the user clicks the button, it sends a command message containing the ID to the parent window containing the button. That is the default behavior of the button, which is the reason for this code. The button sends a message to its parent window because it is a child window. The parent window intercepts the message and uses a message mapping to determine the function you want to call. MFC is scheduled, as long as the specified message appears, the corresponding function is called. The ON_BN_CLICKED message is a uniquely interested message sent by CButton. It is equivalent to the ON_COMMAND message in CWND, just a simple and convenient synonym.
Change the size of the message
In the above code, since the message map, the application window inherited from the CFraMewnd is recognized and the button has a click message generated by the button and responds. The ON_BN_Clicked Macro of the Add Message Map Specifies the function that the button ID and window should call when the command message from the button is received. Because only the user clicks the button, the button will automatically send its ID to the parent window, so that the code can be allowed to process the button event correctly. The frame window of the main window of the application also has the ability to deliver messages. About 100 different messages can be used, they are inherited from the CWND class. Browse the member functions of the CWND class from the MFC Help file, you will see all of these messages. View all members of the "ON". You may have noticed that all the code does not have a good change in size so far. When the window changes the size, the window's frame will make the corresponding adjustment, but the contents of the window are still not movable. This problem can be better processed by handling events that changes in size. One of the messages sent by any window is to change the size message. This message is sent when the shape is changed. We can use this message to control the size of the subsequent window in the frame, as shown below:
// Button3.cpp
#include
#define idb_button 100
// Declare the Application Class
Class CbuttonApp: Public CWINAPP
{
PUBLIC:
Virtual Bool InitInstance ();
}
// Create an instance of the application classcbuttonapp buttonapp;
// Declare the main window class
Class CButtonWindow: Public CFrameWnd
{
CButton * Button;
PUBLIC:
CButtonWindow ();
AFX_MSG Void Handlebutton ();
AFX_MSG VOID Onsize (uint, int, int);
Declare_message_map ()
}
// a Message Handler Function
Void CButtonWindow :: HandleButton ()
{
MessageBeep (-1);
}
// a Message Handler Function
Void CButtonWindow :: Onsize (uint ntype, int Cx,
INT CY)
{
CRECT R;
GetClientRect (& r);
R.INFLATERECT (-20, -20);
Button-> MoveWindow (R);
}
// the message map
Begin_Message_Map (CButtonWindow, CFrameWnd)
ON_BN_CLICKED (IDB_Button, Handlebutton)
ON_WM_SIZE ()
END_MESSAGE_MAP ()
// the initInstance function is caled overce
// when the application first executes
Bool cbuttonapp :: initInstance ()
{
m_pmainwnd = new cbuttonWindow ();
m_pmainwnd-> showwindow (m_ncmdshow);
m_pmainwnd-> UpdateWindow ();
Return True;
}
// the constructor for the window class
CButtonWindow :: CbuttonWindow ()
{
CRECT R;
// Create the window itself
Create (NULL,
"CButton Tests",
WS_OVERLAPPEDWINDOW,
CRECT (0,0,200,200));
// Get the size of the client rectangle
GetClientRect (& r);
R.INFLATERECT (-20, -20);
// Create a button
Button = new cbutton ();
Button-> Create ("Push ME",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
R,
this,
IDB_BUTTON);
}
In order to understand the above code, start from the message mapping of the window. You will find an entry ON_WM_SIZE. The inlet indicates that the message mapping responds to a variable dimension message from the CButtonWindow object. Variable dimension messages are generated when the user changes the size of the window. This message comes from the window itself, not as an ON_COMMAND message by the button to its parent window. This is because the window mine rack is not a sub-window. Note that there is no parameter in the ON_WM_SIZE entry in the message mapping. Your CWnd class in the MFC document, the ON_WM_SIZE entry in the message map always calls the onsize function, and the function must receive three parameters. The Onsize function must be a member function of the message map belonging, and the function must be illustrated with AFX_MSG (as seen above in the definition of CButtonWindow).
If you look at the MFC document, you will find that there are nearly 100 functions "on ..." in the CWnd. CWnd :: OnSize is one of them. All of these functions have a label such as ON_WM_ in the message mapping. For example, ON_WM_SIZE corresponds to Onsize. ON_WM_ The entry does not receive any parameters, like ON_BN_Clicked. The parameter is assumed and automatically passed to the corresponding "on ..." function such as Onsize. Repeat it, because it is very important: the onsize function always wants to correspond to the on_wm_size entrance in the message map. You must name the handler onsize, and it must receive three parameters. The parameters of different functions will vary. In the above code, in the inside of the onsize function itself, there are three lines of code modify the size of the button in the window. You can enter any code you want in this function. Calling GetClientRect is to restore the new size of the window user area. This rectangle will be reduced and call the MoveWindow function of the button. MoveWindow is inherited from CWnd, changing the size and moving sub-window is done in one step. When you perform the program that changes the size of the window, you will find that the button can change the size correctly. In the code, the Onsize function in the country's message map produces a call, which calls the MoveWindow function to change the size of the button.
Window message
View the MFC documentation, you can see a variety of CWND messages processed by the main window. Some similar to what we described above. For example, the ON_WM_MOVE message is a message sent when the user moves the window, and the ON_WM_PAINT message is sent when any of the windows needs to be returned. So far, all of our procedures, heavy paintings are automatically completed, because it is controlled to be responsible for its appearance. If you use the GDI command to draw in the user area, the application should be responsible for heavy painting. Therefore, ON_ WM_Paint has become important. There are also some event messages sent to the window more deeper. For example, you can use the ON_WM_TIMER message to receive the time interval for receiving pre-set. The following code gives the process. When you run the code, the program will spell every 1 second. You can use other more useful features to replace the whistle.
// Button4.cpp
#include
#define idb_button 100
#define idt_timer1 200
// Declare the Application Class
Class CbuttonApp: Public CWINAPP
{
PUBLIC:
Virtual Bool InitInstance ();
}
// Create an Instance of the Application Class
CButtonApp ButtonApp;
// Declare the main window class
Class CButtonWindow: Public CFrameWnd
{
CButton * Button;
PUBLIC:
CButtonWindow ();
AFX_MSG Void Handlebutton ();
AFX_MSG VOID Onsize (uint, int, int);
AFX_MSG Void Ontimer (UINT);
Declare_message_map ()
}
// a Message Handler Function
Void CButtonWindow :: HandleButton ()
{
MessageBeep (-1);
}
// a Message Handler Function
Void CButtonWindow :: Onsize (uint ntype, int Cx,
INT CY)
{
CRECT R;
GetClientRect (& r);
R.INFLATERECT (-20, -20); Button-> MoveWindow (R);
}
// a Message Handler Function
Void CButtonWindow :: ONTIMER (UINT)
{
MessageBeep (-1);
}
// the message map
Begin_Message_Map (CButtonWindow, CFrameWnd)
ON_BN_CLICKED (IDB_Button, Handlebutton)
ON_WM_SIZE ()
ON_WM_TIMER ()
END_MESSAGE_MAP ()
// the initInstance function is caled overce
// when the application first executes
Bool cbuttonapp :: initInstance ()
{
m_pmainwnd = new cbuttonWindow ();
m_pmainwnd-> showwindow (m_ncmdshow);
m_pmainwnd-> UpdateWindow ();
Return True;
}
// the constructor for the window class
CButtonWindow :: CbuttonWindow ()
{
CRECT R;
// Create the window itself
Create (NULL,
"CButton Tests",
WS_OVERLAPPEDWINDOW,
CRECT (0,0,200,200));
// set up the Timer
Settimer (IDT_TIMER1, 1000, NULL); // 1000 ms.
// Get the size of the client rectangle
GetClientRect (& r);
R.INFLATERECT (-20, -20);
// Create a button
Button = new cbutton ();
Button-> Create ("Push ME",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
R,
this,
IDB_BUTTON);
}
Inside the program, we built a button, as indicated, change the size of the code without changing. In the constructor of the window, we added the call of the SetTimer function. This function receives three parameters: the id of the clock (can be used in both multiple clocks at the same time, each clock is shut down to the called function), and the time is in milliseconds. Here, we pass NULL to the function so that the window message maps yourself automatically send functions. In the message mapping, we have notified the ON_WM_TI MER message, which automatically calls the ONTIMER function to pass the ID of the clock that has been closed.
When the program runs, it whists every 1 millisecond. The time incrementation of each clock passes, the window will send a message to your own. Message mapping selection message to the ONTIMER function, it whistle. You can place more useful code here.
Rolling strip control
Windows processes the scroll bar in two different ways. Some controls, such as editing control and list control, can have a scroll bar. In this case, the scroll bar will be processed automatically, and do not handle additional code. The scroll bar can also be used as a separate component. When used in this way, the scroll bar has independent power. You can see the relevant chapters of CScrollBar in the MFC Reference Manual. The establishment of the scroll bar control is the same as the static label and buttons described above. It has four member functions to allow you to set up and get the position and range of the scroll bar. The following code demonstrates the process of establishing a horizontal scroll bar and its message mapping:
// sb1.cpp
#include
Const int max_range = 100;
Const int min = 0;
// Declare the Application Class
Class Cscrollbarapp: Public CWINAPP
{
PUBLIC:
Virtual Bool InitInstance ();
}
// Create an Instance of the Application Class
Cscrollbarapp scrollbarapp;
// Declare the main window class
Class CscrollBarwindow: Public CFrameWnd
{
CScrollBar * SB;
PUBLIC:
Cscrollbarwindow ();
AFX_MSG Void Onhscroll (uint nsbcode, uint npos,
CScrollBar * pscrollbar;
Declare_message_map ()
}
// the message handler function
Void CscrollBarwindow :: Onhscroll (uint nsbcode,
UINT NPOS, CSCROLLBAR * PSCROLLBAR)
{
MessageBeep (-1);
}
// the message map
Begin_MESSAGE_MAP (CScrollBarwindow, CFrameWnd)
ON_WM_HSCROLL ()
END_MESSAGE_MAP ()
// the initInstance function is caled overce
// when the application first executes
Bool cscrollbarapp :: initInstance ()
{
m_pmainwnd = new cscrollbarwindow ();
m_pmainwnd-> showwindow (m_ncmdshow);
m_pmainwnd-> UpdateWindow ();
Return True;
}
// the constructor for the window class
Cscrollbarwindow :: CscrollBarwindow ()
{
CRECT R;
// Create the window itself
Create (NULL,
"CScrollBar Tests",
WS_OVERLAPPEDWINDOW,
CRECT (0,0,200,200));
// Get the size of the client rectangle
GetClientRect (& r);
// Create A Scroll Bar
SB = new cscrollbar ();
SB-> CREATE (WS_CHILD | WS_VISIBLE | SBS_HORZ,
CRECT (10, 10, r.Width () - 10, 30),
this,
IDM_ScrollBar);
SB-> setscrollRange (min_range, max_range, true);
}
Windows will distinguish between horizontal and vertical scroll bars while also supporting control of a size box in CScrollbar. The size box is a small square. It is at the intersection of horizontal and vertical scroll bars, and the mouse drags it automatically change the size of the window. In the following code, you see how to create a horizontal scroll bar with the SBS_horz style of the Create function. After the scroll bar is established, the Min_Range and Max_RANGE dragons in EtscrollRange immediately give the roller bars 0 to 100 (they are defined at the top of the program).
Event Processing Functions OnHScroll From the CWND class. We use this function because the code establishes a horizontal scroll bar. ONVSCROLL should be used for vertical scroll bars. In the code, the message mapping is associated with the scroll function and makes the scroll bar when the user operates a thistle. When you run the program, you can click the arrow to drag the small square on the scroll bar. There will be a thistle at each operation, but the small square on the scroll bar will actually move because we have not associated it with the actual code. Each time the scroll strip calls onhscroll, your code must determine the user's operation. Inside the onhscroll function, you can verify the first parameter passed to the handler, as shown below. If you use the code above, the small square of the scroll bar will move to the location of the user.
// the message handling function
Void CscrollBarwindow :: Onhscroll (uint nsbcode,
UINT NPOS, CSCROLLBAR * PSCROLLBAR)
{
INT POS;
POS = SB-> GetScrollPos ();
Switch (nsbcode)
{
Case SB_LineUp:
POS - = 1;
Break;
Case SB_LINEDown:
POS = 1;
Break;
Case SB_PAGEUP:
POS - = 10;
Break;
Case SB_PAGEDOWN:
POS = 10;
Break;
Case SB_TOP:
POS = Min_Range;
Break;
Case SB_BOTTOM:
POS = MAX_RANGE;
Break;
Case sb_thumbposition:
POS = NPOS;
Break;
DEFAULT:
Return;
}
IF (POS POS = Min_Range; Else IF (POS> MAX_RANGE) POS = MAX_RANGE; SB-> SetscrollPos (POS, TRUE); } The different constant values of SB_LineUp and SB_Linedown are introduced in the CWnd :: OnhScroll function document. The above code first uses the GetScrollPos function to restore the current location of the scroll bar. Then use the switch statement to determine the user's operation of the scroll bar. SB_LINEUP and SB_LINEDown constant values mean vertical directions, but can also be used in horizontal direction indicating left and right movement. SB_PAGEUP and SB _PAGEDOWN are used when the user clicks the scroll bar. SB_TOP and SB_BOTTOM are used to move the scroll bar small square to the top and bottom of the scroll bar. SB_thumbPosition is used to drag the small square to the specified position. The code will automatically adjust the location, then make sure it is still within the range when setting its new location. Once the scroll bar is set, the small square will move to the appropriate location. The processing of the vertical scroll is also similar, just use the SBS_vert style in the ONVSCROLL function. Comprehension message mapping The message mapping structure can only be used for MFC. Master it and how it is important to apply it in your code. Pure C users will generate questions about message mapping: why Microsoft does not use virtual functions to replace message mapping. The virtual function is a standard C way that handles message mapping in the MFC, so use macro declare_MESSAGE_MAP and Begin_M Essage_map may be a bit weird. MFC uses message mapping to solve the basic problem of virtual functions. See the CWND class in the MFC Help file. It contains more than 200 member functions, all member functions are virtual when not using message mapping. Now let's take a look at all the subclasses of all CWND classes. There are approximately 30 categories in the MFC to be based on CWnd. This includes all visible controls such as buttons, static tags, and lists. Imagine now, MFC uses virtual functions, and you create an application contains 20 controls. Each of the 200 virtual functions in CWnd requires its own virtual function table, and each routine that controls should have a set of 200 virtual functions and associated. The program may have nearly 4,000 virtual function tables in memory, which is a big problem for the machine with limited memory. Because most of them are not. The message mapping copies the operation of the virtual function table, but it is based on the needs. When you create an entry in the message map, you said to the system, "When you see a special message, call the specified function." Only these functions are actually overloaded into the message map, saving the burden on memory and CPU. When you use Declare_Message_Map and Begin_Message_map, the system will select all messages through your message mapping. If the message map has processed a given message, your function will be called, and the unloading will stay here. However, if you do not contain a message in your message mapping, the system sends the message to the class specified by the second begin_message_map. That class may not process it, so repeated. Finally, if there is no message map processing a given message, the message will be processed by a default processing function. in conclusion All message mapping processing concepts described in this lecture can be applied to all controls and windows in Windows NT. In most cases, you can use ClassWizard to install the entry of the message map, which will be introduced later about ClassWizard, AppWizard, and Resource Editor.