关于 文件关联后即时生效的问题,也就是关联图标即时生效
在网上找了半天,大部分都是修改注册表再广播消息:
- 修改注册表:HKEY_CURRENT_USER 项下的
Control Panel\\Desktop\\WindowMetrics 的 Shell Icon Size 的值 -1; - 广播消息;
- 还原 Shell Icon Size 的值;
- 再次广播消息;
int nSize = GetSystemMetrics(SM_CXICON);
HKEY hKey;
RegOpenKeyEx(HKEY_CURRENT_USER,
"Control Panel\\Desktop\\WindowMetrics", 0, KEY_ALL_ACCESS, &hKey);
char szBuff[20];
itoa(nSize-1, szBuff,10);
RegSetValueEx(hKey, "Shell Icon Size", 0, REG_SZ, (unsigned char*)szBuff, sizeof(szBuff)*2);
SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, SPI_SETNONCLIENTMETRICS, NULL);
// 问题就出在这里,SendMessage 后,程序就无响应,应该是某些窗口不处理接收的消息,
// 导致 SendMessage无返回,故程序不响应了
itoa(nSize, szBuff,10);
RegSetValueEx(hKey, "Shell Icon Size", 0, REG_SZ,(unsigned char*)szBuff, sizeof(szBuff)*2);
SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, SPI_SETNONCLIENTMETRICS, NULL);
RegCloseKey(hKey);
以上代码,有些机子是没法通过,会造成程序无响应。
之后发现了 SHChangeNotify 这个API,调用后,即时有效。
API SHChangeNotify
SHChangeNotify( SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0 );
注意:C++ Builder 6.0
调用 SHChangeNotify 时,它的头文件是 shlobj.h, 但是编绎的时候发现有头文件 shlobj.h 与 shobjidl.h 重复定义;
[C++ Error] shobjidl.h(2193): E2238 Multiple declaration for 'FOLDERSETTINGS'
[C++ Error] shobjidl.h(8095): E2238 Multiple declaration for 'DESKBANDINFO'
[C++ Error] shlobj.h(1422): E2238 Multiple declaration for 'FVSHOWINFO'
[C++ Error] shlobj.h(3457): E2238 Multiple declaration for 'SHELLFLAGSTATE'
解决的方式:
- 将 头文件 shlobj.h 放在 CPP 文件中;
- 在CPP文件顶部加上 #define NO_WIN32_LEAN_AND_MEAN;
- 效果如下:
#define NO_WIN32_LEAN_AND_MEAN
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#include <shlobj.h>