2014-09-05 24 views
2

我試圖通過將其放入類中來清除一些現有的win32 UI代碼。以前我有一個AppDlgProc功能是這樣的:調用win32 API並給予類功能回調

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

這在我以前像這樣:

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

現在我把所有這一切在SettingsWindow對象,我叫settingsWindow->顯示()這揭開了這個:

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) { ... } 
+3

Raymond Chen寫道:[我如何使回調函數成爲我的C++類的成員?](http://blogs.msdn.com/b/oldnewthing/archive/2014/ 01/27/10492898.aspx) – 2014-09-05 05:07:52

+0

調用約定不匹配,你不能只將一個非靜態成員函數傳遞給一個需要'CALLBACK'函數的函數。 – user657267 2014-09-05 05:08:37

回答

7

窗口和對話框的程序(和其他Win32回調函數)必須是靜態或全局函數 - 它們不能是非靜態類功能。 Win32基本上是一個基於C的API,它沒有關於類函數需要的隱藏指針的概念。

執行此操作的正常方法是將該函數聲明爲靜態,並在窗口屬性中存儲指向該類實例的指針。例如,

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); 
+1

謝謝,完美的作品。但我有個問題; if/else語句的目的是什麼? – Crummy 2014-09-05 05:33:33

+3

'SetProp'文檔說你必須在窗口被銷燬之前移除窗口屬性 - 大概是爲了避免內存泄漏,儘管我不知道這是否是實際情況。無論如何,最好的做法是自己整理一下。 – 2014-09-05 05:37:55