文章目录
编写一个Windows程序
这次创建一个标准窗口并在这个窗口上绘制文本和图形。
DirectX SDK随后章节有安装步骤,还要配置C++编译器,目前还未需要用到。
创建一个Win32项目,添加main.cpp。(创建过程参照第1章)
main.cpp源码如下:
#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)
{
RECT drawRect;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_PAINT:
{
hdc = BeginPaint(hWnd, &ps); //start drawing
for (int n = 0; n < 20; n++)
{
int x = n * 20;
int y = n * 20;
drawRect = {
x, y, x + 100, y + 20 };
DrawText(hdc, ProgramTitle.c_str(), ProgramTitle.length(), &drawRect, DT_CENTER);
}
EndPaint(hWnd, &ps); //stop drawing
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
// Helper function to set up the window properties
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
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
InitInstance
creates the program window.
Note that InitInstance
is not a Windows function like WinMain
, but simply a helper function.
The instance handle is a global variable used in the program to keep track of the main instance.
InitInstance函数调用
bool InitInstance( HINSTANCE hInstance, int nCmdShow )
-
HINSTANCE hInstance
. The first parameter is passed by WinMain with the program instance that it receives from Windows. InitInstance will check this with the global instance to see whether the new instance needs to be killed. ()When this happens, the main instance of the program is set as the foreground window. To the user, it will seem as if running the program again just brought the original instance forward. -
int nCmdShow
. The second parameter is passed to InitInstance by WinMain, which
receives the parameter from Windows.
The InitInstance function returns a bool value, which is either 1 (true) or 0 (false), and simply tells WinMain
whether startup succeeded or failed.
InitInstance的结构
The whole point of InitInstance
is to create the new window needed by this application and display it.
// Helper function to create the window and refresh it
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