Transparentes Einblenden von Grafiken mittels der WinApi:
Diese Funktionen/Variablen müssen im Projekt hinterlegt werden:
Delphi-Quellcode:
// basiert auf:
// [url]http://groups.google.de/groups?selm=3d4a7380_1%40dnews[/url]
// Dll-Variable, am besten im Form deklarieren und
// mit 0 initialisieren
var Hmsimg32: THandle = 0;
// Funktion fürs AlphaBlending, bei Fehlschlag einfaches Copy
// Gründe fürs Fehlschlagen:
// kein Win98/2000/XP
// Kein Source 32bit
// ...
function TryAlphaBlend(
DC: HDC; p2, p3, p4, p5: Integer;
DC6: HDC; p7, p8, p9, p10: Integer; p11: TBlendFunction): Boolean;
var F:
function(
DC: HDC; p2, p3, p4, p5: Integer;
DC6: HDC; p7, p8, p9, p10: Integer;
p11: TBlendFunction): BOOL;
stdcall;
begin
Result := False;
if Hmsimg32 = 0
then
Hmsimg32 := LoadLibrary(msimg32);
if Hmsimg32 <> 0
then
begin
@F := GetProcAddress(Hmsimg32, '
AlphaBlend');
if @F <>
nil then
Result := F(
DC, p2, p3, p4, p5, DC6, p7, p8, p9, p10, p11);
end;
if not Result
then
Result := BitBlt(
DC, p2, p3, p4, p5, DC6, p7, p8, SRCCOPY);
end;
// TryAlphaBlend
Die Funktion
TryAlphaBlend kapselt die
WinAPI-Funktion
AlphaBlend und lädt diese Funktion dynamisch. Das ist notwendig, um das Projekt auch auf Win95/NT lauffähig zu erhalten, wo es diese Funktion noch nicht gibt. Zum Dynamischen Lader der
DLL wird die Variable
Hmsimg32 genutzt, welche das
Handle der
DLL zwischenspeichert. Dies Variable wird bleibt nach dem Laden der
DLL mit
LoadLibrary dauerhaft belegt, da jeder dynamische Ladevorgang in Delphi sonst 4kB Speicher verbraucht.
Die Funktion AlphaBlend wird der Variablen F zugeordnet und kann dann aufgerufen werden. Natürlich kann auch irgendwas schief gehen, der Anwender kann das falsche BS haben oder eine zu geringe Farbtiefe oder die kopierten Bereiche liegen auf der gleichen Bitmap und überlappen sich... In diesem Falle würde die Funktion nicht durchgeführt. Als Rettungsanker wird darum noch BitBlt aufgerufen, der dafür sorgt, dass die Zeichnung dann wenigsten noch nicth transparent eingeblendet wird (besser als nichts
).
Aufruf der Funkion:
Delphi-Quellcode:
var BlendFunction: TBlendFunction;
...
// Aufruf der Funktion
BlendFunction.AlphaFormat := 0;
BlendFunction.BlendFlags := 0;
BlendFunction.BlendOp := AC_SRC_OVER;
BlendFunction.SourceConstantAlpha := 100; // 0 .. 255 (255 = volle Sichtbarkeit)
TryAlphaBlend(DstCanvas.Handle,
DstLeft, DstTop,
DstWidth, DstHeight,
SrcCanvas.Handle,
SrcLeft, SrcTop,
SrcWidth, SrcHeight,
BlendFunction);
Der Funktion muss einerseits der Zielbereich übergeben werden, dazu gehört das
Handle vom entsprechenden Canvas, sowie der linke obere Rand und die Ausdehnung (DstLeft, DstTop, DstWidth, DstHeight). Ferner werden die gleichen Daten von der Quelle (Src) benötigt. Sind die Breite oder Höhe unterschiedlich wird die Grafik laut Dokumentation gestreckt (nicht getestet).
Weiterhin muss der Parameter vom Typ
TBlendFunction übergeben werden. Die drei ersten Werte sollten nicht geändert werden, mit dem Wert
SourceConstantAlpha kann die Transparent stufenlos von 0 (vollständig transparent = nicht sichtbar) bis 255 (keine Transparenz) gesteuert werden.
Wichtig - Kurzfassung
Nur Win98/2000/XP
Quellbereich 32Bit Farbtiefe
keine Bereichsüberlappung bei Quell- und Zielbereich
Anmerkung
Ich habe die Funktion für die Einblendung des Profiles auf eine Grafik benötigt. Das Profil hatte aber keine rechteckige Abmessung, es war also Freiraum, welcher eigentlich nicht eingeblendet werden durfte. In diesem Falle empfiehlt es sich, vorm dem Zeichnen des einzukopierenden Objektes den Zielhintergrund als Basis zu verwenden. Wenn gleich aussehende Bereiche in einander kopiert werden, ist das Ergebnis unabhängig von der Transparenz
keine Veränderung. Dies wirkt dann so, als würde man eine freigestellt Grafik transparent einblenden.