MouseWheelEvent bei TGraphicControl funktioniert nicht
-
Hallo zusammen,
ich erstelle gerade eine Komponente die ich von TGraphicControl abgeleitet habe.
Auf dem GraphicControl würde ich jetzt gerne das Mouserad verwenden. Leider funktioniert nichts um das Event ab zu fangen.
1. Versuch: Vorhandene OnMouseWheel funktion nutzen:
__fastcall void MouseWheel(System::TObject* Sender, Classes::TShiftState Shift, int WheelDelta, const Types::TPoint &MousePos, bool &Handled); //im Konstruktor this->OnMouseWheel=MouseWheel; void __fastcall TMyGraphic::MouseWeeel(System::TObject* Sender, Classes::TShiftState Shift, int WheelDelta, const Types::TPoint &MousePos, bool &Handled) { ShowMessage("Wheel"); }
2. Versuch: Mouse Nachricht abfangen:
void __fastcall TMyGraphic::WndProc(Messages::TMessage &Message) { switch(Message.Msg) { case WM_LBUTTONUP: ShowMessage("L Button"); // Funktioniert break; case WM_MOUSEWHEEL: ShowMessage("Mouse Wheel"); break; } }
Bin für jede Hilfe Dankbar
-
Ich vermute mal, daß du von TWinControl erben mußt, weil die Windows und/oder die VCL solche Nachrichten nur an Controls mit Window-Handle weiterleitet.
-
audacia schrieb:
Ich vermute mal, daß du von TWinControl erben mußt, weil die Windows und/oder die VCL solche Nachrichten nur an Controls mit Window-Handle weiterleitet.
Genau das Problem gatte ich auch. Von WinControl wollte ich aber nict erben, da die Komponente transparent sein muss.
Eine Lösung:
in Komponnente eine geeignete DoWheel- Methode einbauen
in Hauptform den MousWheelHandler nutzen (der wird gerufen!)
darin checke ich die Mouse- Position, ob die in der Komponente liegt
Wenn ja: die DoWheel- Methode rufen.
Klappt bei mir problemlos - mache das auch mit Kompos, die von WinControl abstammen. Dann reagiert immer die Komponente, über der die Maus steht!
Gruss
Frank
-
Ist halt ziemlich dirty, wenn man die Sache eigentlich in eine Komponente auslagern wollte.
Vermutlich kann man den Workaround auch systematisch anwenden, indem man das Window-Handle des nächsten Parents, das eins hat, subclasst.
-
Danke für die Infos,
sieht ja ziemlich schlecht für mich aus.
Ich muss von TGraphicControl ableiten weil das meiner Meinung nach am besten als Zeichenunterlage geeignet ist.
das DoWheel von der übergeordneten komponente zu holen ist zu mindestens schonmal eine Lösung auch wenn die nicht schön ist.
Hmm... Alternativ bleibt mir halt nur auf das Mausrad zu verzichten. ich wollte eignelich einen Zoom damit realisieren.
-
JBOpael schrieb:
Ich muss von TGraphicControl ableiten weil das meiner Meinung nach am besten als Zeichenunterlage geeignet ist.
Ist das der einzige Grund? Sonst würde ichs doch mal mit TWinControl versuchen.
Ansonsten kannst du dich ja mal ans Subclassing wagen.
-
Hmm... Kann mir denn jemand sagen wie ich an Canvas komme wenn ich von TWinControl ableite?
-
TWinControl hat kein Canvas als Member, du kannst aber im
OnPaint
Ereignishandler ein TCanvas Objekt an ein Handle "kleben":void TMyWinControl::OnPaint( TMessage& msg ) { // PAINTSTRUCT initialisieren PAINTSTRUCT ps; TCanvas* Canvas = new TCanvas(); Canvas->Handle = ::BeginPaint( Handle, &ps ); // Canvas benutzen // PAINTSTRUCT freigeben ::EndPaint( Handle, &ps ); }
Dazu musst du aber noch einen Ereignis Handler für die WM_PAINT Nachricht für dein Control registrieren (BEGIN_MESSAGE_MAP()/END_MESSAGE_MAP).
Edit:
Oder einen weiteren switch fürWM_PAINT
in dieWndProc
einbauen
-
Danke für eure Hilfe.
Also um die ganze Canvas Geschichte etwas zu vereinfachen habe ich nach etwas längerem Googlen raus gefunden das es sinnvoller ist von von TCustomControl ab zu leiten. Da steht TWinControl drüber und Canvas ist Implementiert.
Jetzt komm ich wieder zu meinem eigentlichem Problem. Das MouseWheelEvent reagiert auch nicht bei TWinContol oder bei TCustomControl.
Auch bei Tastatureingaben kommt nichts durch (WM_KEYUP,WM_KEYDOWN). Kann es sein das das Objekt irgendwie den Fokus haben muss?
-
Habe auch eine Komponente abgeleitet von TCustomControl um MouseWheel abzufangen
Ich verwende dabei folgende ControlStyles:
ControlStyle = ControlStyle << csOpaque << csCaptureMouse << csAcceptsControls << csClickEvents << csDoubleClicks << csReflector;
-
Das war es Tatsächlich.
im WM_LBUTTONUP einfach SetFocus() aufrufen und schon funktioniert alles.