窗口类
窗口类定义了几个窗口可能共有的一组行为。例如,在一组按钮中,当用户单击按钮时,每个按钮都具有相似的行为。当然,按钮并不完全相同,每个按钮都显示自己的文本字符串,并具有自己的屏幕坐标。每个窗口唯一的数据称为实例数据。
每个窗口都必须与窗口类关联,即使您的程序只创建该类的一个实例。 理解一个窗口类不是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是窗口类的名称。这定义了您正在创建的窗口的类型。
- 窗口文本被不同类型的窗口以不同的方式使用。如果窗口有标题栏,则文本显示在标题栏中。
- 窗口样式是一组定义窗口外观和感觉的标志。常量WS_OVERLAPPEDWINDOW实际上是几个标志组合在一起的一个按位或。这些标记一起给窗口一个标题栏,一个边框,一个系统菜单,和最小化和最大化按钮。这组标志是顶级应用程序窗口最常见的样式。
- 对于位置和大小,常量CW_USEDEFAULT意味着使用默认值。
- 下一个参数为新窗口设置父窗口或所有者窗口。如果您正在创建一个子窗口,请设置父项。对于顶层窗口,将其设置为NULL。
- 对于应用程序窗口,下一个参数定义窗口的菜单。这个例子不使用菜单,所以值是NULL。
- hInstance是前面介绍的实例句柄。(请参阅WinMain:应用程序入口点。)
- 最后一个参数是指向void*类型的任意数据的指针。您可以使用此值将数据结构传递给您的窗口过程。我们将在管理应用程序状态一节中给出一个可能的使用方法。
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应用程序中,窗口将响应来自用户和操作系统的事件。 下一节将介绍窗口消息如何提供这种交互性。
下一个
窗口消息
原文链接:Creating a Window