我目前正在编写自己的迷你可视化框架,以便将纯WinAPI包装在类中。
目前分析邮件的过程如下:
static Application::Run
有一个消息循环;它会收到新消息并将其发送给适当的WndProc。
我创建的所有窗口都是从同一个类(就WinAPI而言)创建的,因此调用了相同的WndProc
。实际上,它是一种静态FormAPI::WndProc
方法。这个检查消息所引用的窗口并调用其WndProc
。
Form::WndProc
方法,该方法分析消息。假设它是WM_MOUSEMOVE
。它会调用ProcessMouseMove
然后调用DefWindowProc
。请记住这一点[1]。
私人Form::ProcessMouseMove
从消息中获取实际数据(例如,x,y,班次状态),将其转换为可用数据并调用受保护的Form::OnMouseMove
。
最后,受保护的OnMouseMove
检查,是否设置了事件处理程序(即std::function<void(Form *, int, int, ShiftState)>
),如果是,则调用处理程序。否则它什么都不做。
我关注的是调用DefWindowProc
。看起来,它只是“为我做默认行为”,但有时它实际上做了一些关键的事情。例如,通过不调用WM_LBTNDOWN
来禁用DefWindowProc
将导致无法通过单击[X]按钮关闭窗口。
另一方面,有时我不想拨打DefWindowProc
。例如,如果WM_CLOSE
到来,我可能决定不关闭申请。在这种情况下,DefWindowProc
会调用DestroyWindow
。
我的问题是:我应该拨打DefWindowProc
吗?如果是这样,总是或只是有时候?
答案 0 :(得分:13)
在决定如何处理邮件时,您有三个选项:
不调用DefWindowProc()。适用于您希望完全自定义消息处理方式而不希望默认实现的情况。 WM_COMMAND和WM_PAINT是典型的例子。
做一些自定义的事情,然后调用DefWindowProc()。适合您喜欢或需要默认实现。 WM_CLOSE是一个典型的例子。
首先调用DefWindowProc(),然后根据需要更改结果。典型的例子是WM_NCHITTEST
选择适当的选择没有黄金法则,它在很大程度上取决于特定的消息和窗口的特定默认处理。请注意,如果您是窗口的子类,则这可能不是文档化的默认处理。然而,通常很容易诊断出错误。
答案 1 :(得分:1)
看来,我只是通过询问就回答了我的问题。我提出了两个案例:
WM_LBTNDOWN
当DefWindowProc
要调用时 - 否则窗口将无法正常工作; WM_CLOSE
,当 - 取决于事件处理程序 - DefWindowProc
不得被调用 - 否则它将破坏框架的逻辑。答案是:它取决于消息的种类。我必须仔细阅读,DefWindowProc如何在每种情况下都能正常工作并采取相应的行动。