在类中对按钮控件进行子类化

发布于 2024-10-20 06:09:07 字数 1514 浏览 5 评论 0原文

我创建了自己的自定义 GUI 按钮类以在 Windows Mobile 应用程序中使用。意识到我需要一些更精细的控制并消除双击的烦恼,我认为我需要做的就是像往常一样将其子类化。

但是,由于我已将所有内容封装到一个类中,似乎使问题变得复杂。

下面是我想做的事情的一个片段

// Graphic button class for Wizard(ing) dialogs.
class CButtonUXnav
{
private:

    // Local subclasses of controls.
    WNDPROC wpOldButton;        // Handle to the original callback.
    LRESULT CALLBACK Button_WndProc (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);

。 。 。

int CButtonUXnav::CreateButton (LPCTSTR lpButtonText, int x, int y, int iWidth, int iHeight, bool gradeL2R)
    {
    xLoc = x;
    yLoc = y;
    nWidth = iWidth;
    nHeight = iHeight;
    wcscpy (wszButtonText, lpButtonText);

    PaintButtonInternals (x, y, iWidth, iHeight, gradeL2R);

    hButton = CreateWindow (L"BUTTON", wszButtonText,
                            WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON | BS_OWNERDRAW,
                            xLoc, yLoc, nWidth, nHeight,
                            hWndParent, IDbutn, hInstance, NULL);

    // Subclass
    // (to remove double-click annoyance.)
    wpOldButton = (WNDPROC)GetWindowLong (hButton, GWL_WNDPROC);

    if (wpOldButton == 0)
        return 1;

    // Insert our own callback.
    SetWindowLong (hButton, GWL_WNDPROC, (LONG)Button_WndProc);

    return 0;
    }

但我似乎无法逃避解决这个错误:

错误 C2440:“类型转换”:不能 从 'LRESULT (__cdecl CButtonUXnav::* )(HWND,UINT,WPARAM,LPARAM)' 为 'LONG'

你的想法是什么?

I created my own custom GUI button class for use in Windows Mobile apps. Realizing that I needed some finer control and to remove the double-click annoyance, I figured all I need to do is subclass it like I always have.

But, being that I have encapsulated everything into a Class though, seems to have complicated the matter.

Below is a snippet of what I want to do

// Graphic button class for Wizard(ing) dialogs.
class CButtonUXnav
{
private:

    // Local subclasses of controls.
    WNDPROC wpOldButton;        // Handle to the original callback.
    LRESULT CALLBACK Button_WndProc (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);

.
.
.

int CButtonUXnav::CreateButton (LPCTSTR lpButtonText, int x, int y, int iWidth, int iHeight, bool gradeL2R)
    {
    xLoc = x;
    yLoc = y;
    nWidth = iWidth;
    nHeight = iHeight;
    wcscpy (wszButtonText, lpButtonText);

    PaintButtonInternals (x, y, iWidth, iHeight, gradeL2R);

    hButton = CreateWindow (L"BUTTON", wszButtonText,
                            WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON | BS_OWNERDRAW,
                            xLoc, yLoc, nWidth, nHeight,
                            hWndParent, IDbutn, hInstance, NULL);

    // Subclass
    // (to remove double-click annoyance.)
    wpOldButton = (WNDPROC)GetWindowLong (hButton, GWL_WNDPROC);

    if (wpOldButton == 0)
        return 1;

    // Insert our own callback.
    SetWindowLong (hButton, GWL_WNDPROC, (LONG)Button_WndProc);

    return 0;
    }

But I can't seem to escape resolving this error:

error C2440: 'type cast' : cannot
convert from 'LRESULT (__cdecl
CButtonUXnav::*
)(HWND,UINT,WPARAM,LPARAM)' to 'LONG'

Your thoughts?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

2024-10-27 06:09:07

您试图将成员函数传递给外部实体来调用它,这是不可能的。

尝试想象有人正在调用 CallWindowProc(MyEditHandle, ...)。 Button_WndProc 应该在 CButtonUXnav 的哪个对象(实例)上进行操作?它的 this 指针是什么?

如果您确实希望将回调函数作为类的成员,则必须将其声明为static,使其可从外部访问,但只能访问 CButtonUXnav 的静态成员变量。
要解决此问题,请使用 SetWindowLong(hWnd, GWL_USERDATA, &CButtonUXnav) 将指针绑定到带有编辑窗口句柄的 CButtonNXnav,这将解决您的问题。

编辑:

您实际上需要三件事:

  • 将回调函数声明为静态:
    static Button_WndProc(HWND,UINT,WPARAM,LPARAM);
  • 执行子类时存储指向 CButtonUXnav 对象的指针:
    SetWindowLong(hWnd, GWL_USERDATA, (LONG)this);
  • 从静态回调中检索该指针以对其进行操作;
    CButtonUXnav *pMyObj = (CButtonUXnav*)GetWindowLong(hWnd, GWL_USERDATA);
    (注意:这可能更直接:)
    CButtonUXnav& pMyObj = *(CButtonUXnav*)GetWindowLong(hWnd, GWL_USERDATA);

希望这样可以:)

You're trying to pass a member function to an outside entity to call it, and that's impossible.

Try to imagine that someone is calling CallWindowProc(MyEditHandle, ...). On which object (instance) of CButtonUXnav should Button_WndProc operate on? What would be its this pointer?

If you really want to have the callback function as your class' member, you must declare it as static, rendering it accessible from outside, but able to access only static member variables of CButtonUXnav.
To tackle this, bind a pointer to your CButtonNXnav with the edit's window handle using SetWindowLong(hWnd, GWL_USERDATA, &CButtonUXnav), and that would solve your problem.

EDIT:

You actually need three things:

  • Have the callback function declared as static:
    static Button_WndProc(HWND,UINT,WPARAM,LPARAM);
  • Store a pointer to your CButtonUXnav object when performing the subclass:
    SetWindowLong(hWnd, GWL_USERDATA, (LONG)this);
  • Retrieve that pointer from within the static callback to act upon it;
    CButtonUXnav *pMyObj = (CButtonUXnav*)GetWindowLong(hWnd, GWL_USERDATA);
    (note: It might be more straight-forward to:)
    CButtonUXnav& pMyObj = *(CButtonUXnav*)GetWindowLong(hWnd, GWL_USERDATA);

Hope this does it :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文