调用win32 API并给类函数提供回调

时间:2014-09-05 05:03:50

标签: c++ winapi

我正在尝试将一些现有的win32 UI代码放入一个类中来清理它。以前我有这样的AppDlgProc函数:

BOOL CALLBACK AppDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { ... }

我使用的是这样的:

DialogBoxParam(hInstance, (LPCTSTR)IDD_SETTINGS, 0, AppDlgProc, 0);

现在我将所有这些放在一个SettingsWindow对象中,然后调用settingsWindow-> show()来启动它:

void SettingsWindow::show(HINSTANCE hInstance) {
     DialogBoxParam(hInstance, (LPCTSTR)IDD_SETTINGS, 0, &SettingsWindow::AppDlgProc, 0);
}

我很确定我在这里错误地给出了回调方法。 Visual Studio告诉我“Intellisense:类型的参数......与DLGPROC类型的参数不兼容”。谷歌似乎告诉我似乎告诉我I need another argument - 没有别的办法吗?

作为参考,我的AppDlgProc功能现在看起来像这样:

BOOL CALLBACK SettingsWindow::AppDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {  ... }

1 个答案:

答案 0 :(得分:8)

窗口和对话框程序(以及其他Win32回调函数)需要是静态或全局函数 - 它们不能是非静态类函数。 Win32基本上是一个基于C的API,它没有类函数所需的隐藏this指针的概念。

执行此操作的常规方法是将函数声明为static,并在window属性中存储指向类实例的指针。例如,

struct SettingsWindow
{
    // static wrapper that manages the "this" pointer
    static INT_PTR CALLBACK AppDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        if (uMsg == WM_INITDIALOG)
            SetProp(hWnd, L"my_class_data", (HANDLE)lParam);
        else
        if (uMsg == WM_NCDESTROY)
            RemoveProp(hWnd, L"my_class_data");

        SettingsWindow* pThis = (SettingsWindow*)GetProp(hWnd, L"my_class_data");
        return pThis ? pThis->AppDlgFunc(hWnd, uMsg, wParam, lParam) : FALSE;
    }

    INT_PTR AppDlgFunc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        // the real dialog procedure goes in here
    }
};


// to show the dialog - pass "this" as the dialog parameter
DialogBoxParam(hInstance, (LPCTSTR)IDD_SETTINGS, 0, SettingsWindow::AppDlgProc,
    (LPARAM)this);