【问题标题】:How to sync ListView checkbox with selection?(WIN32)如何将 ListView 复选框与选择同步?(WIN32)
【发布时间】:2016-09-18 06:30:22
【问题描述】:

我正在编写一个简单的 Win32 程序,它有一个带有复选框和启用多行选择的 ListView。 :

似乎复选框检查和行选择是两种不同的行为。有没有办法同步这两个行为,只要检查复选框,将选择该行,并且只要选择相应的复选框就会检查?

【问题讨论】:

    标签: c windows listview winapi win32gui


    【解决方案1】:

    “只要选择行,将检查相应的复选框” em>

    检查WM_NOTIFYLVIS_SELECTED 标志以检测用户何时选择一行。并使用ListView_SetCheckState 勾选复选框:

    BOOL CALLBACK DialogProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        static HWND hListView;
        switch (msg)
        {
        case WM_INITDIALOG:
            hListView = GetDlgItem(hWnd, IDC_LIST1);
            break;
    
        case WM_NOTIFY:
        {
            NMHDR* header = (NMHDR*)lParam;
            NMLISTVIEW* nmlist = (NMLISTVIEW*)lParam;
            if (header && header->idFrom == IDC_LIST1 && header->code == LVN_ITEMCHANGED)
                if (nmlist->uNewState & LVIS_SELECTED)
                    ListView_SetCheckState(hListView, nmlist->iItem, 1);
            break;
        }
        ...
    }
    

    “只要选中一个复选框,就会选择该行”

    检查WM_NOTIFYLVIS_STATEIMAGEMASK 标志以检测复选框何时被选中,然后使用ListView_SetItemState 选择行。

    这也可能导致递归调用,因为我们更改行以响应复选框,并且我们更改复选框以响应行选择。使用busy 变量停止递归调用。

    case WM_NOTIFY:
        if (lParam)
        {
            NMHDR* header = (NMHDR*)lParam;
            NMLISTVIEW* nmlist = (NMLISTVIEW*)lParam;
    
            //use `busy` as a flag to prevent recursive calls:
            static BOOL busy = FALSE;
            if (!busy && header->hwndFrom == hListView && header->code == LVN_ITEMCHANGED)
            {
                busy = TRUE;
                if (nmlist->uNewState & LVIS_SELECTED)
                {
                    //row has been selected => check the checkbox
                    ListView_SetCheckState(hListView, nmlist->iItem, 1);
                }
                else if (nmlist->uNewState & LVIS_STATEIMAGEMASK)
                {
                    //checkbox has been changed => select/unselect the row
                    BOOL checked = ListView_GetCheckState(hListView, nmlist->iItem);
                    ListView_SetItemState(hListView, nmlist->iItem,
                         checked ? LVIS_SELECTED : 0, LVIS_SELECTED);
                }
                busy = FALSE;
            }
        }
        break;
    

    【讨论】:

      猜你喜欢
      • 2021-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-30
      • 2021-09-23
      • 2012-07-18
      • 1970-01-01
      相关资源
      最近更新 更多