1

我正在学习如何包装一些基本的 WinAPI 功能(如创建窗口)。我为窗口类和一个基本窗口编写了一个包装类。

在我的窗口过程的实现中,我一直密切关注此链接中描述的消息路由器:创建 Win32 窗口包装器

this这是将我的基本窗口类的指针传递给CreateWindowEx函数并将其附加到窗口的想法SetWindowLongPtr。消息路由器作为窗口过程传递给我创建的每个窗口类,它调用每个窗口具有的窗口过程作为私有函数。(消息路由器是我的基本窗口类的朋友)

我现在的主要问题是我应该如何处理我的窗口收到的消息。我不喜欢作者在上面的链接中使用的解决方案,因为如果我必须为要处理的每个窗口消息注册一个回调函数,我会觉得这很烦人。我还想在单独的控制器类而不是窗口类本身中处理这些消息。

在我看来,最佳解决方案是:

BasicWindow window("Window Class", program_instance);
window.create()

Controller controller;
window.setController(controller);

从那里开始,我希望窗口能够自行确定控制器为哪些消息提供回调。

我已经有了一些想法:

  1. 有一个控制器的抽象基类,它有各种回调函数的原型。但是这样,即使我不需要它们,我也必须在每个控制器中处理它们(例如,我不必在普通的编辑控件中处理 WM_PAINT。)所以这太死板了。

  2. 让每个控制器都有一个函数,它返回一个无符号整数的数组/向量,告诉窗口控制器处理哪些消息。这很烦人,因为每次我为控制器添加另一个消息的新回调函数时,我都不能忘记更新向量。这种方法的另一个缺点是,我必须将这个向量保存在BasicWindow类中,或者每次调用 windows 窗口过程时从控制器请求它,并且我必须搜索向量是否包含窗口接收到的消息。

  3. 我最近的想法是某种预处理。由于我不考虑在运行时更改窗口的控制器,我认为这可能是预处理甚至元编程有用的情况。我只阅读了几篇关于元编程的文章,并没有太多的线索,但我认为这可能是一个合适的解决方案。我想到的是以下内容:

    • 在我的控制器中,我想为我的回调函数添加某种限定符。类似的东西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;
}

我的主要问题是我不知道是否和/或如何做到这一点。也许我可以进一步澄清我的问题。

4

0 回答 0