你的第一个Windows程序——创建一个窗口
窗口类
一个窗口类定义了一组数个窗口可以共有的行为。比如有一组按钮,当用户单击按钮,每个按钮都有类似的行为。当然,按钮也不是完全相同的;每个按钮都有自己的显示文本字符串和自己的屏幕坐标。对于被称为实例数据的每个窗口的数据是唯一的。每个窗口必须有一个窗口类关联,即使你的程序只创建该类的一个实例。重要的是要明白,一个窗口类不是C++意义上的类。切确的说,它是一个操作系统内部使用的数据结构,窗口类是向系统运行时注册的。注册一个新的窗口类,通过填充一个
WNDCLASS(英文)结构开始:
// Register the window class.
const wchar_t CLASS_NAME[] = L"Sample Window Class";
WNDCLASS wc = { };
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
你必须设置一下结构成员:
- lpfnWndProc 是一个指针,指向应用程序定义的被称为窗口过程(或"window proc")的的函数。窗口过程定义了大部分窗口行为,窗口过程的细节我们将在以后研究。现在,只是把这个作为一个前瞻性的参考。
- hInstance 是应用程序的实例句柄,从wWinMain的hInstance参数获取这个值。
- lpszClassName 是一个表示窗口类的字符串。
类名是局部的,属于当前进程,所以这个名字只需要在当前进程中是唯一的。然而标准的windows控件也同样是类,如果你使用任何这些控件,你必须选择不与控件类名冲突的类名。比如按钮控件的窗口类名是"Button"。
这里没有显示
WNDCLASS结构的其它成员,你可以设置它们为零,就如在这个例子所示的,或者填写它们,在MSDN文档中有描述这个结构的详细信息。
下一步,传递
WNDCLASS结构的地址给
RegisterClass 函数,这个函数注册窗口类给操作系统。
RegisterClass(&wc);
创建窗口
创建一个窗口的一个新实例,调用CreateWindowEx函数:
HWND hwnd = CreateWindowEx(
0, // Optional window styles(可选的窗口样式).
CLASS_NAME, // Window class(窗口类)
L"Learn to Program Windows", // Window text(窗口标题)
WS_OVERLAPPEDWINDOW, // Window style(窗口样式)
// Size and position(大小和定位)
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, // Parent window (父窗口)
NULL, // Menu (菜单)
hInstance, // Instance handle (实例句柄)
NULL // Additional application data(额外的应用程序数据)
);
if (hwnd == NULL)
{
return 0;
}
你可以阅读MSDN上详细的参数说明,这里只是一个简略的总结。
- 第一个参数可以让你指定的窗口的一些可选的行为(比如透明窗口),这个参数设置零为缺省行为。
- CLASS_NAME是窗口类名,这个定义了你正在创建窗口的类型。
- WIndow text 根据不同的窗口类型使用不同的方式,如果这个窗口有标题栏,在标题栏显示文本。
- window style 是窗口风格的设置,常量 WS_OVERLAPPEDWINDOW实际上是几个标记按位或运算的组合。分别是标题栏、边框、系统菜单、最小化和最大化按钮。这组标记是一个顶层应用程序最常见的窗口风格。
- size and position 常量CW_USEDEFAULT表示默认值。
- parent window 设置了新窗口是所有者窗口还是父窗口,如果是创建子窗口就设置父窗口,如果是创建顶层窗口就是NULL。
- 对于应用程序,下个参数定义窗口的菜单,这个例子没有菜单,所以值是NULL。
- hInstance是示例句柄,前面描述过。(参考:应用程序入口点WinMain)
- 最后一个参数是个指针,指向void*类型的任意数据。您可以使用这个值来传递一个数据结构到你的窗口过程,我们将在 Managing Application State这节中演示一个可能的方式使用这个参数。
CreateWindowEx返回新窗口的句柄,若是创建窗口失败则返回零值。要显示窗口,使窗口可见,传递句柄给
ShowWindow 函数:
ShowWindow(hwnd, nCmdShow);
hwnd是
CreateWindowEx返回的窗口句柄。nCmdShow可用来最小化和最大化窗口,这个参数通过操作系统传给wWinMain函数。
下面是完整的代码来创建窗口。记住WindowProc函数仍然只是一个预先的声明。
// Register the window class.
const wchar_t CLASS_NAME[] = L"Sample Window Class";
WNDCLASS wc = { };
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
RegisterClass(&wc);
// Create the window.
HWND hwnd = CreateWindowEx(
0, // Optional window styles.
CLASS_NAME, // Window class
L"Learn to Program Windows", // Window text
WS_OVERLAPPEDWINDOW, // Window style
// Size and position
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, // Parent window
NULL, // Menu
hInstance, // Instance handle
NULL // Additional application data
);
if (hwnd == NULL)
{
return 0;
}
ShowWindow(hwnd, nCmdShow);
恭喜!你已经创建了一个窗口。目前,窗口不包含任何内容或与用户交互。在一个真正的GUI应用程序,窗口会响应来自用户和操作系统的事件。下一节描述窗口消息如何提供这种互动。