Управление кнопками подклассов внутри класса - PullRequest
1 голос
/ 03 марта 2011

Я создал свой собственный класс кнопок графического интерфейса пользователя для использования в приложениях 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) 'до' ДОЛГО '

Ваши мысли?

1 Ответ

3 голосов
/ 03 марта 2011

Вы пытаетесь передать функцию-член внешней сущности для ее вызова, и это невозможно.

Попробуйте представить, что кто-то вызывает CallWindowProc(MyEditHandle, ...).На каком объекте (экземпляре) CButtonUXnav должен работать Button_WndProc?Каким будет его указатель this?

Если вы действительно хотите иметь функцию обратного вызова в качестве члена вашего класса, вы должны объявить ее как static, делая ее доступной извне, но имея доступ толькостатические переменные-члены CButtonUXnav.
Чтобы решить эту проблему, привяжите указатель к вашему CButtonNXnav с помощью дескриптора окна редактирования, используя SetWindowLong(hWnd, GWL_USERDATA, &CButtonUXnav), и это решит вашу проблему.

РЕДАКТИРОВАТЬ:

Вам на самом деле нужны три вещи:

  • Объявите функцию обратного вызова как статическую:
    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);

Надеюсь, что это делает:)

...