为什么我的WndProc不能上课?

问题描述 投票:12回答:3

这似乎应该很简单。我上了课:

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 Simple();
    ...

    wndClass.lpfnWndProc = simple->WndProc;
    ...
 }

当我尝试时,我得到:

error C2440: '=' :cannot convert from 'LRESULT (__stdcall Simple::* )(HWND,UINT,WPARAM,LPARAM)' to 'WNDPROC'

有什么理由不能让我的WndProc上课吗?似乎这样真的很有用。

c++ winapi
3个回答
27
投票

C ++将成员函数和自由函数区别对待-成员函数需要访问this指针,通常将其作为隐藏的第一个参数传递。因此,n参数成员函数与(n + 1)无参数函数最相似,这意味着试图调用WndProc的代码将传递错误数量的参数。

但是,您可以将WndProc声明为static成员函数,从而消除了this指针。此代码应工作:

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;
    ...
 }

当然,这意味着您不能直接访问该类的字段。您可以通过将指向类的指针嵌入到为每个窗口实例保留的额外字节中来解决此问题,也许可以使用SetWindowLongPtr。完成此操作后,您可以通过编写如下代码来恢复接收器对象指针:

SetWindowLongPtr

希望这会有所帮助!


1
投票

指向成员函数的指针具有隐式的第一参数class Simple { public: static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { Simple* me = reinterpret_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! } }; ,因此具有与“自由”函数的指针不同的签名。参见this



0
投票

这不是答案,而是对已接受答案的一种抱怨!

这不起作用!

// Header  
class Foo   
{  
public:
  Foo();   

  ~Foo();  

  static LRESULT CALLBACK WinProc(HWND, UINT, WPARAM, LPARAM);

private:
  LRESULT CALLBACK MyWinProc(HWND, UINT, WPARAM, LPARAM);

  static Foo *m_pInstance;
}

// Implementation

#include "Foo.h"

Foo * Foo::m_pInstance = NULL;

Foo::Foo()
{  
  m_pInstance = this;   
}  

Foo::~Foo()
{
}

LRESULT CALLBACK Foo::WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)  
{  
  return m_pInstance->MyWinProc(hWnd, message, wParam, lParam);  
}  

LRESULT CALLBACK Foo::MyWinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)  
{  
  return DefWindowProc(hWnd, message, wParam, lParam);  
}  

使用此“简单”示例,static_cast生成C2440:static_cast:无法从“ LONG”转换为“ Simple *”。

我正在VS 2019上使用C ++。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.