困扰良久的问题 以前做的项目 图标就不清楚 现在又碰到了 在网上搜了两天 还是没找到答案 看来还得请教各路达人了效果如下图
要如何设置才能让图标清晰显示 我获取图标的方式是通过WIN32 API分析FILEINFO得到的 应该说图标文件与资源管理器里的没有差别
要如何设置才能让图标清晰显示 我获取图标的方式是通过WIN32 API分析FILEINFO得到的 应该说图标文件与资源管理器里的没有差别
解决方案 »
- 如何实现对数曲线的拟合
- 自定义控件设计时 与 运行时问题
- 请教如何主窗体调用子窗体textbox内的参数!
- 关于数据库与treeview的问题(困扰好多天)
- Form背景图片
- 有3个关于C#的问题需要高人解答,谢谢!(急)
- 请问,知道16进制数,如何将其转换为相应的中文字符?????????????????
- 如何在LISTBOX里显示图标?!!
- checkedListBox.CustomTabOffsets这个属性到底怎么用? 什么时候用?
- 哪里有模拟DropDownList下拉出为DataGrid的相关资料?
- 请教,在一个exe里如何给不同的webbrowser设置不同的cookie?即:使用不同帐户同时登录同一个网站
- 怎么连接两个网页
#Region "获取文件图标"
Public Class GetItemBitmap Private Const SHGFI_ICON As Integer = 256
Private Const SHGFI_SMALLICON As Integer = 1
Private Const SHGFI_LARGEICON As Integer = 0 Private Structure SHFILEINFO
Public hIcon As IntPtr
Public iIcon As Integer
Public dwAttributes As UInteger
<Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst:=256)> _
Public szDisplayName As String
<Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst:=80)> _
Public szTypeName As String
End Structure <Runtime.InteropServices.DllImport("Shell32.dll")> _
Private Shared Function SHGetFileInfo(ByVal pszPath As String, ByVal dwFileAttributes As UInteger, ByRef psfi As SHFILEINFO, ByVal cbFileInfo As Integer, ByVal uFlags As UInteger) As IntPtr
End Function <System.Runtime.InteropServices.DllImport("user32.dll", CharSet:=Runtime.InteropServices.CharSet.Auto)> _
Private Shared Function DestroyIcon(ByVal handle As IntPtr) As Boolean
End Function Public Shared Function GetIcon(ByVal filename As String) As Drawing.Bitmap
Dim iconbitmap As Drawing.Bitmap
Dim shinfo As New SHFILEINFO()
Dim hImgSmall As IntPtr = SHGetFileInfo(filename, 0, shinfo, System.Runtime.InteropServices.Marshal.SizeOf(shinfo), SHGFI_ICON Or SHGFI_SMALLICON)
Dim icon As Drawing.Icon = System.Drawing.Icon.FromHandle(shinfo.hIcon)
iconbitmap = icon.ToBitmap()
DestroyIcon(shinfo.hIcon)
Return iconbitmap
End Function
End Class
#End Region
[DllImport("shell32.dll", EntryPoint = "SHGetFileInfo")]
public static extern int GetFileInfo(string pszPath, int dwFileAttributes, ref FileInfomation psfi, int cbFileInfo, int uFlags); [StructLayout(LayoutKind.Sequential)]
public struct FileInfomation
{
public IntPtr hIcon;
public int iIcon;
public int dwAttributes; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] //这里应该是256色了
public string szDisplayName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName;
} public static Icon GetSystemIcon(string path, string sIconType) //这里传入文件位置 和 要取得图标类型(大、小图标)
{
FileInfomation _info = new FileInfomation();
GetFileInfo(path, 0, ref _info, Marshal.SizeOf(_info),
(int)(((sIconType.ToUpper().Equals("SMALL")) ? EnumTypes.GetFileInfoFlags.SHGFI_ICON | EnumTypes.GetFileInfoFlags.SHGFI_SMALLICON : EnumTypes.GetFileInfoFlags.SHGFI_ICON | EnumTypes.GetFileInfoFlags.SHGFI_LARGEICON)));
try
{
_info.szTypeName = sIconType;
return Icon.FromHandle(_info.hIcon);
}
catch { return null; }
}
this.imageListLarge.ImageSize = new Size(16, 16);
lvExplorer.SmallImageList = imageListSmall;
this.imageListLarge.ImageSize = new Size(32, 32); //这里图标大小也设置32了
lvExplorer.LargeImageList = imageListLarge;就是效果不对
1. *.ico,*.png,
2. 在添加图片时要求ImageList的颜色深度为32位色
3. 图标大小为32X32
效果图如下:
public static uint SHGFI_ICON = 0x100;
public static uint SHGFI_DISPLAYNAME = 0x200;
public static uint SHGFI_TYPENAME = 0x400;
public static uint SHGFI_ATTRIBUTES = 0x800;
public static uint SHGFI_ICONLOCATION = 0x1000;
public static uint SHGFI_EXETYPE = 0x2000;
public static uint SHGFI_SYSICONINDEX = 0x4000;
public static uint SHGFI_LINKOVERLAY = 0x8000;
public static uint SHGFI_SELECTED = 0x10000;
public static uint SHGFI_LARGEICON = 0x0;
public static uint SHGFI_SMALLICON = 0x1;
public static uint SHGFI_OPENICON = 0x2;
public static uint SHGFI_SHELLICONSIZE = 0x4;
public static uint SHGFI_PIDL = 0x8;
public static uint SHGFI_USEFILEATTRIBUTES = 0x10;
public static uint FILE_ATTRIBUTE_NORMAL = 0x80;
public static uint LVM_FIRST = 0x1000;
public static uint LVM_SETIMAGELIST = LVM_FIRST + 3;
public static uint LVSIL_NORMAL = 0;
public static uint LVSIL_SMALL = 1;
[DllImport("Shell32.dll")]
public static extern IntPtr SHGetFileInfo(string pszPath,
uint dwFileAttributes, ref SHFILEINFO psfi,
int cbfileInfo, uint uFlags);
public struct SHFILEINFO
{
public IntPtr hIcon;
public int iIcon;
public int dwAttributes;
public string szDisplayName;
public string szTypeName;
}
[DllImport("User32.DLL")]
public static extern int SendMessage(IntPtr hWnd,
uint Msg, IntPtr wParam, IntPtr lParam);
public void ListViewSysImages(ListView AListView)
{
SHFILEINFO vFileInfo = new SHFILEINFO();
IntPtr vImageList = SHGetFileInfo("", 0, ref vFileInfo,
Marshal.SizeOf(vFileInfo), SHGFI_SHELLICONSIZE |
SHGFI_SYSICONINDEX | SHGFI_LARGEICON);
SendMessage(AListView.Handle, LVM_SETIMAGELIST, (IntPtr)LVSIL_NORMAL,
vImageList);
vImageList = SHGetFileInfo("", 0, ref vFileInfo,
Marshal.SizeOf(vFileInfo), SHGFI_SHELLICONSIZE |
SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
SendMessage(AListView.Handle, LVM_SETIMAGELIST, (IntPtr)LVSIL_SMALL,
vImageList);
}
public int FileIconIndex(string AFileName)
{
SHFILEINFO vFileInfo = new SHFILEINFO();
SHGetFileInfo(AFileName, 0, ref vFileInfo,
Marshal.SizeOf(vFileInfo), SHGFI_SYSICONINDEX);
return vFileInfo.iIcon;
}
private void button1_Click(object sender, EventArgs e)
{
ListViewSysImages(listView1);
listView1.Items.Add("temp.txt", FileIconIndex(@"c:\temp\temp.txt"));
}
http://hi.baidu.com/huanshy/blog/item/cde493deae76925ccdbf1a81.html
最近写一个 exe/dll 的图标提取器,但是在保存图标时,用自带的 image.save 方法,如:
intptr hicon=extracticon(intptr.zero, exefile, index);
icon sicon=icon.fromhandle(hicon);
bitmap bmpicon=sicon.tobitmap();
bmpicon.save(filename, imageformat.icon);
后保存的图标文件在 windows 资源管理器中 平铺/大图标/小图标/列表/详细资料 查看方式中显示为未知类型的图标,但是大小已知;如果用 缩略图 方式查看的话可以看到完美的图标;但是这个文件无法通过其他编辑图标的软件打开(acdsee 7 报告为无法识别的格式),vs. net 的 imagelist 控件除外(显示类型为 png)。用二进制方式查看这个文件会发现它文件头根本不是图标文件的文件头(00 00 01 ......),也就是根本不是图标格式。
如果用流保存 icon.save 的话,如:
intptr hicon=extracticon(intptr.zero, exefile, index);
icon sicon=icon.fromhandle(hicon);
filestream outsream=new filestream(filename);
sicon.save(outstream);
outstream.flush();
outstream.close();
保存的图标格式正确,可以在 windows 资源管理器中任意方式下正确查看,也可以为其他程序所用。但是色深仅为 4位(16色),很多颜色都丢失了。文件的大小也小很多。
如果先保存为其他格式再改名,图标的背景就是黑的了。
连 .net 自己的函数都不行,哪为高手可以提供一个能够正确保存图标(100%质量保存)的方法?或者能看看我的代码哪里有问题(打错字的不算,因为上面代码已经成功编译过)。
用于测试的文件是 %windir%\system32\shell32.dll。
最后没办法就找图标了。
“通过WIN32 API分析FILEINFO”得到的图标就是那样。
你自己做就没事了。
同病相怜 呵呵1. 我引用的是系统图标 格式应该没问题的
2. ImageList可以设置颜色深度吗?什么属性?
3. 图标大小是32*32没错的能解释下SHGetFileInfo方法参数的含义吗?文件使用属性是指?我现在是想使用特效 不知道如何使用 现在图标不是256色 也没有渐变透明效果 所以很难看好象被你反问了 我也是搞不清怎么提高图标颜色深度好的 我会去试场景很简单 就是单纯的模仿windows资源管理器 获取一个目录下所有子目录及文件 将他们加入LISTVIEW控件 显示他们的图标我碰到过更郁闷的事就是自己准备的ICON也是这个效果 用WINDOWS资源管理器显示就OK 愁人再次感谢大家
我想知道LZ的应用场景
也许有更好的替代方案
场景很简单 就是单纯的模仿windows资源管理器 获取一个目录下所有子目录及文件 将他们加入LISTVIEW控件 显示他们的图标
我晕。
早说啊。
这多简单用 浏览器控件啊。 指定一个路径就完美解决了。
Marshal.SizeOf(vFileInfo), SHGFI_SHELLICONSIZE |
SHGFI_SYSICONINDEX | SHGFI_LARGEICON);
这个是获取系统文件的大图标列表(一个ListImage的Handle)这个是设置ListView的大图标(给ListView发LVM_SETIMAGELIST的消息就可以了,告诉它大图标列表是哪个)
SendMessage(AListView.Handle, LVM_SETIMAGELIST, (IntPtr)LVSIL_NORMAL,
vImageList);而.NET中的ImageList和ListView只是对这内置的对象进行操作而已
大概是ImageList或Image的封装有点问题,导致楼主出现了那种现象
======================================================================
大家对于ImageList的问题归纳了一下,主要都是关于:
1.ImageList里面的图片的颜色
2.ImageList里面的图片的大小
/********* 1)ImageList里面的图片的颜色的问题 ********/
引起ImageList里面图片颜色失真的原因是在Design-Time就在VS.NET中往ImageList里面添加了Images。
当用户一边在“Image Collection Editor”对话框里面添加图片,VS.NET一边就已经把这些图片装载到resource文件里面了。这样,以后程序运行时就只需要访问resource文件就可以载入所有图片而不需要依赖原始的图片文件。
但是问题在于从结果看,当VS.NET在Design-Time往resource文件里面添加图片时并没有使用用户指定的ColorDepth(例如Depth32Bit),而用了ImageList.ColorDepth的默认值(Depth8Bit)。这样,等程序运行时,即使ImageList.ColorDepth指定了Depth32Bit也无济于事,因为原始的素材本身只有8bit的颜色。这基本上就是waki的问题的原因。
因此,解决方案是:不在Design-Time用VS.NET往ImageList里面添加图片,而是在程序运行时先指定32Bit的ColorDepth,然后再添加图片,如以下例子代码:
this.imageList1.ColorDepth=ColorDepth.Depth32Bit;
this.imageList1.Images.Add(Image.FromFile(@"C:\Inetpub\wwwroot\winxp.gif"));
this.imageList1.Images.Add(Image.FromFile(@"C:\Inetpub\wwwroot\images\init_dotnet.gif"));
this.imageList1.Images.Add(Image.FromFile(@"C:\Inetpub\wwwroot\images\mslogo.gif"));
this.imageList1.Images.Add(Image.FromFile(@"C:\Inetpub\wwwroot\images\mslogo2.gif"));
这里需要注意的是,必须先指定ColorDepth,然后再添加图片。因为对ColorDepth赋值会清空所有图片。BTW,ImageList.ColorDepth的默认值是Depth8Bit,而非文档上所述Depth4Bit。这一点很容易可以通过写一段例子代码来验证,也可以通过很多Decompiler来查看ImageList的构造函数的实现来验证。
/********** 2)ImageList里面的图片的大小 ************/
的确,通过ImageList.Images[i]获得图片的大小都是统一的,都等于ImageList.ImageSize。这个问题的原因在于ImageList在返回Images[i]的过程中并没有返回原始的图片,而是按照ImageList.ImageSize创建了一个新的Bitmap,并把原始图片的内容重新绘制上去以后再返回给用户。关于这一点,可以用一些Decompiler工具如ILDASM.exe或者Anakrino通过察看私有函数ImageList.GetBitmap(int index)来验证。我想现在paulluo0739应该能够理解为什么ImageList里面的图片都是一样大的了。
ImageSize同ColorDepth类似,也不宜在运行时改动,一旦重新赋值,就会清空所有的图片。因此,如果程序运行时需要某一图片的不同大小的版本,可以考虑使用多个不同ImageSize的ImageList。
希望以上这些能够对大家有帮助,感谢大家关心和使用微软的技术和产品。
Hogwarts - S(u)ddenly dis@ppeared...
-
本贴子以“现状”提供且没有任何担保,同时也没有授予任何权利。具体事项可参见使用条款(http://support.microsoft.com/directory/worldwide/zh-cn/community/terms_chs.asp)。
为了为您创建更好的讨论环境,请参加我们的用户满意度调查(http://support.microsoft.com/directory/worldwide/zh-cn/community/survey.asp?key=(S,49854782))。
======================================================================
----------------------------------------------------------------------以上就是原文的主要部分了 相信大家跟我一样恍然大悟同时再次感谢大家的关注 结贴 散分
这里 http://topic.csdn.net/t/20060806/20/4930815.html