这个是Delphi的限制,我也正在研究这个。有一个没有完成的单元Icons.pas,你自己看看吧:
//Icons.pas
//the Data Struct For Icon
unit Icons;interfaceuses windows, sysutils;type
  LPByte = pointer;// These first two structs represent how the icon information is stored
// when it is bound into a EXE or DLL file. Structure members are WORD
// aligned and the last member of the structure is the ID instead of
// the imageoffset.type
  PMEMICONDIRENTRY = ^MEMICONDIRENTRY;
  MEMICONDIRENTRY = packed record
    bWidth: BYTE; // Width of the image
    bHeight: BYTE; // Height of the image (times 2)
    bColorCount: BYTE; // Number of colors in image (0 if >=8bpp)
    bReserved: BYTE; // Reserved
    wPlanes: WORD; // Color Planes
    wBitCount: WORD; // Bits per pixel
    dwBytesInRes: DWORD; // how many bytes in this resource?
    nID: WORD; // the ID
  end;type
  PMEMICONDIR = ^MEMICONDIR;
  MEMICONDIR = packed record
    idReserved: WORD; // Reserved
    idType: WORD; // resource type (1 for icons)
    idCount: WORD; // how many images?
    idEntries: array[0..0] of MEMICONDIRENTRY; // the entries for each image
  end;// These next two structs represent how the icon information is stored
// in an ICO file.type
  PICONDIRENTRY = ^ICONDIRENTRY;
  ICONDIRENTRY = packed record
    bWidth: BYTE; // Width of the image
    bHeight: BYTE; // Height of the image (times 2)
    bColorCount: BYTE; // Number of colors in image (0 if >=8bpp)
    bReserved: BYTE; // Reserved
    wPlanes: WORD; // Color Planes
    wBitCount: WORD; // Bits per pixel
    dwBytesInRes: DWORD; // how many bytes in this resource?
    dwImageOffset: DWORD; // where in the file is this image
  end;type
  PICONDIR = ^ICONDIR;
  ICONDIR = packed record
    idReserved: WORD; // Reserved
    idType: WORD; // resource type (1 for icons)
    idCount: WORD; // how many images?
    idEntries: array[0..0] of ICONDIRENTRY; // the entries for each image
  end;// The following two structs are for the use of this program in
// manipulating icons. They are more closely tied to the operation
// of this program than the structures listed above. One of the
// main differences is that they provide a pointer to the DIB
// information of the masks.
type
  PICONIMAGE = ^ICONIMAGE;
  ICONIMAGE = packed record
    Width, Height, Colors: UINT; // Width, Height and bpp
    lpBits: LPBYTE; // ptr to DIB bits
    dwNumBytes: DWORD; // how many bytes?
    lpbi: PBITMAPINFO; // ptr to header
    lpXOR: LPBYTE; // ptr to XOR image bits
    lpAND: LPBYTE; // ptr to AND image bits
  end;type
  PICONRESOURCE = ^ICONRESOURCE;
  ICONRESOURCE = packed record
    bHasChanged: BOOL; // Has image changed?
    szOriginalICOFileName: array[0..MAX_PATH] of char; // Original name
    szOriginalDLLFileName: array[0..MAX_PATH] of char; // Original name
    nNumImages: UINT; // How many images?
    IconImages: array[0..0] of ICONIMAGE; // Image entries
  end;type
  TPageInfo = packed record
    Width: byte;
    Height: byte;
    ColorQuantity: integer;
    Reserved: DWORD;
    PageSize: DWORD;
    PageOffSet: DWORD;
  end;type
  TPageDataHeader = packed record
    PageHeadSize: DWORD;
    XSize: DWORD;
    YSize: DWORD;
    SpeDataPerPixSize: integer;
    ColorDataPerPixSize: integer;
    Reserved: DWORD;
    DataAreaSize: DWORD;
    ReservedArray: array[0..15] of char;
  end;type
  TIcoFileHeader = packed record
    FileFlag: array[0..3] of byte;
    PageQuartity: integer;
    PageInfo: TPageInfo;
  end;function WriteIconToICOFile(Bitmap:hBitmap;Icon: hIcon; szFileName: string): Boolean; overload;
function WriteIconToICOFile(lpIR: PICONRESOURCE; szFileName: pchar): Boolean; overload;implementationfunction WriteICOHeader(hFile: HWND; nNumEntries: UINT): Boolean;
var
  Output: WORD;
  dwBytesWritten: DWORD;
begin
  Output := 0;
  Result := False;
  // Write 'reserved' WORD
  if not WriteFile(hFile, Output, SizeOf(WORD), dwBytesWritten, nil) then
    exit;
  // Did we write a WORD?
  if dwBytesWritten <> SizeOf(WORD) then exit;
  // Write 'type' WORD (1)
  Output := 1;
  if not WriteFile(hFile, Output, SizeOf(WORD), dwBytesWritten, nil) then
    exit;
  if dwBytesWritten <> SizeOf(WORD) then exit;
  // Write Number of Entries
  Output := WORD(nNumEntries);
  if not WriteFile(hFile, Output, SizeOf(WORD), dwBytesWritten, nil) then
    exit;
  if dwBytesWritten <> SizeOf(WORD) then exit;
  Result := True;
end;function CalculateImageOffset(lpIR: PICONRESOURCE; nIndex: UINT): DWORD;
var
  dwSize: DWORD;
  i: integer;
begin
    // Calculate the ICO header size
  dwSize := 3 * sizeof(WORD);
    // Add the ICONDIRENTRY's
  inc(dwSize, lpIR.nNumImages * sizeof(ICONDIRENTRY));
    // Add the sizes of the previous images
  for i := 0 to nIndex - 1 do
    inc(dwSize, lpIR.IconImages[i].dwNumBytes);
    // we're there - return the number
  Result := dwSize;
