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/)
-   -   Delphi Maus-transparente Komponente (https://www.delphipraxis.net/106042-maus-transparente-komponente.html)

stahli 4. Jan 2008 09:52


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

xaromz 4. Jan 2008 10:05

Re: Maus-transparente Komponente
 
Hallo,

um Deine Komponente für die Maus transparent zu setzen, musst Du die Message CM_HITTEST behandeln.

Gruß
xaromz

stahli 4. Jan 2008 10:49

Re: Maus-transparente Komponente
 
Super Klasse!
Danke!

Delphi-Quellcode:
  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;
Da ich keine Transparent-Farbe habe setze ich Result einfach immer auf 0. Perfekt! :-)

stahli

stahli 27. Mär 2008 08:52

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

SirThornberry 27. Mär 2008 09:38

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

stahli 27. Mär 2008 09:48

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:
  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;
Hier wird CMHitTest aber nicht erreicht...

Medium 27. Mär 2008 10:01

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 MSDN-Library durchsuchenRegions und TWinControl Nachfahren gearbeitet. Diese funktionieren alledings dann auch nur mit TWinControl-Nachfahren (was ein TPanel ja auch ist).

Muetze1 27. Mär 2008 11:45

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.

stahli 27. Mär 2008 12:40

Re: Maus-transparente Komponente
 
Hallo Muetze1,

danke dafür.

Die Methode wird ausgeführt:
Delphi-Quellcode:
procedure TPanelHead.WMNCHitTest(var Message: TWMNCHitTest);
begin
  inherited;
  Beep;
  Message.Result := 0;
end;
Der Mausklick erreicht aber nicht das Parent meines TPanelHead.
Kannst Du das nochmal anschauen? Ich komme da nicht voran.

Muetze1 27. Mär 2008 13:02

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 angeschaut? Was ist denn nun 0? Ich würde HTTRANSPARENT zurück geben, wenn nicht 0 zufälligerweise schon dieser Wert sein sollte.

stahli 27. Mär 2008 13:23

Re: Maus-transparente Komponente
 
Ok danke!
Eine Doku habe ich in der Delphi-Hilfe umsonst gesucht.
-> HTTRANSPARENT = -1
Damit funktioniert das perfekt :-)

Muetze1 27. Mär 2008 13:49

Re: Maus-transparente Komponente
 
Zitat:

Zitat von stahli
Ok danke!
Eine Doku habe ich in der Delphi-Hilfe umsonst gesucht.

Naja, die Delphi Hilfe ist definitv keine Windows Hilfe. Die MSDN Library ist zwar mit integriert aber mehr minder als voll. Von daher lohnt es sich grundsätzlich eher in die MSDN direkt zu schauen bei solchen Dingen.

achi 3.0 8. Jul 2015 09:45

AW: Maus-transparente Komponente
 
Hallo,

habe momentan das gleiche Problem. Ist es möglich diese funktion auf eine standard Paintbox zu übertragen? Wenn ja wie denn, irgendwie bekomme ich es nicht hin eine neue komp zu erstellen.

Gruß

stahli 8. Jul 2015 12:01

AW: Maus-transparente Komponente
 
Ich denke, ohne eigene Komponente wirst Du nichts erreichen.

Mal ein paar Rückfragen:
- Nutzt Du D5 Prof?
- Hast Du schon versucht, eine eigene Komponente abzuleiten und wie weit bist Du gekommen?

So schwierig ist das im Grunde nicht. Vielleicht können wir Dich auf den Weg bringen...

hathor 8. Jul 2015 12:22

AW: Maus-transparente Komponente
 
Zitat:

Zitat von achi 3.0 (Beitrag 1308081)
Hallo,

habe momentan das gleiche Problem. Ist es möglich diese funktion auf eine standard Paintbox zu übertragen? Wenn ja wie denn, irgendwie bekomme ich es nicht hin eine neue komp zu erstellen.

Gruß

Vielleicht geht es mit einem PageControl (PC1):
(Ich habe in einem Projekt viele Tabs und darauf bis zu 9 Images.)
Delphi-Quellcode:
procedure TForm1.PC1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var r : TPoint;
begin          
GetCursorPos(r);
Label2.Caption:= INTTOSTR(r.X) +' - '+ INTTOSTR(r.Y);
end;

achi 3.0 13. Jul 2015 13:17

AW: Maus-transparente Komponente
 
Hi jungs,

sorry für meine späte antwort.

Ja ich nutze D5 Prof aber irgendwie hat es mit der eigenen komponente nicht geklappt. Hatte mir das eine oder andere turorial angeschaut aber das ging in die hose :-(

Gruß

Achi

stahli 13. Jul 2015 13:30

AW: Maus-transparente Komponente
 
Schau mal, ob Dir das etwas bringt: http://www.delphipraxis.net/176730-k...er-tshape.html

Ansonsten kleine Schritte versuchen und hier möglichst konkrete Fragen stellen. Je genauer die Frage ist, desto besser kann die Hilfe aussehen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:22 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