【发布时间】:2021-03-24 15:13:42
【问题描述】:
我想创建一个用于创建静态控件的类。问题是当子类化控件时,回调应该是静态的,这意味着我将无法访问回调中的非静态变量和函数。
我一直在努力使我的代码正常工作,但仍然没有成功。
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, NULL, NULL, 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, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, 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 我无法正确设置我的类的指针。谁能帮帮我?
编辑:我输入了我拥有的确切代码。
【问题讨论】:
-
@RemyLebeau -我试过
MyClass* pThis = reinterpret_cast<MyClass*>(dwRefData);,它给了我read access violation, pThis was nullptr的错误。 -
那是因为你在调用
SetWindowSubclass时传递了0 作为dwRefData。你可能打算通过(DWORD_PTR)this。 -
@RaymondChen - 我尝试
SetWindowSubclass(StaticControl, &SubClassProc, ID, (DWORD_PTR)this);然后转换MyClass* pThis = reinterpret_cast<MyClass*>(dwRefData);,代码运行,但是,我无法获得非静态变量的值。 -
将
MyClass myClass;的声明移到WM_CREATE之外将解决问题。尝试使其成为全球性的。MyClass myClass; CALLBACK YouMainWndProc(...){...case WM_CREATE:{...myClass.SetValue(888);}}
标签: c++ winapi visual-studio-2019 subclassing