Visual C ++ MFC Confidential Tutorial

zhaozj2021-02-16  97

http://www.ittide.com/document/book/mfc.html

Visual C MFC Confidential Tutorial

Original: Marshall Brain compile: Zhang Shenghua

Part 1: MFC introduction

Visual C is more than just a compiler. It is a comprehensive application development environment that uses it you take advantage of C with object-oriented features to develop professional Windows applications. In order to make full use of these features, you must understand the C programming language. Master C , you must master the hierarchy of the Microsoft Basic Class Bank (MFC). This hierarchy is tolerate the user interface part in the Windows API and enable you to easily establish a Windows application in an object-oriented manner. This hierarchy is suitable for all versions of Windows and compatible with each other. 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 enter, compile and run a simple MFC program. These code will be explained in detail in the next section. The third part discusses the MFC 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 set the corresponding user interface object as needed. The Windows user interface has some standard controls, such as buttons, menus, scroll bars, and lists, which are 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 possible for some of the relatively small projects, as well as the early prototyping phase of some major projects.

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). This interface is composed of hundreds of C functions, which are introduced in the Windows API reference manual. For Windows NT, the 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 that makes programmers' work easier. It is the Microsoft Basic Class Library (MFC), the main advantage of this library is efficient. It reduces the code that must be written in a large number of WINDOWS programs. At the same time, it also provides all the best C programming advantages, 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 Windows 95. Therefore, the MFC is worth recommending to develop a Windows application method, which is MFC in this tutorial.

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 to respond to users to operate these controls. 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 users who are new to this environment, review several definitions below to make our discussion easier.

Windows applications use several standard controls:

Static text label

Button

List box

Combination box (a more advanced list box)

single button

Check button

Edit box (single line and multi-line)

scroll bar

You can build these controls via code or "resource editor", you can create dialogs and these controls in the resource editor. 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 the "Frame Window". A frame window is a full-featured main window, and the user can change the size, minimize, maximize, and so on. Windows also supports two types of dialogs: mode and non-Mode dialog. Once the Mode dialog box appears on the screen, only the rest of the application on the screen can respond when it exits. 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. The good and bad application interface 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 the "appearance and feelings" of these interface elements may differ, these interface objects have the same way. For example, scroll bars may be somewhat different for Windows, Mac and Motif, but their role is completely.

From a programmer's point of view, these systems are conceptually similar, although they may have a lot. In order to establish a GUI program, the programmer should put all the required user interface controls on the window. For example, if the programmer is to establish a simple program from the transition from Celsius, the user interface selected by the programmer is completed and displayed on the screen. In this simple program, the programmer may need the user to enter the temperature value in an editable editing box, display the conversion result in an inable editable edit box, and then let the user can click a button labeled "exit". To exit the application. Because it is the user to operate the application, the program must respond. The response is dependent on the user using the mouse or keyboard in different controls. Each user interface object on the screen is different for the response of the event. For example, if a user clicks an exit button, the button must update the screen and highlight itself. The program then must respond to exit.

The modes used by Windows are also similar. In a typical application, you will create a main window and place some user interface controls. These controls are often referred to as sub-windows they are like some smaller and more special sub-windows in the main window. As a programmer, you should call to send information operations through a function to send these controls to respond to the user's operation by sending information to your code.

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 Windows API application directly with C, the amount of code is very large, 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 handle which object is clicked and what you need to do what you need to do.

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; // Description 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 "Window" 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 bit small matter, but in any actual program, the concept of the project is very useful. A project mainly stores the following three different types of information:

It can remember to create all source program code files that can be implemented. In this simple example, the 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. It will remember the compiler and connector options used for your application. For example, it remembers which library connects to the executive, and whether you preparatively translate the header file and so on.

It will remember the type of project you want to build: a console application, or a window application, etc.

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. Enter "Hello" as the project name in "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 "Source 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.

After that, you must 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:

