C++ Winapi - 在 class 中结束 subclass 的回调
C++ Winapi - wrapping up a callback of subclass in a class
我想创建一个 class 用于创建静态控件。问题是当 subclassing 控件时,回调应该是静态的,这意味着我将无法访问回调内的非静态变量和函数。
我一直在努力使我的代码工作,但仍然没有成功。
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;
};
然后从我的 window 主程序调用 WM_CREATE
中的 class,我是这样使用的。
...
case WM_CREATE:{
MyClass myClass;
myClass.CreateStaticControl(hwnd);
myClass.SetValue(888);
break;
}
您可能认为这是与其他人的重复,我发现了很多,但由于这是关于 subclassing 的,而且我无权访问 WM_NCCREATE
我可以'没有正确设置我的 class 的指针。谁能帮帮我?
编辑: 我输入了我的确切代码。
您可以使用SetWindowSubclass()
的dwRefData
参数将this
指针传递给回调的dwRefData
参数。然后您可以对该参数进行类型转换以访问非静态成员。根本不需要使用 GWLP_USERDATA
(特别是因为您在设置 GWLP_USERDATA
时没有正确使用回调的 lParam
)。
试试这个:
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, NULL, NULL, this);
SetWindowSubclass(StaticControl, &SubClassProc, ID, reinterpret_cast<DWORD_PTR>(this));
}
LRESULT CALLBACK MyClass::SubClassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, 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);
}
我想创建一个 class 用于创建静态控件。问题是当 subclassing 控件时,回调应该是静态的,这意味着我将无法访问回调内的非静态变量和函数。
我一直在努力使我的代码工作,但仍然没有成功。
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;
};
然后从我的 window 主程序调用 WM_CREATE
中的 class,我是这样使用的。
...
case WM_CREATE:{
MyClass myClass;
myClass.CreateStaticControl(hwnd);
myClass.SetValue(888);
break;
}
您可能认为这是与其他人的重复,我发现了很多,但由于这是关于 subclassing 的,而且我无权访问 WM_NCCREATE
我可以'没有正确设置我的 class 的指针。谁能帮帮我?
编辑: 我输入了我的确切代码。
您可以使用SetWindowSubclass()
的dwRefData
参数将this
指针传递给回调的dwRefData
参数。然后您可以对该参数进行类型转换以访问非静态成员。根本不需要使用 GWLP_USERDATA
(特别是因为您在设置 GWLP_USERDATA
时没有正确使用回调的 lParam
)。
试试这个:
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, NULL, NULL, this);
SetWindowSubclass(StaticControl, &SubClassProc, ID, reinterpret_cast<DWORD_PTR>(this));
}
LRESULT CALLBACK MyClass::SubClassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, 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);
}