c++ - CustomDialogProc 必须是静态的吗? WinAPI

标签 c++ winapi visual-studio-2015 com

我一直在考虑使用 WinApi 为我的应用程序创建自定义控件,并且我制作了一个包含 CustomDialogProcCreateWindowEx 以及 RegisterClass 的类() 函数。

我可以在 CustomDialogProc 中设置一个断点,它会命中,所以该类已正确注册。

但是,我必须将 CustomDialogProc 函数声明为我的类的 header static int

static LRESULT CALLBACK CustomDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam,LPARAM lParam);

如果我不将其设置为静态,则会出现错误

Error   C3867   'CustomControl::CustomDialogProc': non-standard syntax; use '&' to create a pointer to member   

这是必要的吗,这要求我在此控件中创建的所有控件也都是静态的。如果我想要此控件的多个实例怎么办? 我该如何解决这个问题?主要的 MsgProc 似乎不是静态函数。下面显示的第一个链接中的 UpDownDialogProc 也不是

下面是我的 CustomControl.h 代码,以备不时之需。 从以下位置找到的代码放在一起: https://msdn.microsoft.com/en-us/library/windows/desktop/hh298353(v=vs.85).aspx https://www.codeproject.com/Articles/485767/True-Windows-control-subclassing

谢谢,

#pragma once
#include <windows.h>

#include <commctrl.h>

#pragma comment(lib, "comctl32.lib")

class CustomControl
{
public:
    CustomControl();
    ~CustomControl();

    LRESULT CALLBACK CustomDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam,LPARAM lParam)
    {
        switch (message)
        {
            case WM_CREATE:
            //DO STUFF HERE
            break;
        }
    }

    bool CreateControl(HWND hwnd, HINSTANCE* m_hApp_instance)
    {
        g_hInst = m_hApp_instance;

        RegisterSubClass(*g_hInst, WC_LISTBOX, TEXT("CustomControl"), CustomDialogProc);

        HWND hwndCustom = CreateWindow(TEXT("CustomControl"), NULL, WS_CHILD | WS_VISIBLE,
        0, 0, 0, 0, hwnd, (HMENU)100, *g_hInst, NULL);

        return true;
    }

private:

    HINSTANCE* g_hInst;

    WNDPROC RegisterSubClass(HINSTANCE hInstance, LPCTSTR ParentClass, LPCTSTR ChildClassName, WNDPROC ChildProc) {
        WNDCLASSEX  twoWayStruct;
        WNDPROC     parentWndProc;

        if (GetClassInfoEx(NULL, ParentClass, &twoWayStruct)) {
            parentWndProc = twoWayStruct.lpfnWndProc; // save the original message handler 

            twoWayStruct.cbSize = sizeof(WNDCLASSEX); // does not always get filled properly
            twoWayStruct.hInstance = hInstance;
            twoWayStruct.lpszClassName = ChildClassName;
            twoWayStruct.lpfnWndProc = ChildProc;

            /* Register the window class, and if it fails return 0 */
            if (RegisterClassEx(&twoWayStruct))
                return parentWndProc; // returns the parent class WndProc pointer;
                                      // subclass MUST call it instead of DefWindowProc();
                                      // if you do not save it, this function is wasted
        }
        return 0;
    }
};

最佳答案

最常用的方法是使用SetWindowLongPtr存储指向与窗口句柄关联的对象的指针。

HWND hWnd = CreateWindow(...);
SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR) this);

然后在您的对话过程中,获取该指针并调用您的类:

// this static method is registered with your window class
static LRESULT CALLBACK CustomDialogProcStatic(HWND hWnd, UINT uMsg, WPARAM wParam,LPARAM lParam)
{
    auto pThis = (CustomControl*) GetWindowLongPtr(hWnd, GWLP_USERDATA);
    if (pThis != NULL)
        return pThis->CustomDialogProcInstance(hWnd, uMsg, wParam, lParam);
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

// this instance method is called by the static method
LRESULT CustomDialogProcInstance(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    ...
}

确保适本地管理窗口和类的生命周期,以防止窗口过程调用已删除的对象实例。在许多情况下,这就像确保在您的类被破坏时调用 DestroyWindow 一样简单。

关于c++ - CustomDialogProc 必须是静态的吗? WinAPI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42167965/

相关文章:

c++ - 不能使用 CV_32UC1

c++ - 在 C++ (Win32) 中解析 XML 的方法

c - Windows 7 中 C 的 API 和编译器,主要关注的是

c# - Visual Studio C# - 找不到 SQLite.Interop.dll

c++ - 未命名的命名空间与私有(private)变量

c++ - 具有可变参数模板的更多依赖类型

c++ - C中的&&&&操作是什么

api - 访问SysTreeView32的子节点

visual-studio-2015 - Visual Studio 2015 数据库项目目录包含扩展名为 jfm 的文件

dll - 如何检查 dll 是如何生成的?