我正在学习如何包装一些基本的 WinAPI 功能(如创建窗口)。我为窗口类和一个基本窗口编写了一个包装类。
在我的窗口过程的实现中,我一直密切关注此链接中描述的消息路由器:创建 Win32 窗口包装器。
this
这是将我的基本窗口类的指针传递给CreateWindowEx
函数并将其附加到窗口的想法SetWindowLongPtr
。消息路由器作为窗口过程传递给我创建的每个窗口类,它调用每个窗口具有的窗口过程作为私有函数。(消息路由器是我的基本窗口类的朋友)
我现在的主要问题是我应该如何处理我的窗口收到的消息。我不喜欢作者在上面的链接中使用的解决方案,因为如果我必须为要处理的每个窗口消息注册一个回调函数,我会觉得这很烦人。我还想在单独的控制器类而不是窗口类本身中处理这些消息。
在我看来,最佳解决方案是:
BasicWindow window("Window Class", program_instance);
window.create()
Controller controller;
window.setController(controller);
从那里开始,我希望窗口能够自行确定控制器为哪些消息提供回调。
我已经有了一些想法:
有一个控制器的抽象基类,它有各种回调函数的原型。但是这样,即使我不需要它们,我也必须在每个控制器中处理它们(例如,我不必在普通的编辑控件中处理 WM_PAINT。)所以这太死板了。
让每个控制器都有一个函数,它返回一个无符号整数的数组/向量,告诉窗口控制器处理哪些消息。这很烦人,因为每次我为控制器添加另一个消息的新回调函数时,我都不能忘记更新向量。这种方法的另一个缺点是,我必须将这个向量保存在
BasicWindow
类中,或者每次调用 windows 窗口过程时从控制器请求它,并且我必须搜索向量是否包含窗口接收到的消息。我最近的想法是某种预处理。由于我不考虑在运行时更改窗口的控制器,我认为这可能是预处理甚至元编程有用的情况。我只阅读了几篇关于元编程的文章,并没有太多的线索,但我认为这可能是一个合适的解决方案。我想到的是以下内容:
- 在我的控制器中,我想为我的回调函数添加某种限定符。类似的东西
void paint() <WM_PAINT>;
- 然后我希望编译器在 Windows 窗口过程中生成一个 if 语句,该语句在
paint
收到 WM_PAINT 消息时调用该函数。这将节省我对向量/数组的运行时检查,并使其非常轻松且仍然可以灵活地编写我的控制器。
- 在我的控制器中,我想为我的回调函数添加某种限定符。类似的东西
就我个人而言,我会喜欢我在 3 中描述的方式。不幸的是,正如我之前提到的,我的元编程技能几乎不存在。我希望你们中的一些人能把我推向正确的方向。
[编辑] 睡个好觉后,我也许可以更好地解释我在寻找什么。
我有一个Controller
在编译时完全知道的类。它应该看起来像这样:
class Controller {
public:
Controller(DeviceContext& device_context);
~Controller();
// If WM_PAINT is received by the window it is supposed to call
void paint();
// WM_RESIZE
void resize(LPARAM lParam);
...
private:
// class members needed during the performance of the callback functions
...
};
在我的BasicWindow
课堂上,我有一个由消息路由器调用的窗口过程,如上所述。它看起来有点像:
LRESULT CALLBACK BasicWindow::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// Here I want the magic to happen. I want the compiler to somehow figure out
// which messages are handled by the controller and generate code like
if (message == WM_PAINT)
controller->paint();
return 0;
}
我的主要问题是我不知道是否和/或如何做到这一点。也许我可以进一步澄清我的问题。