Почему мой Control не улавливает сообщения MouseWheel?
Использование C++Builder 2006.
Я пытаюсь изменить производный класс TCustomControl, и мне нужен этот класс, чтобы улавливать события (или сообщения) колесика мыши. Я попытался использовать ответ на этот вопрос Delphi, но не понимаю события.
Это мой соответствующий код:
TMouseWheelHandler.h
class PACKAGE TMouseWheelHandler : public TCustomControl
{
private:
typedef TCustomControl inherited;
protected:
virtual void __fastcall Paint();
void __fastcall WMSize (TWMSize &Message);
void __fastcall CMMouseEnter (TMessage &Message);
void __fastcall CMMouseLeave (TMessage &Message);
void __fastcall WMMouseMove (TMessage &Message);
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(WM_SIZE, TWMSize, WMSize)
VCL_MESSAGE_HANDLER(CM_MOUSEENTER , TMessage, CMMouseEnter)
VCL_MESSAGE_HANDLER(CM_MOUSELEAVE , TMessage, CMMouseLeave)
VCL_MESSAGE_HANDLER(WM_MOUSEMOVE , TMessage, WMMouseMove)
END_MESSAGE_MAP(TCustomControl)
virtual bool DoMouseWheel (TShiftState Shift, int WheelDelta, TPoint & MousePos);
virtual bool DoMouseWheelDown (TShiftState Shift, TPoint & MousePos);
virtual bool DoMouseWheelUp (TShiftState Shift, TPoint & MousePos);
void MouseWheelHandler (const TMessage &Message);
public:
__fastcall TMouseWheelHandler(TComponent* Owner);
__published:
__property OnMouseWheelUp;
__property OnMouseWheelDown;
__property OnMouseWheel;
__property OnClick;
};
TMouseWheelHandler.cpp
//===========================================================================
//===========================================================================
//===========================================================================
bool TMouseWheelHandler::DoMouseWheel (TShiftState Shift, int WheelDelta, TPoint & MousePos)
{
OutputDebugString(__FUNC__);
return inherited::DoMouseWheel(Shift,WheelDelta,MousePos);
}
//===========================================================================
bool TMouseWheelHandler::DoMouseWheelDown (TShiftState Shift, TPoint & MousePos)
{
OutputDebugString(__FUNC__);
return inherited::DoMouseWheelDown(Shift, MousePos);
}
//===========================================================================
bool TMouseWheelHandler::DoMouseWheelUp (TShiftState Shift, TPoint & MousePos)
{
OutputDebugString(__FUNC__);
return inherited::DoMouseWheelUp(Shift, MousePos);
}
//===========================================================================
// MOUSE MANAGEMENT TAKEN FROM STACKOVERFLOW DELPHI SOLUTION
//===========================================================================
void __fastcall TMouseWheelHandler::CMMouseEnter (TMessage &Message)
{
OutputDebugString(__FUNC__);
SetFocus();
MouseCapture = true;
Refresh();
}
//===========================================================================
void __fastcall TMouseWheelHandler::CMMouseLeave (TMessage &Message)
{
OutputDebugString(__FUNC__);
MouseCapture = false;
Refresh();
}
//===========================================================================
void __fastcall TMouseWheelHandler::WMMouseMove (TMessage &Message)
{
if (MouseCapture) {
TPoint pt;
POINTSTOPOINT(pt , MAKEPOINTS(Message.LParam) );
if (PtInRect(ClientRect, pt) ) {
OutputDebugString("MOUSE IN");
}else{
OutputDebugString("MOUSE OUT");
MouseCapture = false;
Refresh();
}
}else{
OutputDebugString("NO_CAPTURE");
}
}
//===========================================================================
void TMouseWheelHandler::MouseWheelHandler (const TMessage &Message)
{
OutputDebugString(__FUNC__);
TMessage MyMessage = Message; // In the DELPHI sample Message was'nt a const
MyMessage.Result = Perform(CM_MOUSEWHEEL, MyMessage.WParam, MyMessage.LParam);
if (MyMessage.Result == 0) {
inherited::MouseWheelHandler(MyMessage);
}
}
//===========================================================================
//===========================================================================
//===========================================================================
И вот как я использую Control в своей форме:
WH = new TMouseWheelHandler(this);
WH->Parent = Panel1;
WH->Align = alTop;
WH->Height = Panel1->Height/2;
WH->OnMouseWheel = GGMouseWheel;
WH->OnMouseWheelDown = GGMouseWheelDown;
WH->OnMouseWheelUp = GGMouseWheelUp;
void __fastcall TTestForm::GGMouseWheel(TObject *Sender, TShiftState Shift, int WheelDelta, const TPoint &MousePos, bool &Handled)
{
OutputDebugString(__FUNC__);
}
//---------------------------------------------------------------------------
void __fastcall TTestForm::GGMouseWheelDown(TObject *Sender, TShiftState Shift, const TPoint &MousePos, bool &Handled)
{
OutputDebugString(__FUNC__);
}
//---------------------------------------------------------------------------
void __fastcall TTestForm::GGMouseWheelUp(TObject *Sender, TShiftState Shift, const TPoint &MousePos, bool &Handled)
{
OutputDebugString(__FUNC__);
}
//---------------------------------------------------------------------------
Что я вижу из отладочных отпечатков, так это то, что ни одна из функций DoMouse *, а также функция MouseWheelHandler никогда не вызывается , в то время как функции Form GGMouseWheel * вызываются.
Все, что мне нужно, это управлять некоторыми переменными в функциях DoMouse *.
Что я делаю неправильно?
1 ответ
Вы должны быть объявлены не
protected
, поскольку он переопределяет виртуальный
Dispatch()
метод, который
public
. Лично я предпочитаю переопределить виртуальный
WndProc()
метод вместо использования
MESSAGE_MAP
с.
При этом нет необходимости напрямую обрабатывать сообщения колесика мыши, просто переопределите виртуальные методы. Обратите внимание, что ваш
DoMouseWheel...()
а также
MouseWheelHandler()
все методы объявлены неправильно, поэтому они НЕ переопределяют виртуальные методы с такими же именами.
Вместо этого попробуйте эти объявления (вы могли бы заглянуть в
Controls.hpp
чтобы получить их, или прочтите документацию):
DYNAMIC bool __fastcall DoMouseWheel(TShiftState Shift, int WheelDelta, const TPoint &MousePos);
DYNAMIC bool __fastcall DoMouseWheelDown(TShiftState Shift, const TPoint &MousePos);
DYNAMIC bool __fastcall DoMouseWheelUp(TShiftState Shift, const TPoint &MousePos);
DYNAMIC void __fastcall MouseWheelHandler(TMessage &Message);