One of the most regular actions you perform when working on a project consists of creating classes. Microsoft Visual Studio provides various means and tools to assist you with this. From your knowledge of C++, you can create a class in different files: a header file and a source file. To create any of these:
Any of these actions would open the Add New Item dialog box. In the Installed Templates list, click Code. Then,
After naming the file, click Add. After generating the files, you can use them following rules and suggestions of the C++ language. For example, you can create the layout of a class in the header file and define it in the source file.
As you know from your knowledge of C++, you can create a stand-alone class or derive one from another existing class. Microsoft Visual Studio provides all the necessary tools to visually create or derive a class. To create a class:
Any of these actions would open the Add Class dialog box: Make sure C++ Class is selected and click Add. This would open the Generic C++ Class Wizard. The wizard presents many options:
Once you are ready, click Finish. If you specified that you are deriving a class, when you click Finish, the wizard would look for the base class, first in the current project, then in the libraries (if any) referenced in the project. If the wizard doesn't find the parent class, it would display a message box. Here is an example:
If know for sure that the class exists or you will create it later, click Yes. If you click, you will be given the opportunity of rectifying. Here is an example of deriving a class from CWinApp: class CSimpleApp : public CWinApp { }; Because the CWinApp class is defined in the AFXWIN.H header file, make sure you include that file where CWinApp is being used.
After creating a class, you can manage it. Microsoft Visual C++ provides various tools to assist you. Managing a class consists of accessing its file(s), adding member variables, and adding methods.
Instead of creating an application using "raw" Win32 classes and functions, the MFC library simplifies this process by providing a mechanism called the framework. The framework is a set of classes, functions, and techniques used to create an application as complete as possible with as few lines of code as possible. To provide all this functionality, the framework works behind the scenes with the CWinApp class to gather the necessary MFC classes and functions, to recognize and reconcile the Win32 classes that the application needs. This reconciliation is also made possible by a set of global functions. These functions have names that start with Afx... Some of these functions are:
We will come back to some of these functions and we will see many other MFC macros in later lessons.
To make your application class available and accessible to the objects of your application, you must declare a global variable from it and there must be only one variable of your application. This variable is of the type of the class derived from CWinApp. Here is an example: class CSimpleApp : public CWinApp { }; CSimpleApp MyApplication; As you can see, you can name this global variable anything you want. By tradition, in Microsoft Visual C++, this variable is named theApp. Here is an example: CSimpleApp theApp; To get a pointer to this variable from anywhere in your application, call the AfxGetApp() framework function. Its syntax is: CWinApp* AfxGetApp(); To implement the role of the Win32's WinMain() function, the framework uses its own implementation of this function and the MFC provides it as AfxWinInit(). It is declared as follows: BOOL AFXAPI AfxWinInit(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow); As you can see, the Win32's WinMain() and the MFC's AfxWinInit() functions use the same arguments.
When you start an application such as Notepad, you are said to have created an instance of the application. In the same way, when you declare a variable of a class, an instance of the class is created and made available to the project. The WinMain() function also allows you to create an instance of an application, referred to as the hInstance argument of the WinMain() function. The instance is created as an HINSTANCE. The CWinApp class provides a corresponding instance variable called m_hInstance. This variable can let you get a handle to the instance of your application. Alternatively, to get a handle to the instance of your application, you can call the AfxGetInstanceHandle() global function. Its syntax is: HINSTANCE AfxGetInstanceHandle(); Even more, to get a handle to your application, you can call the Win32 API's GetWindowLong() function. Suppose you have opened Notepad to view the source code of an HTML document. This is said that you have an instance of Notepad. Imagine that you want to open a text document using Notepad without closing the first instance of Notepad. To do this, you must open another copy of Notepad. This second copy of Notepad is another instance. In this case, the first instance is referred to as a previous instance. For a Win32 application, the previous instance would be the hPrevInstance argument of the WinMain() function. For a Win32 application, the hPrevInstance argument always has the NULL value. If you want to find out whether a previous instance of an application already exists, you can call the CWnd::FindWindow() method. Its syntax is: static CWnd* PASCAL FindWindow(LPCTSTR lpszClassName, LPCTSTR lpszWindowName); If you created the window or if it is a window you know for sure, in which case it could be a WNDCLASS or WNDCLASSEX object, specify it as the lpszClassName argument. If you do not know its name with certainty, set this argument as NULL. The lpszWindowName argument is the possible caption of the window you are looking for. Imagine you position a button on a dialog box and you want the user to launch Notepad with that button and imagine that, if Notepad is already opened, there would be no reason to create another instance of it. The CWinApp class provides all the basic functionality that an application needs. It is equipped with a method called InitInstance(). Its syntax is: virtual BOOL InitInstance(); When creating an application, you must override this method in your own class. This method is used to create an application. If it succeeds, it returns TRUE or a non-zero value. If the application could not be created, the method returns FALSE or 0. Here is an example of implementing it: class CSimpleApp : public CWinApp { BOOL InitInstance() { return TRUE; } }; Based on your knowledge of C++, keep in mind that the method could also have been implemented as: struct CSimpleApp : public CWinApp { BOOL InitInstance() { return TRUE; } }; or: struct CSimpleApp : public CWinApp { BOOL InitInstance(); }; BOOL CSimpleApp::InitInstance() { return TRUE; }
To execute a program, you must communicate its path and possibly some additional parameters to the compiler. This information is called the command line information and it is supplied as a string. You need to keep that in mind although all programs of our lessons will be compiled inside of Visual C++. The command line information is supplied to the compiler as the lpCmdLine argument of the WinMain() function. Internally, Visual C++ creates the path and communicates it to the compiler when you execute the program. If you want to find out what command line was used to execute your program, you can call the Win32's GetCommandLine() function. Its syntax is: LPTSTR GetCommandLine(VOID); This function takes no argument but returns the command line of an application as a null-terminated string.
In an MFC application, a resource is a text file that allows the compiler to manage such objects as pictures, sounds, mouse cursors, dialog boxes, etc. Microsoft Visual C++ makes creating a resource file particularly easy by providing the necessary tools in the same environment used to program. This means you usually do not have to use an external application to create or configure a resource file (as done in other programming environments).
Although an application can use various resources that behave independently of each other, these resources are grouped into a text file that has the .rc extension. You can create this file manually and fill out all necessary parts but it is advantageous to let Microsoft Visual C++ create it for you. To start creating the resources:
Any of these actions would display the Add Resource dialog box. From this dialog box, you would select the type of resource you want and click New (or Import...). You will then be expected to design or customize the resources. Throughout our lessons, we will see various examples. After creating or designing a resource, you must save it. In most cases, you can try closing the resource. In this case, Microsoft Visual C++ would prompt you to save the resource. If you agree to do this (which you mostly should), Microsoft Visual Studio would create a new file with the extension .rc. To make your resource recognizable to the other files of the program, you must also create a header file, usually called resource.h. This header file must provide a constant integer that identifies each resource and makes it available to any part that needs it. This also means that most, if not all, of your resources will be represented by an identifier. Because resources are different entities, they are created one at a time. They can also be imported from existing files. The Add Resource dialog box provides an extensive list of resources to accommodate almost any need. Still, if you do not see a resource you need and know you can use it, you can add it manually to the .rc file before executing the program.
An identifier is a constant integer whose name usually starts with ID. Although in Win32 programming you usually can use the name of a resource as a string, in MFC applications, resources are usually referred to by their identifier. To make an identifier name (considered a string) recognizable to an MFC (or Win32) function, you use a macro called MAKEINTRESOURCE. Its syntax is: LPTSTR MAKEINTRESOURCE(WORD IDentifier); This macro takes the identifier of the resource and returns a string that is given to the function that called it. In the strict sense, after creating the resource file, it must be compiled to create a new file that has the extension .res. Fortunately, Microsoft Visual C++ automatically compiles the file and links it to the application. |
|
|||||||||||||||||||||||||||||||||||
|