Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   WM_MOUSEMOVE in mehr als einem TControl verarbeiten. (https://www.delphipraxis.net/192888-wm_mousemove-mehr-als-einem-tcontrol-verarbeiten.html)

alleinherrscher 30. Mai 2017 15:45

WM_MOUSEMOVE in mehr als einem TControl verarbeiten.
 
Hi@all.

Habe vermutlich eine ziemlich einfache Frage, auf die ich aber keine schöne Lösung gefunden habe: Wie kann ich WM_MOUSEMOVE messages in mehr als einem TControl verarbeiten?

Hintergrund: Ich habe ein tImage, was bei einem OnMouseMove Event kleine Pfeile auf den dazugehörigen Linealen außerhalb des TImages bewegen soll. Das funktioniert auch. Jetzt habe ich zusätzlich ein eigenes TGraphicControl abgeleitet, mit welchem ich eine Art Selektierbox erstellen möchte, um bestimmte Bildbereiche auf dem TImage auszuwählen. Mein TGraphicControl ist somit ein Child des TImages. Sobald ich mit der Maus über das TGraphicControl fahre, werden die WM_MOUSEMOVE Messages natürlich von TImage zum TGraphicControl weitergeleitet. Damit bleiben die Pfeilchen an einen Linealen stehen, was ich aber nicht möchte.

Ich habe es schon mit WndProc(var Message: TMessage) versucht, um die WM_MOUSEMOVE messages wieder an das TImage zu leiten, aber das gibt natürlich eine Endlosschleife...

Beste Grüße und vielen Dank,
Michael

EWeiss 30. Mai 2017 16:05

AW: WM_MOUSEMOVE in mehr als einem TControl verarbeiten.
 
Subclass dein Control und gut ist ;)

Oder die WM_MOUSEMOVE Message vom TImage nicht behandeln. (bzw.. dein TGraphicControl wenn es die Messagen weiterleitet und du das nicht willst)

Delphi-Quellcode:
WM_MOUSEMOVE:
  begin
    Result := 1;
    Exit;
  end;
gruss

alleinherrscher 30. Mai 2017 16:29

AW: WM_MOUSEMOVE in mehr als einem TControl verarbeiten.
 
Hey EWeiss,

vielen Dank für die schnelle Hilfe! Auf die Gefahr hin, wie ein totaler Neuling zu wirken: Was meinst du mit "Subclass dein Control" - ist es das nicht schon, wenn ich eine Klasse von TGraphicControl ableite? Und wo genau müsste ich deinen Codeschnipsel unterbringen?

Besten Gruß,
Michael

EWeiss 30. Mai 2017 16:33

AW: WM_MOUSEMOVE in mehr als einem TControl verarbeiten.
 
Jedes Control hat doch seine eigene message quewe..

Du hattest doch schon den Anfang gemacht so wie ich gelesen habe.
Zitat:

Ich habe es schon mit WndProc(var msg: TMessage) versucht, um die WM_MOUSEMOVE messages wieder an das TImage zu leiten
genau so und dort.. ;)
Delphi-Quellcode:
if msg.Message = WM_MOUSEMOVE then
 bla.. bla..
Du musst nur dafür sorgen das die Message dann an das TImage nicht weitergeleitet wird.
Wenn ich dich richtig verstanden habe.

gruss

alleinherrscher 30. Mai 2017 16:44

AW: WM_MOUSEMOVE in mehr als einem TControl verarbeiten.
 
Also: Momentan habe ich es so:

Delphi-Quellcode:
procedure TSelection.WndProc(var Message: TMessage);
begin
  inherited;
  if (Parent <> nil) and (Parent.HandleAllocated) then
    if Message.Msg=WM_MOUSEMOVE then
       Message.Result:=1; //oder 0 oder LongInt(False), keine Änderung
end;
In TSelection (abgeleitet von TGraphicControl) funktioniert MouseMove -> :thumb: soll auch so sein
Im Parent funktioniert MouseMove nicht, wenn die Maus auf dem TSelection Control ist. -> schlecht! :cry:

