在类中子类化按钮控件

时间:2011-03-03 11:59:46

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

我创建了自己的自定义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:'type cast':不能   转换自'LRESULT(__ cdecl   CButtonUXnav :: *   )(HWND,UINT,WPARAM,LPARAM)'到'LONG'

你的想法?

1 个答案:

答案 0 :(得分:3)

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

试着想象某人正在呼叫CallWindowProc(MyEditHandle, ...)。应该在Button_WndProc上运行CButtonUXnav的哪个对象(实例)?它的this指针是什么?

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

编辑:

你实际上需要三件事:

  • 将回调函数声明为static:
    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);

希望这样做:)