Compile hello.cpp (only when the window containing hello.cpp is activated)

Build Hello.exe

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:

Application framework

Graphic drawn drawn object

File service

Abnormal processing

Structure - List, Array and Map

Internet service

OLE 2

database

General class

In this tutorial, we will focus on visual objects. The following list gives some classes:

COBJECT

CCMDTARGET

CWINTHREAD

CWINAPP

CWnd

Cframewnd

CDIALOG

CView

CSTATIC

CButton

Clistbox

CCOMBOBOX

Cedit

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 creation of an application and use it 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:

An application object that initializes the application and hovered it on Windows. The application object handles all lower level events.

A window object comes as the main window.

A static text object is 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 input information for the application and collecting the application. Once you have completed the interface design and decide to implement the control required for this interface, you need to write code 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 object 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, sections 18 to 26, 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 Executes.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) establishes 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 call 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 can click 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 you want to display 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, CButton, CEDIT, CLIST, CCOMBOBOX and CSCROLLLBAR. In addition, Windows 95 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 you can use the resource editor through the resource file. Of course, the dialog editor is more convenient, and it is especially useful for the case that has been basically controlled.

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, border or icon, etc. by modifying the style of the label.

CSTATIC control is always in the form of 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 to the user area of ​​its parent window.

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. Available in CSTATIC is as follows:

Style from CWND inheritance:

WS_CHILD CSTATIC must be.

WS_Visible indicates that the control should be visible to the user.

WS_DISABLED indicates that the control refuses to accept user events.

The text area controlled by WS_Border has a border.

CSTATIC inherent style:

SS_BLACKFRAME This control area is displayed in a rectangular boundary. Colors are the same as the window frame.

SS_BLACKRECT? This control is displayed in a filling rectangle. Colors are the same as the current window frame.

SS_CENTER text home.

SS_GRAYFRAME control is displayed in a rectangular border. The color is the same as the current desktop.

SS_GRAYRECT This control is displayed in a fill rectangle. The color is the same as the current desktop.

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.

SS_LEFT text is left. Text can be wrapped around.

SS_LEFTNOWORDWRAP text is left. Excess text is tailored.

SS_NOPREFIX indicates that "&" characters in the string do not represent an acceleration prefix.

SS_RIGHT text is displayed. Text can be wrapped around.

SS_SIMPLE is simply displaying a line of text. Any CTLColor information is ignored by its parent window.

SS_USERITEM user definition item.

SS_WHITEFRAME is displayed in a rectangular border. The color is the same as the current window background.

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 following 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 CTestWindow 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. The variable R is the CRECT type, and the beginning portion of the function is illustrated as a local variable.

There may be two questions when understanding this code 1) What is the getClientRect function? 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, you will see a member function and operator that defines more than 30 processing rectangles.

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. Creat :: Inflatrect is called in line 3, while also increases or decreases 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 is the same as CSTATIC. 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:

Class of CButtonWindow now contains a new member function and a new macro indicating message map. The HandleButton 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.

The HandleButton function is created as a member function in the same way. In this function, we call the MessageBeep function in the Windows API.

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 will be 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 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);

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 frame 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 part of the window needs to redraw. 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. So ON_WM_Paint became 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 transmit NULL to the function so that the window message maps yourself automatically send functions. In the message mapping, we have notified the ON_WM_TIMER 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 yourself. 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

#define idm_scrollbar 100

Const int max_range = 100; const INT min_range = 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 range of the scroll bar is given by 0 to 100 (they define the top of the program) with the min_range and max_range dragon in SetscrollRange.

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 have questions about message mapping: Why does Microsoft does not use virtual functions to replace message mappings? The virtual function is a standard C way to process the message mapping in the MFC, so it may be a bit weird in using macro declare_message_map and begin_message_map.

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.

Visual C MFC Confidential Tutorial

Original: Marshall Brain compile: Zhang Shenghua

