在 WndProc 消息中声明和初始化的智能指针对象的生命周期 (WM_CREATE)

Lifespan of smart pointer objects declared and initialized inside WndProc message (WM_CREATE)

如果我在主 window 回调函数中声明并初始化对象,如下所示:

LRESULT CALLBACK WndProc
(
      HWND hWnd // handle to window of this process
    , UINT msg // message constant
    , WPARAM wParam // holder of message parameters
    , LPARAM lParam // holder of message parameters
)
{
    switch (msg)
    {
        case WM_CREATE:
        {
            std::unique_ptr<Foo> foo = std::unique_ptr<Foo>(new Foo);
        }
        break;
    }
}

对象 foo 会在 WM_CREATE 消息的 break 之后保持初始化状态吗?如果不是,那么最好在哪里声明它,以便它的范围不受case范围的限制?

顺便说一下,foo 对象正在主 window 中创建控件,所以我认为要求是让它一直存在到运行时结束。

我怀疑它活不下去了。我正在考虑将它们声明为全局变量(但出于显而易见的原因我不喜欢该选项)或声明为回调函数中的静态对象(但在 switch 之外)。但是我可能没有看到更好的选择,所以我正在寻求您的建议。

感谢您的帮助!

这是 RbMm 建议的处理,我自己在自己的代码中使用了它。智能指针在这里提供的东西很少,所以使用它真的没有多大意义。请注意,为简洁起见,我使用了 C 风格的转换,但如果您愿意,也可以使用 reinterpret_cast

class MyWindowData { ... };

MyWindowData *window_data = new MyWindowData;
HWND hWnd = CreateWindow (... ... ..., (LPARAM) window_data);

LRESULT CALLBACK WndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        case WM_NCCREATE:
            CREATESTRUCT *cs = (CREATESTRUCT *) lParam;
            SetWindowLongPtr (hWnd, GWLP_USERDATA, cs->lpCreateParams);
            break;

        case NC_DESTROY:
            MyWindowData *window_data = (MyWindowData *) GetWindowLongPtr (hWnd, GWLP_USERDATA);
            SetWindowLongPtr (hWnd, GWLP_USERDATA, 0);
            delete window_data;
            break;
    }

    // return something here;
}

然后你可以这样做:

MyWindowData *window_data = (MyWindowData *) GetWindowLongPtr (hWnd, GWLP_USERDATA);

在您需要时随时检索 MyWindowData,但检查是否返回零,以防 WM_NCCREATE 不是您的 WNDPROC 根据评论收到的第一条消息。