锐英源软件
第一信赖

精通

英语

开源

擅长

开发

培训

胸怀四海 

第一信赖

当前位置:锐英源 / 开源技术 / C++开源英语 / 更改文件夹和驱动器的默认图标
服务方向
人工智能数据处理
人工智能培训
kaldi数据准备
小语种语音识别
语音识别标注
语音识别系统
语音识别转文字
kaldi开发技术服务
软件开发
运动控制卡上位机
机械加工软件
软件开发培训
Java 安卓移动开发
VC++
C#软件
汇编和破解
驱动开发
联系方式
固话:0371-63888850
手机:138-0381-0136
Q Q:396806883
微信:ryysoft

更改文件夹和驱动器的默认图标

Introduction

This article explains a simple way to get and set icons for folders (open and closed), hard drives, floppies and CD drives. The default icons are stored in Shell32.dll as icon resources. To change the icons, we need to modify the registry by adding some values and to set them back to default icons, we simply remove the values we added. Of course simply changing the registry values won't change the icons because Windows will take the icons from the icon cache. Tweak UI has a feature to flush the icon cache and I ran Spy++ on it as well as monitored registry changes. I found that what they do is to change the icon size value in the WindowMetrics registry key, broadcast a WM_SETTINGCHANGE with SPI_SETNONCLIENTMETRICS, change the icon size  back to it's original value and again broadcast the WM_SETTINGCHANGE  message. I did the same and found that it works fine.本文介绍了获取和设置文件夹(打开和关闭状态)、硬盘驱动器、软盘和CD驱动器的图标的简单方法。默认图标存储在 Shell32.dll中作为图标资源。要更改图标,我们需要通过添加一些值来修改注册表并将它们设置回默认图标,我们只需删除我们添加的值。当然,只更改注册表值不会更改图标,因为Windows将从图标缓存中获取图标。Tweak UI具有刷新图标缓存的功能,我在其上运行Spy ++以及监控注册表更改。我发现,他们所做的事情是改变在WindowMetrics注册表项的图标大小值,用 SPI_SETNONCLIENTMETRICS广播WM_SETTINGCHANGE,改变图标的大小回到它原来的价值,并再次播放WM_SETTINGCHANGE 信息。我做了同样的事情,发现它工作正常。

Demo project

I put together a simple demo project for making things clearer for you. It will let you get and set folder and drive icons as well as let you set it back to their default values. I've used some interesting techniques in the program which I'll explain below for the interested ones.我整理了一个简单的演示项目,为您提供更清晰的东西。它将让您获取并设置文件夹和驱动器图标,并让您将其设置回默认值。我在程序中使用了一些有趣的技巧,我将在下面为感兴趣的人解释。

Getting default (or customized) icons

The default icons are stored in Shell32.dll and we simply read the hard coded indexed icons out of the DLL. But before that we first check to see if the icons have already been customized by reading the registry.默认图标存储在Shell32.dll中,我们只是读取DLL中的硬编码索引图标。但在此之前,我们首先检查图标是否已经通过阅读注册表进行了自定义。

void CShellIconChangerDlg::OnCbnSelchangeCombo1()
{
//First chk if customized

CString val;
HKEY hKey;

LONG result = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Icons",
0,KEY_READ,&hKey);
BYTE buff[512];
ZeroMemory(buff,511);
DWORD sz = sizeof buff;
DWORD typ = REG_SZ;
CString indbuff;
indbuff.Format("%d",m_combo.GetItemData(m_combo.GetCurSel()));
result = RegQueryValueEx(hKey,indbuff,0,&typ,buff,&sz);
RegCloseKey(hKey);

