Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi LayeredWindows, sporadische Zugriffsverletzung bei Streams? (https://www.delphipraxis.net/126837-layeredwindows-sporadische-zugriffsverletzung-bei-streams.html)

Prototypjack 3. Jan 2009 10:05


LayeredWindows, sporadische Zugriffsverletzung bei Streams?
 
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

Garfield 4. Jan 2009 15:48

Re: LayeredWindows, sporadische Zugriffsverletzung bei Strea
 
Bei mir gibt es unter TD keinen Fehler. Eventuell bringt es die eine Zeile:

Delphi-Quellcode:
// Start Veränderungen
    AStream.Position := 0;
    OleStream := TStreamAdapter.Create(AStream);

    OleStream.Seek(0, 0, tPos); // <- tPos : Int64;

    if GdipLoadImageFromStream(OleStream, img) <> 0 then Result := False;
// Ende Veränderungen; Diese Zeilen ersetzen "if GdipLoadImageFromFile(imageFilename, img) <> 0 then Result:=false;" im Originalcode.


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