Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何将ListView复选框与所选内容同步?(WIN32)_C_Windows_Listview_Winapi_Win32gui - Fatal编程技术网

C 如何将ListView复选框与所选内容同步?(WIN32)

C 如何将ListView复选框与所选内容同步?(WIN32),c,windows,listview,winapi,win32gui,C,Windows,Listview,Winapi,Win32gui,我正在编写一个简单的Win32程序,该程序有一个启用复选框和多行选择的ListView: 复选框检查和行选择似乎是两种截然不同的行为。是否有一种同步这两种行为的方法,即每当选中一个复选框时,该行将被选中;每当选中一行时,相应的复选框将被选中?“每当选中一行时,相应的复选框将被选中” 选中并LVIS_SELECTED标记,以便在用户选择行时进行检测。和用于选中复选框: BOOL CALLBACK DialogProc(HWND hWnd, UINT msg, WPARAM wParam, LPA

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

复选框检查和行选择似乎是两种截然不同的行为。是否有一种同步这两种行为的方法,即每当选中一个复选框时,该行将被选中;每当选中一行时,相应的复选框将被选中?

“每当选中一行时,相应的复选框将被选中”

选中并
LVIS_SELECTED
标记,以便在用户选择行时进行检测。和用于选中复选框:

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\u NOTIFY
LVIS\u statemagemask
标志以检测何时选中复选框,然后使用
ListView\u 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;