Building the Skeleton Example Program


At this point, you've seen the major portions of a Windows program isolated into individual parts . Understandably, it's difficult to get a feel for a complete Windows program when viewing it in small chunks of code. For this reason, it's very important to see how a complete Windows program comes together. This section shows you a complete, yet minimal, Windows program called Skeleton that will form the basis for games to come throughout the book. Following are the files that go into the Skeleton program example:

  • Skeleton.h ” Header file for the application

  • Skeleton.cpp ” Source code file for the application

  • Resource.h ” Header file for the resource IDs

  • Skeleton.rc ” Resource file for the application

The next couple of sections explore the program code and the related resources that go into the Skeleton application. All of this code is available on the accompanying CD-ROM, along with Microsoft Visual C++ project files.

Writing the Program Code

The Skeleton.h header file is surprisingly simple, and does nothing but import a couple of headers for use by Skeleton.cpp. Listing 2.1 contains the code for this file.

Listing 2.1 The Skeleton.h Header File Simply Imports a Couple of Header Files
 1: #pragma once  2:  3: //-----------------------------------------------------------------  4: // Include Files  5: //-----------------------------------------------------------------  6: #include <windows.h>  7: #include "Resource.h" 

In case you aren't familiar with it, line 1 shows how to use the #pragma once compiler directive to keep the Skeleton.h header from being accidentally referenced more than once. This gets to be more of an issue in larger programs in which there are a lot of dependencies between different source files, but it's a good idea to get in the habit of using the directive. Lines 6 and 7 contain the important code, which is the inclusion of the standard windows.h header file and the Resource.h resource identifier header file, which you learn about in a moment.

The bulk of the code for the Skeleton program is in the Skeleton.cpp source code file, which is shown in Listing 2.2.

Listing 2.2 The Skeleton.cpp Source Code File Builds on the Code You Saw Throughout This Lesson to Create a Complete Windows Program
 1: //-----------------------------------------------------------------  2: // Include Files  3: //-----------------------------------------------------------------  4: #include "Skeleton.h"  5:  6: //-----------------------------------------------------------------  7: // Global Function Declarations  8: //-----------------------------------------------------------------  9: LRESULT CALLBACK  WndProc(HWND hWindow, UINT msg, WPARAM wParam, 10:   LPARAM lParam); 11: 12: //----------------------------------------------------------------- 13: // Global Functions 14: //----------------------------------------------------------------- 15: int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 16:   PSTR szCmdLine, int iCmdShow) 17: { 18:   static TCHAR  szAppName[] = TEXT("Skeleton"); 19:   WNDCLASSEX    wndclass; 20:   HWND          hWindow; 21:   MSG           msg; 22: 23:   // Create the window class for the main window 24:   wndclass.cbSize         = sizeof(wndclass); 25:   wndclass.style          = CS_HREDRAW  CS_VREDRAW; 26:   wndclass.lpfnWndProc    = WndProc; 27:   wndclass.cbClsExtra     = 0; 28:   wndclass.cbWndExtra     = 0; 29:   wndclass.hInstance      = hInstance; 30:   wndclass.hIcon          = LoadIcon(hInstance, 31:     MAKEINTRESOURCE(IDI_SKELETON)); 32:   wndclass.hIconSm        = LoadIcon(hInstance, 33:     MAKEINTRESOURCE(IDI_SKELETON_SM)); 34:   wndclass.hCursor        = LoadCursor(NULL, IDC_ARROW); 35:   wndclass.hbrBackground  = (HBRUSH)(COLOR_WINDOW + 1); 36:   wndclass.lpszMenuName   = NULL; 37:   wndclass.lpszClassName  = szAppName; 38: 39:   // Register the window class 40:   if (!RegisterClassEx(&wndclass)) 41:     return 0; 42: 43:   // Create the window 44:   hWindow = CreateWindow(szAppName, szAppName, WS_OVERLAPPEDWINDOW, 45:     CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, 46:     NULL, hInstance, NULL); 47: 48:   // Show and update the window 49:   ShowWindow(hWindow, iCmdShow); 50:   UpdateWindow(hWindow); 51: 52:   // Enter the main message loop 53:   while (GetMessage(&msg, NULL, 0, 0)) 54:   { 55:     // Process the message 56:     TranslateMessage(&msg); 57:     DispatchMessage(&msg); 58:   } 59:   return (int)msg.wParam; 60: } 61: 62: LRESULT CALLBACK WndProc(HWND hWindow, UINT msg, WPARAM wParam, 63:   LPARAM lParam) 64: { 65:   HDC         hDC; 66:   PAINTSTRUCT ps; 67:   RECT        rect; 68: 69:   switch (msg) 70:   { 71:     case WM_PAINT: 72:       // Draw some text centered in the client area of the main window 73:       hDC = BeginPaint(hWindow, &ps); 74:       GetClientRect(hWindow, &rect); 75:       DrawText(hDC, TEXT("This is a skeleton application!"), -1, &rect, 76:         DT_SINGLELINE  DT_CENTER  DT_VCENTER); 77:       EndPaint(hWindow, &ps); 78:       return 0; 79: 80:     case WM_DESTROY: 81:       // Exit the application 82:       PostQuitMessage(0); 83:       return 0; 84:   } 85:   return DefWindowProc(hWindow, msg, wParam, lParam); 86: } 