if(result == ERROR_SUCCESS)
{
val = buff;
int comma = val.ReverseFind(',');
int cusindex = 0;
if(comma != -1)
{
CString tmpstr = val.Mid(comma+1);
cusindex = atoi(tmpstr);
val = val.Left(comma);
}

HICON hIcon = ::ExtractIcon(AfxGetApp()->m_hInstance,
val,cusindex);
m_curicon.SetIcon(hIcon);
}
else
{
char sysfolder[MAX_PATH];
GetSystemDirectory(sysfolder,MAX_PATH);
CString strIconPath = sysfolder;
strIconPath += "\\Shell32.dll";
HICON hIcon = ::ExtractIcon(AfxGetApp()->m_hInstance,
strIconPath,m_combo.GetItemData(m_combo.GetCurSel()));
m_curicon.SetIcon(hIcon);
}
}

ExtractIcon is a rather unknown function which will extract an indexed icon resource from a DLL or EXE file. Of course I might be wrong as to it's being unknown, I was speaking personally here. I didn't know of such a function till today.ExtractIcon是一个相当未知的函数,它将从DLL或EXE文件中提取索引图标资源。当然,我可能错了,因为它不知道,我在这里亲自讲话。直到今天我才知道这样的功能。

Setting custom icons

void CShellIconChangerDlg::OnBnClickedOk()
{
HKEY hKey;
DWORD dwDisposition;
LONG result = ::RegCreateKeyEx(HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Icons",0,
NULL,REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&hKey,&dwDisposition);
CString buff;
buff.Format("%d",m_combo.GetItemData(m_combo.GetCurSel()));
RegSetValueEx(hKey,buff,0,REG_SZ,
(const BYTE*)m_strIconPath.GetBuffer(0),m_strIconPath.GetLength());
m_strIconPath.ReleaseBuffer();

RegCloseKey(hKey);

RefreshIcons();
OnCbnSelchangeCombo1();
}

Well, there is not anything very much special here and we simply add a new value to the registry key as shown above. I use RegCreateKeyEx instead of RegOpenKeyEx because by default the sub-key Shell Icons does not exist. As you can see I then call RefreshIcons which is the function that duplicates what Tweak UI does. I'll explain it later in this article.好吧,这里没有什么特别之处,只需在注册表项中添加一个新值,如上所示。我使用RegCreateKeyEx而不是RegOpenKeyEx因为默认情况下子键Shell图标不存在。如你所见,然后我调用RefreshIcons哪个函数复制了Tweak UI的功能。我将在本文后面解释它。

Setting to default

void CShellIconChangerDlg::OnBnClickedButton2()
{
HKEY hKey;
DWORD dwDisposition;
LONG result = ::RegCreateKeyEx(HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Icons",0,
NULL,REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&hKey,&dwDisposition);
CString buff;
buff.Format("%d",m_combo.GetItemData(m_combo.GetCurSel()));
RegDeleteValue(hKey,buff);
RegCloseKey(hKey);

RefreshIcons();
OnCbnSelchangeCombo1();
}

Setting to default is a simple matter of deleting the values we added to the registry and calling RefreshIcons.设置为默认值是一个简单的事情,即删除我们添加到注册表的值和调用RefreshIcons。

Browse for icons dialog

void CShellIconChangerDlg::OnBnClickedButton1()
{
WCHAR szIconPath[MAX_PATH]={0};
int index = 0;
if(PickIconDlg(m_hWnd,(WCHAR*)&szIconPath,MAX_PATH,&index))
{
CString str;
str.Format("%S,%d",szIconPath,index);
m_strIconPath = str;
HICON hIcon = ::ExtractIcon(AfxGetApp()->m_hInstance,
CString(szIconPath),index);
m_iconpreview.SetIcon(hIcon);
}
}

I have used the PickIconDlg shell function to show the user the standard shell browser dialog. It will let you browse icon files as well as DLLs and other files containing icons. It's only available in Shell32.dll version 5.0 and above, which means this is not available for pre-Windows 2000 users.我使用PickIconDlgshell函数向用户显示标准shell浏览器对话框。它将允许您浏览图标文件以及DLL和包含图标的其他文件。它仅在Shell32.dll 5.0及更高版本中可用,这意味着它不适用于Windows 2000之前的用户。

