Beginner in Game Development: Windows Programming

Source: Internet
Author: User
Tags old windows
Introduction

This article aims to introduce the basics of Windows programming. At the end of this article, you should be able to work well, although it may be a simple wiindows program. You need to have basic knowledge of C language. I will extend the C ++ code to the program. Of course, because Windows itself is object-oriented, a certain kind of knowledge will not harm you. If you are not familiar with C ++, it doesn't matter. I think you can still learn most of the things from me. All program code has been compiled by Microsoft Visual C ++ 6.0. If you do not have a proper compiler, It will be great to get it as well as me. Start it!

  Start

Most Windows programs require the windows. h and Windows X. h headers. Make sure to use them. Of course, you also need other standard C header files, such as stdio. h and conio. h. In addition, you will often see such a line of code at the beginning of the program:


# Define win32_leanand_mean

It indicates that the windows header file will reject the content of MFC, which will accelerate your build time. If you have never intended to use MFC in your game programming, use it. If you have never seen this declaration type before-Add a "word" directly after # define, then its function is Conditional compilation. Take a look at the following example:

# Ifdef debug_mode
Printf ("debug mode is active! ");
# Endif

If the program starts to contain # define debug_mode, printf (); otherwise, exit. This is very helpful for tracking program logic errors.

  Winmain () function

The C language in DOS starts from main (), and the C language in Windows starts from winmain (). An empty winmain () function is as follows:

Int winapi winmain (hinstance, hinstance hprevinstance, lpstr lpcmdline, int ncmdshow)
{
Return (0 );
}

A function should return a value even if nothing is done. Yes. We are not familiar with many things. First, what is the declaration of winapi? Winapi is a macro defined in the windows. h header file. It translates function calls into correct call conventions. When we need to use the assembly language in the program, let's take a deeper look at it. Remember, if we want to use winmain (), we must have winapi.

Next, let's take a look at the four parameters in brackets:

◎ Hinstance: hinstance is a handle type identifier. The variable hinstance is an integer used to identify the program instance. In Windows, set the value of this parameter and pass it to your program code. Many Windows functions need to use it.

◎ Hinstance hpreinstance: You don't have to worry about this parameter. It has been scrapped. It only serves the old Windows version. You will see a similar situation.

◎ Lpstr lpcmdline: a pointer to a string. It takes effect only when the program name is input from the doscommand line or from the run dialog box. Therefore, it is rarely used by program code.

◎ Int ncmdshow: determines the initial display status of the window. Windows usually assigns a value to this parameter. It is usually a constant starting with SW. For example, sw_shownormal indicates the default state, and sw_maxinize or sw_minimize indicates the maximum and minimum modes, respectively.

  Message

When you program in DOS, you don't have to worry about running other programs, because DOS is an exclusive mode. But when you program on Windows, you have to consider other running programs. In view of this, Windows uses "messages" to connect to the application and specific operations. To put it simply, we instruct the program or program itself to send applications to Windows, such as mobile windows, enlarged windows, and closed windows. Then, based on the application, Windows checks the on-site information, deny or issue commands to allow the program (Computer) to take appropriate actions. For example, if you send a message to windows at any time, report the cursor position, left-click, or right-click whether to press the message, Windows then responds accordingly according to the message. In short, windows always has control over all messages at any time, and Windows keeps receiving various messages.

This function is implemented by a callback function type. You don't need to be afraid. The transfer of messages is completed by windows. You only need to declare a callback function, just like before winmain. If you haven't understood it yet, it doesn't matter. You'll understand it later. Now, I want to leave this topic for a while, because you only need to create a window (Windows) to transmit messages.

  Window Type

Now let's talk about a little c ++ knowledge, because to create a window, you must first create a window class. The window class contains all information about the window, such as the mouse symbol and menu style. Developing any window program is inseparable from the establishment of window classes. To achieve this, you must enter the wndclassex structure. Ex means "expansion", because there is an old structure called wndclass. Here we will use the wndclassex structure, which looks like this:

Typedef struct _ wndclassex {

Uint cbsize;
Uint style;
Wndproc lpfnwndproc;
Int cbclsextra;
Int cbwndextra;
Handle hinstance;
Hicon;
Hcursor;
Hbrush hbrbackground;
Lpctstr lpszmenuname;
Lpctstr lpszclassname;
Hicon hiconsm;
} Wndclassex;

This structure has many Members. what's annoying is that you must set every member for the window class. Don't worry, paper tiger. Let's take a quick look.