//Edit: Ah, habe ich falschherum gedacht, und muss mich um WndProc des Parents kümmern?

EWeiss 30. Mai 2017 16:49

AW: WM_MOUSEMOVE in mehr als einem TControl verarbeiten.
 
Zitat:

Edit: Ah, habe ich falschherum gedacht, und muss mich um WndProc des Parents kümmern?
Versuchs einfach mal ist ja kein Aufwand ;)

Das weiterleiten der WM_MOUSEMOVE Message an das Parent Fenster mache ich auf diese weise.
Delphi-Quellcode:
    WM_MOUSEMOVE:
      SendMessageW(GetParent(WinHandle), WM_MOUSEMOVE, MakeLong(GetDlgCtrlID(WinHandle), 0), 0);
gruss

alleinherrscher 31. Mai 2017 09:43

AW: WM_MOUSEMOVE in mehr als einem TControl verarbeiten.
 
Wessen Handle wäre denn dann WinHandle?

EWeiss 31. Mai 2017 10:15

AW: WM_MOUSEMOVE in mehr als einem TControl verarbeiten.
 
Zitat:

Zitat von alleinherrscher (Beitrag 1373059)
Wessen Handle wäre denn dann WinHandle?

Das eigene bzw. das Window welches die Message versendet.
Zitat:

Mein TGraphicControl ist somit ein Child des TImages
Überlege gerade..

Eigentlich ist doch TImage 'STATIC' oder ? Wie kann dann TGraphicControl ein Child von TImage sein.
Ich glaube du behandelst das falsche Parent.
Verwende mal irgendein Spy Tool und prüfe welches Parent welches Control denn nun wirklich hat.

gruss

alleinherrscher 31. Mai 2017 10:42

AW: WM_MOUSEMOVE in mehr als einem TControl verarbeiten.
 
Moment ich glaube wir brauchen mal was mehr Code:

Delphi-Quellcode:
TSelection = class(TGraphicControl)
private
   //[...]
public
  constructor Create(AOwner: TComponent; X,Y:integer);
published
  property OnMouseMove;
protected
  procedure Paint; override;
  procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
  procedure WndProc(var Message: TMessage); override;
end;


Tf2DData = class(TForm)
 imgData: TImage;
 //[...]
 procedure imgDataMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
 private
    { Private-Deklarationen }
     //[...]
     procedure SelectionBoxTest;
 public
    { Public-Deklarationen }

end;

procedure Tf2DData.SelectionBoxTest;
var test:TSelection;
begin
  test:=TSelection.Create(self,100,100);
  test.Parent:=PanImage;
end;
So, imgDataMouseMove wird logischerweise nicht mehr aufgerufen, wenn der Mauscursor oberhalb von TSelection ist. Die obigen Codes können das bisher nicht verhindern und wenn ich an ImgData eine WM_MOUSEMOVE Nachricht schicke, bekomme ich einen STACK Overflow, vermutlich weil ImgData die Nachricht dann wieder an TSelection weiterschickt ...

//edit: ich sehe gerade, dass du Recht hast: Ich habe das Panel, auf welchem ImgData liegt, als Parent angegeben und nicht das Image ImgData selbst. Mein Fehler... sorry!! Aber wie löse ich das generelle Problem? Eine Nachricht direkt an ImgData? Aber wie finde ich allgemein heraus, welches Objekt unterhalb meiner TSelectionBox liegt, an die ich die Nachricht schicken muss?

EWeiss 31. Mai 2017 10:47

AW: WM_MOUSEMOVE in mehr als einem TControl verarbeiten.
 
Lade mal die Exe hoch wenn es geht muss die mal analysieren.
So bringt mir das nichts.

Zitat:

Aber wie finde ich allgemein heraus, welches Objekt unterhalb meiner TSelectionBox liegt, an die ich die Nachricht schicken muss?
Ein Spy Tool?

Zitat:

als Parent angegeben und nicht das Image ImgData selbst
TImage kann kein Parent sein. Es ist "STATIC"
Parent ist das Window auf dem das TImage als Child abgelegt wurde.

Versuche doch mal folgendes.
Erstelle eine Simple Form pack ein Image drauf und versuche dann einen Button in das Image zu setzen.

