|
Antwort |
Registriert seit: 30. Mär 2003 Ort: Freital 694 Beiträge |
#1
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? Danke UC I wish it was legal to marry software because I'm madly in love with Delphi...
|
Zitat |
Registriert seit: 31. Okt 2003 1.120 Beiträge Delphi 7 Personal |
#2
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. |
Zitat |
Registriert seit: 30. Mär 2003 Ort: Freital 694 Beiträge |
#3
Mhhhh... ich kann dir jetzt nicht ganz folgen
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? Danke UC I wish it was legal to marry software because I'm madly in love with Delphi...
|
Zitat |
Registriert seit: 31. Okt 2003 1.120 Beiträge Delphi 7 Personal |
#4
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. |
Zitat |
Ansicht |
Linear-Darstellung |
Zur Hybrid-Darstellung wechseln |
Zur Baum-Darstellung wechseln |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
LinkBack URL |
About LinkBacks |