![]() |
Icon ersetzen funktioniert nicht
Ich habe jetzt 2 Methoden probiert das Icon einer anderen selbsterstellten Delphi Anwendung zuändern, aber keine davon hat funktioniert, was muss ich denn noch machen?
Hier mal die beiden Funktionen:
Delphi-Quellcode:
Als Fehlercode habe ich bei der oberen Funktion '0' erhalten.
type
PICONDIRENTRYCOMMON = ^ICONDIRENTRYCOMMON; ICONDIRENTRYCOMMON = packed record bWidth: Byte; // Width, in pixels, of the image bHeight: Byte; // Height, in pixels, of the image bColorCount: Byte; // Number of colors in image (0 if >=8bpp) bReserved: Byte; // Reserved ( must be 0) wPlanes: Word; // Color Planes wBitCount: Word; // Bits per pixel dwBytesInRes: DWord; // How many bytes in this resource? end; PICONDIRENTRY = ^ICONDIRENTRY; ICONDIRENTRY = packed record common: ICONDIRENTRYCOMMON; dwImageOffset: DWord; // Where in the file is this image? end; PICONDIR = ^ICONDIR; ICONDIR = packed record idReserved: Word; // Reserved (must be 0) idType: Word; // Resource Type (1 for icons) idCount: Word; // How many images? idEntries: ICONDIRENTRY; // An entry for each image (idCount of 'em) end; PGRPICONDIRENTRY = ^GRPICONDIRENTRY; GRPICONDIRENTRY = packed record common: ICONDIRENTRYCOMMON; nID: Word; // the ID end; PGRPICONDIR = ^GRPICONDIR; GRPICONDIR = packed record idReserved: Word; // Reserved (must be 0) idType: Word; // Resource type (1 for icons) idCount: Word; // How many images? idEntries: GRPICONDIRENTRY; // The entries for each image end; function UpdateApplicationIcon(icofile: PChar; exefile: PChar; resID:PcHar; LangID:DWORD): Boolean; var hInst,hFile: THandle; id: ICONDIR; pid: PICONDIR; pgid: PGRPICONDIR; uRead: DWord; nSize: DWord; pvFile: PByte; begin result := False; hFile := CreateFile(icofile, GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if hFile <> INVALID_HANDLE_VALUE then try ReadFile(hFile, id, sizeof(id), uRead, nil); SetFilePointer(hFile, 0, nil, FILE_BEGIN); GetMem(pid, sizeof(ICONDIR) + sizeof(ICONDIRENTRY)); GetMem(pgid, sizeof(GRPICONDIR) + sizeof(GRPICONDIRENTRY)); ReadFile(hFile, pid^, sizeof(ICONDIR) + sizeof(ICONDIRENTRY), uRead, nil); move(pid^, pgid^, sizeof(GRPICONDIR)); pgid^.idEntries.common := pid^.idEntries.common; pgid^.idEntries.nID := 1; nSize := pid^.idEntries.common.dwBytesInRes; GetMem(pvFile, nSize); SetFilePointer(hFile, pid^.idEntries.dwImageOffset, nil, FILE_BEGIN); ReadFile(hFile, pvFile^, nSize, uRead, nil); hInst := BeginUpdateResource(exefile, False); if hInst <> 0 then try result:=UpdateResource(hInst, RT_ICON, resID, LangID, pvFile, nSize); finally EndUpdateResource(hInst, False); end; FreeMem(pvFile); FreeMem(pgid); FreeMem(pid); finally CloseHandle(hFile); end; end; procedure TForm1.Button1Click(Sender: TObject); begin if UpdateApplicationIcon('Test.ico', 'Test.exe', MAKEINTRESOURCE(1), 1031) then Showmessage('Icon successfully updated') else Showmessage('Icon update failed Errorcode:', GetLastError); end; Hier meine andere Methode, diese funktioniert ebenfalls nicht :(
Delphi-Quellcode:
function ErsetzeICO(Datei, ICO: string): Boolean;
var stream : TFilestream; hInst: THandle; ptr : Pointer; begin result := false; Stream := TFileStream.Create(ICO,fmOpenRead); getmem (ptr,Stream.size+1); try Stream.Seek(0,sofrombeginning); stream.read(ptr^,Stream.size); hInst:=BeginUpdateResource(Pchar(Datei), true); if hInst > 0 then begin UpdateResource(hInst, RT_Icon, MAKEINTRESOURCE(1), 1031,ptr,Stream.size); EndUpdateResource(hInst, False); result := true; end; finally freemem (ptr,Stream.size+1); stream.Free; end; end; Weiß vielleicht jemand, warum das Icon der EXE nicht ersetzt wird? Oder kennt vielleicht noch jemand eine andere Funktion zum ersetzten eines Icons? :love: Danke UC |
Re: Icon ersetzen funktioniert nicht
Die obere Funktion klappt bei mir wunderbar, allerdings dürfte es damit Probleme geben, wenn das zu ersetzende Icon zu einer Icon-Gruppe gehört (RT_GROUP_ICON). Dann wird nämlich nur ein Icon ersetzt, die dazugehörigen (andere Auflösungen wie 16x16 32x32 oder Farbtiefe 4bit 8bit 24bit) werden aber nicht ersetzt.
Die untere Funktion dürfte aus selbem Grund von vornherein nicht funktionieren, da du ja den Header und alle in der .ICO enthaltenen Icons versuchst in ein einziges Icon zu quetschen. |
Re: Icon ersetzen funktioniert nicht
Mhhhh... ich kann dir jetzt nicht ganz folgen :roll:
Ich habe jetzt ein Icon das 16x16 Groß ist, mit einer Farbtiefe von 32 Bit. Mit der oberen Funktion kann ich dieses Icon jedoch nicht ersetzten, muss ich ein anderes Format bzw. die Farbtiefe des Icons ersetzten oder was? :love: Danke UC |
Re: Icon ersetzen funktioniert nicht
Es ist noch nicht ganz fertig, aber funktionieren tuts schon:
So, hier die fertige Version:
Delphi-Quellcode:
Diese Funktion braucht den Code, den du schon oben angegeben hast. Der einzige Unterschied beim Aufruf ist, das man die ID der Icongruppe angibt, anstatt die des einzelnen Icons. Also zum Beispiel bei einem Delphi-Prog 'MAINICON' statt MAKEINTRESOURCE(1).
// You can add unit Math to uses instead of using this function
function Log2(X: Extended): Extended; asm FLD1 FLD X FYL2X FWAIT end; type PIconHeader = ^TIconHeader; TIconHeader = packed record idReserved: Word; // Reserved (must be 0) idType: Word; // Resource Type (1 for icons) idCount: Word; // How many images? end; function UpdateApplicationIconGroup(icofile: PChar; exefile: PChar; resID:PcHar; LangID:DWORD): Boolean; type PIconResInfoArray = ^TIconResInfoArray; TIconResInfoArray = packed record idReserved: Word; // Reserved (must be 0) idType: Word; // Resource Type (1 for icons) idCount: Word; // How many images? idEntries: array[0..(MaxInt div SizeOf(GRPICONDIRENTRY))-2] Of GRPICONDIRENTRY; end; TIconOffsetArray = array[0..(MaxInt div SizeOf(DWORD))-1] Of DWORD; PIconOffsetArray = ^TIconOffsetArray; TIconResIDArray = array[0..(MaxInt div SizeOf(Word))-1] Of Word; PIconResIDArray = ^TIconResIDArray; var hExeInst : HMODULE; hResInst : THANDLE; AIconHeader : TIconHeader; AIconResInfo : GRPICONDIRENTRY; AIconResInfoArray : PIconResInfoArray; AIconOffsetArray : PIconOffsetArray; AIconResIDArray : PIconResIDArray; i,CurResID : integer; //AIconOrdinals : array Of Word; hFile: THandle; id: ICONDIR; ide: ICONDIRENTRY; pid: PICONDIR; pgid: PGRPICONDIR; uRead: DWord; nSize: DWord; pvFile: PByte; hResSrc : HRSRC; hResGlob : HGLOBAL; pRes : Pointer; ResSize : DWORD; begin result := False; hFile := CreateFile(icofile, GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); FillChar(id, sizeof(id), 0); if hFile <> INVALID_HANDLE_VALUE then try ReadFile(hFile, id, sizeof(id), uRead, nil); finally CloseHandle(hFile); end; AIconResIDArray := nil; FillChar(AIconHeader, SizeOf(AIconHeader), 0); hExeInst := LoadLibraryEx(exefile, 0, LOAD_LIBRARY_AS_DATAFILE); If (hExeInst <> 0) then begin hResSrc := FindResourceEx(hExeInst, RT_GROUP_ICON, resID, LangID); If (hResSrc <> 0) Then begin // get resource size ResSize := SizeofResource(hInstance, hResSrc); If (ResSize <> INVALID_FILE_SIZE) Then begin hResGlob := LoadResource(hExeInst, hResSrc); If (hResGlob <> 0) Then begin pRes := LockResource(hResGlob); If (pRes <> nil) Then begin // Collect information about old Icon group CopyMemory(@AIconHeader, pRes, SizeOf(AIconHeader)); Inc(PChar(pRes), SizeOf(AIconHeader)); {Form1.ListBox1.Items.Add('Type: ' + IntToStr(AIconHeader.idType) + ', ' + 'Count: ' + IntToStr(AIconHeader.idCount));} FillChar(AIconResInfo, SizeOf(AIconResInfo), 0); //SetLength(AIconOrdinals, AIconHeader.wCount); If (AIconHeader.idCount < id.idCount) then GetMem(AIconResIDArray, id.idCount*SizeOf(Word)) else GetMem(AIconResIDArray, AIconHeader.idCount*SizeOf(Word)); FillChar(AIconResIDArray^, AIconHeader.idCount*SizeOf(Word), 0); for i := 1 to AIconHeader.idCount do begin CopyMemory(@AIconResInfo, pRes, SizeOf(AIconResInfo)); Inc(PChar(pRes), SizeOf(AIconResInfo)); AIconResIDArray^[i-1] := AIconResInfo.nID; //If (AIconResInfo.common.wBitCount = 0) then // AIconResInfo.common.wBitCount := Trunc(log2(AIconResInfo.common.bColorCount)); {Form1.ListBox1.Items.Add(IntToStr(AIconResInfo.common.bWidth) + 'x' + IntToStr(AIconResInfo.common.bHeight) + ', ' + IntToStr(AIconResInfo.common.bColorCount + (AIconResInfo.common.bReserved * $100)) + ' colors' //+ ', ' + IntToStr(AIconResInfo.common.bReserved) + ' bReserved' + ', ' + IntToStr(AIconResInfo.common.wPlanes) + ' planes' + ', ' + IntToStr(AIconResInfo.common.wBitCount) + ' bit' + ', ' + IntToStr(AIconResInfo.common.dwBytesInRes) + ' byte' + ', ' + 'Ordinal ' + IntToStr(AIconResInfo.nID));} end; // Search for unused Icon resource IDs If (AIconHeader.idCount < id.idCount) then begin i := AIconHeader.idCount; CurResID := 1; while (i < id.idCount) and (CurResID < $7FFF) do begin hResSrc := FindResourceEx(hExeInst, RT_ICON, MAKEINTRESOURCE(CurResID), LangID); If not (hResSrc <> 0) Then begin Inc(i); AIconResIDArray^[i-1] := CurResID; end; Inc(CurResID); end; end; end; end; end; end; FreeLibrary(hExeInst); end; If not ((AIconHeader.idCount > 0) and (id.idCount > 0)) then Exit; hFile := CreateFile(icofile, GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if hFile <> INVALID_HANDLE_VALUE then try // Read Data from new icon group in file ReadFile(hFile, id, sizeof(id), uRead, nil); SetFilePointer(hFile, 0, nil, FILE_BEGIN); GetMem(pid, sizeof(ICONDIR) {+ sizeof(ICONDIRENTRY)}); ReadFile(hFile, pid^, sizeof(ICONDIR) {+ sizeof(ICONDIRENTRY)}, uRead, nil); GetMem(pgid, sizeof(GRPICONDIR) {+ sizeof(GRPICONDIRENTRY)}); move(pid^, pgid^, sizeof(GRPICONDIR)); pgid^.idEntries.common := pid^.idEntries.common; pgid^.idEntries.nID := AIconResIDArray^[0]; If (pgid^.idEntries.common.wBitCount = 0) then pgid^.idEntries.common.wBitCount := Trunc(Log2(pgid^.idEntries.common.bColorCount + (pgid^.idEntries.common.bReserved*$100))); {Form1.ListBox1.Items.Add(IntToStr(uRead));} // Write new data to EXE resources hResInst := BeginUpdateResource(exefile, False); // Resource deletion doesn't really work { for i := 1 to AIconHeader.idCount do begin ShowMessage(IntToStr(AIconResIDArray^[i-1])); UpdateResource(hResInst, RT_Icon, MAKEINTRESOURCE(AIconResIDArray^[i-1]), LangID, nil, 0); end; } //CopyMemory(pgid, @AIconHeader, SizeOf(TIconHeader)); //pgid^.idCount := 1; //If (AIconHeader.idCount < pgid^.idCount) then // pgid^.idCount := AIconHeader.idCount; //SetFilePointer(hFile, SizeOf(TIconHeader), nil, FILE_BEGIN); GetMem(AIconResInfoArray, SizeOf(TIconHeader)+(SizeOf(GRPICONDIRENTRY)*pgid^.idCount)); GetMem(AIconOffsetArray , SizeOf(DWORD)*pgid^.idCount); AIconResInfoArray^.idReserved := pgid^.idReserved; AIconResInfoArray^.idType := pgid^.idType; AIconResInfoArray^.idCount := pgid^.idCount; AIconResInfoArray^.idEntries[0] := pgid^.idEntries; AIconOffsetArray^[0] := pid^.idEntries.dwImageOffset; {Form1.ListBox1.Items.Add(IntToStr(AIconResInfoArray^.idEntries[0].common.bColorCount));} for i := 2 to pgid^.idCount do begin ReadFile(hFile, ide, sizeof(ICONDIRENTRY), uRead, nil); AIconResInfoArray^.idEntries[i-1].common := ide.common; AIconResInfoArray^.idEntries[i-1].nID := AIconResIDArray^[i-1]; AIconOffsetArray^[i-1] := ide.dwImageOffset; {Form1.ListBox1.Items.Add(IntToStr(AIconResInfoArray^.idEntries[i-1].common.bColorCount + (AIconResInfoArray^.idEntries[i-1].common.bReserved*$100)));} If (AIconResInfoArray^.idEntries[i-1].common.wBitCount = 0) then AIconResInfoArray^.idEntries[i-1].common.wBitCount := Trunc(Log2(AIconResInfoArray^.idEntries[i-1].common.bColorCount + (AIconResInfoArray^.idEntries[i-1].common.bReserved*$100))); end; pvFile:= nil; result := true; for i := 1 to pgid^.idCount do begin nSize := AIconResInfoArray^.idEntries[i-1].common.dwBytesInRes; GetMem(pvFile, nSize); SetFilePointer(hFile, AIconOffsetArray^[i-1], nil, FILE_BEGIN); ReadFile(hFile, pvFile^, nSize, uRead, nil); result := result and UpdateResource(hResInst, RT_ICON, MAKEINTRESOURCE(AIconResInfoArray^.idEntries[i-1].nID), LangID, pvFile, nSize); end; UpdateResource(hResInst, RT_Group_Icon, resID, LangID, AIconResInfoArray, SizeOf(TIconHeader)+(SizeOf(GRPICONDIRENTRY)*pgid^.idCount)); EndUpdateResource(hResInst, False); FreeMem(AIconOffsetArray); FreeMem(AIconResInfoArray); FreeMem(pvFile); FreeMem(pgid); FreeMem(pid); finally CloseHandle(hFile); end; If Assigned(AIconResIDArray) then FreeMem(AIconResIDArray); end; EDIT 1: Habe sie jetzt soweit erweitert, das alle Icons einer Gruppe ersetzt werden. EDIT 2: for-Schleife korrigiert. Die Funktion geht jetzt übrigens ohne die weiter oben, nur die Typendeklarationen sind davon noch erforderlich. EDIT 3: So, jetzt stimmt alles soweit. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:50 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 by Thomas Breitkreuz