gruss

alleinherrscher 31. Mai 2017 11:26

AW: WM_MOUSEMOVE in mehr als einem TControl verarbeiten.
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von EWeiss (Beitrag 1373073)
Ein Spy Tool?

Wie kommst du denn bitte darauf??? Es geht doch nur um 2 Controls, die beide in meiner Anwendung übereinander liegen und die beide ein Mousemove ausführen sollen. Ich will nichts an ein anderes Programm oder sonst was weiterleiten?! Nur an das Control, welches unter meinem TGraphicControl liegt und was in meinem Fall ein Image ist.

Zitat:

Zitat von EWeiss (Beitrag 1373073)
TImage kann kein Parent sein. Es ist "STATIC"

Richtig!

Zitat:

Zitat von EWeiss (Beitrag 1373073)
Parent ist das Window auf dem das TImage als Child abgelegt wurde.

Parent ist das Panel, auf dem auch das TImage als Child abgelegt wurde.

Zitat:

Zitat von EWeiss (Beitrag 1373073)
Lade mal die Exe hoch wenn es geht muss die mal analysieren.

Ich weiß nicht, ob mein Arbeitgeber das so toll fände ;-)

Zitat:

Zitat von EWeiss (Beitrag 1373073)
Versuche doch mal folgendes.
Erstelle eine Simple Form pack ein Image drauf und versuche dann einen Button in das Image zu setzen.

Ja, ist eine gute Idee. Anbei ein Testprojekt, was mein Problem 1:1 reproduziert. Bitte die Kommentarzeilen in den "OnMouseMove" procedures beachten.

Achja und: Vielen Dank für Deine Hilfe!!!!

EWeiss 31. Mai 2017 11:37

AW: WM_MOUSEMOVE in mehr als einem TControl verarbeiten.
 
[quote]
Zitat:

Zitat von alleinherrscher (Beitrag 1373078)
Zitat:

Zitat von eweiss (Beitrag 1373073)
ein spy tool?

wie kommst du denn bitte darauf??? Es geht doch nur um 2 controls, die beide in meiner anwendung übereinander liegen und die beide ein mousemove ausführen sollen. Ich will nichts an ein anderes programm oder sonst was weiterleiten?! Nur an das control, welches unter meinem tgraphiccontrol liegt und was in meinem fall ein image ist.

Verstehe nicht was du möchtest.
Deine Frage!
Zitat:

Aber wie finde ich allgemein heraus, welches Objekt unterhalb meiner TSelectionBox liegt, an die ich die Nachricht schicken muss?
Meine korrekte Antwort.
Zitat:

ein spy tool?
Wenn ich wissen will welches Objekt unter meinem Control liegt kann ich das mit einem Spy Tool ermitteln anhand des Handle des Parent Fensters.
Alternativ innerhalb, einfach ein GetParent(SelectionBox.Handle) mit einbauen.
Zitat:

Ich weiß nicht, ob mein Arbeitgeber das so toll fände
Sorry dann weis ich auch nicht.

gruss

EWeiss 31. Mai 2017 11:58

AW: WM_MOUSEMOVE in mehr als einem TControl verarbeiten.
 
Zitat:

Zitat:

Zitat von EWeiss (Beitrag 1373073)
Versuche doch mal folgendes.
Erstelle eine Simple Form pack ein Image drauf und versuche dann einen Button in das Image zu setzen.

Ja, ist eine gute Idee. Anbei ein Testprojekt, was mein Problem 1:1 reproduziert. Bitte die Kommentarzeilen in den "OnMouseMove" procedures beachten.

Achja und: Vielen Dank für Deine Hilfe!!!!
Was soll ich jetzt mit deinem Test Tool machen?

Dieser Vorschlag war dazu gedacht um dir zu zeigen das TImage kein Parent von TGraphicControl ist.
Auch kein Child von TForm oder Child von TPanel. Nochmal es ist STATIC
Sorry ich möchte gerne helfen aber du verstehst es scheinbar nicht.