Part 1: MFC introduction

Visual C is more than just a compiler. It is a comprehensive application development environment that uses it you take advantage of C with object-oriented features to develop professional Windows applications. In order to make full use of these features, you must understand the C programming language. Master C , you must master the hierarchy of the Microsoft Basic Class Bank (MFC). This hierarchy is tolerate the user interface part in the Windows API and enable you to easily establish a Windows application in an object-oriented manner. This hierarchy is suitable for all versions of Windows and compatible with each other. 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 enter, compile and run a simple MFC program. These code will be explained in detail in the next section. The third part discusses the MFC 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 set the corresponding user interface object as needed. The Windows user interface has some standard controls, such as buttons, menus, scroll bars, and lists, which are 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 possible for some of the relatively small projects, as well as the early prototyping phase of some major projects.

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). This interface is composed of hundreds of C functions, which are introduced in the Windows API reference manual. For Windows NT, the 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 that makes programmers' work easier. It is the Microsoft Basic Class Library (MFC), the main advantage of this library is efficient. It reduces the code that must be written in a large number of WINDOWS programs. At the same time, it also provides all the best C programming advantages, 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 Windows 95. Therefore, the MFC is worth recommending to develop a Windows application method, which is MFC in this tutorial.

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 to respond to users to operate these controls. 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 users who are new to this environment, review several definitions below to make our discussion easier.

Windows applications use several standard controls:

Static text label

Button

List box

Combination box (a more advanced list box)

single button

Check button

Edit box (single line and multi-line)

scroll bar

You can build these controls via code or "resource editor", you can create dialogs and these controls in the resource editor. 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 the "Frame Window". A frame window is a full-featured main window, and the user can change the size, minimize, maximize, and so on. Windows also supports two types of dialogs: mode and non-Mode dialog. Once the Mode dialog box appears on the screen, only the rest of the application on the screen can respond when it exits. 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. The good and bad application interface 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 the "appearance and feelings" of these interface elements may differ, these interface objects have the same way. For example, scroll bars may be somewhat different for Windows, Mac and Motif, but their role is completely.

From a programmer's point of view, these systems are conceptually similar, although they may have a lot. In order to establish a GUI program, the programmer should put all the required user interface controls on the window. For example, if the programmer is to establish a simple program from the transition from Celsius, the user interface selected by the programmer is completed and displayed on the screen. In this simple program, the programmer may need the user to enter the temperature value in an editable editing box, display the conversion result in an inable editable edit box, and then let the user can click a button labeled "exit". To exit the application.

Because it is the user to operate the application, the program must respond. The response is dependent on the user using the mouse or keyboard in different controls. Each user interface object on the screen is different for the response of the event. For example, if a user clicks an exit button, the button must update the screen and highlight itself. The program then must respond to exit.

The modes used by Windows are also similar. In a typical application, you will create a main window and place some user interface controls. These controls are often referred to as sub-windows they are like some smaller and more special sub-windows in the main window. As a programmer, you should call to send information operations through a function to send these controls to respond to the user's operation by sending information to your code.

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 Windows API application directly with C, the amount of code is very large, 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 handle which object is clicked and what you need to do what you need to do. 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 "Window" menu to close all windows. Select "Close" option in the "File" menu to close other windows. Now you are in the beginning. If you are running after installing VC , the screen should be as follows: 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 bit small matter, but in any actual program, the concept of the project is very useful. A project mainly stores the following three different types of information:

It can remember to create all source program code files that can be implemented. In this simple example, the 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.

It will remember the compiler and connector options used for your application. For example, it remembers which library connects to the executive, and whether you preparatively translate the header file and so on.

It will remember the type of project you want to build: a console application, or a window application, etc.

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. Enter "Hello" as the project name in "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 "Source 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.

After that, you must 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:

Compile hello.cpp (only when the window containing hello.cpp is activated)

