SHGetFileInfo函数获取48x48图标并在ListControl平铺视图中显示

VS2010工程下载链接:https://pan.baidu.com/s/1ACXQSpoNdFVFLdvWntT7mA?pwd=wfy5

C语言写法:

#define COBJMACROS
#include <stdio.h>
#include <Windows.h>
#include <CommCtrl.h>
#include <commoncontrols.h>

HICON load_icon_48x48(const char *ext)
{
	HICON hicon = NULL;
	HRESULT hr;
	IImageList *iiml;
	SHFILEINFOA sfi;

	SHGetFileInfoA(ext, FILE_ATTRIBUTE_NORMAL, &sfi, sizeof(SHFILEINFO), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX);
	hr = SHGetImageList(SHIL_EXTRALARGE, &IID_IImageList, &iiml);
	if (SUCCEEDED(hr))
	{
		IImageList_GetIcon(iiml, sfi.iIcon, ILD_TRANSPARENT, &hicon);
		IImageList_Release(iiml);
	}
	return hicon;
}

void display_icon_size(HICON hicon)
{
	BITMAP bm;
	ICONINFO info;

	GetIconInfo(hicon, &info);
	GetObject(info.hbmColor, sizeof(BITMAP), &bm);
	printf("size: %dx%d\n", bm.bmWidth, bm.bmHeight);
	DeleteObject(info.hbmColor);
	DeleteObject(info.hbmMask);
}

int main(void)
{
	HICON hicon;

	hicon = load_icon_48x48(".png");
	if (hicon != NULL)
	{
		display_icon_size(hicon);
		DestroyIcon(hicon);
	}
	return 0;
}

C++写法:

#include <iostream>
#include <Windows.h>
#include <CommCtrl.h>
#include <commoncontrols.h>

using namespace std;

HICON load_icon_48x48(const char *ext)
{
	HICON hicon = NULL;
	HRESULT hr;
	IImageList *iiml;
	SHFILEINFOA sfi;

	SHGetFileInfoA(ext, FILE_ATTRIBUTE_NORMAL, &sfi, sizeof(SHFILEINFO), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX);
	hr = SHGetImageList(SHIL_EXTRALARGE, IID_PPV_ARGS(&iiml));
	if (SUCCEEDED(hr))
	{
		iiml->GetIcon(sfi.iIcon, ILD_TRANSPARENT, &hicon);
		iiml->Release();
	}
	return hicon;
}

void display_icon_size(HICON hicon)
{
	BITMAP bm;
	ICONINFO info;

	GetIconInfo(hicon, &info);
	GetObject(info.hbmColor, sizeof(BITMAP), &bm);
	cout << "size: " << bm.bmWidth << "x" << bm.bmHeight << endl;
	DeleteObject(info.hbmColor);
	DeleteObject(info.hbmMask);
}

int main(void)
{
	HICON hicon;

	hicon = load_icon_48x48(".png");
	if (hicon != NULL)
	{
		display_icon_size(hicon);
		DestroyIcon(hicon);
	}
	return 0;
}

C语言示例窗口程序:

#define COBJMACROS
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
#include <CommCtrl.h>
#include <commoncontrols.h>
#include <windowsx.h>
#include "resource.h"

#pragma comment(lib, "comctl32.lib")
#pragma comment(linker, "\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' language='*' publicKeyToken='6595b64144ccf1df'\"")

HINSTANCE hinstMain;
HWND hwndDlg, hwndList;

HICON load_icon_48x48(const char *ext)
{
	HICON hicon = NULL;
	HRESULT hr;
	IImageList *iiml;
	SHFILEINFOA sfi;

	SHGetFileInfoA(ext, FILE_ATTRIBUTE_NORMAL, &sfi, sizeof(SHFILEINFO), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX);
	hr = SHGetImageList(SHIL_EXTRALARGE, &IID_IImageList, &iiml);
	if (SUCCEEDED(hr))
	{
		IImageList_GetIcon(iiml, sfi.iIcon, ILD_TRANSPARENT, &hicon);
		IImageList_Release(iiml);
	}
	return hicon;
}