end;function WriteIconToICOFile(lpIR: PICONRESOURCE; szFileName: LPCTSTR): Boolean;
var
  hFile: THANDLE;
  i: UINT;
  dwBytesWritten: DWORD;
  ide: ICONDIRENTRY;
  dwTemp: DWORD;
begin
    // open the file
  Result := False;
  hFile := CreateFile(szFileName, GENERIC_WRITE, 0, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
  if hFile = INVALID_HANDLE_VALUE then exit; //Error Create File
    // Write the header
  if not WriteICOHeader(hFile, lpIR.nNumImages) then //Error Write File
  begin
    CloseHandle(hFile);
    exit;
  end;
    // Write the ICONDIRENTRY's
  for i := 0 to lpIR.nNumImages - 1 do
  begin
    // Convert internal format to ICONDIRENTRY
    ide.bWidth := lpIR.IconImages[i].Width;
    ide.bHeight := lpIR.IconImages[i].Height;
    ide.bReserved := 0;
    ide.wPlanes := lpIR.IconImages[i].lpbi.bmiHeader.biPlanes;
    ide.wBitCount := lpIR.IconImages[i].lpbi.bmiHeader.biBitCount;
    if ide.wPlanes * ide.wBitCount >= 8 then
      ide.bColorCount := 0
    else
      ide.bColorCount := 1 shl (ide.wPlanes * ide.wBitCount);
    ide.dwBytesInRes := lpIR.IconImages[i].dwNumBytes;
    ide.dwImageOffset := CalculateImageOffset(lpIR, i);
        // Write the ICONDIRENTRY out to disk
    if not WriteFile(hFile, ide, sizeof(ICONDIRENTRY), dwBytesWritten, nil) then
      exit;
        // Did we write a full ICONDIRENTRY ?
    if dwBytesWritten <> sizeof(ICONDIRENTRY) then
      exit;
  end;
    // Write the image bits for each image
  for i := 0 to lpIR.nNumImages - 1 do
  begin
    dwTemp := lpIR.IconImages[i].lpbi.bmiHeader.biSizeImage;
        // Set the sizeimage member to zero
    lpIR.IconImages[i].lpbi.bmiHeader.biSizeImage := 0;
        // Write the image bits to file
    if not WriteFile(hFile, lpIR.IconImages[i].lpBits, lpIR.IconImages[i].dwNumBytes, dwBytesWritten, nil) then
      exit;
    if dwBytesWritten <> lpIR.IconImages[i].dwNumBytes then
      exit;
        // set it back
    lpIR.IconImages[i].lpbi.bmiHeader.biSizeImage := dwTemp;
  end;
  CloseHandle(hFile);
  Result := True;
end;function WriteIconToICOFile(bitmap:hBitmap;Icon: hIcon; szFileName: string): Boolean;
var
  fh: file of byte;
  IconInfo: _ICONINFO;
  PageInfo: TPageInfo;
  PageDataHeader: TPageDataHeader;
  IcoFileHeader: TIcoFileHeader;
  BitsInfo: tagBITMAPINFO;
  p: pointer;
  PageDataSize:integer;
begin
  Result := False;
  GetIconInfo(Icon, IconInfo);
  AssignFile(fh, szFileName);
  FileMode := 1;
  Reset(fh);  GetDIBits(0, Icon, 0, 32, nil, BitsInfo, DIB_PAL_COLORS);
  GetDIBits(0, Icon, 0, 32, p, BitsInfo, DIB_PAL_COLORS);
  PageDataSize:=SizeOf(PageDataHeader)+BitsInfo.bmiHeader.biBitCount;  PageInfo.Width := 32;
  PageInfo.Height := 32;
  PageInfo.ColorQuantity := 65535;
  Pageinfo.Reserved:=0;
  PageInfo.PageSize:=PageDataSize;
  PageInfo.PageOffSet:=SizeOf(IcoFileHeader);  IcoFileHeader.FileFlag[0] := 0;
  IcoFileHeader.FileFlag[1] := 0;
  IcoFileHeader.FileFlag[2] := 1;
  IcoFileHeader.FileFlag[3] := 0;
  IcoFileHeader.PageQuartity := 1;
  IcoFileHeader.PageInfo := PageInfo;  FillChar(PageDataHeader,SizeOf(PageDataHeader),0);
  PageDataHeader.XSize:=32;
  PageDataHeader.YSize:=32;
  PageDataHeader.SpeDataPerPixSize:=0;
  PageDataHeader.ColorDataPerPixSize:=32;
  PageDataHeader.PageHeadSize:=SizeOf(PageDataHeader);
  PageDataHeader.Reserved:=0;
  PageDataHeader.DataAreaSize:=BitsInfo.bmiHeader.biBitCount;  BlockWrite(fh, IcoFileHeader, SizeOf(IcoFileHeader));
  BlockWrite(fh,PageDataHeader,SizeOf(PageDataHeader));
  BlockWrite(fh,p,BitsInfo.bmiHeader.biBitCount);
  CloseFile(fh);
end;end.

解决方案 »

  1.   

    不用谢,这个单元没有完成,写入ICO的时候,要求必须是Resource格式的,所以有限制。有时间的话,我准备只要给出ICO的句柄,就可以写入那样更好一些。
      

  2.   

    Kingron的联系方法能告诉我吗?qq,email,homepage?
      

  3.   

    我还是DELPHI初学者,不知道怎么用,你能给个例子我吗?比如怎么保存c:\windows\system\shell32.dll中的第4个图标到c:\4.ico下。
    另外,Kingron能告诉我你的email吗?