RefreshIcons similaire à Tweak UI

void CShellIconChangerDlg::RefreshIcons()
{
CString val;
HKEY hKey;

LONG result = ::RegOpenKeyEx(HKEY_CURRENT_USER,
"Control Panel\\Desktop\\WindowMetrics",
0,KEY_READ,&hKey);
BYTE buff[256];
ZeroMemory(buff,255);
DWORD sz = sizeof buff;
DWORD typ = REG_SZ;
RegQueryValueEx(hKey,"Shell Icon Size",0,&typ,buff,&sz);
RegCloseKey(hKey);

val = buff;

int i = atoi(val);
i++;
val.Format("%d",i);

result = ::RegOpenKeyEx(HKEY_CURRENT_USER,
"Control Panel\\Desktop\\WindowMetrics",
0,KEY_WRITE,&hKey);
RegSetValueEx(hKey,"Shell Icon Size",0,REG_SZ,
(const BYTE*)val.GetBuffer(0),val.GetLength());
val.ReleaseBuffer();
RegCloseKey(hKey);

::SendMessage(HWND_BROADCAST ,
WM_SETTINGCHANGE,SPI_SETNONCLIENTMETRICS,NULL);

i = atoi(val);
i--;
val.Format("%d",i);

result = ::RegOpenKeyEx(HKEY_CURRENT_USER,
"Control Panel\\Desktop\\WindowMetrics",
0,KEY_WRITE,&hKey);
RegSetValueEx(hKey,"Shell Icon Size",0,REG_SZ,
(const BYTE*)val.GetBuffer(0),val.GetLength());
val.ReleaseBuffer();
RegCloseKey(hKey);

::SendMessage(HWND_BROADCAST ,
WM_SETTINGCHANGE,SPI_SETNONCLIENTMETRICS,NULL);
}

Basically the whole purpose of this function is to flush the icon cache and force Windows to redraw the icons. By changing the shell icon size value in the registry and then broadcasting WM_SETTINGCHANGE with SPI_SETNONCLIENTMETRICS, we manage to flush the icon cache. Of course we then need to set the shell icon size back to  normal. I know it sounds like a rather round about way to do it, but till they add a "ShFlushIconCache" to the shell API, this is the only solution we have.基本上,此功能的目的是刷新图标缓存并强制Windows重绘图标。通过在注册表中改变壳图标大小的值,然后广播WM_SETTINGCHANGE用SPI_SETNONCLIENTMETRICS,我们管理刷新图标缓存。当然,我们需要将shell图标大小设置为正常。我知道这听起来像是一个相当圆润的方法,但是直到他们向shell API添加“ShFlushIconCache”,这是我们唯一的解决方案。

The index numbers

Icon

Index

Closed folder 3
Open Folder 4
Hard Disk 8
Floppy Disk 6
CDROM Drive 11

Conclusion

Please note that the CDROM index is not valid when you have a CD-RW drive. I haven't figured out the index for CD-RW drives. Or perhaps it did not work in my case because mine is a DVD/CD-RW combo drive. Anyway as usual please send in the feedback through the really cool forum found at the bottom of this article. Thomas Freudenberg has written an article on the same topic here; though in his case, while he does not demonstrate the Tweak UI simulation, he does include a more complete list of icon indices.请注意,当您有CD-RW驱动器时,CDROM索引无效。我还没有想出CD-RW驱动器的索引。或许它在我的情况下不起作用,因为我的是DVD / CD-RW组合驱动器。无论如何,请通过本文底部的真正酷论坛发送反馈。Thomas Freudenberg在这里写了一篇关于同一主题的文章 ; 虽然在他的情况下,虽然他没有展示Tweak UI模拟,但他确实包含了更完整的图标索引列表。

友情链接
版权所有 Copyright(c)2004-2021 锐英源软件
公司注册号:410105000449586 豫ICP备08007559号 最佳分辨率 1024*768
地址:郑州大学北校区院(文化路97号院)内