Siehe die Enumerierungen aller Childs von TForm auf dem dein Image liegt.
Ich denke deine Herangehensweise ist einfach falsch.
Nimm eine TPaintBox ohne irgendwelche Ableitungen und zeichne ausschließlich alles dort hinein.
Du willst zwischen verschiedenen Fenstern hin und her jonglieren.. Messagen senden, gut aber TImage hat kein Fenster-Handle "STATIC" und nun?

Um das zu analysieren habe ich dir gesagt verwende ein Spy Tool.
So wie du sehen kannst ist TPanel ein Kind Fenster von TForm und TButton ein Kind Fenster von TPanel.

Die MouseMove Messagen also in deinem Beispiel WM_SETCURSOR werden von der TForm ausgewertet und über Image.canvas.TextOut in das Image gezeichnet.
Die Frage ist was sagt dir das ?

gruss

alleinherrscher 31. Mai 2017 12:36

AW: WM_MOUSEMOVE in mehr als einem TControl verarbeiten.
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Du willst zwischen verschiedenen Fenstern hin und her jonglieren.. Messagen senden, gut aber TImage hat kein Fenster-Handle "STATIC" und nun?
Nein, nein, nein. Alles viel zu kompliziert. Sorry! Sieh dir bitte nochmal das Testtool an: Ich möchte einfach nur, dass der Text "Image: x,y" sich immer noch ändert, wenn ich mit der Maus über den Button fahre, und das, ohne dass ich dafür das OnMouseMove des Buttons verwende. Das muss doch möglich sein?

Oder eben in kompletter Analogie: s. Anhang: Ich möchte, dass sich die mit roten Kreisen markierten Pfeilchen weiterbewegen, wenn ich mit der Maus über meinem TGraphicControl (das ist das gedrehte, gestrichelte Rechteck) fahre. Das muss doch irgendwie auf elegante Art und Weise gehen? Selbstverständlich kann ich einfach alles Zeichnen in einer Paintbox. Das habe ich in der bisherigen Version auch so gelöst. Ich dachte, wenn ich ein eigenes Control erstelle, ist das vielleicht etwas professioneller, da diese Auswahlbox (also das Rechteck) auf Mausevents reagieren soll und auch Callback Procedures bekommen soll, und es beliebig viele Instanzen davon zur gleichen Zeit geben können soll. etc.

EWeiss 31. Mai 2017 12:43

AW: WM_MOUSEMOVE in mehr als einem TControl verarbeiten.
 
Zitat:

Das muss doch irgendwie auf elegante Art und Weise gehen?
Wie schon gesagt du musst mit dem MouseMove Ereignis von TForm arbeiten.

Zitat:

Die MouseMove Messagen also in deinem Beispiel WM_SETCURSOR werden von der TForm ausgewertet und über Image.canvas.TextOut in das Image gezeichnet.
Die Frage ist was sagt dir das ?
Zitat:

wenn ich mit der Maus über den Button fahre, und das, ohne dass ich dafür das OnMouseMove des Buttons verwende. Das muss doch möglich sein?
Ok werde mir das nochmal anschauen. ;)

gruss

alleinherrscher 31. Mai 2017 12:45

AW: WM_MOUSEMOVE in mehr als einem TControl verarbeiten.
 
Okay, ich versuche es mit dem Mousemove des TForms! Danke!!

EWeiss 31. Mai 2017 13:22

AW: WM_MOUSEMOVE in mehr als einem TControl verarbeiten.
 
Zitat:

Zitat von alleinherrscher (Beitrag 1373094)
Okay, ich versuche es mit dem Mousemove des TForms! Danke!!

sagen wir mal dein Pfeil oben ist die Aktuelle X Position von der aktuellen CursorPosition dann sollte das ganz einfach so gehen.
Auf dein Beispiel angewendet.
Musst du aber auf dein Control hin noch ändern.. (Button1 wäre dann dein TGraphicControl)

Delphi-Quellcode:
procedure TForm1.Button1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var
  p: TPoint;
