从列表视图控件中删除项目

时间:2014-04-06 11:12:03

标签: c++ listview winapi

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

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

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

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

编辑:

以下是代码:

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;

}

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

您正在呼叫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);