You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在SysListView32中创建带图标的列表项时图标不显示求助

SysListView32列表项图标不显示问题排查与解决

问题描述

在Microsoft Visual C/C++ 6.0环境下,给SysListView32控件添加带图标的列表项时,列表项文本正常显示,但图标始终无法加载。尝试过传入NULL、资源索引以及使用GetModuleHandle(NULL),均未解决问题。

相关代码

HWND CreateListView (HWND hwndParent) 
{
    INITCOMMONCONTROLSEX icex;           // 控件初始化结构
    icex.dwICC = ICC_LISTVIEW_CLASSES;
    InitCommonControlsEx(&icex);

    RECT rcClient;                       // 父窗口客户区

    GetClientRect (hwndParent, &rcClient); 

    // 创建报表视图的列表控件,允许编辑标签
    HWND hWndListView = CreateWindow(WC_LISTVIEW, 
                                     "",
                                     WS_CHILD | LVS_REPORT | LVS_EDITLABELS,
                                     0, 0,
                                     rcClient.right - rcClient.left,
                                     rcClient.bottom - rcClient.top,
                                     hwndParent,
                                     NULL,
                                     (HINSTANCE)GetWindowLong(hwndParent,GWL_HINSTANCE),
                                     NULL); 

    return (hWndListView);
}
VOID SetView(HWND hWndListView, DWORD dwView) 
{ 
    // 获取当前窗口样式
    DWORD dwStyle = GetWindowLong(hWndListView, GWL_STYLE); 
    
    // 仅当视图样式变化时修改窗口样式
    if ((dwStyle & LVS_TYPEMASK) != dwView) 
    {
        SetWindowLong(hWndListView,
                      GWL_STYLE,
                      (dwStyle & ~LVS_TYPEMASK) | dwView);
    }               
}                   
BOOL InitListViewColumns(HWND hWndListView, int C_COLUMNS, int FirstColumn) 
{ 
    LPSTR szText[256];     // 临时缓冲区
    LVCOLUMN lvc;
    int iCol;

    // 初始化LVCOLUMN结构,指定有效字段
    lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;

    // 添加列
    for (iCol = 0; iCol < C_COLUMNS; iCol++)
    {
        lvc.iSubItem = iCol;
        lvc.pszText = (LPSTR)szText;
        lvc.cx = 100;               // 列宽(像素)

        if ( iCol < 2 )
            lvc.fmt = LVCFMT_LEFT;  // 左对齐
        else
            lvc.fmt = LVCFMT_RIGHT; // 右对齐

        // 从字符串资源加载列标题
        LoadString((HINSTANCE)GetWindowLong((HWND)GetWindowLong(hWndListView,GWL_HWNDPARENT),GWL_HINSTANCE),
                   FirstColumn + iCol,
                   (LPSTR)szText,
                   sizeof(szText)/sizeof(szText[0]));

        // 插入列到列表控件
        if (ListView_InsertColumn(hWndListView, iCol, &lvc) == -1)
            return FALSE;
    }
    
    return TRUE;
}
BOOL InsertListViewItems(HWND hWndListView, LPSTR text, LPVOID iImage)
{
    LVITEM lvI;

    // 初始化LVITEM公共字段
    lvI.pszText   = text; // 触发LVN_GETDISPINFO消息
    lvI.cchTextMax= strlen(text);
    lvI.mask      = LVIF_TEXT | LVIF_IMAGE |LVIF_STATE;
    lvI.stateMask = 0;
    lvI.iSubItem  = 0;
    lvI.state     = 0;
    int index=ListView_GetItemCount(hWndListView)+1;
    lvI.iItem  = index;
    lvI.iImage = (int)iImage;
    
    // 插入列表项
    if (ListView_InsertItem(hWndListView, &lvI) == -1)
        return FALSE;

    return TRUE;
}
BOOL InitListViewImageLists(HWND hWndListView, LPVOID IDI_ITEM, HINSTANCE hInstance) 
{ 
    HICON hiconItem;     // 列表项图标
    HIMAGELIST hLarge;   // 大图标视图的图像列表
    HIMAGELIST hSmall;   // 其他视图的小图标图像列表

    // 创建大图标图像列表
    hLarge = ImageList_Create(GetSystemMetrics(SM_CXICON), 
                              GetSystemMetrics(SM_CYICON), 
                              ILC_MASK, 1, 1); 

    // 创建小图标图像列表
    hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), 
                              GetSystemMetrics(SM_CYSMICON), 
                              ILC_MASK, 1, 1); 
    
    // 加载图标并添加到图像列表
    hiconItem = LoadIcon(hInstance,(LPCTSTR)IDI_ITEM);

    ImageList_AddIcon(hLarge, hiconItem);
    ImageList_AddIcon(hSmall, hiconItem);

    DestroyIcon(hiconItem);

    
    // 给列表控件绑定图像列表
    ListView_SetImageList(hWndListView, hLarge, LVSIL_NORMAL); 
    ListView_SetImageList(hWndListView, hSmall, LVSIL_SMALL); 
    
    return TRUE; 
}

// 调用代码片段
hWnd[1] = CreateListView((HWND)hWnd[0]);
InitListViewImageLists((HWND)hWnd[1], NULL, NULL);
SetView((HWND)hWnd[1], LVS_ICON);
InitListViewColumns((HWND)hWnd[1], 1, IDS_FIRSTCOLUMN);
InsertListViewItems((HWND)hWnd[1], "Windows", NULL);

问题根源与修复步骤

1. 图标加载参数无效

当前调用InitListViewImageLists时传入NULL作为图标ID和实例句柄,导致LoadIcon无法加载有效图标。需传入已存在的图标资源ID和正确的实例句柄:

// 假设资源中已定义IDI_MYICON图标
InitListViewImageLists(hWnd[1], (LPVOID)IDI_MYICON, GetModuleHandle(NULL));

2. 列表项图标索引错误

InsertListViewItems中传入NULL作为图标索引,而图标索引是图标在图像列表中的位置(从0开始计数),并非NULL。应传入0(因仅向图像列表添加了一个图标):

InsertListViewItems(hWnd[1], "Windows", (LPVOID)0);

3. 添加错误检查避免空指针

在图像列表创建、图标加载步骤中添加错误检查,提前定位问题:

BOOL InitListViewImageLists(HWND hWndListView, LPVOID IDI_ITEM, HINSTANCE hInstance) 
{ 
    HICON hiconItem;
    HIMAGELIST hLarge;
    HIMAGELIST hSmall;

    hLarge = ImageList_Create(GetSystemMetrics(SM_CXICON), 
                              GetSystemMetrics(SM_CYICON), 
                              ILC_MASK, 1, 1); 
    if (!hLarge) return FALSE;

    hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), 
                              GetSystemMetrics(SM_CYSMICON), 
                              ILC_MASK, 1, 1); 
    if (!hSmall) { ImageList_Destroy(hLarge); return FALSE; }
    
    hiconItem = LoadIcon(hInstance,(LPCTSTR)IDI_ITEM);
    if (!hiconItem) { 
        ImageList_Destroy(hLarge); 
        ImageList_Destroy(hSmall); 
        return FALSE; 
    }

    ImageList_AddIcon(hLarge, hiconItem);
    ImageList_AddIcon(hSmall, hiconItem);

    DestroyIcon(hiconItem);

    ListView_SetImageList(hWndListView, hLarge, LVSIL_NORMAL); 
    ListView_SetImageList(hWndListView, hSmall, LVSIL_SMALL); 
    
    return TRUE; 
}

4. 优化控件创建样式

原代码先创建报表视图的ListView再切换到图标视图,可直接在CreateWindow时指定LVS_ICON样式,避免样式切换的潜在问题:

HWND hWndListView = CreateWindow(WC_LISTVIEW, 
                                 "",
                                 WS_CHILD | LVS_ICON | LVS_EDITLABELS,
                                 0, 0,
                                 rcClient.right - rcClient.left,
                                 rcClient.bottom - rcClient.top,
                                 hwndParent,
                                 NULL,
                                 (HINSTANCE)GetWindowLong(hwndParent,GWL_HINSTANCE),
                                 NULL); 

修改后可省略SetView调用。

修复后的完整调用示例

hWnd[1] = CreateListView(hWnd[0]);
// 初始化图像列表,传入有效图标ID和实例句柄
if (!InitListViewImageLists(hWnd[1], (LPVOID)IDI_MYICON, GetModuleHandle(NULL))) {
    MessageBox(NULL, "图像列表初始化失败", "错误", MB_ICONERROR);
    DestroyWindow(hWnd[1]);
    hWnd[1] = NULL;
    return;
}
InitListViewColumns(hWnd[1], 1, IDS_FIRSTCOLUMN);
// 传入图标索引0
InsertListViewItems(hWnd[1], "Windows", (LPVOID)0);

内容的提问来源于stack exchange,提问作者winapiadmin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 02:35:55