我正在尝试将一些现有的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) { ... }
答案 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);