我正在尝试编写一个类来处理按钮的创建,并在内部处理它的消息。我希望保留类本身包含的所有代码。这可能很简单或不可能,因为我对Winapi和C ++相对较新,更广泛地使用了vb.net。我无法找到一个完成这个看似简单的转换的例子。我确实找到了建议我使用备用API的例子,或者使用SetWindowLongPtr,我被告知SetWindowSubclass是更好的选择。我的尝试代码如下:
#pragma once
#include <iostream>
#include <Windows.h>
#include <Commctrl.h>
using namespace std;
class button {
public:
bool initialize();
buttton(int x, int y, int length, int width, LPCWSTR text, HWND parent, HINSTANCE hInstance); // This is the constructor
private:
LPCWSTR text = L"Button";
int height = 25;
int width = 100;
int x = 0;
int y = 0;
HWND parent;
HWND thisHandle;
HINSTANCE thisInstance;
bool initialized = false;
LRESULT CALLBACK mySubClassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
};
button::button(int x, int y, int height, int width, LPCWSTR text, HWND parent, HINSTANCE hInstance) {
this->x = x;
this->y = y;
this->height = height;
this->width = width;
this->text = text;
this->parent = parent;
thisInstance = hInstance;
}
bool button::initialize()
{
thisHandle = CreateWindowW(
L"BUTTON", // Predefined class; Unicode assumed
text, // Button text
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON | WS_CLIPSIBLINGS | BS_NOTIFY, // Styles
x, // x position
y, // y position
width, // Button width
height, // Button height
parent, // Parent window
NULL, // No ID.
thisInstance,
NULL); // Pointer not needed.
if (!thisHandle)
{
return false;
}
initialized = true;
//Problem Code****
SetWindowSubclass(thisHandle, mySubClassProc, 1, 0);
//****
return true;
}
LRESULT CALLBACK button::mySubClassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) {
//Code handling messages here.
}
}
这会引发错误:
类型“LRESULT(__stdcall button :: *)(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam,UINT_PTR uIdSubclass,DWORD_PTR dwRefData)”的参数与“SUBCLASSPROC”类型的参数不兼容
我希望有人可以解释一个简单的解决方案,或者在Winapi中提出替代方案,因为我希望学习本机窗口和C ++而不依赖于其他库。
答案 0 :(得分:1)
您正在尝试使用非静态类方法作为子类回调。这不起作用,因为非静态类方法具有API无法传递的隐藏this
参数。
要执行您尝试的操作,您必须删除this
参数(您可以使用dwRefData
的{{1}}参数代替):
使用静态类方法:
SetWindowSubclass()
使用非会员功能:
class button {
public:
bool initialize();
...
private:
...
static LRESULT CALLBACK mySubClassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
};
bool button::initialize()
{
...
SetWindowSubclass(thisHandle, mySubClassProc, 1, (DWORD_PTR) this);
return true;
}
LRESULT CALLBACK button::mySubClassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
button *pThis = (button*) dwRefData;
//Code handling messages here.
}