Win32 ListView无法分配不同图标:所有项仅显示单个图标
Win32 ListView 不同项显示不同图标的可运行实现(MinGW适配)
完整可运行代码
1. 资源文件定义
resource.h
#define IDI_FEMALE 101 #define IDI_MALE 102 #define IDI_NETWORK 103
resource.rc
#include "resource.h" IDI_FEMALE ICON "female.ico" IDI_MALE ICON "male.ico" IDI_NETWORK ICON "network.ico"
注意:将对应的ico文件放在源码同目录,或修改路径为实际文件位置
2. 主程序代码(main.c)
#include <windows.h> #include <commctrl.h> #pragma comment(lib, "comctl32.lib") #define LISTVIEW_ID 1001 LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX wc = {0}; wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; wc.hInstance = hInstance; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wc.lpszClassName = "ListViewIconDemo"; if(!RegisterClassEx(&wc)) { MessageBox(NULL, "窗口类注册失败!", "错误", MB_ICONEXCLAMATION | MB_OK); return 0; } HWND hwnd = CreateWindowEx( WS_EX_CLIENTEDGE, "ListViewIconDemo", "ListView 多图标演示", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 600, 400, NULL, NULL, hInstance, NULL); if(hwnd == NULL) { MessageBox(NULL, "窗口创建失败!", "错误", MB_ICONEXCLAMATION | MB_OK); return 0; } ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); MSG msg; while(GetMessage(&msg, NULL, 0, 0) > 0) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { static HWND hListView; static HIMAGELIST hImageList; HINSTANCE hInstance = GetModuleHandle(NULL); switch(msg) { case WM_CREATE: // 初始化通用控件 INITCOMMONCONTROLSEX icex; icex.dwSize = sizeof(INITCOMMONCONTROLSEX); icex.dwICC = ICC_LISTVIEW_CLASSES; InitCommonControlsEx(&icex); // 创建ListView控件 hListView = CreateWindow(WC_LISTVIEW, "", WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS, 10, 10, 560, 340, hwnd, (HMENU)LISTVIEW_ID, hInstance, NULL); // 创建ImageList(16x16图标,对应小图标模式) hImageList = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 3, 0); if(hImageList == NULL) { MessageBox(hwnd, "ImageList创建失败!", "错误", MB_ICONERROR); break; } // 加载图标并添加到ImageList,保存每个图标的索引 int idxFemale = ImageList_AddIcon(hImageList, LoadIcon(hInstance, MAKEINTRESOURCE(IDI_FEMALE))); int idxMale = ImageList_AddIcon(hImageList, LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MALE))); int idxNetwork = ImageList_AddIcon(hImageList, LoadIcon(hInstance, MAKEINTRESOURCE(IDI_NETWORK))); // 检查图标是否成功加载 if(idxFemale == -1 || idxMale == -1 || idxNetwork == -1) { MessageBox(hwnd, "图标加载失败!", "错误", MB_ICONERROR); ImageList_Destroy(hImageList); break; } // 给ListView设置ImageList(小图标模式,对应列表项的iImage) ListView_SetImageList(hListView, hImageList, LVSIL_SMALL); // 添加ListView列 LVCOLUMN lvc = {0}; lvc.mask = LVCF_TEXT | LVCF_WIDTH; lvc.cx = 200; lvc.pszText = "名称"; ListView_InsertColumn(hListView, 0, &lvc); lvc.cx = 150; lvc.pszText = "类型"; ListView_InsertColumn(hListView, 1, &lvc); // 添加列表项,每个项指定不同的图标索引 LVITEM lvi = {0}; lvi.mask = LVIF_TEXT | LVIF_IMAGE; // 第一项:女性图标 lvi.iItem = 0; lvi.iSubItem = 0; lvi.pszText = "张三"; lvi.iImage = idxFemale; ListView_InsertItem(hListView, &lvi); ListView_SetItemText(hListView, 0, 1, "用户"); // 第二项:男性图标 lvi.iItem = 1; lvi.pszText = "李四"; lvi.iImage = idxMale; ListView_InsertItem(hListView, &lvi); ListView_SetItemText(hListView, 1, 1, "用户"); // 第三项:网络图标 lvi.iItem = 2; lvi.pszText = "云服务器"; lvi.iImage = idxNetwork; ListView_InsertItem(hListView, &lvi); ListView_SetItemText(hListView, 2, 1, "设备"); break; case WM_DESTROY: ImageList_Destroy(hImageList); PostQuitMessage(0); break; default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; }
编译命令(MinGW)
在命令行执行以下步骤:
- 编译资源文件:
windres resource.rc -o resource.o - 编译主程序并链接:
g++ main.c resource.o -o ListViewIconDemo.exe -lcomctl32
关键问题排查与解释
1. 你之前遇到的共性错误
- 图标索引混淆:直接用资源ID(比如IDI_FEMALE的101)作为
LVITEM.iImage的值,而不是用ImageList_AddIcon返回的ImageList内部索引,导致所有项默认显示索引0的图标。 - ImageList模式不匹配:设置ListView的ImageList时未指定
LVSIL_SMALL或LVSIL_NORMAL,导致图标无法关联到列表项。 - MinGW资源加载疏漏:未用
MAKEINTRESOURCE转换资源ID,导致图标加载失败,最终所有项显示默认占位图标。
2. 核心实现要点
- ImageList创建:指定
ILC_COLOR32 | ILC_MASK保证图标透明显示,同时设置与加载图标一致的尺寸(这里用16x16适配小图标模式)。 - 图标索引管理:
ImageList_AddIcon返回的是图标在ImageList中的顺序索引,这才是LVITEM.iImage需要使用的正确值。 - 列表项属性设置:必须在
LVITEM.mask中包含LVIF_IMAGE,否则ListView会忽略图标设置。
内容的提问来源于stack exchange,提问作者CoderBittu
相关产品推荐
相关产品推荐