begin

  GetCursorPos(p); // p.x und p.y wären dann die aktuellen Position von deinen Pfeilen
  Windows.ScreenToClient(Handle, p); // <<< Form Handle deshalb "Windows.ScreenToClient" und nicht ScreenToClient
  image1.Canvas.TextOut(1,30,'Button: ' +inttostr(x)+','+inttostr(y) + ' '); // + ' ' damit überschüssige Zeichen gelöscht werden (Uninteressant für dein Problem)
  image1.Canvas.TextOut(1,1,'Image: '+inttostr(p.x)+','+inttostr(p.y)+ ' ');
end;
Wenn du nun auf den Button gehst ändert sich die X-Position vom Image Relativ zum Screen.
Sorry es war nicht ganz einfach zu verstehen was du eigentlich wolltest.

gruss

alleinherrscher 31. Mai 2017 13:54

AW: WM_MOUSEMOVE in mehr als einem TControl verarbeiten.
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von EWeiss (Beitrag 1373103)
Zitat:

Zitat von alleinherrscher (Beitrag 1373094)
Okay, ich versuche es mit dem Mousemove des TForms! Danke!!

sagen wir mal dein Pfeil oben ist die Aktuelle X Position von der aktuellen CursorPosition dann sollte das ganz einfach so gehen.
Auf dein Beispiel angewendet.
Musst du aber auf dein Control hin noch ändern.. (Button1 wäre dann dein TGraphicControl)

Delphi-Quellcode:
procedure TForm1.Button1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var
  p: TPoint;
begin

  GetCursorPos(p);
  Windows.ScreenToClient(Handle, p); // <<< Form Handle deshalb "Windows.ScreenToClient" und nicht ScreenToClient
  image1.Canvas.TextOut(1,30,'Button: ' +inttostr(x)+','+inttostr(y));
  image1.Canvas.TextOut(1,1,'Image: '+inttostr(p.x)+','+inttostr(p.y));
end;
Wenn du nun auf den Button gehst ändert sich die X-Position vom Image Relativ zum Screen.
Sorry es war nicht ganz einfach zu verstehen was du eigentlich wolltest.

gruss

Das meinte ich leider auch nicht. Sorry! Wie man zwischen Client und Parent Koordinaten umrechnet, ist mir klar. Guck mal, du hast jetzt beide TextOuts in Button1MouseMove gepackt. Genau das wollte ich aber ja nicht, weil es nicht allgemein genug ist. Vielleicht geht das, was ich vorhabe einfach nicht...

Guck dir bitte, wenn du Zeit hast, nochmal modifizierte Beispiel im Anhang an. Ich habe jetzt eine neues TControl Namens TMyButton, abgeleitet von TButton definiert. Dieses soll irgendetwas machen, sobald die Maus darauf rumfährt (das funktioniert: Es erscheint als Button.caption die position der Maus, und diese wird aktuallisiert, solange die Maus auf dem Button ist). Allerdings wird, während die Maus auf dem Button ist, das OnImage1MouseMove Ereignis logischerweise nicht mehr ausgeführt. Wie kann ich erreichen, dass dieses Ereignis ausgeführt wird, OBWOHL die Maus auf dem TMyButton ist? Ich kann es ja schlecht in das OnMouseMove des TMyButtons schreiben, denn der kennt das TImage ja gar nicht... Verständlicher? Ich weiß einfach nicht, wie ich mich sonst ausdrücken soll?!

EWeiss 31. Mai 2017 13:57

AW: WM_MOUSEMOVE in mehr als einem TControl verarbeiten.
 
Ok ;)
Letzter Versuch.
Werde es mir Anschauen.

EDIT:
Das wird so nicht gehen weil dein Image kein Handle zur Verfügung hat an dem ich Messagen schicken könnte.

gruss

alleinherrscher 31. Mai 2017 14:25

AW: WM_MOUSEMOVE in mehr als einem TControl verarbeiten.
 
Schade, aber wie teilt denn das Panel (oder die Form) dem Image mit, dass sich gerade die Maus darauf bewegt und kann man da nicht irgendwie eingreifen? Oder beim Bearbeiten des WM_MouseMove im TButton irgendwie zurückmelden, dass die Nachricht nicht verarbeitet worden ist, oder so? -> Message.Result... ?

