![]() |
Hamsterlaufrad ääh Mauslaufrad
Hallilallo,
ich bin ziemlich neu hier, hab mich bisher mehr schlecht als recht als Einzelkämpfer durchgeschlagen (es gibt gar nicht so viele Delphianer!) und bleib regelmäßig mal hier mal dort im Programmcode stecken ..., bin so etwa in der Phase eines ganz leicht fortgeschrittenen Anfängers. Meine hoffnungslose Situation: Ich habe eine Komponente TZeichenBlatt von TImage abgeleitet. Wenn ich mit der Maus über die fertige Komponente fahre, soll beim Mausraddrehen gezoomt werden. Ich möchte nicht nur das OnMouseWheel Ereignis im Objektinspektor sehen, sondern ich möchte auch, dass das dann funktioniert, ohne dass ich eine entsprechende Procedure erst schreiben muss, NACHDEM ich meine Komponente auf Form1 plaziert habe; der Code soll schon im Quelltext der Komponente drinnen sein; ich glaube man sagt dazu, ein Ereignis zur Laufzeit realisieren (?). Frage: Wie kann ich auf das OnMouseWheel Ereignis zugreifen? Das OnClick Ereignis ist ja bei TImage standartmäßig dabei, aber das OnMouseWheel nicht! Kann ich es irgendwie von TControl ableiten? Wie geht das? Hab auch schon untenstehendes versucht, aber auf das Mausrad ragiert nix!!!!!!!! Es tut sich überhaupt nix, nix, nix!-((( Wie kann ich tun, dass irgendetwas auf mein Mauslaufrad reagiert? Ich hab sicher einen easycollen extrasimplen Fehler oder ein IQ-Problem! Vielleich kann mir jemand helfen, damit ich nicht den ganzen Tag :wall: Danke feste Schneck
Delphi-Quellcode:
type TMausAnzeige = procedure(Sender: TObject; Shift: TShiftState; X, Y: Integer) of Object; TZeichenBlatt = class(TImage) private procedure MausDrehen(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean); ... protected ... public ... published Property OnMouseWheel; ... ... procedure TZeichenblatt.MausDrehen(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean); begin if WheelDelta > 0 then ShowMessage('ää'); Canvas.TextOut(10,10,'hjhjhhjhgjkghk'); Handled := True; end; constructor TZeichenBlatt.Create(aOwner: TComponent); begin inherited create(aOwner); ... OnMouseWheel := Mausdrehen; .. end; ... |
Re: Hamsterlaufrad ääh Mauslaufrad
Delphi-Quellcode:
Is etwas komisch geschrieben, aber hier die Erklärung:
...
protected procedure MeinVerstecktesOnMouseWheel(...) fOnMouseWheel: ... published property OnMouseWheel: ... constructor TZeichenBlatt.Create(...) begin inherited OnMouseWheel := MeinVersteckesOnMouseWheel; end; procedure MeinVersteckesOnMouseWheel(...) begin if assigned(OnMouseWheel) then fOnMouseWheel(...); end; du überschreibst zwar das alte OnMouseWheel, kannst es aber noch mit inherited ansprechen! In deinem OnMouseWheel musst du halt noch eventuell das von Benutzer verwendete OnMouseWheel aufrufen! |
Re: Hamsterlaufrad ääh Mauslaufrad
Hallo da bin ich wieder,
geht leider immer noch nicht, ist da noch was faul? Es tut sich immer noch nix...
Delphi-Quellcode:
type TMausAnzeige = procedure(Sender: TObject; Shift: TShiftState; X, Y: Integer) of Object; TZeichenBlatt = class(TImage) private ... protected fOnMouseWheel: TMouseWheelEvent; procedure MausDrehen(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean); ... public constructor Create(aOwner: TComponent); override; ... published property OnMouseWheel: TMouseWheelEvent Read fOnMouseWheel Write fOnMouseWheel; ... end; ... procedure TZeichenblatt.MausDrehen(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean); begin if assigned(OnMouseWheel) then fOnMouseWheel(Sender, Shift, WheelDelta, MousePos, Handled); if WheelDelta > 0 then ShowMessage('ää'); Canvas.TextOut(10,10,'hjhjhhjhgjkghk'); end; ... constructor TZeichenBlatt.Create(aOwner: TComponent); begin inherited create(aOwner); ... inherited OnMouseWheel := Mausdrehen; end; |
Re: Hamsterlaufrad ääh Mauslaufrad
Hast du schon mal probiert, ob das MouseWheel-Event vom Formular funzt?
Bei mir gabs mal das Problem, dass es da nicht funktioniert hat! Am Source dürfte eigentlich nichts fehlen! (glaub ich halt!) |
Re: Hamsterlaufrad ääh Mauslaufrad
Was heißt funzen:?:
|
Re: Hamsterlaufrad ääh Mauslaufrad
funzen = funktionieren
|
Re: Hamsterlaufrad ääh Mauslaufrad
nur zur information, WM_MOUSEWHEEL messages werden nur an das Fenster geschickt, das den Eingabefokus hat!
|
Re: Hamsterlaufrad ääh Mauslaufrad
Zitat:
ps: CM_Xxx entsprechen nicht unbedingt 'durchgereichten' Windows-Nachrichten (das sind eher die CN_Xxx) |
Re: Hamsterlaufrad ääh Mauslaufrad
ojeoje, da steig ich voll aus.
Und übigens, mein Form1 funzt schon, auch der Objektinspektor der Komponente TZeichenBlatt zeigt jetzt OnMouseWheel an, aber wenn ich beim OnMouseWheel-Ereignis vom Form1 eine Prozedur einfüge, funzt immer nur die Procedur vom Form1, auch wenn ich im OnMouseWheel vom ZeichenBlatt eine andere Procedure einfüge, diese wird immer ignoriert. :( Danke jedenfalls für die vielen Tipps, ich glaub, ich muss aufgeben Schnief Schneck |
Re: Hamsterlaufrad ääh Mauslaufrad
Hi! :hi:
Meines wissens nach musst du einfach mal für deine Kompo ein Nachrichtenfenster erstellen das dann die Msg vom Mausrad (ka wie die jetzt heißt) abfragt, dann noch gucken ob die Maus innerhalb deiner Kompo ist und schon kannst den Event drum herum basteln ;) mfg phlux :hi: |
Re: Hamsterlaufrad ääh Mauslaufrad
Zitat:
Hast Du denn schon...
Delphi-Quellcode:
...probiert?
type
TZeichenblatt = class(TImage) private procedure WMMouseWheel(var Message: TWMMouseWheel); message = WM_MOUSEWHEEL; procedure CMMouseWheel(var Message: TCMMouseWheel); message = CM_MOUSEWHEEL; //... end; //... procedure TZeichenBlatt.WMMouseWheel(var Message: TWMMouseWheel); begin with TMessage(Message) do begin TCMMouseWheel(Message).ShiftState := KeysToShiftState(Message.Keys); Result := Perform(CM_MOUSEWHEEL, WParam, LParam); end; end; procedure TZeichenBlatt.CMMouseWheel(var Message: TCMMouseWheel); begin //... end; |
Re: Hamsterlaufrad ääh Mauslaufrad
Huhu,
hab noch nicht aufgegeben ... aber der Tipp mit dem "TWMMouseWheel", "WM_MOUSEWHEEL", u.s.w. liefert nur die Fehlermeldungen "undefinierter Bezeichner"; übersteigt auch meinen begrenzten Programmierhorizont. In der Dephi-Hilfe ist auch nix näheres dazu zu finden und meine Delphibiebel von Doberenz (Programmierenlernen mit BD7, und das Kochbuch zu BD7) schweigen sich auch aus. :pale: Können die Fehlermeldungen daran liegen dass meine Personal 7 Version zu billig war? Aber ich glaub es nicht, gibt es wirklich keinen easy einfachen Trick mit normalen Mitteln auf das ONMousWheelEvent zuzugreifen? Gruß Schneck |
Re: Hamsterlaufrad ääh Mauslaufrad
Zitat:
|
Re: Hamsterlaufrad ääh Mauslaufrad
Hallo,
großes Dankeschön für den coolen geheimen Messages-Tipp, fetzt funzt es FAST! :wink: Da ist aber noch ein großes Problem: Auf das Mauslaufraddrehen reagiert nun endlich das Programm, aber NICHT wenn ich genau über der Komponente TZeichenBlatt bin, sondern irgendwo weiter oben links, ich bin dann nichteinmal mehr über dem Formular, aber beim MausWheelen reagierte es fröhlich weiter und weiter rechts und unten geht nix?! Weis da noch jemand Hilfe? Mein orginaler Quelltext schaut jetzt so aus:
Delphi-Quellcode:
Hat jemand vielleicht auch einen guten Link, wo ein FastAnfänger auf verständliche Weise etwas über das da lernen kann, was da oben im Quelltext steht. Die Messages-Unit ist nichteinal in der Delphi-Hilfe enthalten; und ich hab keine Ahnung was die WM... und CM... und LParam und und und sind. Woher weiß wer sowas?
...
uses SysUtils, Classes, Controls, ExtCtrls, ... Messages; ... type TZeichenBlatt = class(TImage) private ... procedure WMMouseWheel(var Message: TWMMouseWheel); message WM_MOUSEWHEEL; procedure CMMouseWheel(var Message: TCMMouseWheel); message CM_MOUSEWHEEL; ... procedure TZeichenBlatt.WMMouseWheel(var Message: TWMMouseWheel); begin with TMessage(Message) do begin TCMMouseWheel(Message).ShiftState := KeysToShiftState(Message.Keys); Result := Perform(CM_MOUSEWHEEL, WParam, LParam); end; end; procedure TZeichenBlatt.CMMouseWheel(var Message: TCMMouseWheel); begin Canvas.TextOut(100,20,Format('WheelDelta = %d',[Message.WheelDelta])); Canvas.TextOut(100,50,Format('xPos = %d; yPos = %d',[Message.XPos,Message.YPos])); end; ... Gruß Schneck |
Re: Hamsterlaufrad ääh Mauslaufrad
Zitat:
Zum Problem: sieh Dir mal folgendes Beispiel an...
Delphi-Quellcode:
...wie man schon an der Nomenklatur erkennt, ist FWheelAccumulator eine private Variable der Klasse.
procedure TZeichenBlatt.CMMouseWheel(var Message: TCMMouseWheel);
var MousePos: TPoint; IsNeg: Boolean; procedure MouseWheelUp(); begin //... DoScroll(WHEEL_DELTA); end; procedure MouseWheelDown(); begin //... DoScroll(-WHEEL_DELTA); end; begin MousePos := SmallPointToPoint(Message.Pos); Inc(FWheelAccumulator, Message.WheelDelta); while (Abs(FWheelAccumulator) >= WHEEL_DELTA) do begin IsNeg := FWheelAccumulator < 0; FWheelAccumulator := Abs(FWheelAccumulator) - WHEEL_DELTA; if (IsNeg) then begin if (FWheelAccumulator <> 0) then FWheelAccumulator := -FWheelAccumulator; MouseWheelDown(); end else MouseWheelUp(); end; end; Gruss Nico ps: hab hier kein Delphi zum Testen, sorry |
Re: Hamsterlaufrad ääh Mauslaufrad
Hallo Nico,
der neue Code funktioniert gut, das Problem ist damit aber nicht behoben. Ich hab ein bischen herumgetestet und jetzt kann ich es genauer beschreiben: Das Programm reagiert auf das Mauslaufraddrehen nur dann, wenn ich mit der Maus über einem Gebiet bin, das mein ZeichenBlatt ausfüllen würde, wenn es die Positionskoordinaten (Left und Top) nicht vom Formular sondern vom Bilschirm hätte. Also wenn ich das Formular (auf dem sich z. B. irgendwo links oben mein ZeichenBlatt befindet) als Vollbild vergrößere, dann stimmt alles relativ gut überein, hier ist nur eine vertikale Diskrepanz in der Größenordnung der Formularkopfleistenhöhe vorhanden (das Programm reagiert bereits wenn ich z. B. um die Formularkopfleistenhöhe höher oben als der obere Rand des ZeichenBlattes bin); wenn ich das Formular aber verkleinere und z. B. nach links unten schiebe, hab ich immernoch das Porblem dass ich mit der Maus auf dem Bildschirm rechts oben sein muss um eine Reaktion auf das Mausraddrehen zu erhalten, auch wenn das Formular ganz wo anders ist, geschweige denn das ZeichenBlatt. Igendwie glaubt das Programm, dass der Parent vom ZeichenBlatt nicht das Formular sonder der Bildschirm ist. Meine Testtexte schreibt das Programm aber brav ins Canvas vom ZeichenBlatt. :freak: Oh Schreck ein Schneck |
Re: Hamsterlaufrad ääh Mauslaufrad
edit: siehe unten
|
Re: Hamsterlaufrad ääh Mauslaufrad
OK, Delphi ist installiert und es sieht nicht mehr so aufwendig aus...
Laut der Hilfe sollte es ausreichen DoMouseWheel (von TControl geerbt) zu überschreiben:
Delphi-Quellcode:
type
TZeichenBlatt = class(TImage) protected function DoMouseWheel(Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint): Boolean; override; published property OnMouseWheel; end; function TZeichenBlatt.DoMouseWheel(Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint): Boolean; begin //... hier die Aktionen VOR einem eventuellen OnMouseWheel[Down|Up] Result := inherited DoMouseWheel(Shift, WheelDelta, MousePos); //... hier die Aktionen NACH einem eventuellen OnMouseWheel[Down|Up] end; Gruss Nico |
Re: Hamsterlaufrad ääh Mauslaufrad
Hallo Nico,
der neue Code ist viel cooler, den würd ich auch besser verstehen, mein Compiler tut das aber nicht. :gruebel: Ich hab jetzt meine Komponente total auf Minimaltestversion abgespeckt, und der vollständige Code steht unten: Alles was die Kompo soll ist beim Mauslaufradwheelen eine Botschaft rausgeben ... aber nix und wiedernix! Hast Du noch eine Ahnung was da faul sein kann?
Delphi-Quellcode:
unit MZBlatt_TEST1;
interface uses Classes, ExtCtrls, WinTypes, Dialogs; type TZeichenBlatt_TEST1 = class(TImage) private protected function DoMouseWheel(Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint): Boolean; override; public constructor Create(aOwner: TComponent); override; published property OnMouseWheel; end; procedure Register; implementation procedure Register; begin RegisterComponents('Test', [TZeichenBlatt_TEST1]); end; constructor TZeichenBlatt_TEST1.Create(aOwner: TComponent); begin inherited create(aOwner); end; function TZeichenBlatt_TEST1.DoMouseWheel(Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint): Boolean; begin ShowMessage('Vorher: DräDichDräDichRäädchen'); Result := inherited DoMouseWheel(Shift, WheelDelta, MousePos); ShowMessage('Nacher: HasteDichGutGeräätMeinRäädchen'); end; end. Der Schneck verreckt :pale: |
Re: Hamsterlaufrad ääh Mauslaufrad
Hi Schneck!
Ist nur so ne Frage, hast du wenn du das Zeichenblatt auf deine Form droppst auch nochmal ein Event für das erstellte Object geschrieben, denn wenn kein Event erstellt wurde kann auch der Code in der Komponente nicht ausgeführt werden, hoffe ich du verstehst was ich meine ;) mfg phlux :hi: |
Re: Hamsterlaufrad ääh Mauslaufrad
Hallo da draußen,
null blassen Schimmer, was Du meinst :( Aber wenn ich die MousDown-Procedure überschreibe, das geht dann sehr gut. Auf Klicken geht's auf Wheelen geht's nicht. Hier jetzt die vollständige erweiterte Kompo mit funzo Mausklick aber nixfunzo Mousewheel:
Delphi-Quellcode:
Schneck
unit MZBlatt_TEST1;
interface uses Classes, ExtCtrls, WinTypes, Dialogs, Controls; type TZeichenBlatt_TEST1 = class(TImage) private protected function DoMouseWheel(Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint): Boolean; override; procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; constructor Create(aOwner: TComponent); override; published property OnMouseWheel; end; procedure Register; implementation procedure Register; begin RegisterComponents('Test', [TZeichenBlatt_TEST1]); end; constructor TZeichenBlatt_TEST1.Create(aOwner: TComponent); begin inherited create(aOwner); end; procedure TZeichenBlatt_TEST1.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin inherited MouseDown(Button, Shift, X, Y); ShowMessage('MoiseleKlickGehtSupertoll'); end; function TZeichenBlatt_TEST1.DoMouseWheel(Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint): Boolean; begin ShowMessage('Vorher: DräDichDräDichRäädchen'); Result := inherited DoMouseWheel(Shift, WheelDelta, MousePos); ShowMessage('Nacher: HasteDichGutGeräätMeinRäädchen'); end; end. chneck hneck neck eck ck k |
Re: Hamsterlaufrad ääh Mauslaufrad
Halloa, schon wieder ich :zwinker: ,
bin der Lösung meines Problemes noch auf der Spur. Aber warum funzt das Wheelereignis vom Form1 und nich das von der Kompo ZeichenBlatt, obwohl im Objektinspektor dieses Event auch per Hand belegt werden kann? Kann ich da vielleicht etwas mit dem MouseWheelHandler drehn, oder ist diese Idee ganz falsch (keine Ahnung was ein Handler überhaupt tut)? Fragt sich Schneck |
Re: Hamsterlaufrad ääh Mauslaufrad
Hallo ihr...
Achtet mal darauf, dass mouse-wheel nur auf Komponenten geht, die den Focus haben können... vieleicht TWinControl oder TCustomControl zum vererben nehmen... Grüfe :wall: McFly |
Re: Hamsterlaufrad ääh Mauslaufrad
Halloa,
der Tipp mit dem Focus ist sicher gut, den hab ich auch schon von anderen Seiten bekommen; aber wie geht das mit dem Focus? :gruebel: Konnte unter der Delphihilfe und in meiner bescheidenen Literatur nicht viel dazu finden. Habs auch schon mit Updaten, Registrieren und Neuinstallieren versucht, aber nix hilft. Mein Arzt sagt, ich sei depressiv; ich weiß jetzt warum :mrgreen: Werde mir damit helfen, dass ich zomme, wenn ich die linke Maustaste gedrückt halte ... das ist zwar nich so cool wie Wheelen, aber auf MausClick funzt bei meiner Komponente alles gut. Aber vielleicht kann mir jemand doch noch eine Kurznachhilfestunde im Focusieren geben, vielleich geht es ja doch noch damit?! Liebe Grüße und Danke Schneck |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:46 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz