AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

"Transparenz" bei eigener Komponente

Ein Thema von H4ndy · begonnen am 28. Feb 2004 · letzter Beitrag vom 3. Feb 2005
Antwort Antwort
Benutzerbild von H4ndy
H4ndy

Registriert seit: 28. Jun 2003
Ort: Chemnitz
515 Beiträge
 
Delphi XE3 Professional
 
#1

"Transparenz" bei eigener Komponente

  Alt 28. Feb 2004, 16:27
Hallo DP'ler!

Und zwar folgendes:
Ich habe angefangen, mich mal mit der Entwicklung
einer graphischen Komponente zu beschäftigen.
Dazu habe ich meine meine Komponente von TGroupBox
abgeleitet und habe auch schon einiges geschafft.

Nur scheitere ich jetzt daran, meine GroupBox transparent
zu machen, sprich den Hintergrund des Forms zu zeigen.
(Wie z.b. bei TextEd -> http://www.delphipraxis.net/internal...ect.php?t=8203 )

Bin ja schon auf die Idee gekommen mit CopyRect das zu
machen, nur weiss ich jetzt nicht, wie ich an das Canvas von dem
Form komme, auf welchem die Komponente plaziert wurde.

Weiss jemand rat?
( Ich hoffe das war jetzt verständlich genug )
Manuel
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#2

Re: "Transparenz" bei eigener Komponente

  Alt 28. Feb 2004, 16:46
du musst dazu die Message wm_draw abfangen wenn du selbst zeichnen willst, oder du überschreibst die methode paint
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Benutzerbild von H4ndy
H4ndy

Registriert seit: 28. Jun 2003
Ort: Chemnitz
515 Beiträge
 
Delphi XE3 Professional
 
#3

Re: "Transparenz" bei eigener Komponente

  Alt 28. Feb 2004, 23:07
Zitat von SirThornberry:
du musst dazu die Message wm_draw abfangen wenn du selbst zeichnen willst, oder du überschreibst die methode paint
Naja Paint hab ich ja schon überschrieben,
da ich ja die Caption beliebig ausrichten wollte.

Gibts ne einfachere Methode als wm_draw abzufangen,
um an das Canvas des Forms zu kommen?
Oder überhaupt ne andere Methode, dass
ich meine Komponente durchsichtig machen kann?
Manuel
  Mit Zitat antworten Zitat
Benutzerbild von H4ndy
H4ndy

Registriert seit: 28. Jun 2003
Ort: Chemnitz
515 Beiträge
 
Delphi XE3 Professional
 
#4

Re: "Transparenz" bei eigener Komponente

  Alt 1. Mär 2004, 14:12
Nach längerem nachforschen hab ich festgestellt, dass
sich die Transparenz nicht ohne weiteres einfügen lässt.

Hab meine Kompo jetzt von TGraphicControl abgeleitet.
Hat zwar jetzt keine "echte" GroupBox-Funktionalität,
schiebt aber trotzdem seine Dienst =)
Manuel
  Mit Zitat antworten Zitat
franz

Registriert seit: 23. Dez 2003
Ort: Bad Waldsee
112 Beiträge
 
Delphi 5 Professional
 
#5

Re: "Transparenz" bei eigener Komponente

  Alt 21. Jul 2004, 23:42
Hi,
Ich habe hier eine Lösung für alle Komponenten, die von TWinControl abgeleitet sind. Allerdings funktioniert die Lösung nicht mit folgenden Farben, was im übrigen gar nicht so schlimm ist, da die transparente Farbe automatisch ermittelt werden kann.

clScrollBar, clBackground, clActiveCaption, clInactiveCaption, clMenu, clWindow, clWindowFrame, clMenuText, clWindowText, clCaptionText, clActiveBorder, clInactiveBorder, clAppWorkSpace, clHighlight, clHighlightText, clBtnFace, clBtnShadow, clGrayText, clBtnText, clInactiveCaptionText, clBtnHighlight, cl3DdkShadow, cl3Dlight, clInfoText, clInfoBk


1. Grundlagen:
Ab Windows 95 unterstützt Windows beliebige Fensterformen.

Nach Microsoft Definition ist ein Fester, unter Windows, ein Objekt, das von einer registrierten Fensterklasse abgeleitet ist und über die Eigenschaften von TWinControl verfügt:

Also sind alle von TWinControl abgeleiteten Klassen Fenster.


2. Komponente transparent machen
Komponente, die von TGraphicControl abgeleitet sind, sind bereits transparent. Mit dem folgenden Code kann man nur Komponenten transparent machen, die von TWinControl abgeleitet sind (Erklärung siehe 1. Grundlagen).


Zunächst müssen wir sicherstellen, dass wir das Steuerelement wieder zurücksetzen können. Also die Transparenz wieder entfernen:

Hinweis: Die Prozedur UndoTransparent wird von MakeTransparent (weiter unten) aufgerufen
Delphi-Quellcode:
// Transparenz rückgängig machen
procedure UndoTransparent(Control: TWinControl);
var
  HR: HRgn;
begin
  if not Assigned(Control) then
     Exit;

  HR := CreateRectRgn(0,0,Control.Width,Control.Height);
  SetWindowRgn(Control.Handle, HR, true);
end;

Nun müssen wir einen ScreenShot des Steuerelements anfertigen, damit der Inhalt des Steuerelements nicht verloren geht und wir somit am Schluss gar nicht mehr sehen würden:

Hinweis: Die Prozedur TakeControlScreenShot wird von MakeTransparent (weiter unten) aufgerufen
Delphi-Quellcode:
// ScreenShot des Steuerelements anfertigen und an das übergebene Bitmap
// übergeben
procedure TakeControlScreenShot(Control: TWinControl; var Bitmap: TBitmap);

type
  LogPal = record
    lpal : TLogPalette;
    dummy: array[0..255] of TPaletteEntry;
  end;

var
  SysPal: LogPal;
  mImage: TImage;
  mPal: HPalette;
  mHDC: HDC;
  mCanvas: TCanvas;
  mRect: TRect;
begin
  if not Assigned(Control) then
     Exit;

  mHDC := GetWindowDC(Control.Handle);

  SysPal.lPal.palVersion := $300;
  SysPal.lPal.palNumEntries := 256;

  GetSystemPaletteEntries(mHDC, 0, 256, SysPal.lpal.PalpalEntry);
  mPal := CreatePalette(SysPal.lpal);

  mCanvas := TCanvas.Create;
  try
    mCanvas.Handle := mHDC;
    mRect := Rect(0, 0, Screen.Width, Screen.Height);

    mImage := TImage.Create(nil);
    try
      with mImage do
        begin
          Height := Control.Height;
          Width := Control.Width;

          Canvas.CopyRect(mRect, mCanvas, mRect);
          ReleaseDC(GetDeskTopWindow, mHDC);
          Picture.Bitmap.Palette := mPal;
        end;

      Bitmap.Assign(mImage.Picture.Bitmap);
    finally
      mImage.Free;
    end;

    ReleaseDC(GetDeskTopWindow, mHDC);
    ReleaseDC(Control.Handle, mCanvas.Handle)
  finally
    mCanvas.Free;
  end;
end;

Jetzt kommt erst die eigentliche Prozedur, die das Steuerelement transparent macht.
Dummerweise muss zu diesem Zweck die Pixels Eigenschaft von TBitmap.Canvas verwendet werden. Mit ScanLine hat es einfach nicht funktioniert.

Hinweis: Die Prozedur MakeTransparent muss logischerweise aufgerufen werden
Delphi-Quellcode:
// Steuerelement Transparent machen
procedure MakeTransparent(Control: TWinControl; TranspColor: TColor = clNone);
var
  HR, mBuf: HRgn;
  ix, iy: Integer;
  Bitmap: TBitmap;
begin
  // Objekte Prüfen
  [Edit]
     // Alter Quelltext:
     // Vorher wurde ein Bitmap an die Prozedur übergeben
     {if (not Assigned(Control)) or (not Assigned(Bitmap)) then
        Exit;}


     // Neuer Quelltext
     // Da das Bitmap nicht mehr an die Prozedur übergeben wird
     if (not Assigned(Control)) then
         Exit;
  [/Edit]

  // Transparenz rückgängig machen
  UndoTransparent(Control);

  // Steuerelement transparent machen
  HR := CreateRectRgn(0,0,0,0);
  Bitmap := TBitmap.Create;
  try
    // Screen Shot des Steuerlement anfertigen
    TakeControlScreenShot(Control,Bitmap);

    // Transparente Farbe einstellen, falls nötig
    if TranspColor = clNone then
       TranspColor := Bitmap.Canvas.Pixels[0,0];

    // Sichtbaren Bereich erstellen
    for iy := 0 to Bitmap.Height-1 do
      begin
        if (iy mod 50) = 0 then
           Application.ProcessMessages;

        for ix := 0 to Bitmap.Width-1 do
          begin
            if Bitmap.Canvas.Pixels[ix,iy] <> TranspColor then
               begin
                 mBuf := CreateRectRgn(ix,iy,1+ix,1+iy);
                 try
                   CombineRgn(HR, HR, mBuf, RGN_OR);
                 finally
                   DeleteObject(mBuf);
                 end;
               end;
          end;
      end;

    // Sichtbaren Bereich dem Steuerelement zuordnen
    SetWindowRgn(Control.Handle, HR, true);
  finally
    DeleteObject(HR);
    Bitmap.Free;
  end;
end;

Aufgerufen wird das ganze folgendermaßen. Dabei wird GroupBox1 transparent gemacht.
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  MakeTransparent(GroupBox1);
end;
Zunächst muss sichergestellt werden, dass das Steuerelement nicht mehr transparent ist. Danach wird es wieder transparent gemacht. Der zweite Parameter von MakeTransparent gibt die transparente Farbe an. Wenn nichts angegeben wird, wird als transparente Farbe die Farbe des ersten Pixels verwendet.

Warnung!
MakeTransparent greift auf die Eigenschaft TCanvas.Pixels zu. Dadurch kann je nach Größe des Steuerelements die Berechnung etwas dauern. Rufe NIEMALS MakeTransparent innerhalb von OnPaint auf! Sonst „steht“, unter Umständen, der Computer! Es empfiehlt sich einen Thread für das transparent machen eines Steuerelements zu verwenden.
Miniaturansicht angehängter Grafiken
twincontrol_transp.gif  
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#6

Re: "Transparenz" bei eigener Komponente

  Alt 22. Jul 2004, 00:49
das einfachste ist "CreateParams" zu überschreiben und einfach anzugeben das die Komponente transparent ist
Delphi-Quellcode:
procedure TNewCompo.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  Params.ExStyle := Params.ExStyle + WS_EX_Transparent;
end;
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#7

Re: "Transparenz" bei eigener Komponente

  Alt 22. Jul 2004, 00:59
Moin!

Zitat von franz:
Hi,
Ich habe hier eine Lösung für alle Komponenten, die von TWinControl abgeleitet sind. Allerdings funktioniert die Lösung nicht mit folgenden Farben, was im übrigen gar nicht so schlimm ist, da die transparente Farbe automatisch ermittelt werden kann.

clScrollBar, clBackground, clActiveCaption, clInactiveCaption, clMenu, clWindow, clWindowFrame, clMenuText, clWindowText, clCaptionText, clActiveBorder, clInactiveBorder, clAppWorkSpace, clHighlight, clHighlightText, clBtnFace, clBtnShadow, clGrayText, clBtnText, clInactiveCaptionText, clBtnHighlight, cl3DdkShadow, cl3Dlight, clInfoText, clInfoBk
Dazu kann ich Abhilfe geben. Diese Farben sind Konstanten mit einem negativen Wert und enthalten keine RGB Werte, weshalb sie nicht funktionieren bei dem Pixels[] Vergleich. Abhilfe schafft hier einfach, wenn man die Transparenzfarbe vorher durch ColorToRGB() durchjagt, danach sind diese Konstanten zu den aktuellen RGB Werten der Systemeinstellungen umgewandelt. Danach ist dann auch der Vergleich möglich.

MfG
Muetze1
  Mit Zitat antworten Zitat
Benutzerbild von CReber
CReber

Registriert seit: 26. Nov 2003
Ort: Berlin
343 Beiträge
 
Delphi 2006 Professional
 
#8

Re: "Transparenz" bei eigener Komponente

  Alt 1. Feb 2005, 19:50
*Thread ausbuddel

Wollte grad dem von SirThornberry nachgehen und habe eine mit eine TTransPageControl gebastelt aber leider scheint es nur zur Hälfte zur funktionieren. Sobald TabSheets drauf sind ist da leider nichts mehr Transparent

Kann wer helfen?

Delphi-Quellcode:
unit uMain;

interface

uses
  Windows, Classes, Controls, ComCtrls, ExtCtrls;

type
  TTransPageControl = class(TPageControl)
  private
  public
    procedure CreateParams(var Params: TCreateParams); override;
  published
  end;

procedure Register;

implementation

procedure TTransPageControl.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  Params.ExStyle := Params.ExStyle + WS_EX_Transparent;
end;

procedure Register;
begin
  RegisterComponents('Test', [TTransPageControl]);
end;

end.
Christian Reber
  Mit Zitat antworten Zitat
delphifan2004

Registriert seit: 26. Nov 2004
Ort: Dresden
266 Beiträge
 
Delphi 10.3 Rio
 
#9

Re: "Transparenz" bei eigener Komponente

  Alt 3. Feb 2005, 14:23
Hallo Christian!

Ich vermute, dass dann das TabSheet auch explizit als TransTabSheet abgeleitet werden muß und dann anstelle des Delphi-eigenen TabSheets zu verwenden ist.

Delphifan2004 alias Wilfried
  Mit Zitat antworten Zitat
Benutzerbild von CReber
CReber

Registriert seit: 26. Nov 2003
Ort: Berlin
343 Beiträge
 
Delphi 2006 Professional
 
#10

Re: "Transparenz" bei eigener Komponente

  Alt 3. Feb 2005, 18:00
Und wie weise ich dem TTransPageControl zu, dass es TTransTabSheets verwenden soll? Daran bin ich nämlich gescheitert
Christian Reber
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:16 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