//edit gut, dann werde ich wohl vermutlich auf die Variante umsteigen, alles in eine Paintbox bzw ein Image zu zeichnen... :-(

EWeiss 31. Mai 2017 14:47

AW: WM_MOUSEMOVE in mehr als einem TControl verarbeiten.
 
Zitat:

Zitat von alleinherrscher (Beitrag 1373124)
Schade, aber wie teilt denn das Panel (oder die Form) dem Image mit, dass sich gerade die Maus darauf bewegt und kann man da nicht irgendwie eingreifen? Oder beim Bearbeiten des WM_MouseMove im TButton irgendwie zurückmelden, dass die Nachricht nicht verarbeitet worden ist, oder so? -> Message.Result... ?

//edit gut, dann werde ich wohl vermutlich auf die Variante umsteigen, alles in eine Paintbox bzw ein Image zu zeichnen... :-(

Ich versuche mal eine Alternative mit Subclassing eines STATIC Image Window.. was dann auch ein Handle hat.
Versprechen kann ich aber nichts ;)

gruss

Zacherl 31. Mai 2017 14:56

AW: WM_MOUSEMOVE in mehr als einem TControl verarbeiten.
 
Delphi-Quellcode:
TImage
hat weder ein eigenes Handle, noch ein eigenes Canvas und verwendet stattdessen die entsprechenden Resourcen des Parent Controls.

Entweder nimmst du eine
Delphi-Quellcode:
TPaintBox
und zeichnest komplett alles darauf, oder du leitest weiterhin von
Delphi-Quellcode:
TGraphicControl
ab und zeichnest zusätzlich manuell den Inhalt, der vorher vom Image dargestellt wurde.

EWeiss 31. Mai 2017 17:59

AW: WM_MOUSEMOVE in mehr als einem TControl verarbeiten.
 
Dein Testprojekt zurück das soll dir zeigen warum es mit einem normalen Image nicht funktioniert.
Scheint niemand zu brauchen, hab's gelöscht.
Du benötigst also eine Alternative ein Panel mit BorderStyle None wäre eine lösung das hat ein Handle..
Darauf kannst du genauso zeichnen wie auf einem Image.

gruss

HolgerX 31. Mai 2017 18:35

AW: WM_MOUSEMOVE in mehr als einem TControl verarbeiten.
 
Hmm..

Es geht Dir, wenn ich es richtig verstanden habe, um ein formularweites MouseMove, egal über welchem Control sich dein Mousezeiger befindet, und ohne, dass Du das in jedem Control implementieren musst.

Also, da bietet sich (Quick and Dirty) folgendes an:

Delphi-Quellcode:
procedure TForm1.MyApplicationOnMessage(var Msg: tagMSG;
  var Handled: Boolean);
var
  P : TPoint;
  C : TControl;
begin
  if Msg.message = WM_MOUSEMOVE then begin

    P := ScreenToClient(Msg.pt);

    c := ControlAtPos(P,false,true);
    if Assigned(c) then Edit1.Text := c.Name else Edit1.Text := '';

    Label1.Caption := IntToStr( P.X);
    Label2.Caption := IntToStr( P.Y);
  end;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  Application.OnMessage := MyApplicationOnMessage;
end;
Somit hättest Du hier ein Formular-Hook. Eventuelle OnMouseMove auf Controls bleiben bestehen und funktionieren weiter.

EWeiss 31. Mai 2017 18:46

AW: WM_MOUSEMOVE in mehr als einem TControl verarbeiten.
 
TImage = TGraphicControl <> TControl ?
Auch wenn es eine Ableitung von TControl ist.

Das soll gehen ?
Dann kann man ja direkt ein Handle abgeleitet von TControl für das Image erstellen wenn das so einfach ist und gut ist.

Nun gut. (Ich bin jetzt raus ;) )

gruss

Ghostwalker 1. Jun 2017 07:17

AW: WM_MOUSEMOVE in mehr als einem TControl verarbeiten.
 
@Zacherl

Öhm....da sagt die Doku von Emba aber was anderes. Lt. derer hat TImage einen Canvas auf das es zeichnet.

