6

我想问一下,为什么在使用API​​开发Windows GUI时,需要注册一个窗口类?它的概念是什么?

我已经阅读了Charles Petzold编写的Programming Windows的前 3 章,但我仍然想知道显式注册一个类的目的是什么。我为什么要明确地这样做?为什么它不在后台完成,例如在 CreateWindow()(或 CreateWindowEx())函数中?我的意思是,为什么 RegisterClass() 的代码不在 CreateWindow() 中执行,或者为什么 CreateWindow() 不调用 RegisterClass() 本身?

我也一直在阅读 MSDN 上的文档,并且我知道 RegisterClass() 函数通过填充 WNDCLASS 结构将窗口过程与窗口类相关联。我知道这是处理来自操作系统的消息的函数,但是为什么需要将该函数(WinProc 函数)注册到 CreateWindow() 的单独函数中的类中?

我可以理解存在 CreateWindow() 函数的原因,以及为什么它不会自动显示创建的窗口。这意味着我也了解 ShowWindow() 函数的用途。

我确信这种行为一定有充分的理由,让程序员在他想要的时候注册一个类,我只是看不到这些原因,这就是为什么我要求你们阐明这个问题。

请记住,我对使用 Windows API 进行 GUI 开发非常陌生。我在 MATLAB 中做了一些与 Windows API 不同的 GUI,仍然让我理解了一些 Windows 哲学,特别是回调函数的目的。我不知道这些信息是否有用,但如果您需要做一些类比,请成为我的客人。

4

4 回答 4

11

既然你已经用 C++ 标记了你的问题,我会给你一个 C++ 类比......

RegisterClass基本上是您定义一个类并将其包含在您的程序中(很像#includeC++ 中的一个)。WNDPROC如果和当创建实例时,它是您在窗口内发生的任何事情的处理程序。

CreateWindow在概念上与您new在 C++ 中执行的操作相同。您要求 Windows 创建一个新窗口,并且您必须告诉它窗口的类型。Windows 包含一组预定义的窗口,例如 Button 或 Edit,但如果您想创建自己的窗口的实例,那很好,您只需告诉它您要创建的“类”。您已经通过调用注册了这个类RegisterClass,因此 Windows 现在可以直接进入定义并创建您的窗口的实例。

于 2014-07-02T14:53:31.360 回答
0

另一种思考方式是因为 Windows 是一个封闭源代码,所以 API 编写者不希望您了解太多 API 内部。所以现在,他们想:“如果用户想用自己的行为创建自己的窗口类怎么办?”。这就是为什么创建 WNDCLASS 让用户通过在成员字段中分配名称、过程等值来声明他们需要的类的信息。这有点像填写表格。因此,您可以看到 API 编写者实现了 2 件事:

(1) 用户对 API 一无所知,因为他们没有明确地将 API 类扩展为自定义,因为如果他们这样做了,那么 API 编写者必须提供类的标头,用户可能会搞砸使 Windows不再关闭。

(2) 用户仍然可以定义自己的窗口类。

现在,在您定义了自己的窗口类之后,并且您想使用它,所以您必须注册该类,以便 Windows 操作系统知道它是什么类,以便他们可以维护有关它的信息以备不时之需,然后您就可以创建它的实例。

于 2017-05-10T03:37:03.283 回答
0

我认为实际原因是由于系统窗口类:

“许多系统类可供所有进程使用,而其他系统类仅由系统内部使用。因为系统注册了这些类,所以进程无法销毁它们。” 来源:https ://docs.microsoft.com/en-us/windows/win32/winmsg/about-window-classes

请注意,从该链接中可以看出,win32 中许多被认为是“小部件”的东西(例如按钮、工具栏、组合框等)实际上是窗口,因为它们有一个窗口类。这些由系统提供,并且可以覆盖行为,但它们的默认源代码对应用程序程序员是隐藏的。

于 2021-03-09T02:39:26.640 回答
0

您需要注册类来定义样式,窗口的过程,这是对拥有窗口的线程进行编程以响应消息和事件并为窗口接收到的每条消息和发生的每个事件做某事或不做任何事情所必需的,图标你的窗口,用户在窗口上悬停时看到的光标,窗口客户端的背景和窗口的菜单。

你怎么能想象一个没有所有这些属性的窗口呢?

也许你会问为什么这些窗口属性都不是 CreateWindow 函数的参数,所以我用 CreateWindow 函数而不是 RegisterClass 函数来设置它们,对吧?

如果所有窗口属性都是 CreateWindow 函数的参数,那么 CreateWindow 函数非常复杂,正确调用 CreateWindow 的行很长

这使得代码非常大,可读性差,效率低下。

RegisterClass 大大简化了 CreateWindow。

这是微软希望 Win32 开发人员在 CreateWindow 之前首先调用 RegisterClass 的原因之一。

还假设您需要至少两个具有相同属性的窗口。

您只分配一个WNDCLASS 结构的实例,设置他的字段来设置窗口的公共属性,并且您只调用一次RegisterClass 函数,但是您根据需要多次调用 CreateWindow 来创建您想要的所有窗口,但是每个人都有相同的类名。

RegisterClass 不仅大大简化和缩短了代码,而且还防止了在 CreateWindow 中重复相同的大代码。

RegisterClass 还使代码更有效率。

这是一个很好的设计,首先分配一个 WNDCLASS 实例,设置他的字段,调用 RegisterClass 函数,然后根据需要多次调用 CreateWindow 函数。

虽然您需要多次调用RegisterClass,但如果您想要具有不同属性的窗口当然。

您还必须在每次调用 RegisterClass 函数之前修改 WNDCLASS 实例。

于 2018-06-26T12:35:01.323 回答