开发者

Subclassing Button Control within a Class

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 clas开发者_高级运维s 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?


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 :)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