Build Hello.exe

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:

Application framework

Graphic drawn drawn object

File service

Abnormal processing

Structure - List, Array and Map

Internet service

OLE 2

database

General class

In this tutorial, we will focus on visual objects. The following list gives some classes:

COBJECT

CCMDTARGET

CWINTHREAD

CWINAPP

CWnd

Cframewnd

CDIALOG

CView

CSTATIC

CButton

Clistbox

CCOMBOBOX

Cedit

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 creation of an application and use it 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:

An application object that initializes the application and hovered it on Windows. The application object handles all lower level events.

A window object comes as the main window.

A static text object is 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 input information for the application and collecting the application.

Once you have completed the interface design and decide to implement the control required for this interface, you need to write code 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 object 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, sections 18 to 26, 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) establishes 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 call 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 can click 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 CFrameWnd's Create member function (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 to assign, constructs and establishes a static text object (lines 36-0):

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 you want to display 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, CButton, CEDIT, CLIST, CCOMBOBOX and CSCROLLLBAR. In addition, Windows 95 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 you can use the resource editor through the resource file. Of course, the dialog editor is more convenient, and it is especially useful for the case that has been basically controlled.

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, border or icon, etc. by modifying the style of the label.

CSTATIC control is always in the form of 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 to the user area of ​​its parent window.

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. Available in CSTATIC is as follows:

Style from CWND inheritance:

WS_CHILD CSTATIC must be.

WS_Visible indicates that the control should be visible to the user.

WS_DISABLED indicates that the control refuses to accept user events.

The text area controlled by WS_Border has a border.

CSTATIC inherent style:

SS_BLACKFRAME This control area is displayed in a rectangular boundary. Colors are the same as the window frame.

SS_BLACKRECT? This control is displayed in a filling rectangle. Colors are the same as the current window frame.

SS_CENTER text home.

SS_GRAYFRAME control is displayed in a rectangular border. The color is the same as the current desktop.

SS_GRAYRECT This control is displayed in a fill rectangle. The color is the same as the current desktop.

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.

SS_LEFT text is left. Text can be wrapped around.

SS_LEFTNOWORDWRAP text is left. Excess text is tailored.

SS_NOPREFIX indicates that "&" characters in the string do not represent an acceleration prefix.

SS_RIGHT text is displayed. Text can be wrapped around.

SS_SIMPLE is simply displaying a line of text. Any CTLColor information is ignored by its parent window.

SS_USERITEM user definition item.

SS_WHITEFRAME is displayed in a rectangular border. The color is the same as the current window background.

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 following 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 CTestWindow 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. The variable R is the CRECT type, and the beginning portion of the function is illustrated as a local variable.

There may be two questions when understanding this code 1) What is the getClientRect function? 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, you will see a member function and operator that defines more than 30 processing rectangles.

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. Creat :: Inflatrect is called in line 3, while also increases or decreases 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, 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 is the same as CSTATIC. 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:

Class of CButtonWindow now contains a new member function and a new macro indicating message map. The HandleButton 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.

The HandleButton function is created as a member function in the same way. In this function, we call the MessageBeep function in the Windows API.

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 will be 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 frame 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 part of the window needs to redraw. 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. So ON_WM_Paint became 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 transmit NULL to the function so that the window message maps yourself automatically send functions. In the message mapping, we have notified the ON_WM_TIMER 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 yourself. 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

#define idm_scrollbar 100

Const int max_range = 100; const INT min_range = 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 range of the scroll bar is given by 0 to 100 (they define the top of the program) with the min_range and max_range dragon in SetscrollRange.

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 have questions about message mapping: Why does Microsoft does not use virtual functions to replace message mappings? The virtual function is a standard C way to process the message mapping in the MFC, so it may be a bit weird in using macro declare_message_map and begin_message_map.

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.

转载请注明原文地址:https://www.9cbs.com/read-10640.html

New Post(0)