Ghostwalker 1. Jun 2017 07:28

AW: WM_MOUSEMOVE in mehr als einem TControl verarbeiten.
 
Hmm...also wenn ich den code in Post #9 angugg, dann ist der Parent sowohl vom Image als auch vom Selection jeweils das PANEL.

Da würd ich WM_MOUSEMOVE im Panel abfangen, und dann sowohl ans Image schicken als auch ans Selection-Control, so das beide tun, was immer sie da machen sollen (SendMessage oder PostMessage).

Das sollte eigentlich funktionieren.

EWeiss 1. Jun 2017 10:15

AW: WM_MOUSEMOVE in mehr als einem TControl verarbeiten.
 
Zitat:

Zitat von Ghostwalker (Beitrag 1373179)
Das sollte eigentlich funktionieren.

Nein funktioniert nicht..

Da beide Controls TImage und seine eigene Ableitung von TGraphicControl wie auch immer sie benannt wurden
über kein eigenes Fenster bzw.. Handle verfügen gibt es auch keine Parent für diese Controls.
Hier einfach das Panel als Parent zu definieren wäre also sinnlos denn beide Controls wissen doch gar nichts vom Panel.

Ohne das sie wissen was ihr Parent ist können sie auch nichts übergeben bzw. Messagen schicken.
Außerdem haben beide Controls KEIN Handle was willst du also vom Panel aus wohin schicken mit (SendMessage oder PostMessage)?

Wie soll das gehen ?
Delphi-Quellcode:
HandleZumSenden := GetParent(HabeKeinEigenesHandleUmDasParentAbzufragen);

Ich hatte ihm ein SubClassed Beispiel gepostet das nicht verwendet wurde basierend auf einem STATIC Window mit realen Handle.
Delphi-Quellcode:
    dwStyle := SS_BITMAP or SS_CENTERIMAGE or SS_NOTIFY or WS_CHILD or WS_VISIBLE;
    dwExStyle := WS_EX_STATICEDGE;
    Result := CreateWindowEx(dwExStyle, 'STATIC', '', dwStyle, 5 , 5, rc.Right - 10, rc.Bottom - 10,
      Panel1.Handle, 0, hInstance, nil);
Delphi-Quellcode:
procedure TMyButton.MouseMove(Shift: TShiftState; X, Y: Integer);
var
  p: TPoint;
begin

  self.Caption:='Button:' +inttostr(x)+','+inttostr(y);
  GetCursorPos(p);
  Windows.ScreenToClient(GetParent(Handle), p);
  // Dein vorheriges Image was kein Handle hat
  // ersetzt mit einem STATIC Window
  SendMessage(hImage, WM_MOUSEMOVE, 0, Makelong(p.x, p.y));
end;
Delphi-Quellcode:
    WM_MOUSEMOVE:
      begin
        DC := GetDC(WinHandle);
        txt := PWideChar('Image: '+inttostr(LoWord(lp))+','+inttostr(HiWord(lp)));
        SetTextColor(DC, RGB(255, 0, 0));
        TextOut(DC, 1,1,txt, Length(txt));
        ReleaseDC(WinHandle, DC);
      end;
Wenn es nicht benutzt oder verwendet wird kann ich auch nichts machen.
oops.. sehe gerade war doch schon raus aus dem Thread.

Zitat:

egal über welchem Control sich dein Mousezeiger befindet
@Holger Die Lösung ist nicht schlecht funktioniert aber nur wenn das Control unter dem Mauszeiger auch über ein Handle (eigenes Fenster)verfügt.
Siehe http://www.delphipraxis.net/attachme...iten-31.05.jpg

gruss

Ghostwalker 1. Jun 2017 11:42

AW: WM_MOUSEMOVE in mehr als einem TControl verarbeiten.
 
Liste der Anhänge anzeigen (Anzahl: 1)
@EWeiss

Doch, die Basisklasse TGraphiControl hat bereits die eigenschaft Parent (sogar TControl). So stehts zumindest in der Doku. :) (siehe Anhang)

