Что нового

[Элементы GUI] ListView: как отловить щелчок по чекбоксу?

avmaksimov

Новичок
Сообщения
40
Репутация
2
Хочу сделать так, чтобы по клику менялся чек-бокс. Всё ок, только теперь когда щелкаешь по чек-боксу, то он сам не меняется. Почему? Потому что он меняет значение и потом срабатывает клик, который ещё раз инвертирует значение (или наоборот).

Использую сообытие $NM_CLICK. Так вот для первой колонки он совпадает: что для чек-бокса, что по тексту. Это как-то можно побороть? Может быть, я что-то делаю не так?

Для иллюстрации доработал чуть пример из GUICtrlListView_ClickItem, добавив чек-боксы.

Помогите, пожалуйста.
 

Вложения

Khaibit

Знающий
Сообщения
79
Репутация
18
Код:
_GUICtrlListView_SetItemChecked

_GUICtrlListView_GetItemChecked



Код:
Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
	#forceref $hWnd, $iMsg, $wParam
	Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView, $tInfo
	$hWndListView = $g_idListView
	If Not IsHWnd($g_idListView) Then $hWndListView = GUICtrlGetHandle($g_idListView)

	$tNMHDR = DllStructCreate($tagNMHDR, $lParam)
	$hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
	$iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
	$iCode = DllStructGetData($tNMHDR, "Code")
	Switch $hWndFrom
		Case $hWndListView
			Switch $iCode
				Case $NM_CLICK ; Sent by a list-view control when the user clicks an item with the left mouse button
					$tInfo = DllStructCreate($tagNMITEMACTIVATE, $lParam)
					_GUICtrlListView_SetItemChecked($hWndListView, DllStructGetData($tInfo, "Index"));<<<<<<<<<<<<<<<<<
			EndSwitch
	EndSwitch
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY
 
Автор
avmaksimov

avmaksimov

Новичок
Сообщения
40
Репутация
2
Khaibit сказал(а):
Код:
_GUICtrlListView_SetItemChecked

_GUICtrlListView_GetItemChecked
Да, я в курсе и на клик как раз стоит инверсия. Так вот вопрос в том, как отличить клик в первой колонке от клика по чеку? Иначе чек два раза состояние меняет, то есть возвращается к своему же.
 

Khaibit

Знающий
Сообщения
79
Репутация
18
Код:
Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
	#forceref $hWnd, $iMsg, $wParam
	Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView, $tInfo
	$hWndListView = $g_idListView
	If Not IsHWnd($g_idListView) Then $hWndListView = GUICtrlGetHandle($g_idListView)

	$tNMHDR = DllStructCreate($tagNMHDR, $lParam)
	$hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
	$iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
	$iCode = DllStructGetData($tNMHDR, "Code")
	Switch $hWndFrom
		Case $hWndListView
			Switch $iCode
				Case $NM_CLICK ; Sent by a list-view control when the user clicks an item with the left mouse button
					$tInfo = DllStructCreate($tagNMITEMACTIVATE, $lParam)
					$index = DllStructGetData($tInfo, "Index")
					Local $iX = DllStructGetData($tInfo, "X")
					Local $aIconRect = _GUICtrlListView_GetItemRect($hWndListView, $index, 2)
					If $iX > $aIconRect[0]  And $iX < $aIconRect[2] Then
						If _GUICtrlListView_GetItemChecked($hWndListView, $index) = 0 Then
							_GUICtrlListView_SetItemChecked($hWndListView, $index, 1)
						Else
							_GUICtrlListView_SetItemChecked($hWndListView, $index, 0)
						EndIf
					EndIf
			EndSwitch
	EndSwitch
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY
 
Автор
avmaksimov

avmaksimov

Новичок
Сообщения
40
Репутация
2
Khaibit
спасибо. Очень помогли. :laugh: :laugh: :laugh: :IL_AutoIt_1:

Только чуть поменял вашу проверку на
Код:
If (DllStructGetData($tInfo, "SubItem") > 0) Or ($iX > $aIconRect[0]  And $iX < $aIconRect[2]) Then
, а-то клики не срабатывали в других колонках!
 

Tempo

Скриптер
Сообщения
568
Репутация
181
Код:
#include <GUIConstants.au3>
#include <GUIListView.au3>

GUICreate("", 400, 400)
Global $g_idLV = GUICtrlCreateListView("Item|SubItem", 5, 5, 390, 390, -1, BitOR($LVS_EX_CHECKBOXES, $LVS_EX_FULLROWSELECT, $WS_EX_CLIENTEDGE))
For $i = 0 To 10
    GUICtrlCreateListViewItem("Item " & $i & "|" & "SubItem " & $i, $g_idLV)
Next
_GUICtrlListView_SetColumnWidth($g_idLV, 0, $LVSCW_AUTOSIZE_USEHEADER)
_GUICtrlListView_SetColumnWidth($g_idLV, 1, $LVSCW_AUTOSIZE_USEHEADER)
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUISetState()

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
    Local $tNMHDR, $hWndFrom, $idFrom, $iCode
    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $hWndFrom = DllStructGetData($tNMHDR, "hWndFrom")
    $idFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $idFrom
        Case $g_idLV
            Switch $iCode
                Case $NM_CLICK
                    Local $tNMITEMACTIVATE = DllStructCreate($tagNMITEMACTIVATE, $lParam)
                    Local $aHit = _GUICtrlListView_HitTest($hWndFrom, DllStructGetData($tNMITEMACTIVATE, "X"), DllStructGetData($tNMITEMACTIVATE, "Y"))
                    If Not @error And $aHit[0] <> -1 And ($aHit[2] Or $aHit[3]) Then _GUICtrlListView_SetItemChecked($hWndFrom, $aHit[0], Not _GUICtrlListView_GetItemChecked($hWndFrom, $aHit[0]))
            EndSwitch
    EndSwitch
EndFunc   ;==>WM_NOTIFY
 
  • Like
Реакции: Norm
Автор
avmaksimov

avmaksimov

Новичок
Сообщения
40
Репутация
2
Tempo, спасибо. Ещё лучше! :shok: :beer: :ok:
 
Верх