【发布时间】:2017-02-10 20:16:53
【问题描述】:
我一直在寻找使用 WinApi 为我的应用程序创建自定义控件,并且我创建了一个包含 CustomDialogProc 和 CreateWindowEx 和 RegisterClass() 函数的类。
我可以在CustomDialogProc 中设置一个断点,它会命中,所以类注册正确。
但是,我必须将 CustomDialogProc 函数声明为我的类的静态标题
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;
}
};
【问题讨论】:
-
DialogProcs(和类似的回调)不能是非静态成员函数,因为它们需要传递给 C API,而 C API 不理解这些东西。
-
既然您已经安装了 Visual Studio,您应该阅读 MFC 源代码。它是少数几个能做到这一点的实现之一(公认的答案没有)。
-
说实话,编写一个好的 Windows API 包装器是一项全职工作。这可不是那么容易被拍打的东西。 API 足够复杂,有各种曲折,如果你对 C++ 的了解不够(至少接近高级水平),这本身就是一个攀登的障碍。
标签: c++ winapi visual-studio-2015 com