![]() |
Maus-transparente Komponente
Hallo Alle,
ich habe eine Komponente von TPaintBox abgeleitet, die einige Linien zeichnet.
Delphi-Quellcode:
TLineMode = (lmNone, lmLTRTRB, lmLBRBRT, lmRTLTLB, lmRBLBLT);
TLine = class(TPaintBox) private FLineMode: TLineMode; procedure SetLineMode(const Value: TLineMode); protected procedure Paint; override; // procedure Click; override; // procedure MouseMove(Shift: TShiftState; X, Y: Integer); override; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; procedure SetPosition(X1, Y1, X2, Y2: Integer); virtual; procedure SetPositionTo(X, Y: Integer); virtual; published property LineMode: TLineMode read FLineMode write SetLineMode; end; constructor TLine.Create(AOwner: TComponent); begin inherited; // ControlStyle := [csNoStdEvents]; end; Kann ich erreichen, dass diese für die Maus "durchlässig" ist? Mit ControlStyle := [csNoStdEvents] erreiche ich, dass keine Mausereignisse behandelt werden. Die Komponente verdeckt aber immer noch den Parent. Ich möchte gern, dass MouseOver von meiner Kompo gar nicht oder nur auf den nicht transparenten Bereichen "abgefangen" wird. Mindestens wo meine Kompo unsichtbar ist, soll MouseOver der "sichbaren Komponente dahinter" behandelt werden. (Alternativ habe ich schon versucht, direkt auf den Canvas zu zeichnen. Das ist etwas ungünstig, da schlecht auf Veränderungen reagiert werden kann.) stahli |
Re: Maus-transparente Komponente
Hallo,
um Deine Komponente für die Maus transparent zu setzen, musst Du die Message CM_HITTEST behandeln. Gruß xaromz |
Re: Maus-transparente Komponente
Super Klasse!
Danke!
Delphi-Quellcode:
Da ich keine Transparent-Farbe habe setze ich Result einfach immer auf 0. Perfekt! :-)
procedure CMHitTest(var Msg: TWMMouse); message CM_HITTEST;
procedure TLine.CMHitTest(var Msg: TWMMouse); begin inherited; { if Assigned(PicUp) and Assigned(PicUp.Bitmap) and Transparent and (Msg.XPos < PicUp.Bitmap.Width) and (Msg.YPos < PicUp.Bitmap.Height) and (PicUp.Bitmap.Canvas.Pixels[Msg.XPos, Msg.YPos] = (Picture.Bitmap.TransparentColor and $FFFFFF)) then Msg.Result := 0; } Msg.Result := 0; end; stahli |
Re: Maus-transparente Komponente
Mit der TPaintBox ging das wunderbar...
Wie kann ich das auch für ein TPanel machen? CMHitTest wird bei meiner abgeleitetetn Komponente nicht aufgerufen. Ein Klick soll sich direkt auf dessen Parent beziehen. Danke Stahli |
Re: Maus-transparente Komponente
auch beim panel sollte es funktionieren. Mich wundert eigentlich das bei deiner Paintbox der gepostete Code funktioniert. Du solltest am besten von deiner Komponenten ableiten und darin das Messagehandling direkt implementieren. Andernfalls musst du eben die gesamte WindowProc umbiegen
|
Re: Maus-transparente Komponente
Ich weiß noch nicht recht, was Du genau meinst.
Die TLine funktioniert so:
Delphi-Quellcode:
TLine = class(TPaintBox)
private FLineMode: TLineMode; FFromX: Integer; FFromY: Integer; FToX: Integer; FToY: Integer; protected procedure SetLineMode(const Value: TLineMode); procedure SetFromX(const Value: Integer); procedure SetToX(const Value: Integer); procedure SetFromY(const Value: Integer); procedure SetToY(const Value: Integer); procedure Paint; override; procedure CMHitTest(var Msg: TWMMouse); message CM_HITTEST; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; procedure SetPosition(X1, Y1, X2, Y2: Integer); virtual; procedure SetPositionTo(X, Y: Integer); virtual; procedure DefineStyle; virtual; published property LineMode: TLineMode read FLineMode write SetLineMode; property FromX: Integer read FFromX write SetFromX; property FromY: Integer read FFromY write SetFromY; property ToX: Integer read FToX write SetToX; property ToY: Integer read FToY write SetToY; end; ... { TLine } procedure TLine.CMHitTest(var Msg: TWMMouse); begin inherited; { if Assigned(PicUp) and Assigned(PicUp.Bitmap) and Transparent and (Msg.XPos < PicUp.Bitmap.Width) and (Msg.YPos < PicUp.Bitmap.Height) and (PicUp.Bitmap.Canvas.Pixels[Msg.XPos, Msg.YPos] = (Picture.Bitmap.TransparentColor and $FFFFFF)) then Msg.Result := 0; } Msg.Result := 0; end; Für meine Panelableitung habe ich das genau so geregelt:
Delphi-Quellcode:
Hier wird CMHitTest aber nicht erreicht...
TPanelHead = class(TPanel)
private protected procedure CMHitTest(var Msg: TWMMouse); message CM_HITTEST; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; end; ... { TPanelHead } procedure TPanelHead.CMHitTest(var Msg: TWMMouse); begin beep; // HIER GEHT NIX inherited; { if Assigned(PicUp) and Assigned(PicUp.Bitmap) and Transparent and (Msg.XPos < PicUp.Bitmap.Width) and (Msg.YPos < PicUp.Bitmap.Height) and (PicUp.Bitmap.Canvas.Pixels[Msg.XPos, Msg.YPos] = (Picture.Bitmap.TransparentColor and $FFFFFF)) then Msg.Result := 0; } Msg.Result := 0; end; |
Re: Maus-transparente Komponente
Ich würde TLine nebenbei von TGraphicControl oder TWinControl ableiten (je nach dem, ob du dafür ein Handle brauchst, bzw. die Komponente andere WinControls verdecken können soll).
Bei dem Panel bin ich auch etwas ratlos. Bevor ich auf CM_HITTEST gestoßen bin, habe ich allerdings mit ![]() |
Re: Maus-transparente Komponente
CM_HITTEST ist die VCL Interne Botschaft welche von dem Parent ausgelöst wird (auf Erhalt der WM_NCHITTEST Botschaft) und entsprechend er Botschaft diese beantwortet. TPaintBox implementiert kein Fenster und erhält somit diese Windows Botschaft nicht sondern wird von dem Parent mit der CM_HITTEST gefragt. Bei einem Panel ist das anders, dieses hat ein Fensterhandle und bekommst somit direkt die WM_NCHITTEST Botschaft und behandelt diese selber. Somit dort nicht CM_HITTEST behandeln sondern WM_NCHITTEST.
|
Re: Maus-transparente Komponente
Hallo Muetze1,
danke dafür. Die Methode wird ausgeführt:
Delphi-Quellcode:
Der Mausklick erreicht aber nicht das Parent meines TPanelHead.
procedure TPanelHead.WMNCHitTest(var Message: TWMNCHitTest);
begin inherited; Beep; Message.Result := 0; end; Kannst Du das nochmal anschauen? Ich komme da nicht voran. |
Re: Maus-transparente Komponente
Klemm doch einfach mal die alte Behandlungsroutine ab, also inherited auskommentieren.
Zum anderen verstehe ich immer nicht, wie Leute damit arbeiten können direkt irgendwelche Zahlen anzugeben ohne zu Wissen um was es sich handelt bzw anders: zu wissen was man macht. Schonmal die Dokumentation zu der Botschaft ![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:11 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 by Thomas Breitkreuz