Выбрать главу

Just remember a few things and they will be easy to interpret. An LP prefix stands for Long Pointer . In Win32 the Long part is obsolete so don't worry about it. And if you don't know what a pointer is, you can either 1) Go find a book or tutorial on C, or 2) just go ahead anyway and screw up a lot. I'd really recommend #1, but most people go with #2 (I would :). But don't say I didn't warn you.

Next thing is a C following a LP indicates a const pointer. LPCSTR indicates a pointer to a const string, one that can not or will not be modified. LPSTR on the other hand is not const and may be changed.

You might also see a T mixed in there. Don't worry about this for now, unless you are intentionally working with Unicode, it means nothing.

A Simple Window

Example: simple_window

Sometimes people come on IRC and ask "How do I make a window?"… Well it's not entirely that simple I'm afraid. It's not difficult once you know what you're doing but there are quite a few things you need to do to get a window to show up; And they're more than can be simply explained over a chat room, or a quick note.

I always liked to do things first and learn them later… so here is the code to a simple window which will be explained shortly.

#include <windows.h>

const char g_szClassName[] = "myWindowClass";

// Step 4: the Window Procedure

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {

 switch (msg) {

 case WM_CLOSE:

  DestroyWindow(hwnd);

  break;

 case WM_DESTROY:

  PostQuitMessage(0);

  break;

 default:

  return DefWindowProc(hwnd, msg, wParam, lParam);

 }

 return 0;

}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {

 WNDCLASSEX wc;

 HWND hwnd;

 MSG Msg;

 //Step 1: Registering the Window Class

 wc.cbSize = sizeof(WNDCLASSEX);

 wc.style = 0;

 wc.lpfnWndProc = WndProc;

 wc.cbClsExtra = 0;

 wc.cbWndExtra = 0;

 wc.hInstance = hInstance;

 wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);

 wc.hCursor = LoadCursor(NULL, IDC_ARROW);

 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);

 wc.lpszMenuName = NULL;

 wc.lpszClassName = g_szClassName;

 wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

 if (!RegisterClassEx(&wc)) {

  MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);

  return 0;

 }

 // Step 2: Creating the Window

 hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, g_szClassName, "The title of my window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, hInstance, NULL);

 if (hwnd == NULL) {

  MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);

  return 0;

 }

 ShowWindow(hwnd, nCmdShow);

 UpdateWindow(hwnd);

 // Step 3: The Message Loop

 while(GetMessage(&Msg, NULL, 0, 0)> 0) {

  TranslateMessage(&Msg);

  DispatchMessage(&Msg);

 }

 return Msg.wParam;

}

For most part this is the simplest windows program you can write that actually creates a functional window, a mere 70 or so lines. If you got the first example to compile then this one should work with no problems.

Step 1: Registering the Window Class

A Window Class stores information about a type of window, including it's Window Procedure which controls the window, the small and large icons for the window, and the background color. This way, you can register a class once, and create as many windows as you want from it, without having to specify all those attributes over and over. Most of the attributes you set in the window class can be changed on a per-window basis if desired.

A Window Class has NOTHING to do with C++ classes.

const char g_szClassName[] = "myWindowClass";

The variable above stores the name of our window class, we will use it shortly to register our window class with the system.

WNDCLASSEX wc;

wc.cbSize = sizeof(WNDCLASSEX);

wc.style = 0;

wc.lpfnWndProc = WndProc;

wc.cbClsExtra = 0;

wc.cbWndExtra = 0;

wc.hInstance = hInstance;

wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);

wc.hCursor = LoadCursor(NULL, IDC_ARROW);

wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);

wc.lpszMenuName = NULL;

wc.lpszClassName = g_szClassName;

wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

if (!RegisterClassEx(&wc)) {

 MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);

 return 0;

}

This is the code we use in WinMain() to register our window class. We fill out the members of a WNDCLASSEX structure and call RegisterClassEx().

The members of the struct affect the window class as follows:

cbSize

The size of the structure.

style

Class Styles (CS_* ), not to be confused with Window Styles (WS_* ) This can usually be set to 0.

lpfnWndProc

Pointer to the window procedure for this window class.

cbClsExtra

Amount of extra data allocated for this class in memory. Usually 0.

cbWndExtra

Amount of extra data allocated in memory per window of this type. Usually 0.

hInstance

Handle to application instance (that we got in the first parameter of WinMain() ).

hIcon

Large (usually 32×32) icon shown when the user presses Alt+Tab.