11

我目前正在编写自己的迷你可视化框架来将纯 WinAPI 包装在类中。

目前分析消息的过程如下:

  • staticApplication::Run有一个消息循环;它获取新消息并将其分派给适当的 WndProc。

  • 我创建的所有窗口都是从同一个类创建的(就 WinAPI 而言),所以同样WndProc被调用。实际上,它是一种静态FormAPI::WndProc方法。这一项检查消息所指的窗口并调用它的WndProc.

  • Form::WndProc方法被调用,它分析消息。假设它是一个WM_MOUSEMOVE. 它调用ProcessMouseMove然后DefWindowProc。将此点记为 [1]。

  • privateForm::ProcessMouseMove从消息中获取实际数据(例如 x, y, shift state),将其转换为可用数据并调用 protected Form::OnMouseMove

  • 最后,protectedOnMouseMove检查是否设置了事件处理程序(即std::function<void(Form *, int, int, ShiftState)>),如果是,它调用处理程序。否则它什么也不做。

我关心的是打电话DefWindowProc。看起来,它只是“为我做默认行为”,但有时它实际上做了一些关键的事情。例如,WM_LBTNDOWN通过不调用禁用DefWindowProc将导致无法通过单击 [X] 按钮关闭窗口。

另一方面,有时我不想打电话DefWindowProc。例如,如果WM_CLOSE来了,我可能决定不关闭应用程序。DefWindowProc在这种情况下调用DestroyWindow.

我的问题是:我应该打电话DefWindowProc还是不打电话?如果是这样,总是还是有时?

4

2 回答 2

16

在决定如何处理消息时,您有三个选择:

  • 不调用 DefWindowProc()。当您想要完全自定义处理消息的方式并且不想要默认实现时适用。WM_COMMAND 和 WM_PAINT 是典型的例子。

  • 做一些自定义的事情,然后调用 DefWindowProc()。当您喜欢或需要默认实现时适用。WM_CLOSE 就是一个典型的例子。

  • 首先调用 DefWindowProc(),然后根据需要更改结果。一个典型的例子是 WM_NCHITTEST

选择合适的选项没有黄金法则,它在很大程度上取决于特定的消息和窗口的特定默认处理。请注意,如果您对窗口进行子类化,这可能不是记录在案的默认处理。然而,弄错它通常很容易诊断。

于 2013-01-24T14:25:11.617 回答
2

看来,我只是通过提问来回答我的问题。我介绍了两个案例:

  • WM_LBTNDOWN何时DefWindowProc 必须调用 - 否则窗口将无法正常工作;
  • WM_CLOSE, when - 取决于事件处理程序 -DefWindowProc 不能被调用 - 否则它将破坏框架的逻辑。

答案是:这取决于消息的种类。我必须仔细阅读 DefWindowProc 在每种情况下如何工作并采取适当的行动。

于 2013-01-24T11:45:44.263 回答