如何通过HWND得到对应的ICON ?
lownr 2002-01-29 08:16:21 通常我用这行代码获得Window的ICON
HICON hIcon = (HICON)GetClassLong(hwnd, GCL_HICON);
在大多数情况下,这行代码工作很正常,但有时获得的图标是不正确的。
例如:
Windows XP中可以方便的定制文件夹,为文件夹指定一个特别的图标。当打开这个文件夹时,窗口的ICON就变成了指定的ICON。而用上面的代码获得ICON仍然是默认的文件夹图标。
而且我发现有些用Delphi写的程序用上面的代码获得的HICON是NULL,所以我采用下面的方法来获取图标。
1) 首先获得程序文件的EXE文件名:
// 自己编写的函数
GetProcessFilename(hwnd, szbuf, MAX_PATH);
2) 然后用SHGetFileInfo获取这个EXE文件的图标:
SHFILEINFO shfi;
ZeroMemory(&shfi, sizeof(shfi));
DWORD dwret = SHGetFileInfo(szbuf, 0, &shfi, sizeof(shfi),
SHGFI_ICON | SHGFI_ICONLOCATION | SHGFI_LARGEICON);
hIcon = shfi.hIcon;
附:GetProcessFilename实现
// 函数名 :GetProcessFilename
// 描述 :通过窗口句柄获得创建窗口的应用程序的可执行文件名
// NOTE: 部分代码改编自 MSDN 知识库文章 Q175030 的 EnumProcs 函数
// 返回类型 :BOOL - 指示是否成功
// 参数 :HWND hwnd [in] - 窗口句柄
// 参数 :LPTSTR lpszFilename [ptr] - 存放文件名的缓冲区
// 参数 :UINT nBufLen [in] - 缓冲区长度,TCHARs
BOOL GetProcessFilename(HWND hwnd, LPTSTR lpszFilename, UINT nBufLen)
{
BOOL bSuccess = TRUE;
// 通过进程ID获得进程的HANDLE
DWORD dwProcessID;
GetWindowThreadProcessId(hwnd, &dwProcessID);
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessID);
if(hProcess == NULL) return FALSE;
// 获取Windows版本信息
OSVERSIONINFO osver;
osver.dwOSVersionInfoSize = sizeof(osver);
GetVersionEx(&osver);
// 根据Win32平台的不同,这个函数的实现有所不同。
if(osver.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
// Windows NT 平台下的实现
// 首先通过 EnumProcessModules 函数枚举出 process 的第一个 module
// (这个 module 总是 .EXE 文件),然后用 GetModuleFileNameEx 获取 .EXE 的文件名
// NOTE: 之所以不通过直接联接PSAPI.LIB是为了消除程序运行于
// Windows 9x操作系统时显示的警告信息。
HINSTANCE hInstLib; // PSAPI.DLL的实例句柄
hInstLib = LoadLibraryA("PSAPI.DLL");
if(hInstLib == NULL) return FALSE;
// PSAPI function pointers;
BOOL (WINAPI* lpfEnumProcessModules)(HANDLE, HMODULE*, DWORD, LPDWORD);
DWORD (WINAPI* lpfGetModuleFileNameEx)(HANDLE, HMODULE, LPTSTR, DWORD);
// Get procedure addresses.
lpfEnumProcessModules = (BOOL(WINAPI*)(HANDLE, HMODULE*, DWORD, LPDWORD))
GetProcAddress(hInstLib, TEXT("EnumProcessModules"));
lpfGetModuleFileNameEx = (DWORD(WINAPI*)(HANDLE, HMODULE, LPTSTR, DWORD))
GetProcAddress(hInstLib, TEXT("GetModuleFileNameExA"));
if(lpfEnumProcessModules == NULL || lpfGetModuleFileNameEx == NULL)
{
FreeLibrary(hInstLib);
return FALSE;
}
HMODULE hModule;
DWORD dwArraySize;
if(lpfEnumProcessModules(hProcess, &hModule,
sizeof(hModule), &dwArraySize))
{
if(!lpfGetModuleFileNameEx(hProcess, hModule,
lpszFilename, nBufLen))
{
lpszFilename[0] = 0;
bSuccess = FALSE;
}
}
else
{
bSuccess = FALSE;
}
FreeLibrary(hInstLib);
}
else if(osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
{
// Windows 9x 平台下的实现
HINSTANCE hInst = (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE);
if(!GetModuleFileName(hInst, lpszFilename, nBufLen))
bSuccess = FALSE;
}
return bSuccess;
}
======================================
现在的问题是上面两种方法都不能获得自定义文件夹的图标,不知道哪位高手愿意指点一二?
我的联系方式:
OICQ - 9254671
Windows Messenger - dualface@msn.com