我正在学习如何包装一些基本的WinAPI功能(如窗口创建)。我为窗口类编写了一个包装类,为基本窗口编写了一个包装类。
在我的窗口过程的实现中,我一直密切关注此链接中描述的消息路由器:Creating a Win32 Window Wrapper。
将基本窗口类的this
指针传递给CreateWindowEx
函数并使用SetWindowLongPtr
将其附加到窗口的想法。消息路由器作为窗口过程传递给我创建的每个窗口类,它调用每个窗口作为私有函数的窗口过程。 (消息路由器是我的基本窗口类的朋友)
我现在的主要问题是如何处理我的窗口获取的消息。我不喜欢作者在上面的链接中使用的解决方案,因为如果我必须为我想要处理的每个窗口消息注册一个回调函数,我发现它很烦人。我还想在separete控制器类中处理这些消息,而不是窗口类本身。
在我的脑海中,最佳解决方案是:
BasicWindow window("Window Class", program_instance);
window.create()
Controller controller;
window.setController(controller);
从那时起我会喜欢这个窗口自己弄清楚控制器提供回调的消息。
我已经有了一些想法:
为控制器提供一个抽象基类,该控制器具有各种回调函数的原型。但是这样我就不得不在每个控制器中处理它们,即使我不需要它们(例如,我不需要在普通的编辑控件中处理WM_PAINT。)所以这太严格了。
让每个控制器都有一个函数,它返回一个无符号整数的数组/向量,告诉窗口控制器处理哪些消息。这很烦人,因为每次我向控制器添加另一条消息的新回调函数时,我都不能忘记更新向量。这种方法的另一个缺点是我要么必须在BasicWindow
类中保存这个向量,要么每次调用windows窗口过程时都要从控制器请求它,我必须搜索向量是否包含消息收到的窗口。
我最近的想法是某种预处理。由于我不打算在运行时更改窗口的控制器,我认为这可能是预处理甚至元编程可能有用的情况。我只阅读了一些关于元编程的文章,并没有太多关于它的线索,但我认为它可能是一个合适的解决方案。我想到的是以下内容:
void paint() <WM_PAINT>;
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;
}
我的主要问题是我不知道是否和/或如何做到这一点。也许我可以进一步澄清我的问题。