本系列文章由 net_assassin 编写,转载请注明出处。
http://blog.csdn.net/net_assassin/article/category/1100363
作者:net_assassin 邮箱: net_assassin@hotmail.com 期待着与志同道合的朋友们相互交流
好,上一篇文章我们认识了windows这个操作系统的关键——消息处理机制。我们使用所学的新知识来编写一个稍微复杂一点的程序,让它实际穿件一个标准窗口并在这个窗口上绘制文本和图形,如图所示
在窗口上绘图需要许多起始代码,我们通过示例来学习。
创建一个名为WindowTest的Win32项目并在项目中添加新的main.cpp文件
程序代码完整清单如下:
/**
Beginning Game Programming, Third Edition
Chapter 2
WindowTest program
**/
#include <windows.h>
#include <iostream>
using namespace std;
const string ProgramTitle = "Hello Windows";
/**
** The window event callback function
**/
LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
string text = "Hello Windows!";//在窗口中要显示的字符串
switch (message)
{
case WM_PAINT:
{
//get the dimensions of the window
RECT rt;
GetClientRect(hWnd, &rt);
//start drawing on device context
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
//draw some text
DrawText(hdc, text.c_str(), text.length(), &rt, DT_CENTER);
//draw 1000 random pixels
for (int n=0; n<3000; n++)
{
int x = rand() % (rt.right - rt.left);
int y = rand() % (rt.bottom - rt.top);
COLORREF c = RGB(rand()%256, rand()%256, rand()%256);
SetPixel(hdc, x, y, c);
}
//stop drawing
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
/**
** Helper function to set up the window properties
** 这段代码也可以放在WinMain函数中,Windows是不会抱怨的,但是把Windows程序的初始化代码分开
** 放置到可识别的(也是标准的)助手函数中可以使程序更容易理解一些,至少在学习阶段是如此。
**/
ATOM MyRegisterClass(HINSTANCE hInstance)
{
//set the new window's properties
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WinProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = ProgramTitle.c_str();
wc.hIconSm = NULL;
return RegisterClassEx(&wc);
}
/**
** Helper function to create the window and refresh it
** 用于创建应用程序所需的新窗口并显示,InitInstance基本上只创建程序窗口。
** 这个函数的代码本可直接插入到WinMain中,但将它们放到单独的函数中会更方便。
** 注意,InitInstance不是一个像WinMain那样的基本Windows函数,而只是一个“助手”函数。
** 实例句柄是一个程序中使用的全局变量。用于保存主实例。
**/
bool InitInstance(HINSTANCE hInstance, int nCmdShow)
{
//create a new window
HWND hWnd = CreateWindow(
ProgramTitle.c_str(), //window class
ProgramTitle.c_str(), //title bar
WS_OVERLAPPEDWINDOW, //window style
CW_USEDEFAULT,CW_USEDEFAULT, //position of window
640, 480, //dimensions of the window
NULL, //parent window (not used)
NULL, //menu (not used)
hInstance, //application instance
NULL); //window parameters (not used)
//was there an error creating the window?
if (hWnd == 0) return 0;
//display the window
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return 1;
}
/**
** Entry point for a Windows program
**/
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
//create the window
MyRegisterClass(hInstance);
if (!InitInstance (hInstance, nCmdShow)) return 0;
// main message loop
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
InitInstance 和 MyRegisterClass 函数中的代码并不是一定要位于不同的函数中,可以将这些代码直接放在WinMain中,我们在后面的章节中就是这么做的。但目前,分成多个小步骤来实现有助于理解Windows编程。
WinProc的秘密
WinProc 是窗口回调函数,Windows通过它将事件传递给程序。回调函数是被调用回来的函数。这个函数处理所有发送给主程序窗口的消息。
图片引自51cto。