Chapter 1 "Hello, world !"
In this chapter, just like all the entry-level tutorials, I will not use a "Hello, world !" The program starts my tutorial. Then, I will go deeper and introduce you to the necessary information in the ATL version program. In addition, I will introduce some items that you may not know about Win32, including winmain's _ t compatibility and how to add your own icons to MessageBox.
Close, close, close ......
It can be said that all "Hello, world !" The content of the program is almost always a very limited number of lines of code to output a string "Hello, world!" to the current target screen environment !". This program usually has the following features:
- To eliminate the possibility of printing errors, almost all beginners can write, compile and run this program independently.
- This program can reflect the typical configuration methods of the current language environment.
- This program has a specific program entry point in the current language.
- This program contains a typical output Statement (usually the simplest and most commonly used) in the current environment. This statement outputs "Hello, world !" String.
- From this program, you can clearly understand the typical process of running programs in the current language environment.
- This program may also show some other features of the current language.
First, let me use the simplest C Language "Hello, world !" Start:
#include <stdio.h> int main() { printf( "Hello, World!/n" ); return 0; }
|
Although it is less than 10 lines of code, it is still dirty. Now, let me check it against the above features. That is to say, this program can reflect the following features of the C program design:
- C-language programs use the main function as the program entry point.
- Printf is the code used to output strings in C.
- A function is the basic unit of a C language program. It generally consists of the return value, function name, parameter list, function body, and return.
- When calling a function, you must include the corresponding header file.
- /N is an escape character in C language, representing a line break.
Next, let's take a look at the Win32 version of "Hello, world !" :
#include <windows.h> int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd ) { MessageBox( NULL, TEXT("Hello, World!"), TEXT("Hello"), 0 ); return 0; }
|
This program tells you the following:
- All C Programs under Win32 must contain the windows. h header file.
- Programs under Win32 use winmain as the program entry point, rather than main.
- MessageBox is the most common method to output information under Win32.
- Winapi is the call Convention of Win32 API functions, that is, _ stdcall.
- Hinstance and lpstr are custom Win32 Data Types, indicating the application instance handle and ANSI string pointer ending with null characters, respectively.
- The text macro is used to ensure compatibility of ANSI/Unicode strings at the source code level.
If you are still confused about the above knowledge points, please refer to Chapter 1 of Charles Petzold's programming windows. This piece of code is almost unchanged. However, when writing this code, I usually write the following code:
#include <windows.h> #include <tchar.h> int WINAPI _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd ) { MessageBox( NULL, _T("Hello, World!"), _T("Hello"), 0 ); return 0; }
|
Yes, there are a few differences. My explanation for them is:
- Tchar. h contains source code compatibility with ANSI/Unicode strings in the C Runtime Library.
- _ Twinmain provides ANSI/Unicode source code compatibility for the command line parameter lpcmdline.
- _ T macro is also included in tchar. H. It has the same role as text macro, but it is shorter than text macro, so it can save coding time.
Now I can tell you that, as we get closer to each other, the next ATL version of "Hello, world !" The program is coming to our eyes. So, let's take a look at this guy who is still half-covered. (Please note that although this is an ATL version program, you still need to build a Win32 Application project instead of using ATL/COM wizard .)
//////////////////////////////////////// ////////////////////////////////// // The source code of the atl gui Program Design // The first chapter cannot be "Hello, world !" // Project name: helloworld // Author: Li Ma // Http://www.titilima.cn //////////////////////////////////////// //////////////////////////////////# Include <atlbase. h> Ccommodule _ module; int WINAPI _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd ) { _Module.Init( NULL, hInstance ); MessageBox( NULL, _T("Hello, World!"), _T("Hello"), 0 ); _Module.Term(); return 0; }
|
It may be a bit unfamiliar, but fortunately it does not change much-after all, the entire code segment is not long. Well, the content of this section is here. I hope this kind of gradual method of Li Ma will not make everyone feel that everything is coming too suddenly. You can take a deep breath before getting started with the real Atl program.
"But so"
First. Maybe I am so arrogant, maybe I am too naive. In short, I have become more and more fond of saying "but this is the case" since I went to college. For example, after I went to college, I felt that the University was "not so" in less than two months. After I learned to drink, I felt that drinking was "not so". After arriving in Beijing, I also think that Beijing is "not so". After visiting a famous software company, I think it is "not so "...... The book goes back to its original post. I don't know if you have read the "Hello, world!" In the ATL version for the first time !" Will it feel the same way later? -- Naturally, I hope this is the case.
So, before learning about ATL, let's first test this "Hello, world !" Right. Maybe you will guess the following content from the above Code:
- Atlbase. H should probably be the header file that the Atl program needs to include.
- Ccommodule: the class name should be a module class. _ Module is an instance of this module class.
- Winmain has not changed.
- Ccommodule: init should initialize the module. This method should be called during program initialization.
- Ccommodule: the term should end the processing of the module. This method should be called before the program ends.
- Winmain still ends with return.
Okay, isn't that true? That's right!
Big enough
So far, I hope that your conjecture will bring you a sense of fear (if any) about ATL. Now, Li Ma will add the following points for you:
When using ATL for GUI program design, atlbase. H is as important as windows. h In the SDK. For the part of GUI program design, there are several important points in this file:
- The header files necessary for Win32 programming, such as Windows. h and tchar. h.
- Ccommodule definition. For GUI program design, we can simply regard it as an encapsulation of hinstance.
- Some simple tool classes. (Please forgive me for not providing you with their specific names here, because ATL 3.0 and ATL 7.0 are different. VC 6.0 comes with ATL 3.0, whose atlbase. H mainly provides some COM smart pointers and strings, such as ccomptr and ccombstr, while ATL 7.0 in vs2003 includes some more interesting classes, such as cregkey and chandle .)
Next we will talk about ccommodule. I believe you can see from its class name that this class is mainly used to manage various COM information. If you go deep into the source code of ATL, you may feel confused about its many Members and methods. In fact, when designing a GUI program, you only need to care about the following:
- Hresult ccommodule: Init (_ atl_objmap_entry * P, hinstance H, const guid * plibid = NULL );
Initialize the module. The first parameter is null, and the second parameter is the application instance handle, that is, the hinstance passed in winmain.
- Void ccommodule: term ();
Uninstall the module and call it at the end of the program.
- Hinstance ccommodule: getmoduleinstance ();
Obtain the application instance handle ccommodule: m_hinst.
- Hinstance ccommodule: getresourceinstance ();
Obtain the resource module handle ccommodule: m_hinstresource, which is consistent with ccommodule: m_hinst by default. If all the resources of your program are in one DLL, you can assign the ccommodule: m_hinstresource member to the module handle of the DLL in the initialization application.
Next we will talk about the ccommodule instance _ module. It can be said that this global variable runs throughout the entire ATL framework, whether you use it to write COM components or GUI programs. For example, you may need to use the instance handle (loadicon and loadcursor) of the module more than once, then you only need to call it like this:
extern CComModule _Module; HICON hIcon = ::LoadIcon( _Module.GetResourceInstance(), MAKEINTRESOURCE( IDI_YOURICON ) ); |
Now, we can fully demonstrate the specific usage of this module class. Here, I only set my previous "Hello, world !" Some extensions are made as follows:
//////////////////////////////////////// ////////////////////////////////// // The source code of the atl gui Program Design // The first chapter cannot be "Hello, world !" // Project name: helloworldex // Author: Li Ma // Http://www.titilima.cn //////////////////////////////////////// //////////////////////////////////# Include <atlbase. h> Ccommodule _ module; Int winapi _ twinmain (hinstance, hinstance hprevinstance, lptstr lpcmdline, int nshowcmd) { _ Module. INIT (null, hinstance ); _ Module. m_hinstresource = loadlibrary (_ T ("shell32.dll ")); Msgboxparams MBP; Zeromemory (& MBP, sizeof (MBP )); MBP. cbsize = sizeof (MBP ); MBP. dwlanguageid = getsystemdefaultlangid (); MBP. dwstyle = mb_usericon; MBP. hinstance = _ module. getresourceinstance (); MBP. lpszcaption = _ T ("hello "); MBP. lpszicon = makeintresource (44 ); MBP. lpsztext = _ T ("Hello, world! "); Messageboxindirect (& MBP ); FreeLibrary( _Module.m_hInstResource ); _Module.m_hInstResource = NULL; _Module.Term(); return 0; }
|
The program runs like this:
As you can see, here I use resources outside of the application, that is, the ccommodule: getmoduleinstance is specially processed. Wtl derives the cappmodule class by inheriting the class ccommodule, making it a more suitable module class for applications. If you are interested, refer to the atlapp. h file attached to wtl. I will not talk about it here.
"Beautiful and beautiful"
The dictionary explains this word: "On the surface, it is very intimate and actually has two hearts ". Here, I use it on ATL 3.0 and 7.0 to demonstrate the fact that they are "compatible in usage and achieve different implementations. However, for GUI program design, you do not need to have a deep understanding of this aspect. Therefore, what I listed here is only related to the GUI.
- In ATL 3.0, ccommodule directly inherits from _ atl_module, while in ATL 7.0, ccommodule goes through a series of inheritance chains.
- In contrast, ccommodule in ATL 7.0 is more com-like. For example, its moduleinstance and resourceinstance can all be used as the property of the COM component and can be processed using get and put.
Of course, ATL is a framework built to develop COM components, so atlbase. h In ATL 7.0 also contains more tool classes related to com development. These contents have nothing to do with this book, and Li Ma believes that he is not able to explain these contents now, so he will start from the beginning.
Click here to download the supporting code in this Chapter