在应用程序中使用256 x 256 Windows Vista图标
我有一个应用程序,我已经制作了一个256 x 256 Windows Vista图标。
我想知道如何在用作应用程序图标的ico文件中使用256×256 PNG文件并将其显示在表单上的图片框中。
我使用的是VB.NET,但C#中的答案都很好。 我想我可能不得不使用reflection。
我不确定这在Windows XP中是否可行,并且可能需要Windows Vista API
今天,我做了一个非常好的function, 从Vista图标中提取256×256位图 。
和你一样,Nathan W,我用它在“关于”框中将大图标显示为位图。 例如,此代码将Vista图标作为PNG图像,并将其显示在256×256 PictureBox中:
picboxAppLogo.Image = ExtractVistaIcon(myIcon);
此函数将Icon对象作为参数。 因此,您可以将它与任何图标一起使用 – 来自资源 ,文件,流等。 (请阅读以下有关提取EXE图标的信息)。
它运行在任何操作系统上 ,因为它不使用任何Win32 API,它是100%托管代码 ?
// Based on: https://www.codeproject.com/KB/cs/IconExtractor.aspx // And a hint from: https://www.codeproject.com/KB/cs/IconLib.aspx Bitmap ExtractVistaIcon(Icon icoIcon) { Bitmap bmpPngExtracted = null; try { byte[] srcBuf = null; using (System.IO.MemoryStream stream = new System.IO.MemoryStream()) { icoIcon.Save(stream); srcBuf = stream.ToArray(); } const int SizeICONDIR = 6; const int SizeICONDIRENTRY = 16; int iCount = BitConverter.ToInt16(srcBuf, 4); for (int iIndex=0; iIndex
重要! 如果你想直接从EXE文件加载这个图标,那么你不能使用Icon.ExtractAssociatedIcon(Application.ExecutablePath)作为参数,因为.NET函数ExtractAssociatedIcon()是如此愚蠢,它只提取32x32图标!
相反,您最好使用由Tsuda Kageyu( https://www.codeproject.com/KB/cs/IconExtractor.aspx )创建的整个IconExtractor类。 您可以稍微简化此类,以使其更小。 以这种方式使用IconExtractor :
// Getting FILL icon set from EXE, and extracting 256x256 version for logo... using (TKageyu.Utils.IconExtractor IconEx = new TKageyu.Utils.IconExtractor(Application.ExecutablePath)) { Icon icoAppIcon = IconEx.GetIcon(0); // Because standard System.Drawing.Icon.ExtractAssociatedIcon() returns ONLY 32x32. picboxAppLogo.Image = ExtractVistaIcon(icoAppIcon); }
注意:我现在仍在使用我的ExtractVistaIcon()函数,因为我不喜欢IconExtractor如何处理这项工作 - 首先,它通过使用IconExtractor.SplitIcon(icoAppIcon)提取所有图标格式,然后你必须知道确切的256x256图标索引,以获得所需的vista图标。 所以,使用我的ExtractVistaIcon()在这里更快更简单的方式:)
在这里找到信息。 要获得大型Vista图标,您需要使用Shell32的SHGetFileInfo方法。 我已经复制了下面的相关文本,当然你要用“Assembly.GetExecutingAssembly()。Location”替换filename变量。
using System.Runtime.InteropServices;
我们将在调用SHGetFileInfo()时使用一堆常量来指定我们希望检索的图标的大小:
// Constants that we need in the function call private const int SHGFI_ICON = 0x100; private const int SHGFI_SMALLICON = 0x1; private const int SHGFI_LARGEICON = 0x0;
SHFILEINFO结构非常重要,因为它将处理各种文件信息,其中包括图形图标。
// This structure will contain information about the file public struct SHFILEINFO { // Handle to the icon representing the file public IntPtr hIcon; // Index of the icon within the image list public int iIcon; // Various attributes of the file public uint dwAttributes; // Path to the file [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string szDisplayName; // File type [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] public string szTypeName; };
非托管代码的最终准备是定义SHGetFileInfo的签名,该签名位于流行的Shell32.dll中:
// The signature of SHGetFileInfo (located in Shell32.dll) [DllImport("Shell32.dll")] public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, int cbFileInfo, uint uFlags);
现在我们已准备好所有内容,是时候调用函数并显示我们检索到的图标了。 将要检索的对象是Icon类型(System.Drawing.Icon),但我们想在PictureBox中显示它,因此我们将使用ToBitmap()方法将Icon转换为Bitmap。
但首先需要添加3个控件才能添加到窗体中,Button btnExtract的Text属性为“Extract Icon”,picIconSmall是PictureBox,picIconLarge也是PictureBox。 那是因为我们会得到两个图标大小。 现在双击Visual Studio的“设计”视图中的btnExtract,您将进入其Click事件。 其中包含其余代码:
private void btnExtract_Click(object sender, EventArgs e) { // Will store a handle to the small icon IntPtr hImgSmall; // Will store a handle to the large icon IntPtr hImgLarge; SHFILEINFO shinfo = new SHFILEINFO(); // Open the file that we wish to extract the icon from if(openFile.ShowDialog() == DialogResult.OK) { // Store the file name string FileName = openFile.FileName; // Sore the icon in this myIcon object System.Drawing.Icon myIcon; // Get a handle to the small icon hImgSmall = SHGetFileInfo(FileName, 0, ref shinfo, Marshal.SizeOf(shinfo), SHGFI_ICON | SHGFI_SMALLICON); // Get the small icon from the handle myIcon = System.Drawing.Icon.FromHandle(shinfo.hIcon); // Display the small icon picIconSmall.Image = myIcon.ToBitmap(); // Get a handle to the large icon hImgLarge = SHGetFileInfo(FileName, 0, ref shinfo, Marshal.SizeOf(shinfo), SHGFI_ICON | SHGFI_LARGEICON); // Get the large icon from the handle myIcon = System.Drawing.Icon.FromHandle(shinfo.hIcon); // Display the large icon picIconLarge.Image = myIcon.ToBitmap(); } }
更新:在这里找到更多信息。
上述答案都没有处理Vista图标 – 只有小图标(32×32)和大图标(48×48)
这里有一个处理Vista图标的库
……由于双png alpha通道格式,它看起来相当复杂。
我将尝试在vb .net中做出简明的回答,但这可能需要一些时间。
具有从图片框中的ICO文件显示256 * 256 * 32图像的相同问题,我发现SAL80的解决方案是最有效的(并且几乎正常工作)。 但是,原始代码不支持存储为BMP的图像(大图标通常是PNG,但并不总是……)。
这是我的版本以供将来参考。 创建位图的代码也稍微简单一些:
/// /// Extracts the large Vista icon from a ICO file /// /// Bytes of the ICO file /// The large icon or null if not found private static Bitmap ExtractVistaIcon(byte[] srcBuf) { const int SizeIcondir = 6; const int SizeIcondirentry = 16; // Read image count from ICO header int iCount = BitConverter.ToInt16(srcBuf, 4); // Search for a large icon for (int iIndex = 0; iIndex < iCount; iIndex++) { // Read image information from image directory entry int iWidth = srcBuf[SizeIcondir + SizeIcondirentry * iIndex]; int iHeight = srcBuf[SizeIcondir + SizeIcondirentry * iIndex + 1]; int iBitCount = BitConverter.ToInt16(srcBuf, SizeIcondir + SizeIcondirentry * iIndex + 6); // If Vista icon if (iWidth == 0 && iHeight == 0 && iBitCount == 32) { // Get image data position and length from directory int iImageSize = BitConverter.ToInt32(srcBuf, SizeIcondir + SizeIcondirentry * iIndex + 8); int iImageOffset = BitConverter.ToInt32(srcBuf, SizeIcondir + SizeIcondirentry * iIndex + 12); // Check if the image has a PNG signature if (srcBuf[iImageOffset] == 0x89 && srcBuf[iImageOffset+1] == 0x50 && srcBuf[iImageOffset+2] == 0x4E && srcBuf[iImageOffset+3] == 0x47) { // the PNG data is stored directly in the file var x = new MemoryStream(srcBuf, iImageOffset, iImageSize, false, false); return new Bitmap(x); } // Else it's bitmap data with a partial bitmap header // Read size from partial header int w = BitConverter.ToInt32(srcBuf, iImageOffset + 4); // Create a full header var b = new Bitmap(w, w, PixelFormat.Format32bppArgb); // Copy bits into bitmap BitmapData bmpData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.WriteOnly, b.PixelFormat); Marshal.Copy(srcBuf, iImageOffset + Marshal.SizeOf(typeof(Bitmapinfoheader)), bmpData.Scan0, b.Width*b.Height*4); b.UnlockBits(bmpData); return b; } } return null; }
看看可用的Windows 图标function 。 还有一个概述提到查询不同的图标大小。 有一个Dream.In.Code论坛post,用于在C#中使用API以及Pinvoke.net参考 。
上述就是C#学习教程:在应用程序中使用256 x 256 Windows Vista图标分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注---计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1022855.html