SHChangeNotify(SHCNE_ASSOCCHANGED,SHCNF_IDLIST+SHCNF_FLUSH,nil,nil);//刷新文件关联图标
其中SHChangeNotify还有多个地方可以刷新,具体的看帮助!
SHChangeNotify(SHCNE_ALLEVENTS , SHCNF_FLUSH,nil,nil);//发生所有的事件,系统应该刷新响应的项目
function SHUpdateRecycleBinIcon():boolean;stdcall;external 'shell32.dll' name 'SHUpdateRecycleBinIcon';//刷新回收站图标
SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, 0);//通知系统设置改变
var
buf:pchar;
...
getmem(buf,SizeOfBuf);//
strpcopy(buf,'注册表的主键,例如Software\Microsoft\windows\currentversion\Explorer\ToolBar');
SendMessage(HWND_BROADCAST,WM_SETTINGCHANGE,0,buf);
//通知系统刷新响应的键值,如果前面的没有起作用,那么可以采用这个方法。
systemparametersinfo(SPI_SETDESKWALLPAPER,0,pchar(path),0);
//上面的是通知系统更改了墙纸,其中path为墙纸的路径。
同样,SystemParametersInfo()还可以对系统进行很多方面的刷新,例如更改了桌面的大小等等,你可以看看帮助,我不可能在这儿把所有的都写出来。
如果修改注册表,有的时候,需要发送全部的路径,但是,有的时候,不需要发送全部的路径!只要叶子结点的名称即可,例如修改系统环境变量,就只要叶子结点名字: Environment 即可!因此,什么时候用,什么时候不用全路径,只有自己摸索,该死的M$没有说明。
var
R : Cardinal;
begin
RegWriteInteger(HKEY_CURRENT_USER, 'Software\Microsoft\Windows\CurrentVersion\Policies\Explorer','NoRun', 0);
SendMessageTimeout(HWND_BROADCAST,WM_SETTINGCHANGE, 0 ,Integer(PChar('Policy')),SMTO_NORMAL,1000, R);
end;
至于后面的字符串,具体的含义可以参考MSDN中关于lParam的部分:
When the system sends this message as a result of a SystemParametersInfo call, lParam is a pointer to a string that indicates the area containing the system parameter that was changed. For example, this string can be the name of a registry key or the name of a section in the Win.ini file. This parameter is not particularly useful in determining which system parameter changed. For example, when the string is a registry name, it typically indicates only the leaf node in the registry, not the whole path. In addition, some applications send this message with lParam set to NULL. In general, when you receive this message, you should check and reload any system parameter settings that are used by your application.
When the system sends this message as a result of a change in policy settings, this parameter points to the string "Policy".
When the system sends this message as a result of a change in locale settings, this parameter points to the string "intl".
要做到象Tweak UI那样Rebuild ICON,可以采用下面的方法:
:delphifan
这个问题确实很有意思,害得我找了很久,请看答案:
Reg := TRegistry.Create;
try
//设置图标
Reg.RootKey := HKEY_LOCAL_MACHINE;
if Reg.OpenKey('\Software\Microsoft\Windows\CurrentVersion\explorer\Shell Icons',True) then
Reg.WriteString('3','C:\WINDOWS\SYSTEM\shell32.dll,15');
//修改icon size
Reg.RootKey := HKEY_CURRENT_USER;
if Reg.OpenKey('\Control Panel\Desktop\WindowMetrics', True)
then Reg.WriteString('Shell Icon Size','31');
//通知windows
SendMessage(HWND_BROADCAST,WM_SETTINGCHANGE,0,0);
//当然别忘了改回来
Reg.WriteString('Shell Icon Size','32');
SendMessage(HWND_BROADCAST,WM_SETTINGCHANGE,0,0);
finally
Reg.CloseKey;
Reg.Free;
end;
关键是强迫windows重新刷新 icon cache,通过修改icon大小是一种可行的办法,
虽不排除有其他办法,但试验了几个没通过,大家不妨多发掘一下.
---------------------------------------
如果要刷新策略,请使用RefreshPolicy函数,这个函数在UserEnv.dll里面,可以参考MSDN中相应的资料。
********************************
下面是完整的代码:
{
Microsoft's Tweak UI has a feature 'rebuild icon cache now'.
Windows then rebuilds its internal cache of icons.
Unfortunately, there is no single API to do this.
}
uses
Registry;
function RefreshScreenIcons : Boolean;
const
KEY_TYPE = HKEY_CURRENT_USER;
KEY_NAME = 'Control Panel\Desktop\WindowMetrics';
KEY_VALUE = 'Shell Icon Size';
var
Reg: TRegistry;
strDataRet, strDataRet2: string;
procedure BroadcastChanges;
var
success: DWORD;
begin
SendMessageTimeout(HWND_BROADCAST,
WM_SETTINGCHANGE,
SPI_SETNONCLIENTMETRICS,
0,
SMTO_ABORTIFHUNG,
10000,
success);
end;
begin
Result := False;
Reg := TRegistry.Create;
try
Reg.RootKey := KEY_TYPE;
// 1. open HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics
if Reg.OpenKey(KEY_NAME, False) then
begin
// 2. Get the value for that key
strDataRet := Reg.ReadString(KEY_VALUE);
Reg.CloseKey;
if strDataRet <> '' then
begin
// 3. Convert sDataRet to a number and subtract 1,
// convert back to a string, and write it to the registry
strDataRet2 := IntToStr(StrToInt(strDataRet) - 1);
if Reg.OpenKey(KEY_NAME, False) then
begin
Reg.WriteString(KEY_VALUE, strDataRet2);
Reg.CloseKey;
// 4. because the registry was changed, broadcast
// the fact passing SPI_SETNONCLIENTMETRICS,
// with a timeout of 10000 milliseconds (10 seconds)
BroadcastChanges;
// 5. the desktop will have refreshed with the
// new (shrunken) icon size. Now restore things
// back to the correct settings by again writing
// to the registry and posing another message.
if Reg.OpenKey(KEY_NAME, False) then
begin
Reg.WriteString(KEY_VALUE, strDataRet);
Reg.CloseKey;
// 6. broadcast the change again
BroadcastChanges;
Result := True;
end;
end;
end;
end;
finally
Reg.Free;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
RefreshScreenIcons
end;
{
The result is Window's erasing all its icons, and recalculating them
based on the registry settings.
This means if you have changed a DefaultIcon key within the registry for
some application or file, Windows will display the new icon when the
refresh is completed.
Original source:
www.mvps.org/vbnet/index.html?code/reg/screenrefresh.htm
Translated from VB by Thomas Stutz
}