当我离开课程时,WNDPROC DefEditProc;
和EditKeyProc
一切正常。但是现在当我粘贴代码时,它无法编译错误error: invalid use of member function (did you forget the '()' ?)
。所以我的问题是如何将这些代码压缩到类中,这样我就不会污染全局命名空间了?
#include <windows.h>
#include <richedit.h>
class richEdit {
HWND richeditWindow;
WNDPROC DefEditProc;
public:
LRESULT EditKeyProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
return CallWindowProc(DefEditProc, hwnd, uMsg, wParam, lParam);
}
richEdit() {
HMODULE richedit_library = LoadLibrary("Msftedit.dll");
if (NULL == richedit_library) abort();
HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(0);
richeditWindow = CreateWindowExW (
WS_EX_TOPMOST,
MSFTEDIT_CLASS,
L"window text",
WS_OVERLAPPED | WS_SYSMENU | ES_MULTILINE | WS_VISIBLE,
0, 0, 500, 500,
NULL, NULL, hInstance, NULL
);
DefEditProc = (WNDPROC)SetWindowLong(richeditWindow, GWL_WNDPROC, (long)EditKeyProc);
}
~richEdit() {
MSG msg;
while( GetMessageW( &msg, richeditWindow, 0, 0 ) ) {
TranslateMessage( &msg );
DispatchMessageW( &msg );
}
}
};
int main() {
richEdit re;
}
答案 0 :(得分:4)
您应该使用自由函数而不是成员函数,因为成员函数具有隐式this
参数。您必须将EditKeyProc
声明为static CALLBACK
,并在需要时找到另一种传递this
指针的方法。
static LRESULT CALLBACK EditKeyProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
:::
}
此外,您可以使用SetWindowSubclass
来处理正确的子类,并为您保留额外的指针参数。
答案 1 :(得分:3)
试试这个:
#include <windows.h>
#include <richedit.h>
class richEdit
{
private:
HWND richeditWindow;
WNDPROC DefEditProc;
static LRESULT CALLBACK EditKeyProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
richEdit *pThis = (richEdit*) GetWindowLongPtr(hwnd, GWL_USERDATA);
return CallWindowProc(pThis->DefEditProc, hwnd, uMsg, wParam, lParam);
}
public:
richEdit()
: richeditWindow(NULL), DefEditProc(NULL)
{
HMODULE richedit_library = LoadLibrary("Msftedit.dll");
if (NULL == richedit_library) abort();
HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(0);
richeditWindow = CreateWindowExW (
WS_EX_TOPMOST,
MSFTEDIT_CLASS,
L"window text",
WS_OVERLAPPED | WS_SYSMENU | ES_MULTILINE | WS_VISIBLE,
0, 0, 500, 500,
NULL, NULL, hInstance, NULL
);
if (NULL == richeditWindow) abort();
SetWindowLongPtr(richeditWindow, GWL_USERDATA, (LONG_PTR)this);
DefEditProc = (WNDPROC) SetWindowLongPtr(richeditWindow, GWL_WNDPROC, (LONG_PTR)&EditKeyProc);
}
~richEdit()
{
if (richeditWindow != NULL)
{
SetWindowLongPtr(richeditWindow, GWL_WNDPROC, (LONG_PTR)DefEditProc);
DestroyWindow(richeditWindow);
}
}
};
或者:
#include <windows.h>
#include <richedit.h>
namespace myNS
{
LRESULT CALLBACK richEditKeyProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
class richEdit
{
private:
HWND richeditWindow;
WNDPROC DefEditProc;
public:
richEdit()
: richeditWindow(NULL), DefEditProc(NULL)
{
HMODULE richedit_library = LoadLibrary("Msftedit.dll");
if (NULL == richedit_library) abort();
HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(0);
richeditWindow = CreateWindowExW (
WS_EX_TOPMOST,
MSFTEDIT_CLASS,
L"window text",
WS_OVERLAPPED | WS_SYSMENU | ES_MULTILINE | WS_VISIBLE,
0, 0, 500, 500,
NULL, NULL, hInstance, NULL
);
if (NULL == richeditWindow) abort();
SetWindowLongPtr(richeditWindow, GWL_USERDATA, (LONG_PTR)this);
DefEditProc = (WNDPROC) SetWindowLongPtr(richeditWindow, GWL_WNDPROC, (LONG_PTR)&richEditKeyProc);
}
~richEdit()
{
if (richeditWindow != NULL)
{
SetWindowLongPtr(richeditWindow, GWL_WNDPROC, (LONG_PTR)DefEditProc);
DestroyWindow(richeditWindow);
}
}
};
LRESULT CALLBACK richEditKeyProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
richEdit *pThis = (richEdit*) GetWindowLongPtr(hwnd, GWL_USERDATA);
return CallWindowProc(pThis->DefEditProc, hwnd, uMsg, wParam, lParam);
}
}
答案 2 :(得分:0)
您不能将指向成员函数的指针用作窗口过程,因为Windows需要常规函数指针。在内部,在某些情况下,它不会有足够的存储空间用于成员指针(它们在MSVC中最多可以是16个字节,32位),并且在任何情况下它都不会知道要使用什么“this”指针。 / p>
如果您唯一的兴趣是避免命名空间污染,那么最简单的解决方案是使用命名空间而不是类。否则,您必须使EditKeyProc成为该类的静态成员,并使用SetWindowLong存储“this”指针的副本,以供EditKeyProc访问。