【问题标题】:Subclassing Button Control within a Class在类中子类化按钮控件
【发布时间】:2011-07-08 00:23:57
【问题描述】:

我创建了自己的自定义 GUI 按钮类,用于 Windows Mobile 应用程序。意识到我需要一些更好的控制并消除双击的烦恼,我想我需要做的就是像往常一样对它进行子类化。

但是,由于我将所有内容都封装到了一个类中,这似乎使事情变得复杂。

下面是我想做的事情的sn-p

// 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'

你的想法?

【问题讨论】:

    标签: c++ visual-studio-2008 winapi subclass


    【解决方案1】:

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

    试着想象有人打电话给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);

    希望这样做:)

    【讨论】:

    • " 错误 C2275: 'CButtonUXnav' : 非法使用这种类型作为表达式。" 我明白了这个概念,我的挑战是将它翻译成代码。
    • 对不起,我不是说你真的要把&CButtonUXnav写成第三个参数,因为那没有任何意义。你可能会通过 (LONG)this。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-26
    • 1970-01-01
    • 1970-01-01
    • 2013-06-17
    • 2015-05-01
    • 1970-01-01
    相关资源
    最近更新 更多