C++ Winapi - 在类中包装子类的回调

问题描述

我想创建一个用于创建静态控件的类。问题是在子类化控件时,回调应该是静态的,这意味着我将无法访问回调中的非静态变量和函数

我一直在努力使我的代码工作,但仍然没有成功。

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 我无法正确设置我的类的指针.有人可以帮我吗?

编辑:我输入了我拥有的确切代码

解决方法

您可以使用 dwRefDataSetWindowSubclass() 参数将 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);
}