朋友们,我正在尝试实现Windows API的包装,我想从父窗口捕获子窗口事件,所以我创建了一个简单的事件处理程序。我使用函数指针来存储回调函数。我用静态函数做了。请参阅下面的代码。
class Widget;
typedef void (*EventProc)(MSG* EventArgs);
class Widget
{
public:
/// Constructors destructor and methods for Registering and Creating Windows
static LRESULT CALLBACK MainProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
MSG struct_msg;
struct_msg.hWnd=hWnd;
struct_msg.message=msg;
struct_msg.wParam=wParam;
struct_msg.lParam=lParam;
Widget* wid=(Widget*)GetWidgetPointerFromHWND(hWnd);
switch(msg)
{
case WM_CREATE:
if(Created!=NULL)
(*(wid->Created))(&struct_msg);break;
case WM_DESTROY:
if(Destroyed!=NULL)
(*(wid->Destroyed))(&struct_msg);break;
default:
return DefWindowProc(hWnd,msg,wParam,lParam);
}
return 0;
}
EventProc Created;
EventProc Destroyed;
};
class CustomControl: public Widget
{
/// Constructor destructor and other methods
};
class Window: public Widget
{
public:
static void ChildCreated(Widget* Sender,Widget* Self,MSG* EventArgs)
{
MessageBox(0,0,0,0);
}
Window()
{
control1=new CustomControl(100,100,200,200); //left,top,width,height
this->AddChild(control1);
control1->Created = ChildCreated;
}
private:
CustomControl control1;
};
这样可行,但由于静态函数没有这个指针,我无法访问类窗口中的变量和成员函数。 我想将一个成员函数作为回调函数(Event Handler)。 我希望你明白我想要解决的问题。请帮帮我。
答案 0 :(得分:1)
您在此示例中展示的主要想法是正确的。
您制作了一些static
WndProc
函数和映射,将HWND
映射到您的类。
创建窗口小部件的新实例时,将其添加到映射中。在销毁时,您将其从映射中删除。
在你的WndProc函数中,你从映射中获取你的类的实例并调用该实例的虚拟事件处理函数:
class WidgetBase
{
public:
WidgetBase()
{
_handle = CreateWindow(/*...*/, &WidgetBase::MainProc, /*...*/);
_widgets.insert(std::make_pair(handle, this);
}
virtual ~WidgetsBase()
{
_widgets.remove(handle);
}
protected:
HWND _handle;
virtual LRESULT handleEvents(UINT msg,WPARAM wParam,LPARAM lParam)
{
return DefWindowProc(_handle, hWnd,msg,wParam,lParam);
}
private:
static std::map<HWND, WidgetBase*> _widgets;
static WidgetBase* GetWidgetPointerFromHWND(HWND handle)
{
// some error handling should be put there
return _widgets[handle];
}
static LRESULT CALLBACK MainProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
WidgetBase* wid=GetWidgetPointerFromHWND(hWnd);
if (wid) {
return wid->handleEvents(msg, wParam, lParam);
}
else {
return DefWindowProc(hWnd,msg,wParam,lParam);
}
}
};
std::map<HWND, WidgetBase*> WidgetBase::_widgets;
然后在派生类中,您只需覆盖handleEvents
函数:
class Derived: public WidgetBase
{
protected:
virtual LRESULT handleEvents(UINT msg,WPARAM wParam,LPARAM lParam)
{
// This is your event handler, that is memeber function
//...
return WidgetBase::handleEvents(msg, wParam, lParam);
}
};