This is admittedly a lot of code to throw at you at once, but I wanted you to see the Skeleton.cpp source code file in its entirety so that there would be no mysteries regarding what goes into a Windows program. Fortunately, the game engine that you build in the next lesson helps to hide a great deal of this code so that you never have to worry with it again. But for now we must push on and learn how it works!

Line 4 of the code imports the Skeleton.h header file, which is important because it in turn imports windows.h and Resource.h. Line 9 is a forward declaration of the WndProc() function, which is necessary because the function must be referenced in WinMain() before its code appears. Speaking of WinMain() , its job is to create the main window class (lines 24 “37), register the window class (lines 40 and 41), create the main window (lines 44 “46), show the main window (lines 49 and 50), and then get the application message loop going (lines 53 “58). This certainly looks like a lot of interesting code, but it's actually quite boring once you see a few Windows programs; this code is largely duplicated verbatim in every Windows program. Fortunately, you'll be hiding this code in the game engine in the next lesson.

Getting back to WinMain() , you might be curious why the string for the program name is placed inside the apparent function call, TEXT() (line 18). TEXT() is actually a macro, not a function, and its job is to convert text into a form that can be used on a wide range of Windows systems. I won't get into all the details, but let's just say that it's a good idea to work with text using the TEXT() macro so that your program won't act strange on computers that are set up with a version of Windows designed for another language, such as Japanese.

Another important thing to notice in WinMain() is how both large and small icons are set for the program (lines 30 “33). This is more important than you might realize because Windows XP typically displays the small 16x16 icon for programs even though the large 32x32 size was more prevalent in older versions of Windows.

The remainder of the code in the Skeleton.cpp source code file is the WndProc() function, which handles only two messages: WM_PAINT and WM_DESTROY . The WM_PAINT message is sent whenever a program needs to paint the client area (inside) of its window. In this case, a sentence of text is being drawn in the center of the client area to indicate that this is a skeleton application (lines 73 “77). You learn all about painting both text and graphics in Hour 4, "Drawing Basic Graphics," so I'll skip explaining this code in more detail at this point.

Assembling the Resources

The Skeleton program only uses two resources: the large and small application icons. Before listing these icons in a resource script, it's important to assign them unique numeric identifiers, which are also known as resource IDs . This is accomplished in the Resource.h header file, which is shown in Listing 2.3.

Listing 2.3 The Resource.h Header File Contains Resource IDs for the Skeleton Program Example
 1: //-----------------------------------------------------------------  2: // Icons                    Range : 1000 - 1999  3: //-----------------------------------------------------------------  4: #define IDI_SKELETON        1000  5: #define IDI_SKELETON_SM     1001 

As you can see, it only takes two lines (4 and 5) to define identifiers for the icon resources. Pulling the resources into the Skeleton application simply involves listing them in the application's resource script, as shown in Listing 2.4.

Listing 2.4 The Skeleton.rc Resource Script Contains the Resources for the Skeleton Program Example
 1: //-----------------------------------------------------------------  2: // Include Files  3: //-----------------------------------------------------------------  4: #include "Resource.h"  5:  6: //-----------------------------------------------------------------  7: // Icons  8: //-----------------------------------------------------------------  9: IDI_SKELETON       ICON         "Skeleton.ico" 10: IDI_SKELETON_SM    ICON         "Skeleton_sm.ico" 

Notice that the Skeleton.rc resource script first includes the Resource.h header file (line 4), and it then specifies the two icon resources by referencing their IDs (identifiers) and their physical locations (filenames). As long as you associate the Skeleton.rc file with the project file for your program in the development environment (compiler) that you're using, it will be automatically compiled and linked in with the application. As an example, I used Visual C++ to create the examples in this book, and after I added Skeleton.rc to the Skeleton project, I didn't have to worry about compiling or linking it.

Testing the Finished Product

I wish I could tell you that the Skeleton program example is full of excitement and intrigue when you run it for the first time, but unfortunately this just isn't the case. Seeing as how it is a minimal Windows application, there isn't a whole lot you can do with it. However, when you consider that the program "inherits" a lot of functionality from Windows because you can minimize it, maximize it, resize it, drag it around with the mouse, and so on, you start to realize that the Win32 API is quite powerful in its own way. Figure 2.2 shows the finished Skeleton application in action.

Figure 2.2. The Skeleton program is a good example of a minimal Windows program, and not much else.

graphics/02fig02.gif

I warned you: There isn't much to look at here. Fortunately, you now have enough basic Windows programming skills to start doing some fun things.



Sams Teach Yourself Game Programming in 24 Hours
Sams Teach Yourself Game Programming in 24 Hours
ISBN: 067232461X
EAN: 2147483647
Year: 2002
Pages: 271

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net