我一直在考虑使用 WinApi 为我的应用程序创建自定义控件,并且我制作了一个包含 CustomDialogProc
和 CreateWindowEx
以及 RegisterClass 的类()
函数。
我可以在 CustomDialogProc
中设置一个断点,它会命中,所以该类已正确注册。
但是,我必须将 CustomDialogProc 函数声明为我的类的 header static int
static LRESULT CALLBACK CustomDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam,LPARAM lParam);
如果我不将其设置为静态,则会出现错误
Error C3867 'CustomControl::CustomDialogProc': non-standard syntax; use '&' to create a pointer to member
这是必要的吗,这要求我在此控件中创建的所有控件也都是静态的。如果我想要此控件的多个实例怎么办?
我该如何解决这个问题?主要的 MsgProc 似乎不是静态函数。下面显示的第一个链接中的 UpDownDialogProc
也不是
下面是我的 CustomControl.h 代码,以备不时之需。 从以下位置找到的代码放在一起: https://msdn.microsoft.com/en-us/library/windows/desktop/hh298353(v=vs.85).aspx https://www.codeproject.com/Articles/485767/True-Windows-control-subclassing
谢谢,
#pragma once
#include <windows.h>
#include <commctrl.h>
#pragma comment(lib, "comctl32.lib")
class CustomControl
{
public:
CustomControl();
~CustomControl();
LRESULT CALLBACK CustomDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam,LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
//DO STUFF HERE
break;
}
}
bool CreateControl(HWND hwnd, HINSTANCE* m_hApp_instance)
{
g_hInst = m_hApp_instance;
RegisterSubClass(*g_hInst, WC_LISTBOX, TEXT("CustomControl"), CustomDialogProc);
HWND hwndCustom = CreateWindow(TEXT("CustomControl"), NULL, WS_CHILD | WS_VISIBLE,
0, 0, 0, 0, hwnd, (HMENU)100, *g_hInst, NULL);
return true;
}
private:
HINSTANCE* g_hInst;
WNDPROC RegisterSubClass(HINSTANCE hInstance, LPCTSTR ParentClass, LPCTSTR ChildClassName, WNDPROC ChildProc) {
WNDCLASSEX twoWayStruct;
WNDPROC parentWndProc;
if (GetClassInfoEx(NULL, ParentClass, &twoWayStruct)) {
parentWndProc = twoWayStruct.lpfnWndProc; // save the original message handler
twoWayStruct.cbSize = sizeof(WNDCLASSEX); // does not always get filled properly
twoWayStruct.hInstance = hInstance;
twoWayStruct.lpszClassName = ChildClassName;
twoWayStruct.lpfnWndProc = ChildProc;
/* Register the window class, and if it fails return 0 */
if (RegisterClassEx(&twoWayStruct))
return parentWndProc; // returns the parent class WndProc pointer;
// subclass MUST call it instead of DefWindowProc();
// if you do not save it, this function is wasted
}
return 0;
}
};
最佳答案
最常用的方法是使用SetWindowLongPtr
存储指向与窗口句柄关联的对象的指针。
HWND hWnd = CreateWindow(...);
SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR) this);
然后在您的对话过程中,获取该指针并调用您的类:
// this static method is registered with your window class
static LRESULT CALLBACK CustomDialogProcStatic(HWND hWnd, UINT uMsg, WPARAM wParam,LPARAM lParam)
{
auto pThis = (CustomControl*) GetWindowLongPtr(hWnd, GWLP_USERDATA);
if (pThis != NULL)
return pThis->CustomDialogProcInstance(hWnd, uMsg, wParam, lParam);
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
// this instance method is called by the static method
LRESULT CustomDialogProcInstance(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
...
}
确保适本地管理窗口和类的生命周期,以防止窗口过程调用已删除的对象实例。在许多情况下,这就像确保在您的类被破坏时调用 DestroyWindow
一样简单。
关于c++ - CustomDialogProc 必须是静态的吗? WinAPI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42167965/