![]() |
IStream und IPicture freigeben
Moin Moin,
ich habe mir mit Hilfe vom ![]() Könnt ihr euch das mal ansehen und kommentieren? Gruß Malte
Delphi-Quellcode:
PS: Wie man sieht, habe ich das ganze zum Testen auf eine Form gezeichnet, aber ich will es natürlich im Endeffekt in einer richtigen nonVCL-Anwendung haben...
function LoadPicture(const AFile: string; var pPicture: IPicture):Boolean;
const IID_IPicture : TGUID = '{7BF80980-BF32-101A-8BBB-00AA00300CAB}'; var hFile, hMem: THandle; dwFileSize, dwBytesRead: DWord; pData: Pointer; bRead: Boolean; hRes: HResult; pStream: IStream; begin Result := False; bRead := False; dwBytesRead := 0; //Datei öffnen hFile := CreateFile(PChar(AFile), GENERIC_READ, 0, NIL, OPEN_EXISTING, 0, 0); if hFile <> INVALID_HANDLE_VALUE then begin try //Dateigröße ermitteln dwFileSize := GetFileSize(hFile, nil); if dwFileSize <> INVALID_FILE_SIZE then begin //GlobalMemory reservieren und gleichzeitig mit "Nullen" füllen hMem := GlobalAlloc(GMEM_MOVEABLE{ or GMEM_NODISCARD} or GMEM_ZEROINIT, dwFileSize); if hMem <> 0 then begin //Adresse des ersten Bytes des Speicher-Objects abfragen pData := GlobalLock(hMem); if pData <> nil then begin try //Daten in das Speicher-Object lesen bRead := ReadFile(hFile, pData^, dwFileSize, dwBytesRead, nil); finally //Ich bin mit schreiben fertig, Sperre weg --> Daten bleiben GlobalUnlock(hMem); end; end; if (bRead = True) and (dwFileSize = dwBytesRead) then begin //Aus GobalMemory IStream erzeugen --> freigeben?? //(** wird der Stream freigegeben wird auch automatisch //GlobalMemory freigegeben) pStream := nil; hRes := CreateStreamOnHGlobal(hMem, True {**}, pStream); if (hRes = S_OK) and (pStream <> nil) then begin //IPicture aus der Bilddatei in IStream erzeugen --> freigeben?? hRes := OleLoadPicture(pStream, dwFileSize, False, IID_IPicture, pPicture); if (hRes = S_OK) and (pPicture <> nil) then Result := True; end; end; end; end; finally //Datei wieder zumachen CloseHandle(hFile); end; end; end; procedure TForm1.Button1Click(Sender: TObject); const BildDateiname = 'C:\darc.jpg'; var DC: HDC; hmHeight, hmWidth, nHeight, nWidth: Integer; rc: TRect; pPicture: IPicture; begin if LoadPicture(BildDateiname, pPicture) then begin DC := GetDC(Handle); if(pPicture.get_Width(hmWidth) = S_OK) and (pPicture.get_Height(hmHeight) = S_OK) and (Windows.GetClientRect(Handle,rc)) then begin nWidth := MulDiv(hmWidth,GetDeviceCaps(DC,LOGPIXELSX),2540); nHeight := MulDiv(hmHeight,GetDeviceCaps(DC,LOGPIXELSY),2540); pPicture.Render(DC, 0, 0, nWidth, nHeight, 0, hmHeight, hmWidth, -hmHeight, rc); end; ReleaseDC(Handle,DC); //pPicture und zugrundeliegendes IStream wieder freigeben: //??? end; end; |
Re: IStream und IPicture freigeben
Hat denn keiner einen kleinen Tip oder Denkanstoß für mich :cry:
Gruß Malte |
Re: IStream und IPicture freigeben
Hallo,
die Erkenntnis hat mich getroffen wie der Blitz :wink: Also für alle, die das hier mal lesen und denen eine Lösung helfen würde: Sowohl die Variable vom Typ IStream als auch IPicture sind Interfaces und Interfaces verwalten sich bekanntlich selbst (s. ![]()
Delphi-Quellcode:
einfügen.
pStream := nil
//bzw. pPicture := nil; Ich habe das im folgenden in meinem am Anfang geposteten Code nochmal eingefügt (man beachte die blauen Stellen). Außerdem habe ich den Code jetzt so umgebaut, dass der mit GlobalAlloc reservierte Speicher auf jeden Fall von GlobalFree freigegeben wird. (rote Markierung) Das halte ich für die bessere Lösung, da bei der ersten Version im Fehlerfall ein Problem entstehen kann: Speicher wird zwar reserviert, aber Stream nicht erzeugt, also auch nicht wieder freigegeben (wobei der Stream dann ja ursprünglich den Speicher mit hätte freigeben sollen), also wird auch Speicher nicht freigegeben
Code:
Edit: Ich hoffe ich habe alle > und < wieder in < und > verwandelt...
uses
ActiveX; function LoadPicture(const AFile: string; var pPicture: IPicture):Boolean; const IID_IPicture : TGUID = '{7BF80980-BF32-101A-8BBB-00AA00300CAB}'; var hFile, hMem: THandle; dwFileSize, dwBytesRead: DWord; pData: Pointer; bRead: Boolean; hRes: HResult; pStream: IStream; begin Result := False; bRead := False; dwBytesRead := 0; //Datei öffnen hFile := CreateFile(PChar(AFile), GENERIC_READ, 0, NIL, OPEN_EXISTING, 0, 0); if hFile <> INVALID_HANDLE_VALUE then begin try //Dateigröße ermitteln dwFileSize := GetFileSize(hFile, nil); if dwFileSize <> INVALID_FILE_SIZE then begin //GlobalMemory reservieren und gleichzeitig mit "Nullen" füllen hMem := GlobalAlloc(GMEM_MOVEABLE{ or GMEM_NODISCARD} or GMEM_ZEROINIT, dwFileSize); if hMem <> 0 then begin [color=#ff0000]try[/color] //Adresse des ersten Bytes des Speicher-Objects abfragen pData := GlobalLock(hMem); if pData <> nil then begin try //Daten in das Speicher-Object lesen bRead := ReadFile(hFile, pData^, dwFileSize, dwBytesRead, nil); finally //Ich bin mit schreiben fertig, Sperre weg --> Daten bleiben GlobalUnlock(hMem); end; end; if (bRead = True) and (dwFileSize = dwBytesRead) then begin //Aus GobalMemory IStream erzeugen pStream := nil; hRes := CreateStreamOnHGlobal(hMem, [color=#ff0000]False[/color], pStream); if (hRes = S_OK) and (pStream <> nil) then begin //IPicture aus der Bilddatei in IStream erzeugen hRes := OleLoadPicture(pStream, dwFileSize, False, IID_IPicture, pPicture); if (hRes = S_OK) and (pPicture <> nil) then Result := True; [color=#0000ff]pStream := nil;[/color] end; end; [color=#ff0000]finally //Speicher-Objekt freigeben GlobalFree(hMem); end;[/color] end; end; finally //Datei wieder zumachen CloseHandle(hFile); end; end; end; procedure TForm1.Button1Click(Sender: TObject); const BildDateiname = 'C:\darc.jpg'; var DC: HDC; hmHeight, hmWidth, nHeight, nWidth: Integer; rc: TRect; pPicture: IPicture; begin if LoadPictureFromFile(BildDateiname, pPicture) then begin DC := GetDC(Handle); if(pPicture.get_Width(hmWidth) = S_OK) and (pPicture.get_Height(hmHeight) = S_OK) and (Windows.GetClientRect(Handle,rc)) then begin nWidth := MulDiv(hmWidth,GetDeviceCaps(DC,LOGPIXELSX),2540); nHeight := MulDiv(hmHeight,GetDeviceCaps(DC,LOGPIXELSY),2540); pPicture.Render(DC, 0, 0, nWidth, nHeight, 0, hmHeight, hmWidth, -hmHeight, rc); end; ReleaseDC(Handle,DC); [color=#0000ff]//pPicture wieder freigeben: pPicture := nil;[/color] end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:16 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