C++Builder Ошибка компилятора TMouseWheelEvent

Независимо от того, как я пытаюсь использовать его, я не могу динамически создать TScrollBox и назначить OnMouseWheelEvent обработчик к нему. Я получаю следующую ошибку компилятора:

E2034 Невозможно преобразовать 'void (_fastcall * (_closure)(TObject *,TShiftState,int,TPoint &,bool &))(TObject *,TShiftState,int,TPoint &,bool &) "в" TMouseWheelEvent "

Моя декларация для OnMouseWheelEvent обработчик правильный (насколько я могу судить):

....
TScrollBox *sb = new TScrollBox(funnelCharts);
sb->Top = 5000;
sb->Parent = funnelCharts;
sb->Align = alClient;
sb->Height = funnelCharts->ClientHeight;
sb->OnMouseWheel = scrollEvent;
....

// --------------------------------------------------------------

void __fastcall TForm1::scrollEvent(TObject *Sender, TShiftState Shift, int WheelDelta, TPoint &MousePos, bool &Handled)
{
    TScrollBox *scrollbox = dynamic_cast<TScrollBox*>(Sender);
    if (scrollbox)
    {
        for (int i = 1; i < Mouse->WheelScrollLines; i++)
        {
            if (WheelDelta > 0)
            {
                scrollbox->Perform(WM_VSCROLL, SB_LINEUP, 0);
            }
            else
            {
                scrollbox->Perform(WM_VSCROLL, SB_LINEDOWN, 0);
            }
        }
        scrollbox->Perform(WM_VSCROLL, SB_ENDSCROLL, 0);
        Handled = true;
    }
}

1 ответ

Решение

Это ошибка компилятора, а не ошибка компоновщика.

Посмотрите на фактическую декларацию TMouseWheelEvent в Controls.hpp, Ваш scrollEvent() Метод не соответствует тому, что фактически объявлено, иначе вы не получите ошибку.

В зависимости от того, компилируете ли вы для 32-битной или 64-битной, TMouseWheelEvent (в частности, его MousePos параметр) объявляется иначе:

32-бит:

typedef void __fastcall (__closure *TMouseWheelEvent)(System::TObject* Sender, System::Classes::TShiftState Shift, int WheelDelta, const System::Types::TPoint &MousePos, bool &Handled);

64-бит:

typedef void __fastcall (__closure *TMouseWheelEvent)(System::TObject* Sender, System::Classes::TShiftState Shift, int WheelDelta, System::Types::TPoint MousePos, bool &Handled);

Причина этого в том, что BCC32 и BCC64 различаются тем, как они передают 8-байтовые типы структур (например, TPoint). Это различие задокументировано в DocWiki Embarcadero:

События со структурами или наборами из 5-8 байтов не действительны для BCC64

Другие типы событий, затронутые этой разницей, включают TGetSiteInfoEvent, TMouseWheelUpDownEvent, а также TContextPopupEvent,

Чтобы это исправить, вам придется #ifdef ваш код как документально:

class TForm1 : public TForm
{
    ...
    #ifndef _WIN64
    void __fastcall scrollEvent(TObject* Sender, TShiftState Shift, int WheelDelta, const TPoint &MousePos, bool &Handled);
    #else
    void __fastcall scrollEvent(TObject* Sender, TShiftState Shift, int WheelDelta, TPoint MousePos, bool &Handled);
    #endif
    ...
};

...

#ifndef _WIN64
void __fastcall TForm1::scrollEvent(TObject* Sender, TShiftState Shift, int WheelDelta, const TPoint &MousePos, bool &Handled)
#else
void __fastcall TForm1::scrollEvent(TObject* Sender, TShiftState Shift, int WheelDelta, TPoint MousePos, bool &Handled)
#endif
{
    ...
}

Или немного чище:

class TForm1 : public TForm
{
    ...
    void __fastcall scrollEvent(
        TObject* Sender, TShiftState Shift, int WheelDelta,
        #ifndef _WIN64
        const TPoint &MousePos,
        #else
        TPoint MousePos,
        #endif
        bool &Handled);
    ...
};

...

void __fastcall TForm1::scrollEvent(TObject* Sender, TShiftState Shift, int WheelDelta,
    #ifndef _WIN64
    const TPoint &MousePos,
    #else
    TPoint MousePos,
    #endif
    bool &Handled)
{
    ...
}

Или даже чище:

#ifndef _WIN64
#define SAFE_5TO8_PARAM(type, name) const type &name
#else
#define SAFE_5TO8_PARAM(type, name) type name
#endif

class TForm1 : public TForm
{
    ...
    void __fastcall scrollEvent(TObject* Sender, TShiftState Shift, int WheelDelta, SAFE_5TO8_PARAM(TPoint, MousePos), bool &Handled);
    ...
};

...

void __fastcall TForm1::scrollEvent(TObject* Sender, TShiftState Shift, int WheelDelta, SAFE_5TO8_PARAM(TPoint, MousePos), bool &Handled)
{
    ...
}
Другие вопросы по тегам