AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Icon ersetzen funktioniert nicht

Ein Thema von Uncle Cracker · begonnen am 16. Jul 2004 · letzter Beitrag vom 16. Jul 2004
Antwort Antwort
Benutzerbild von Uncle Cracker
Uncle Cracker

Registriert seit: 30. Mär 2003
Ort: Freital
694 Beiträge
 
#1

Icon ersetzen funktioniert nicht

  Alt 16. Jul 2004, 12:04
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:
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;
Als Fehlercode habe ich bei der oberen Funktion '0' erhalten.
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...
  Mit Zitat antworten Zitat
scp

Registriert seit: 31. Okt 2003
1.120 Beiträge
 
Delphi 7 Personal
 
#2

Re: Icon ersetzen funktioniert nicht

  Alt 16. Jul 2004, 14:07
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.
  Mit Zitat antworten Zitat
Benutzerbild von Uncle Cracker
Uncle Cracker

Registriert seit: 30. Mär 2003
Ort: Freital
694 Beiträge
 
#3

Re: Icon ersetzen funktioniert nicht

  Alt 16. Jul 2004, 15:57
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...
  Mit Zitat antworten Zitat
scp

Registriert seit: 31. Okt 2003
1.120 Beiträge
 
Delphi 7 Personal
 
#4

Re: Icon ersetzen funktioniert nicht

  Alt 16. Jul 2004, 16:42
Es ist noch nicht ganz fertig, aber funktionieren tuts schon:
So, hier die fertige Version:

Delphi-Quellcode:
// 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;
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).

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.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es 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

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:24 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