为什么我的WndProc不能在课堂上? [英] Why can't my WndProc be in a class?
问题描述
这似乎应该很简单。我有我的类:
class Simple
{
public:
LRESULT CALLBACK WndProc HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
...
}
};
和我的 WinMain
:
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR commandLine,int cmdShow)
{
Simple * simple = new简单();
...
wndClass.lpfnWndProc = simple-> WndProc;
...
}
/ p>
错误C2440:'=':无法从'LRESULT(__stdcall Simple :: *)(HWND,UINT,WPARAM,LPARAM )'到'WNDPROC'
有任何原因,我不能拥有我的 WndProc
在类中?
C ++将成员函数和自由函数视为不同的 - 成员函数需要访问a this
指针,通常作为隐藏的第一个参数传递。因此,n参数成员函数最类似于(n + 1) - 自由函数,这意味着试图调用 WndProc
的代码将在 WndProc
作为 static
this
指针。此代码应该工作: 类简单
{
public:
static LRESULT CALLBACK WndProc (HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
...
}
};
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR commandLine,int cmdShow)
{
Simple * simple = new Simple();
...
wndClass.lpfnWndProc = simple-> WndProc;
...
}
当然,这意味着你不能直接访问类的字段。你可以通过嵌入一个指向类的指针为每个窗口实例保留的额外字节,或许通过使用 SetWindowLongPtr
。一旦你这样做,你可以通过写这样的东西恢复接收器对象指针:
class Simple
{
public:
static LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
Simple * me = static_cast< Simple *>(GetWindowLongPtr hwnd,GWLP_USERDATA));
if(me)return me-> realWndProc(hwnd,msg,wParam,lParam);
return DefWindowProc(hwnd,msg,wParam,lParam);
}
private:
LRESULT CALLBACK realWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
// Yay!我是会员功能!
}
};
希望这有助于!
This seems like it should be pretty straightforward. I have my class:
class Simple
{
public:
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
...
}
};
and my WinMain
:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR commandLine, int cmdShow)
{
Simple *simple = new Simple();
...
wndClass.lpfnWndProc = simple->WndProc;
...
}
When I try though, I get:
error C2440: '=' :cannot convert from 'LRESULT (__stdcall Simple::* )(HWND,UINT,WPARAM,LPARAM)' to 'WNDPROC'
Is there any reason I can't have my WndProc
in a class? Seems like that would be really useful.
C++ treats member functions and free functions as different - member functions need to have access to a this
pointer, and typically that's passed in as a hidden first parameter. Consequently, an n-argument member function would be most similar to an (n+1)-argument free function, which means that code trying to call your WndProc
would pass in the wrong number of arguments.
You can, however, declare WndProc
as a static
member function, which eliminates the this
pointer. This code should work:
class Simple
{
public:
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
...
}
};
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR commandLine, int cmdShow)
{
Simple *simple = new Simple();
...
wndClass.lpfnWndProc = simple->WndProc;
...
}
Of course, this means you can't directly access the fields of the class. You could get around this by embedding a pointer to the class into the extra bytes reserved for each window instance, perhaps by using SetWindowLongPtr
. Once you've done that, you can recover the receiver object pointer by writing something like this:
class Simple
{
public:
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
Simple* me = static_cast<Simple*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
if (me) return me->realWndProc(hwnd, msg, wParam, lParam);
return DefWindowProc(hwnd, msg, wParam, lParam);
}
private:
LRESULT CALLBACK realWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
// Yay! I'm a member function!
}
};
Hope this helps!
这篇关于为什么我的WndProc不能在课堂上?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!