为什么我的WndProc不能在课堂上? [英] Why can't my WndProc be in a class?

查看:172
本文介绍了为什么我的WndProc不能在课堂上?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这似乎应该很简单。我有我的类:

  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

/ code>成员函数,它消除了 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