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)
{
...
}