void list_init()
{
	char *list[] = {".avi", ".docx", ".jpg", ".gif", ".rxdata", ".png", ".txt", ".rmvb", ".mov", ".pptx", ".xlsx", ".accdb", ".pcbdoc", ".schdoc"};
	char name[50];
	char str[50];
	int i, j;
	HICON hicon;
	HIMAGELIST himl;
	LVCOLUMNA lvc;
	LVITEMA lvi;
	LVTILEVIEWINFO tvi;
	UINT tile_columns[2] = {1, 2};

	// 创建48x48图像列表
	himl = ImageList_Create(48, 48, ILC_COLOR32, 0, 1);
	ListView_SetImageList(hwndList, himl, LVSIL_NORMAL);
	for (i = 0; i < _countof(list); i++)
	{
		hicon = load_icon_48x48(list[i]);
		if (hicon != NULL)
		{
			ImageList_AddIcon(himl, hicon); // 将图标复制到图像列表 (注意是复制!!!)
			DestroyIcon(hicon); // 最后一定要记得删除图标
		}
	}

	// 添加列信息
	lvc.mask = LVCF_TEXT | LVCF_WIDTH;
	lvc.cx = 150;
	lvc.pszText = "文件名";
	SendMessage(hwndList, LVM_INSERTCOLUMNA, 0, (LPARAM)&lvc);
	lvc.cx = 100;
	lvc.pszText = "i";
	SendMessage(hwndList, LVM_INSERTCOLUMNA, 1, (LPARAM)&lvc);
	lvc.cx = 80;
	lvc.pszText = "namelen";
	SendMessage(hwndList, LVM_INSERTCOLUMNA, 2, (LPARAM)&lvc);

	// 设置平铺视图属性
	tvi.cbSize = sizeof(LVTILEVIEWINFO);
	tvi.dwFlags = LVTVIF_FIXEDSIZE;
	tvi.dwMask = LVTVIM_COLUMNS;
	tvi.cLines = _countof(tile_columns);
	ListView_SetTileViewInfo(hwndList, &tvi);

	// 添加项目
	for (i = 0; i < _countof(list); i++)
	{
		for (j = 0; list[i][j + 1] != '\0'; j++)
			name[j] = toupper(list[i][j + 1]);
		name[j] = '\0';
		strcat_s(name, sizeof(name), "文件");
		strcat_s(name, sizeof(name), list[i]);

		lvi.mask = LVIF_IMAGE | LVIF_TEXT | LVIF_COLUMNS;
		lvi.iItem = i;
		lvi.iSubItem = 0;
		lvi.pszText = name;
		lvi.iImage = i;
		lvi.cColumns = _countof(tile_columns); // 平铺视图灰色文字行数
		lvi.puColumns = tile_columns; // 平铺视图每一行灰色文字对应的列号
		lvi.iItem = (int)SendMessage(hwndList, LVM_INSERTITEMA, 0, (LPARAM)&lvi);
		
		_snprintf_s(str, sizeof(str), sizeof(str) - 1, "i=%d", i);
		lvi.mask = LVIF_TEXT;
		lvi.iSubItem = 1;
		lvi.pszText = str;
		SendMessage(hwndList, LVM_SETITEMA, 0, (LPARAM)&lvi);
		
		_snprintf_s(str, sizeof(str), sizeof(str) - 1, "namelen=%d", strlen(name));
		lvi.iSubItem = 2;
		lvi.pszText = str;
		SendMessage(hwndList, LVM_SETITEMA, 0, (LPARAM)&lvi);
	}

	ListView_SetExtendedListViewStyle(hwndList, LVS_EX_DOUBLEBUFFER); // 使用半透明选择框
	ListView_SetView(hwndList, LV_VIEW_TILE); // 切换到平铺视图
}

INT_PTR CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;

	switch (uMsg)
	{
	case WM_COMMAND:
		wmId = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		switch (wmId)
		{
		case IDCANCEL:
			EndDialog(hDlg, 0);
			hwndDlg = NULL;
			hwndList = NULL;
			break;
		}
	case WM_INITDIALOG:
		hwndDlg = hDlg;
		hwndList = GetDlgItem(hDlg, IDC_LIST1);
		list_init();
		break;
	}
	return 0;
}

int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
	LRESULT ret;

	hinstMain = hInstance;
	InitCommonControls();

	ret = DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DlgProc);
	return (int)ret;
}

示例应用:合泰(holtek)单片机串口OTA程序烧写软件(见链接中的download_code5.zip)


【勘误】
2023年8月21日:
visual studio里面使用以_s结尾的函数时,凡是参数名是maxcount的,都要减1,否则程序会闪退
_snprintf_s和vsnprintf_s的正确用法:
_snprintf_s(str, sizeof(str), sizeof(str) - 1, "fmt"); // C语言专用
_snprintf_s(str, sizeof(str) - 1, "fmt"); // C++专用, 和上面的语句等效
vsnprintf_s(str, sizeof(str), sizeof(str) - 1, fmt, list); // C语言专用
vsnprintf_s(str, sizeof(str) - 1, fmt, list); // C++专用, 和上面的语句等效
strcpy_s和strncpy_s的正确用法:
strcpy_s(str, sizeof(str), "xxx"); // C语言专用
strcpy_s(str, "xxx"); // C++专用, 和上面的语句等效
strncpy_s(str, sizeof(str), "xxx", sizeof(str) - 1); // C语言专用
strncpy_s(str, "xxx", sizeof(str) - 1); // C++专用, 和上面的语句等效
C++专用语句中,省略的参数始终是sizeof(str)。 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

巨大八爪鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值