Moin,
Ich arbeite hier ein bisschen mit der
GDI+ und LayeredWindows. Mein Code setzt auf dem Code von AyaKoshigaya auf, gefunden habe ich ihn
hier (einer der letzten Beiträge, User: "Aya").
Die einzigen Veränderungen die ich vornahm waren:
Zum einen habe ich das Laden der
DLL dynamisch gemacht, damit es bei einem Nichtfinden nicht zu einer Exeption und einem Programmabbruch kommt (sondern lediglich die Funktion deaktiviert wird), zum anderen habe ich, und hier liegt das Problem, die Ladeprozedur auf Streams angepasst.
Dafür habe ich folgende Änderungen vorgenommen:
Delphi-Quellcode:
// Funktionsheader
TGdipLoadImageFromStream = function(Stream: IStream; out Image: Cardinal):
Integer; stdcall;
Veränderungen an der Main-Funktion:
Delphi-Quellcode:
function MakeTransparentForm(AFormHandle: hWnd; AWidth, AHeight: Integer;
AStream: TStream): Boolean;
var
tempBitmap: BITMAPINFO;
lngHeight, lngWidth: Cardinal;
curWinLong: Cardinal;
img: Cardinal;
graphics: Cardinal;
winSize: Size;
srcPoint: TPoint;
pvBits: Pointer;
HandleDC: hDC;
OleStream: IStream;
begin
if GdiPlusUsable then
begin
HandleDC := GetDC(AFormHandle);
Result := True;
ZeroMemory(@tempBitmap, SizeOf(BITMAPINFO));
with tempBitmap.bmiHeader do begin
biSize := SizeOf(BITMAPINFOHEADER);
biBitCount := 32;
biWidth := AWidth;
biHeight := AHeight;
biPlanes := 1;
biCompression := BI_RGB;
biSizeImage := biWidth * biHeight * 4;
end;
mDC := CreateCompatibleDC(HandleDC);
mainBitmap := CreateDIBSection(mDC, tempBitmap, DIB_RGB_COLORS, pvBits, 0,
0);
oldBitmap := SelectObject(mDC, mainBitmap);
if GdipCreateFromHDC(mDC, graphics) <> 0 then Result:=false;
// Start Veränderungen
AStream.Position := 0;
OleStream := TStreamAdapter.Create(AStream);
if GdipLoadImageFromStream(OleStream, img) <> 0 then Result := False;
// Ende Veränderungen; Diese Zeilen ersetzen "if GdipLoadImageFromFile(imageFilename, img) <> 0 then Result:=false;" im Originalcode.
if GdipGetImageWidth(img, lngWidth) <> 0 then Result:=false;
if GdipGetImageHeight(img, lngHeight) <> 0 then Result:=false;
if GdipDrawImageRect(graphics, img, 0, 0, lngWidth, lngHeight) <> 0 then
Result:=false;
curWinLong:=GetWindowLong(AFormHandle, GWL_EXSTYLE);
SetWindowLong(AFormHandle, GWL_EXSTYLE, curWinLong or WS_EX_LAYERED);
SetWindowPos(AFormHandle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or
SWP_NOSIZE);
srcPoint.X := 0;
srcPoint.Y := 0;
winSize.cx := AWidth;
winSize.cy := AHeight;
with blendFunc32bpp do begin
AlphaFormat:=AC_SRC_ALPHA;
BlendFlags:=0;
BlendOp:=AC_SRC_OVER;
SourceConstantAlpha:=255;
end;
if GdipDisposeImage(img) <> 0 then Result:=false;
if GdipDeleteGraphics(graphics) <> 0 then Result:=false;
if not UpdateLayeredWindow(AFormHandle, HandleDC, nil, @winSize, mDC,
@srcPoint, 0, @blendFunc32bpp, ULW_ALPHA) then Result := False;
end
else
begin
Result := False;
end;
end;
Irgendwie scheint dies jedoch nicht zu funktionieren, denn ich bekomme (ich füttere hierbei den Stream durch eine Ressource in meinem Programm) sporadisch eine Zugriffsverletzung in einer ntdll.dll. Der Debugger springt mir dabei auf die GdipLoadImageFromStream Anweisung.
Das große Problem bei diesem Fehler ist, dass er nur hin und wieder mal auftritt (wenn, dann aber richtig und es hagelt diese Exeption). Was mache ich hier falsch? Woran kann das liegen?
Danke & Grüße,
Max