【问题标题】:Remove an item from a list-view control从列表视图控件中删除项目
【发布时间】:2014-04-06 11:12:02
【问题描述】:

我的程序中有一个列表视图控件,我想删除选定的项目。这是通过按下按钮来完成的。

问题是,无论我选择什么项目,它总是会删除第一个...

我认为问题在于列表视图焦点丢失。当按钮被按下时,列表视图首先失去焦点,然后它会尝试删除一个不再被选中的项目,因此它会删除第一个。

我的问题是:是否有任何选项可以使列表视图不失去焦点?

编辑:

代码如下:

stdafx.h

// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//

#pragma once

#include "targetver.h"

#define WIN32_LEAN_AND_MEAN    // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>

// C RunTime Header Files
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>


// TODO: reference additional headers your program requires here

Main.cpp

#include "stdafx.h"


LRESULT CALLBACK WindowFunc(HWND, UINT, WPARAM, LPARAM);

void CreateList();
void CreateButtons();

enum
{
    IDC_REMOVE_BUTTON = 1000,
    IDC_LIST
};


struct ListBox
{
    HWND hwnd;

    LVCOLUMN lvc;
    LVITEM   lv;

    ListBox(HWND h = 0, LVCOLUMN l = { 0 }, LVITEM lvi = { 0 })
    {
        hwnd = h;
        lvc = l;
        lv = lvi;
    }

};



int selitm = -1;


HINSTANCE g_hInstance;

HWND hwndRemoveButton;

HWND g_hwnd;

ListBox List;





int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst,
    LPSTR Args, int WinMode)
{
    HWND hWnd;
    MSG Message;
    WNDCLASSEX WinClass = { 0 };
    INITCOMMONCONTROLSEX icc = { 0 };

    g_hInstance = hThisInst;

    icc.dwSize = sizeof(icc);
    icc.dwICC = ICC_LISTVIEW_CLASSES;
    InitCommonControlsEx(&icc);

    WinClass.cbSize = sizeof(WNDCLASSEX);
    WinClass.hInstance = hThisInst;
    WinClass.lpszClassName = "Test";
    WinClass.lpfnWndProc = WindowFunc;
    WinClass.style = 0;
    WinClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    WinClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO);
    WinClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    WinClass.lpszMenuName = NULL;
    WinClass.cbClsExtra = 0;
    WinClass.cbWndExtra = 0;
    WinClass.hbrBackground = (HBRUSH)COLOR_WINDOW;

    if (!RegisterClassEx(&WinClass)) return 0;

    hWnd = CreateWindow("Test", "Test", WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, 660, 350,
        NULL, NULL, hThisInst, NULL);

    ShowWindow(hWnd, WinMode);
    UpdateWindow(hWnd);


    while (GetMessage(&Message, NULL, 0, 0))
    {
        TranslateMessage(&Message);
        DispatchMessage(&Message);
    }


    return Message.wParam;
}


LRESULT CALLBACK WindowFunc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{

    switch (Message)
    {
    case WM_CREATE:

        g_hwnd = hWnd;

        CreateList();
        CreateButtons();

        ListView_InsertItem(List.hwnd, &List.lv);
        ListView_SetCheckState(List.hwnd, List.lv.iItem, true);
        ListView_SetItemText(List.hwnd, List.lv.iItem, 1, "One");
        ListView_SetItemText(List.hwnd, List.lv.iItem, 2, "$1");
        ListView_SetItemText(List.hwnd, List.lv.iItem++, 3, "2010-05-05");


        ListView_InsertItem(List.hwnd, &List.lv);
        ListView_SetCheckState(List.hwnd, List.lv.iItem, true);
        ListView_SetItemText(List.hwnd, List.lv.iItem, 1, "Two");
        ListView_SetItemText(List.hwnd, List.lv.iItem, 2, "$2");
        ListView_SetItemText(List.hwnd, List.lv.iItem++, 3, "2008-05-05");


        ListView_InsertItem(List.hwnd, &List.lv);
        ListView_SetCheckState(List.hwnd, List.lv.iItem, false);
        ListView_SetItemText(List.hwnd, List.lv.iItem, 1, "Three");
        ListView_SetItemText(List.hwnd, List.lv.iItem, 2, "$3");
        ListView_SetItemText(List.hwnd, List.lv.iItem++, 3, "2006-05-05");

        break;


    case WM_COMMAND:

        // The low word of wParam contains the menu ID.
        switch (LOWORD(wParam))
        {

        case IDC_REMOVE_BUTTON:

            selitm = ListView_GetFocusedGroup(List.hwnd);

            ListView_DeleteItem(List.hwnd, selitm);

            break;

        }

        break;

    case WM_DESTROY:
        PostQuitMessage(0);
        break;


    default:
        return DefWindowProc(hWnd,
            Message,
            wParam,
            lParam);
    }
    return 0;
}


void CreateButtons()
{
    hwndRemoveButton = CreateWindow("Button", "Remove",
        BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE,
        20, 265, 70, 30,
        g_hwnd, (HMENU)IDC_REMOVE_BUTTON,
        g_hInstance, NULL);
}


void CreateList()
{

    List.hwnd = CreateWindow(WC_LISTVIEW, NULL,
    WS_CHILD | WS_VISIBLE | LVS_REPORT,
    20, 30, 600, 230,
    g_hwnd, (HMENU)IDC_LIST, g_hInstance, NULL);

    ListView_SetExtendedListViewStyle(List.hwnd, LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT | LVS_EX_HEADERDRAGDROP);

    List.lvc.mask = LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH | LVCF_FMT;
    List.lvc.fmt = LVCFMT_LEFT;

    /* Add four columns to the list-view (first column contains check box). */
    List.lvc.iSubItem = 0;

    List.lvc.cx = 50;
    List.lvc.pszText = "Good?";
    ListView_InsertColumn(List.hwnd, List.lvc.iSubItem++, &List.lvc);

    List.lvc.cx = 300;
    List.lvc.pszText = "Name";
    ListView_InsertColumn(List.hwnd, List.lvc.iSubItem++, &List.lvc);

    List.lvc.cx = 150;
    List.lvc.pszText = "Cost";
    ListView_InsertColumn(List.hwnd, List.lvc.iSubItem++, &List.lvc);

    List.lvc.cx = 100;
    List.lvc.pszText = "Watched Since";
    ListView_InsertColumn(List.hwnd, List.lvc.iSubItem++, &List.lvc);

    List.lv.iItem = 0;

}

【问题讨论】:

  • 如果您显示代码会有所帮助

标签: c++ listview winapi


【解决方案1】:

您的问题与专注无关。您使用错误的 API 来确定所选项目。当您需要使用ListView_GetNextItem() 时,您正在使用ListView_GetFocusedGroup()

selitm = ListView_GetNextItem(List.hwnd, -1, LVNI_SELECTED);
if (selitm != -1)
    ListView_DeleteItem(List.hwnd, selitm);

【讨论】:

    【解决方案2】:

    您正在呼叫ListView_GetFocusedGroup。作为documented这个:

    获取具有焦点的组

    Groups 是列表视图的一项高级功能。同样,documented:

    分组允许用户使用水平分隔线和组标题将列表排列成在页面上视觉划分的项目组。

    所以,这不是你想要的。获取选中项所需的 API 是ListView_GetNextItem。像这样称呼它:

    int selectedIndex = ListView_GetNextItem(List.hwnd, -1, LVNI_ALL | LVNI_SELECTED);
    if (selectedIndex != -1)
        ListView_DeleteItem(List.hwnd, selitm);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-21
      • 1970-01-01
      相关资源
      最近更新 更多