Zacherl 1. Jun 2017 12:54

AW: WM_MOUSEMOVE in mehr als einem TControl verarbeiten.
 
Zitat:

Zitat von Ghostwalker (Beitrag 1373178)
Öhm....da sagt die Doku von Emba aber was anderes. Lt. derer hat TImage einen Canvas auf das es zeichnet.

Klar, hat das
Delphi-Quellcode:
TImage
eine
Delphi-Quellcode:
Canvas
Eigenschaft. Diese ist allerdings nicht wie bei
Delphi-Quellcode:
TWinControl
an ein eigenständiges Handle gebunden, sondern intern lediglich eine
Delphi-Quellcode:
TBitmap
Instanz. Diese beinhaltet die Grafik, welche dann letztlich aber auf das Canvas vom Parent Control gezeichnet wird.

Zitat:

Zitat von Ghostwalker (Beitrag 1373179)
Da würd ich WM_MOUSEMOVE im Panel abfangen, und dann sowohl ans Image schicken als auch ans Selection-Control, so das beide tun, was immer sie da machen sollen (SendMessage oder PostMessage).

Dürfte schwierig werden eine Message an ein Control ohne WindowHandle zu schicken :stupid:

EWeiss 1. Jun 2017 13:01

AW: WM_MOUSEMOVE in mehr als einem TControl verarbeiten.
 
Zitat:

Zitat von Ghostwalker (Beitrag 1373215)
@EWeiss

Doch, die Basisklasse TGraphiControl hat bereits die eigenschaft Parent (sogar TControl). So stehts zumindest in der Doku. :) (siehe Anhang)

Mag ja sein aber wie auch @Zacherl schon sagte ohne Handle bringt das alles nichts.
Und für ein TImage\TGraphiControl das Handle aus der weit entfernten Ableitung TControl zu holen dürfte schwer fallen.
Also ein Panel verwenden oder alles in TPaintBox zeichnen.
Zitat:

Diese beinhaltet die Grafik, welche dann letztlich aber auf das Canvas vom Parent Control gezeichnet wird.
Es gibt kein Parent für TImage im herkömmlichen sinne da kein Fenster vorhanden ist.

Nochmal siehe meinen Screenshot.
http://www.delphipraxis.net/attachme...iten-31.05.jpg
Wenn es ein Parent gäbe wäre das TImage in der Liste der Child Controls von TForm gelistet.

gruss

Ghostwalker 2. Jun 2017 03:33

AW: WM_MOUSEMOVE in mehr als einem TControl verarbeiten.
 
[QUOTE=EWeiss;1373225]
Zitat:

Zitat von Ghostwalker (Beitrag 1373215)
@EWeiss

Doch, die Basisklasse TGraphiControl hat bereits die eigenschaft Parent (sogar TControl). So stehts zumindest in der Doku. :) (siehe Anhang)

Mag ja sein aber wie auch @Zacherl schon sagte ohne Handle bringt das alles nichts.
Und für ein TImage\TGraphiControl das Handle aus der weit entfernten Ableitung TControl zu holen dürfte schwer fallen.
Also ein Panel verwenden oder alles in TPaintBox zeichnen.
[QUOTE]

Ich sagte das die PARENT-Eigenschaft schon in TControl vorhanden ist. Ein eigenes Fensterhandle hat TImage nicht. Wohl aber der Parent. Und auf dessen Handle kann ich via TImage.parent.handle zugreifen :)

In diesem Fall wärs eh einfacher, er fängt das WM_MOUSEMOVE im Panel ab und erledigt dort die entsprechenden Arbeiten. Das spart das ganze hin und her mit zwei Komponenten :)

EWeiss 2. Jun 2017 08:38

AW: WM_MOUSEMOVE in mehr als einem TControl verarbeiten.
 
Zitat:

In diesem Fall wärs eh einfacher, er fängt das WM_MOUSEMOVE im Panel ab und erledigt dort die entsprechenden Arbeiten. Das spart das ganze hin und her mit zwei Komponenten
Richtig Uwe, denke aber das es sich für ihn eh schon erledigt hat.

gruss


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:26 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz