基于這篇文章,我正在嘗試創建一個簡單的 Win32 應用程式,其中對話框視窗的視窗程序/回呼函式是一個類的成員函式。我的代碼如下所示:
H檔案:
class MyClass
{
public:
HINSTANCE hInstance;
HWND hWnd;
int APIENTRY WinMainProc(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);
static LRESULT CALLBACK WinProcWraper(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
LRESULT CALLBACK WinProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
ATOM MyClassRegisterClass(HINSTANCE hInstance);
};
CPP檔案:
LRESULT CALLBACK MyClass::WinProcWraper(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
if (WM_NCCREATE == message)
{
SetWindowLong (hWnd, GWL_USERDATA, (long)((CREATESTRUCT*) lParam)->lpCreateParams);
return TRUE;
}
return ((MyClass*) GetWindowLong (hWnd, GWL_USERDATA))->WinProc (hWnd, message, wParam, lParam);
}
int APIENTRY MyClass::WinMainProc(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
MyClass.hInstance=hInstance;
MyClass.MyClassRegisterClass(hInstance);
//MY PROBLEM IS HERE: cannot convert parameter 4 to int
HWND hWnd = CreateDialog(hInstance,MAKEINTRESOURCE(IDD_MAIN_DIALOG), 0, (DLGPROC)MyClass::WinProc);
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
while (GetMessage(&msg, NULL, 0, 0))
{
if (!IsWindow(hWnd) || !IsDialogMessage(hWnd,&msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return static_cast<int>(msg.wParam);
}
LRESULT CALLBACK MyClass::WinProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
(...)
}
呼叫時CreateDialog(),我收到以下錯誤:
cannot convert from 'long (__stdcall MyClass::*)(struct HWND__ *,unsigned int,unsigned int,long)'
to 'long (__stdcall *)(struct HWND__ *,unsigned int,unsigned int,long)'
在這種情況下如何進行正確的型別轉換?
uj5u.com熱心網友回復:
讓我們從錯誤訊息開始。您正在嘗試使用非靜態類方法WinProc(), 作為您的CreateDialog()回呼。那不管用。您遇到了呼叫的static類方法的麻煩,但實際上并沒有使用它。您需要使用作為實際的視窗程序。WinProcWraper()WinProc()WinProcWraper()CreateDialog()
此外,如果它的簽名一開始是正確的(你的不是),則WinProcWraper在將其傳遞給 時無需進行型別轉換CreateDialog()。
修復后,您仍然有其他問題:
您正在建模的其他代碼是為 的視窗程序設計的
CreateWindow/Ex(),但您正在使用CreateDialog()它,它有不同的要求。由于您使用的是
CreateDialog()代替CreateWindow/Ex(),WinProcWraper()并且WinProc()需要回傳一個BOOL而不是一個LRESULT。如果LRESULT需要將實際值回傳給系統,WinProc()則需要SetWindowLong(DWL_MSGRESULT)為此目的使用。WinProcWraper()期望收到一條WM_NCCREATE訊息以向其傳遞一個MyClass*指標,然后將其分配給HWND. 但是,由于您使用的是CreateDialog(),WinProcWraper()不會收到任何WM_(NC)CREATE訊息,而是會收到一條WM_INITDIALOG訊息。即使這樣,CreateDialog()也不允許您將任何用戶定義的值傳遞給視窗程序,因此您無法傳入需要的MyClass*指標WinProcWraper()。你需要用它CreateDialogParam()來代替。WM_INITDIALOG可能不是視窗收到的第一條訊息,只是可以讓您訪問MyClass*傳遞給的指標的第一條訊息CreateDialogParam()。WinProcWraper()需要在它獲得對MyClass*指標的訪問權之前處理它可以接收訊息的可能性。您正在使用
SetWindowLong(). 如果您的代碼曾經被編譯為 64 位,那么您的代碼將無法作業。使用SetWindowLongPtr()替代,即使是32位的代碼。
話雖如此,試試這個:
class MyClass
{
public:
HINSTANCE hInstance;
HWND hWnd;
int APIENTRY WinMainProc(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);
BOOL CALLBACK WinProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
ATOM MyClassRegisterClass(HINSTANCE hInstance);
private:
static BOOL CALLBACK WinProcWraper(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
};
BOOL CALLBACK MyClass::WinProcWraper(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
MyClass *cls;
if (WM_INITDIALOG == uMsg)
{
cls = reinterpret_cast<MyClass*>(lParam);
SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(cls));
}
else
cls = reinterpret_cast<MyClass*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
if (cls)
return cls->WinProc(uMsg, wParam, lParam);
return FALSE;
}
int APIENTRY MyClass::WinMainProc(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
MyClass.hInstance = hInstance;
MyClass.MyClassRegisterClass(hInstance);
HWND hWnd = CreateDialogParam(hInstance, MAKEINTRESOURCE(IDD_MAIN_DIALOG), NULL, MyClass::WinProcWraper, reinterpret_cast<LPARAM>(this));
if (!hWnd)
return -1;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
while (GetMessage(&msg, NULL, 0, 0))
{
if (!IsWindow(hWnd) || !IsDialogMessage(hWnd, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return static_cast<int>(msg.wParam);
}
BOOL CALLBACK MyClass::WinProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
...
if (needed)
SetWindowLongPtr(hWnd, DWLP_MSGRESULT, ...);
return ...; // TRUE or FALSE as needed...
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/314746.html
上一篇:確定MFT是GPU還是CPU?
