问题描述
我想创建一个用于创建静态控件的类。问题是在子类化控件时,回调应该是静态的,这意味着我将无法访问回调中的非静态变量和函数。
我一直在努力使我的代码工作,但仍然没有成功。
MyClass.cpp
#include "MyClass.h"
MyClass::MyClass(){
non_static_variable = 0; //default is zero.
}
LRESULT CALLBACK MyClass::SubClassproc(HWND hwnd,UINT uMsg,WParaM wParam,LParaM lParam,UINT_PTR uIdSubclass,DWORD_PTR dwRefData) {
MyClass* pThis = reinterpret_cast<MyClass*>(dwRefData);
char buffer[5];
sprintf_s(buffer,"The value of non_static_variable is: %d \n",pThis->non_static_variable);
OutputDebugStringA(buffer);
switch (uMsg) {
case WM_PAINT: {
// do nothing for Now
return 0;
}
case WM_NCDESTROY: {
RemoveWindowSubclass(hwnd,SubClassproc,uIdSubclass);
break;
}
}
return DefSubclassproc(hwnd,uMsg,wParam,lParam);
}
void MyClass::CreateStaticControl(HWND WindowHandle) {
StaticControl = CreateWindowEx(0,L"STATIC",NULL,WS_CHILD | WS_VISIBLE | SS_OWNERDRAW,x,y,width,height,WindowHandle,this);
SetwindowSubclass(StaticControl,&SubClassproc,ID,reinterpret_cast<DWORD_PTR>(this));
}
void MyClass::SetValue(int value){
non_static_variable = value; //test if I can access this in callback
}
MyClass.h
#include "header.h"
public:
MyClass();
void CreateStaticControl(HWND window);
void SetValue(int value);
static LRESULT CALLBACK SubClassproc(HWND hWnd,UINT msg,DWORD_PTR dwRefData);
private:
int non_static_variable;
HWND StaticControl;
};
然后从我的主窗口过程调用 WM_CREATE
中的类,我是这样使用的。
...
case WM_CREATE:{
MyClass myClass;
myClass.CreateStaticControl(hwnd);
myClass.SetValue(888);
break;
}
你可能认为这是其他人的重复,我发现了很多,但由于这是关于子类化,我无权访问 WM_NCCREATE
我无法正确设置我的类的指针.有人可以帮我吗?
编辑:我输入了我拥有的确切代码。
解决方法
您可以使用 dwRefData
的 SetWindowSubclass()
参数将 this
指针传递给回调的 dwRefData
参数。然后,您可以对该参数进行类型转换以访问非静态成员。根本不需要使用 GWLP_USERDATA
(特别是因为您在设置 lParam
时没有正确使用回调的 GWLP_USERDATA
)。
试试这个:
MyClass.h
class MyClass {
public:
MyClass();
void CreateStaticControl(HWND window);
static LRESULT CALLBACK SubClassProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,UINT_PTR uIdSubclass,DWORD_PTR dwRefData);
private:
int non_static_variable;
HWND StaticControl;
};
MyClass.cpp:
void MyClass::CreateStaticControl(HWND WindowHandle) {
StaticControl = CreateWindowEx(0,L"STATIC",NULL,WS_CHILD | WS_VISIBLE | SS_OWNERDRAW,x,y,width,height,WindowHandle,this);
SetWindowSubclass(StaticControl,&SubClassProc,ID,reinterpret_cast<DWORD_PTR>(this));
}
LRESULT CALLBACK MyClass::SubClassProc(HWND hwnd,UINT uMsg,DWORD_PTR dwRefData) {
MyClass* pThis = reinterpret_cast<MyClass*>(dwRefData);
switch (uMsg) {
case WM_PAINT: {
// use pThis->non_static_variable as needed...
return 0;
}
case WM_NCDESTROY: {
RemoveWindowSubclass(hwnd,SubClassProc,uIdSubclass);
break;
}
}
return DefSubclassProc(hwnd,uMsg,wParam,lParam);
}