※Uint cbsize: Specifies the size of the structure in bytes. This member is implemented through sizeof (wndclassex. You will often see it, especially when DirectX is used.

※Uint style: Specifies the window style. It is often defined as a symbolic constant starting with CS. Two or more styles can be combined using the "or" (|) operator in the C language. In most cases, we only apply four styles. for the length of the article, we only list these four styles. If you need another one, go to msdn to find it. Don't tell me that you are not using Visual C ++!

◎ Cs_hredraw: the window is re-drawn once the width of the customer zone is changed by moving or adjusting the size.

◎ Cs_vredraw: the window is re-drawn once the height of the customer zone is changed by moving or adjusting the size.

◎ Cs_owndc: assigns a unique device context for each window in the class.

◎ Cs_dblclks: sends a double-click message to the window when you double-click the mouse.

※Wndproc lpfnwndproc: pointer to the window process. Usually point to the callback function. If you have never used function pointers, simply put, the address of the function is the name of the function, and the name is not followed by parentheses.

※Int cbclsextra: it is the additional information reserved for the class. Most programmers don't need it. You are not likely to use it when writing a game program, so set it to 0.

※Int cbwndextra: The same as the preceding one. Set it to 0.

※Handle hinstance: The handle pointing to the window process instance. It is also a parameter of the winmain () function. It should be set to hinstance.

※Hicon hicon: The handle pointing to the window icon. It is usually set by the loadicon () function. Before you learn how to use resources in your program, set it to loadicon (null, idi_winlogo ). Of course, there are some other Idi _ headers. You can find them in the Help file.

※Hcursor hcursor: The handle pointing to the window cursor. It is usually set by the loadcursor () function. Before you learn how to use resources in your program, use Windows default, loadcursor (null, idc_arrow ).

※Hbrush hbrbackground: when you receive a message during the window process, you must refresh (or re-paint) the window, at least use a solid color or a "brush" to re-paint the window area, the image painter is determined by parameters. You can use the getstockobject () function to call several standing paint brushes, such as black_brush, white_brush, and gray_brush. Now, you can use getstockobject (black_brush. Sorry, you may think it's too simple, but I don't want to make it too complicated. I will explain it in detail in the future, I promise.

※Lpctstr lpszmenuname: If you want to create a window with a drop-down menu, you have to assign a menu name to this parameter (this involves resources), because you do not know how to create a menu, set null to a window without menus.

※Lpcstr lpszclassname: Obviously, you need to name the class as you like, such as **. Use double quotation marks!

※Hicon hiconsm: The handle pointing to the small icon. The small icon is displayed in the title bar of the window. To use the loadicon () function, use the default loadicon (null, idi_winlogo) in windows ).

Well, you know about the wndclassex structure. You can set it by yourself. The following is an example:

Wndclassex sampleclass; // declare Structure Variable
Sampleclass. cbsize = sizeof (wndclassex); // always use this!
Sampleclass. Style = cs_dblclks | cs_owndc | cs_hredraw | cs_vredraw; // Standard settings
Sampleclass. lpfnwndproc = msghandler; // we need to write this!
Sampleclass. cbclsextra = 0; // Extra Class info, not used
Sampleclass. cbwndextra = 0; // extra window info, not used
Sampleclass. hinstance = hinstance; // parameter passed to winmain ()
Sampleclass. hicon = loadicon (null, idi_winlogo); // Windows logo
Sampleclass. hcursor = loadcursor (null, idc_arrow); // standard cursor
Sampleclass. hbrbackground = (hbrush) getstockobject (black_brush); // a simple black brush
Sampleclass. lpszmenuname = NULL; // no menu
Sampleclass. lpszclassname = "sample class" // Class Name
Sampleclass. hiconsm = loadicon (null, idi_winlogo); // Windows logo again
......

I think you are not very fond of Windows programmers anymore. Let's get down to the point where I want to remind you to pay attention to the (hbrush) type configuration before the getstockobject () function, because getstockobject () can call other objects, not just "brush ", therefore, you need an hbrush configuration. You do not need to configure it in the earlier version of Visual C ++, but it is required in the new version 6.0. Otherwise, compilation errors may occur.

The next thing is to register this window class. Only in this way can you create a new window. It is very simple. You only need to call a registerclassex () function, which has only one parameter, that is, the address (name) of your window class. Based on the example above, we should look like this:

Registerclassex (& sampleclass );

Hi, our window class has been created. We can use it to create a window. It's just a matter of time!
Create window

Good news, all you have to do to create a window is call a createmediawex () function. The bad message is that this function has many parameters. Hey! Put the knife down. Is there something to say! It's really not hard. You have to do things in the form of walking! The following figure shows the original function:


Hwnd createmediawex (
DWORD dwexstyle, // extended window style
Maid, // pointer to registered Class Name
Lptstr lpwindowname, // pointer to window name
DWORD dwstyle, // window style
Int X, // horizontal position of window
Int y, // vertical position of window
Int nwidth, // window width
Int nheight, // window height
Hwnd hwndparent, // handle to parent or owner window
Hmenu, // handle to menu, or child-window identifier
Hinstance, // handle to application instance
Lpvoid lpparam // pointer to window-creation data
);

First, the return value of the function. That is, the function type. Isn't the type of all the functions used to create a window really friendly? Not yet? It doesn't matter. You will get used to it. It must be faster than you think. The returned type is hwnd, which is a window handle (the handle is the window identifier ). You will pass the return value of createmediawex () to a window handle, just like a parameter. Now, let's take a look at these parameters. Many people will know what they do based on their names.

※Dword dwexstyle: expanded window style. You will rarely use the extended window style, so you will set it to null most of the time. If you are interested, check the Help file and try the extended style headers of ws_ex.

※Lpctstr lpclassname: Do you still remember the name of your window class? Use it again.

※Lpwindowname: short text displayed in the title bar of the window.

※Dword dwstyle: The window style. It will allow you to describe in detail the style of the window you want to create. There are a lot of styles you can use. They are all headers with WS _. You can use them with the (|) symbol combination. I will introduce several common ones here.

◎ Ws_popup specifies a pop-up window.

◎ Ws_overlapped specifies an overlapping window with the title bar and boundary.

◎ Ws_overlappedwindow specifies a window with all standard controls.

◎ Ws_visible specifies an initial visible window.

Ws_overlappedwindow is a combination. Simply put, you can follow the following rules: If you want to create a window that maximizes, minimizes, and changes the size at will, select ws_overlappedwindow; if you only want a window with a title bar and a size change, select ws_overlapped. If you only want a bare window, select ws_popup; if you only want to display a black box, you may want to use it to write a full-screen game. It is correct to select ws_visible.

※Int X, Y: coordinates of the upper left corner of the window to be created.

※Int nwidth and nheight: You can guess the length and height of the window. The unit is "pixel 』.

※Hwnd hwndparent: The handle pointing to the parent window. If you want to create another window in the window, the first window is called the parent window. Create a main window first, so if it is set to null, it means that Windows desktop is the parent window.

※Hmenu hmenu: This is the menu handle used in the window. If you learn to create and use resources, that is, to create your own menu, you can use the loadmenu () function to call your own menu resources. Currently, this parameter is set to null first.

※Hinstance hinstance: it is a name handle that points to the instance passed to winmain () by windows.

※Lpvoid lpparam: it is useless for game programming. It is only used by simple window programs. Set to null.

Comrades, everything is ready for us now, and Dongfeng is ready for us. Let me give you an example:

Hwnd;
If (! (Hwnd = createappswex (null, // extended style, not needed
"Sample class", // Class Identifier
"Sample window", // window title
Ws_popup | ws_visible, // Parameters
0, 0,320,240, // initial position, size
Null, // handle to parent (the desktop)
Null, // handle to menu (none)
Hinstance, // application instance handle
Null) // who needs it?
Return (0 );

You may use this code in game programming because it is a pop-up window. Note that I use the if form to return a null value when the createwindowsex () function fails. This means that if the window cannot be created for some reason, then winmain () it is simply returned and the program ends.

Now we have learned enough knowledge to create a small functional window. Do you still remember a pointer pointing to the "Callback" type function when we set up the window class "sample class? Yes, it is "lpfnwndproc ". To make your window really do something, we have to deal with the "Window Process" function that it points.

  Display window

Createmediawex () is created from the internal window, but it is not displayed. To display this window, you must call the other two functions: showwindow () and updatewindow (). The display status of the first setting window, and the last one updates the customer area of the window. For the main window of the program, showwindow () must be called once. The call code is as follows:

Showwindow (hwnd, ncmdshow );

The first parameter is the window handle returned by the createmediawex () function. The second parameter is the window display mode parameter. As mentioned in the ☆winmain () function, it will not be repeated. The calling code of the updatewindow () function is as follows:

Updatewindow (hwnd );

The hwnd parameter is the same as that of the showwindow () function.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.