Что нового

Работа с виртуальным ListView. Checkboxes

pvnn

Осваивающий
Сообщения
305
Репутация
32
Всем доброго дня!
Подскажите, как можно создать чекбокс в виртуальном ListView.
$LVS_EX_CHECKBOXES не работает, появляется просто пустая область.

Код:
; Виртуальный ListView

#include <GUIConstants.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include <Array.au3>
#include <ButtonConstants.au3>
#include <GuiListView.au3>

#Include <APIConstants.au3>
#Include <WinAPIEx.au3>

Global $hGui, $hEdit, $idEditSearch, $hLV, $iItems = 100000, $aItems[$iItems][3]


  ; Create GUI
  $hGui = GUICreate( "Virtual ListView", 300, 230 )
  Local $Button1 = GUICtrlCreateButton("Button1", 10, 8, 75, 25)
  ; Create ListView
  Local $idLV = GUICtrlCreateListView( "", 10, 40, 300-20, 200-20, BitOR($LVS_OWNERDATA,$LVS_SHOWSELALWAYS) )
  _GUICtrlListView_SetExtendedListViewStyle($idLV, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT, $LVS_EX_SUBITEMIMAGES,$LVS_EX_CHECKBOXES))
  $hLV = GUICtrlGetHandle( $idLV ) ;    Virtual listview Reduces flicker
; Создаем столбцы
  _GUICtrlListView_AddColumn( $hLV, "Items1",  100 )
  _GUICtrlListView_AddColumn( $hLV, "Items2",  100 )
  _GUICtrlListView_AddColumn( $hLV, "Items3",  100 )

; Создаем массив
  For $i = 0 To $iItems - 1
       $aItems[$i][0]='СтрокаI '&$i+1
       $aItems[$i][1]='СтрокаII '&$i+1
       $aItems[$i][2]='СтрокаIII '&$i+1
  Next

 GUIRegisterMsg( $WM_NOTIFY, "WM_NOTIFY" ) ; Заполнить структуру виртуального ListView
 GUICtrlSendMsg( $idLV, $LVM_SETITEMCOUNT, $iItems, 0 )   ; Display items
GUISetState(@SW_SHOW)

  ; Message loop
  While 1
    Switch GUIGetMsg()
     Case $GUI_EVENT_CLOSE
        Exit
        Case $Button1
             $hLV = GUICtrlGetHandle( $idLV )
              $IndexListView=_GUICtrlListView_GetSelectedIndices($idLV) ; Индекс выделенной записи
              $Name=_GUICtrlListView_GetItemText($hLV,$IndexListView,0) ; Текст
             MsgBox(0,'',$Name)
    EndSwitch
  WEnd



Func WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam )
  Local Static $tText = DllStructCreate( "wchar[1000]" )    ; Размерность данных в столбцах
  Local Static $pText = DllStructGetPtr( $tText )

  Local $tNMHDR, $hWndFrom, $iCode
  $tNMHDR = DllStructCreate( $tagNMHDR, $lParam )
  $hWndFrom = HWnd( DllStructGetData( $tNMHDR, "hWndFrom" ) )
  $iCode = DllStructGetData( $tNMHDR, "Code" )

  Switch $hWndFrom
    Case $hLV
      Switch $iCode
        ; Отобразить виртуальный ListView
        Case $LVN_GETDISPINFOW
          Local $tNMLVDISPINFO = DllStructCreate( $tagNMLVDISPINFO, $lParam )
          $ColumnNumb=DllStructGetData( $tNMLVDISPINFO, "SubItem" )                         ; Номер столбца, для которого ведется опрос
          If BitAND( DllStructGetData( $tNMLVDISPINFO, "Mask" ), $LVIF_TEXT ) Then
             Local $sItem = $aItems[DllStructGetData($tNMLVDISPINFO,"Item")][$ColumnNumb]   ; Данные в столбце
            DllStructSetData( $tText, 1, $sItem )
            DllStructSetData( $tNMLVDISPINFO, "Text", $pText )
            DllStructSetData( $tNMLVDISPINFO, "TextMax", StringLen( $sItem ) )
          EndIf

      EndSwitch
 EndSwitch
  Return $GUI_RUNDEFMSG
EndFunc
 

qqww22

Новичок
Сообщения
115
Репутация
4
Код:
#include <GUIConstants.au3>
#include <GuiConstantsEx.au3>
GUICreate("listview items", 300, 300, 300, 149)
$listview = GUICtrlCreateListView ("1",16, 32, 273, 502,-1, $LVS_EX_CHECKBOXES)
GUICtrlCreateListViewItem("1",$listview)
GUISetState()

sleep(5000)
 
Автор
P

pvnn

Осваивающий
Сообщения
305
Репутация
32
qqww22 ListView виртуальный!
$LVS_OWNERDATA
В таком режиме $LVS_EX_CHECKBOXES не работает, выделяется просто пустое место
 

Prog

Продвинутый
Сообщения
537
Репутация
65
Для этого нужно создать еще один массив под чекбоксы и обрабатывать парочку сообщений винды.
У меня есть пример на другом ЯП, который можно переписать на AutoIt. Если нужен, могу скинуть.
 

Prog

Продвинутый
Сообщения
537
Репутация
65
Исходник во вложении. Состояния чекбоксов хранятся в массиве CheckFlag.
 

Вложения

  • Virtual ListView Checkboxes.zip
    20.4 КБ · Просмотры: 14
Автор
P

pvnn

Осваивающий
Сообщения
305
Репутация
32
Пробую нарисовать Чекбокс через $NM_CUSTOMDRAW и коллекцию
Код:
_GUIImageList_Create
- тоже не получается., не работает:
Код:
_GUICtrlListView_SetItemImage



Код:
; Виртуальный ListView

#include <GUIConstants.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include <Array.au3>
#include <ButtonConstants.au3>
#include <GuiListView.au3>

#Include <APIConstants.au3>
#Include <WinAPIEx.au3>
#include <GuiImageList.au3>

Global $hGui, $hEdit, $idEditSearch, $hLV, $iItems = 100000, $aItems[$iItems][3]





  ; Create GUI
  $hGui = GUICreate( "Virtual ListView", 300, 230 )
  Local $Button1 = GUICtrlCreateButton("Button1", 10, 8, 75, 25)
  ; Create ListView
  Local $idLV = GUICtrlCreateListView( "", 10, 40, 300-20, 200-20, BitOR($LVS_OWNERDATA,$LVS_SHOWSELALWAYS) )
;~     Local $idLV = GUICtrlCreateListView( "", 10, 40, 300-20, 200-20, $LVS_SHOWSELALWAYS)
  _GUICtrlListView_SetExtendedListViewStyle($idLV, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT, $LVS_EX_SUBITEMIMAGES))
  $hLV = GUICtrlGetHandle( $idLV ) ;    Virtual listview Reduces flicker
; Создаем столбцы
  _GUICtrlListView_AddColumn( $hLV, "Items1",  100 )
  _GUICtrlListView_AddColumn( $hLV, "Items2",  100 )
  _GUICtrlListView_AddColumn( $hLV, "Items3",  100 )
;~   _GUICtrlListView_AddItem($hLV,'test')


; Создать коллекцию изображений для ListView
  $hImageLV = _GUIImageList_Create(16, 16, 5, 3)
  _GUIImageList_AddIcon($hImageLV, @SystemDir & "\hnetcfg.dll", 1) ; Check
  _GUIImageList_AddIcon($hImageLV, @SystemDir & "\hnetcfg.dll", 2) ; UnCheck
  _GUICtrlListView_SetImageList($hLV, $hImageLV, 1)

; Создаем массив
  For $i = 0 To $iItems - 1
       $aItems[$i][0]='СтрокаI '&$i+1
       $aItems[$i][1]='СтрокаII '&$i+1
       $aItems[$i][2]='СтрокаIII '&$i+1
  Next

 GUIRegisterMsg( $WM_NOTIFY, "WM_NOTIFY" ) ; Заполнить структуру виртуального ListView
 GUICtrlSendMsg( $idLV, $LVM_SETITEMCOUNT, $iItems, 0 )   ; Display items
GUISetState(@SW_SHOW)

  ; Message loop
  While 1
    Switch GUIGetMsg()
     Case $GUI_EVENT_CLOSE
        Exit
        Case $Button1
             $hLV = GUICtrlGetHandle( $idLV )
              $IndexListView=_GUICtrlListView_GetSelectedIndices($idLV) ; Индекс выделенной записи
              $Name=_GUICtrlListView_GetItemText($hLV,$IndexListView,0) ; Текст
             MsgBox(0,'',$Name)
    EndSwitch
  WEnd



Func WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam )
  Local Static $tText = DllStructCreate( "wchar[1000]" )    ; Размерность данных в столбцах
  Local Static $pText = DllStructGetPtr( $tText )

  Local $tNMHDR, $hWndFrom, $iCode
  $tNMHDR = DllStructCreate( $tagNMHDR, $lParam )
  $hWndFrom = HWnd( DllStructGetData( $tNMHDR, "hWndFrom" ) )
  $iCode = DllStructGetData( $tNMHDR, "Code" )

  Switch $hWndFrom
    Case $hLV
      Switch $iCode
        ; Отобразить виртуальный ListView
        Case $LVN_GETDISPINFOW
          Local $tNMLVDISPINFO = DllStructCreate( $tagNMLVDISPINFO, $lParam )
          $ColumnNumb=DllStructGetData( $tNMLVDISPINFO, "SubItem" )                         ; Номер столбца, для которого ведется опрос
          If BitAND( DllStructGetData( $tNMLVDISPINFO, "Mask" ), $LVIF_TEXT ) Then
             Local $sItem = $aItems[DllStructGetData($tNMLVDISPINFO,"Item")][$ColumnNumb]   ; Данные в столбце
            DllStructSetData( $tText, 1, $sItem )
            DllStructSetData( $tNMLVDISPINFO, "Text", $pText )
            DllStructSetData( $tNMLVDISPINFO, "TextMax", StringLen( $sItem ) )
		  EndIf


		Case $NM_CUSTOMDRAW
                    Local $tNMLVCD = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam)
                    Local $iDrawStage = DllStructGetData($tNMLVCD, 'dwDrawStage')
                    Local $iItem = DllStructGetData($tNMLVCD, 'dwItemSpec')			; Индекс элемента
                    Local $iSubItem = DllStructGetData($tNMLVCD, 'iSubItem')		; Индекс субэлемента
					Local $hDC = DllStructGetData($tNMLVCD, 'hDC') 					; Для изменения шрифта
					Local $fitemindex = DllStructGetData($tNMLVCD, "Index")

                    Switch $iDrawStage
						Case $CDDS_PREPAINT
							; При начале прорисовки листа указываем, что нам нужны нотификации на прорисовку каждой строки
                            Return $CDRF_NOTIFYITEMDRAW

                        Case $CDDS_ITEMPREPAINT
							; Если нужно красить СТРОКИ ЦЕЛИКОМ, то можно остановиться здесь
							; установить цвета текста и фона и выставить Return $CDRF_NEWFONT
							DllStructSetData($tNMLVCD, 'clrText',   0x0000FF) ; Изменить цвет шрифта RGB. Красный

							; Попытка нарисовать CheckBox
							 _GUICtrlListView_SetItemImage($hLV,$fitemindex,1)

                            Return $CDRF_NEWFONT
					EndSwitch

      EndSwitch
 EndSwitch
  Return $GUI_RUNDEFMSG
EndFunc
 

Prog

Продвинутый
Сообщения
537
Репутация
65
pvnn [?]
_GUICtrlListView_SetItemImage
Эта функция задает иконку, а не рисует ее. Рисовать нужно с помощью WinAPI, в контексте hDC контрола.
Посмотрите исходник что выложил выше. В нем не нужно программно рисовать чекбоксы. Необходимо только сообщить системе их состояние (отмечен или нет). И обрабатывать клики по чекбоксам, сохраняя данные в массиве.
 
Автор
P

pvnn

Осваивающий
Сообщения
305
Репутация
32
Prog пытаюсь переделать ваш пример для Autoit
Создал новый одномерный массив $aCheckFlag и забил его нулями.
Добавил
Код:
Case $NM_CLICK

При клике на строку, в соответствующую строчку массива будет заносится 0-1-0. (для проверки вывожу в консоль тоже)
Мне не понятно как сделать это "Рисовать нужно с помощью WinAPI, в контексте hDC контрола."
Добавил в $LVN_GETDISPINFOW
Код:
$fitemindex = DllStructGetData($tNMLVDISPINFO, "Index")
 If $aCheckFlag[$fitemindex]=1 Then
         _GUICtrlListView_SetItemChecked($hLV,$fitemindex,True)
 Else
         _GUICtrlListView_SetItemChecked($hLV,$fitemindex,False)
 EndIf

Не получается сообщить системе состояние




Код:
; Виртуальный ListView

#include <GUIConstants.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include <Array.au3>
#include <ButtonConstants.au3>
#include <GuiListView.au3>

#Include <APIConstants.au3>
#Include <WinAPIEx.au3>
#include <GuiImageList.au3>

Global $hGui, $hEdit, $idEditSearch, $hLV, $iItems = 100000, $aItems[$iItems][3], $aCheckFlag[$iItems]




  ; Create GUI
  $hGui = GUICreate( "Virtual ListView", 300, 230 )
  Local $Button1 = GUICtrlCreateButton("Button1", 10, 8, 75, 25)
  ; Create ListView
  Local $idLV = GUICtrlCreateListView( "", 10, 40, 300-20, 200-20, BitOR($LVS_OWNERDATA,$LVS_SHOWSELALWAYS) )
;~     Local $idLV = GUICtrlCreateListView( "", 10, 40, 300-20, 200-20, $LVS_SHOWSELALWAYS)
  _GUICtrlListView_SetExtendedListViewStyle($idLV, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT, $LVS_EX_SUBITEMIMAGES,$LVS_EX_CHECKBOXES))
  $hLV = GUICtrlGetHandle( $idLV ) ;    Virtual listview Reduces flicker
; Создаем столбцы
  _GUICtrlListView_AddColumn( $hLV, "Items1",  100 )
  _GUICtrlListView_AddColumn( $hLV, "Items2",  100 )
  _GUICtrlListView_AddColumn( $hLV, "Items3",  100 )
;~   _GUICtrlListView_AddItem($hLV,'test')


; Создать коллекцию изображений для ListView
  $hImageLV = _GUIImageList_Create(16, 16, 5, 3)
  _GUIImageList_AddIcon($hImageLV, @SystemDir & "\hnetcfg.dll", 1) ; Check
  _GUIImageList_AddIcon($hImageLV, @SystemDir & "\hnetcfg.dll", 2) ; UnCheck
;  _GUICtrlListView_SetImageList($hLV, $hImageLV, 1)

; Создаем массив
  For $i = 0 To $iItems - 1
       $aItems[$i][0]='СтрокаI '&$i+1
       $aItems[$i][1]='СтрокаII '&$i+1
       $aItems[$i][2]='СтрокаIII '&$i+1
  Next

; $aCheckFlag заполнить нулями
  For $i = 0 To $iItems - 1
       $aCheckFlag[$i]=0
  Next



 GUIRegisterMsg( $WM_NOTIFY, "WM_NOTIFY" ) ; Заполнить структуру виртуального ListView
 GUICtrlSendMsg( $idLV, $LVM_SETITEMCOUNT, $iItems, 0 )   ; Display items
GUISetState(@SW_SHOW)

  ; Message loop
  While 1
    Switch GUIGetMsg()
     Case $GUI_EVENT_CLOSE
        Exit
        Case $Button1
             $hLV = GUICtrlGetHandle( $idLV )
              $IndexListView=_GUICtrlListView_GetSelectedIndices($idLV) ; Индекс выделенной записи
              $Name=_GUICtrlListView_GetItemText($hLV,$IndexListView,0) ; Текст
             MsgBox(0,'',$Name)
    EndSwitch
  WEnd



Func WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam )
  Local Static $tText = DllStructCreate( "wchar[1000]" )    ; Размерность данных в столбцах
  Local Static $pText = DllStructGetPtr( $tText )

  Local $tNMHDR, $hWndFrom, $iCode
  $tNMHDR = DllStructCreate( $tagNMHDR, $lParam )
  $hWndFrom = HWnd( DllStructGetData( $tNMHDR, "hWndFrom" ) )
  $iCode = DllStructGetData( $tNMHDR, "Code" )

  Switch $hWndFrom
    Case $hLV
      Switch $iCode
        ; Отобразить виртуальный ListView
        Case $LVN_GETDISPINFOW
          Local $tNMLVDISPINFO = DllStructCreate( $tagNMLVDISPINFO, $lParam )
          $ColumnNumb=DllStructGetData( $tNMLVDISPINFO, "SubItem" )                         ; Номер столбца, для которого ведется опрос
          If BitAND( DllStructGetData( $tNMLVDISPINFO, "Mask" ), $LVIF_TEXT ) Then
             Local $sItem = $aItems[DllStructGetData($tNMLVDISPINFO,"Item")][$ColumnNumb]   ; Данные в столбце
            DllStructSetData( $tText, 1, $sItem )
            DllStructSetData( $tNMLVDISPINFO, "Text", $pText )
            DllStructSetData( $tNMLVDISPINFO, "TextMax", StringLen( $sItem ) )


			$fitemindex = DllStructGetData($tNMLVDISPINFO, "Index")
			If $aCheckFlag[$fitemindex]=1 Then
				_GUICtrlListView_SetItemChecked($hLV,$fitemindex,True)
			Else
				_GUICtrlListView_SetItemChecked($hLV,$fitemindex,False)
			EndIf

          EndIf



        Case $NM_CLICK
             $tInfo = DllStructCreate($tagNMITEMACTIVATE, $lParam)
             $fitemindex = DllStructGetData($tInfo, "Index")
             $fsubitemindex = DllStructGetData($tInfo, "SubItem")
			 If $aCheckFlag[$fitemindex]=0 Then
				 $aCheckFlag[$fitemindex]=1
			 Else
				 $aCheckFlag[$fitemindex]=0
			 EndIf
			ConsoleWrite($aCheckFlag[$fitemindex])



      EndSwitch
 EndSwitch
  Return $GUI_RUNDEFMSG
EndFunc
 

Prog

Продвинутый
Сообщения
537
Репутация
65
Нужно обрабатывать сообщение $LVN_GETDISPINFO.
Код:
Case $LVN_GETDISPINFO
		   $tNMLVDISPINFO = DllStructCreate( $tagNMLVDISPINFO, $lParam )
		   DllStructSetData($tNMLVDISPINFO, "mask", BitOR($LVIF_IMAGE, $LVIF_STATE) )
		   DllStructSetData($tNMLVDISPINFO, "stateMask", $LVIS_STATEIMAGEMASK)

           if $aCheckFlag[$fitemindex] = 0 Then
		    	DllStructSetData( $tNMLVDISPINFO, "State", 4096)
	       Else
			    DllStructSetData( $tNMLVDISPINFO, "State", 8192)
		   Endif
 
Автор
P

pvnn

Осваивающий
Сообщения
305
Репутация
32
Prog спасибо за ответ
Сделал как написали. Чекбокс все равно не отображается

Код:
; Виртуальный ListView

#include <GUIConstants.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include <Array.au3>
#include <ButtonConstants.au3>
#include <GuiListView.au3>

#Include <APIConstants.au3>
#Include <WinAPIEx.au3>
#include <GuiImageList.au3>

Global $hGui, $hEdit, $idEditSearch, $hLV, $iItems = 100000, $aItems[$iItems][3], $aCheckFlag[$iItems]




  ; Create GUI
  $hGui = GUICreate( "Virtual ListView", 300, 230 )
  Local $Button1 = GUICtrlCreateButton("Button1", 10, 8, 75, 25)
  ; Create ListView
  Local $idLV = GUICtrlCreateListView( "", 10, 40, 300-20, 200-20, BitOR($LVS_OWNERDATA,$LVS_SHOWSELALWAYS) )
;~     Local $idLV = GUICtrlCreateListView( "", 10, 40, 300-20, 200-20, $LVS_SHOWSELALWAYS)
  _GUICtrlListView_SetExtendedListViewStyle($idLV, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT, $LVS_EX_SUBITEMIMAGES,$LVS_EX_CHECKBOXES))
  $hLV = GUICtrlGetHandle( $idLV ) ;    Virtual listview Reduces flicker
; Создаем столбцы
  _GUICtrlListView_AddColumn( $hLV, "Items1",  100 )
  _GUICtrlListView_AddColumn( $hLV, "Items2",  100 )
  _GUICtrlListView_AddColumn( $hLV, "Items3",  100 )
;~   _GUICtrlListView_AddItem($hLV,'test')


; Создаем массив
  For $i = 0 To $iItems - 1
       $aItems[$i][0]='СтрокаI '&$i+1
       $aItems[$i][1]='СтрокаII '&$i+1
       $aItems[$i][2]='СтрокаIII '&$i+1
  Next

; $aCheckFlag заполнить нулями
  For $i = 0 To $iItems - 1
       $aCheckFlag[$i]=0
  Next


 GUIRegisterMsg( $WM_NOTIFY, "WM_NOTIFY" ) ; Заполнить структуру виртуального ListView
 GUICtrlSendMsg( $idLV, $LVM_SETITEMCOUNT, $iItems, 0 )   ; Display items
GUISetState(@SW_SHOW)

  ; Message loop
  While 1
    Switch GUIGetMsg()
     Case $GUI_EVENT_CLOSE
        Exit
        Case $Button1
             $hLV = GUICtrlGetHandle( $idLV )
              $IndexListView=_GUICtrlListView_GetSelectedIndices($idLV) ; Индекс выделенной записи
              $Name=_GUICtrlListView_GetItemText($hLV,$IndexListView,0) ; Текст
             MsgBox(0,'',$Name)
    EndSwitch
  WEnd


Func WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam )
  Local Static $tText = DllStructCreate( "wchar[1000]" )    ; Размерность данных в столбцах
  Local Static $pText = DllStructGetPtr( $tText )

  Local $tNMHDR, $hWndFrom, $iCode
  $tNMHDR = DllStructCreate( $tagNMHDR, $lParam )
  $hWndFrom = HWnd( DllStructGetData( $tNMHDR, "hWndFrom" ) )
  $iCode = DllStructGetData( $tNMHDR, "Code" )

  Switch $hWndFrom
    Case $hLV
      Switch $iCode
        ; Отобразить виртуальный ListView
        Case $LVN_GETDISPINFOW
          Local $tNMLVDISPINFO = DllStructCreate( $tagNMLVDISPINFO, $lParam )
          $ColumnNumb=DllStructGetData( $tNMLVDISPINFO, "SubItem" )                         ; Номер столбца, для которого ведется опрос
          If BitAND( DllStructGetData( $tNMLVDISPINFO, "Mask" ), $LVIF_TEXT ) Then
             Local $sItem = $aItems[DllStructGetData($tNMLVDISPINFO,"Item")][$ColumnNumb]   ; Данные в столбце
            DllStructSetData( $tText, 1, $sItem )
            DllStructSetData( $tNMLVDISPINFO, "Text", $pText )
            DllStructSetData( $tNMLVDISPINFO, "TextMax", StringLen( $sItem ) )
		  EndIf

        Case $LVN_GETDISPINFO
           $tNMLVDISPINFO = DllStructCreate( $tagNMLVDISPINFO, $lParam )
           DllStructSetData($tNMLVDISPINFO, "mask", BitOR($LVIF_IMAGE, $LVIF_STATE) )
           DllStructSetData($tNMLVDISPINFO, "stateMask", $LVIS_STATEIMAGEMASK)
			$fitemindex = DllStructGetData($tNMLVDISPINFO, "Index")

			; Установка CheckBox
           if $aCheckFlag[$fitemindex] = 0 Then
                DllStructSetData( $tNMLVDISPINFO, "State", 4096)
           Else
                DllStructSetData( $tNMLVDISPINFO, "State", 8192)
           Endif

        Case $NM_CLICK
             $tInfo = DllStructCreate($tagNMITEMACTIVATE, $lParam)
             $fitemindex = DllStructGetData($tInfo, "Index")
             $fsubitemindex = DllStructGetData($tInfo, "SubItem")
			 If $aCheckFlag[$fitemindex]=0 Then
				 $aCheckFlag[$fitemindex]=1
			 Else
				 $aCheckFlag[$fitemindex]=0
			 EndIf
			ConsoleWrite($aCheckFlag[$fitemindex])

      EndSwitch
 EndSwitch
  Return $GUI_RUNDEFMSG
EndFunc
 

Prog

Продвинутый
Сообщения
537
Репутация
65
Почему-то не приходит сообщение $LVN_GETDISPINFO, :shok: хотя должно. :scratch: В коде выше все работает....
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Вот так у меня все работает WinXP 32 и Win7 32 в версиях 3.3.8.1 и 3.3.12.0.
Код:
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include <GUIConstantsEx.au3>
#include <Array.au3>

Opt('MustDeclareVars', 1)

Global $iItems = 100000, $iRows = 3, $aTxt, $hGui, $idLV, $iBtnS, $iBtnC, $iBtnAllPlus, $iBtnAllMinus, $iLeft, $iRight, $iSelected = -1

$aTxt = _CreateArrayMy($iItems, $iRows)

$hGui = GUICreate('Virtual ListView - Checkbox&Color&BkColor', 500, 480)
$idLV = GUICtrlCreateListView('', 10, 10, 480, 380, BitOR($GUI_SS_DEFAULT_LISTVIEW, $LVS_OWNERDATA), _
		BitOR($LVS_EX_CHECKBOXES, $WS_EX_CLIENTEDGE, $LVS_EX_DOUBLEBUFFER, $LVS_EX_FULLROWSELECT, $LVS_EX_GRIDLINES))
_GUICtrlListView_SetUnicodeFormat($idLV, 0)
For $i = 1 To $iRows
	_GUICtrlListView_AddColumn($idLV, 'Column ' & $i, 140)
Next
$iBtnS = GUICtrlCreateButton('Show Selected Item', 50, 400, 150, 30)
$iBtnC = GUICtrlCreateButton('Show Checked Items', 300, 400, 150, 30)
$iBtnAllPlus = GUICtrlCreateButton('Check All Items', 50, 440, 150, 30)
$iBtnAllMinus = GUICtrlCreateButton('UnCheck All Items', 300, 440, 150, 30)
GUISetState()

GUIRegisterMsg($WM_NOTIFY, '_WM_NOTIFY')
_GUICtrlListView_SetItemCount($idLV, $iItems)
If Not __Get_Interval_NM_CLICK($idLV, $iLeft, $iRight) Then Exit 13
GUICtrlSetState($idLV, $GUI_FOCUS)

While 1
	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE
			Exit
		Case $iBtnS
			MsgBox(64, 'Info', _GetSelecktedItemMy(), 0, $hGui)
			GUICtrlSetState($idLV, $GUI_FOCUS)
		Case $iBtnC
			_ShowCheckedItemsMy()
		Case $iBtnAllPlus
			For $i = 0 To $iItems - 1
				$aTxt[$i][$iRows] = 1
			Next
			GUICtrlSendMsg($idLV, $LVM_REDRAWITEMS, 0, $iItems - 1)
			GUICtrlSetState($iBtnC, $GUI_DISABLE)
			GUICtrlSetState($idLV, $GUI_FOCUS)
		Case $iBtnAllMinus
			For $i = 0 To $iItems - 1
				$aTxt[$i][$iRows] = 0
			Next
			GUICtrlSendMsg($idLV, $LVM_REDRAWITEMS, 0, $iItems - 1)
			GUICtrlSetState($iBtnC, $GUI_ENABLE)
			GUICtrlSetState($idLV, $GUI_FOCUS)
	EndSwitch
WEnd

Func _ShowCheckedItemsMy()
	Local $a_Checked[$iItems + 1][$iRows + 1]

	For $i = 0 To $iItems - 1
		If Not $aTxt[$i][$iRows] Then ContinueLoop
		$a_Checked[0][0] += 1
		$a_Checked[$a_Checked[0][0]][0] = $i
		For $j = 0 To $iRows - 1
			$a_Checked[$a_Checked[0][0]][$j + 1] = $aTxt[$i][$j]
		Next
	Next
	If $a_Checked[0][0] Then
		GUISetState(@SW_DISABLE)
		ReDim $a_Checked[$a_Checked[0][0] + 1][$iRows + 1]
		_ArrayDisplay($a_Checked, 'Checked items')
		GUISetState(@SW_ENABLE)
		WinActivate($hGui)
	Else
		MsgBox(64, 'Info', 'Not checked items', 0, $hGui)
		GUICtrlSetState($idLV, $GUI_FOCUS)
	EndIf
EndFunc   ;==>_ShowCheckedItemsMy

Func _WM_NOTIFY($h_Wnd, $i_Msg, $i_wParam, $i_lParam)
	Local Static $t__Text = DllStructCreate('char[24]'), $p__Text = DllStructGetPtr($t__Text), $a__State[2] = [0x1000, 0x2000];$a__State[2] = [BitShift(1, -12), BitShift(2, -12)]

	Local $i_Item, $i_SubItem, $t_NMLV

	Switch $h_Wnd
		Case $hGui
			Local $t_NMHDR = DllStructCreate($tagNMHDR, $i_lParam)
			Switch DllStructGetData($t_NMHDR, 'IDFrom')
				Case $idLV
					Switch DllStructGetData($t_NMHDR, 'Code')
						Case $LVN_GETDISPINFOA
							Local $t_NMLVDI = DllStructCreate($tagNMLVDISPINFO, $i_lParam), $i_Mask = DllStructGetData($t_NMLVDI, 'Mask')

							If BitAND($i_Mask, $LVIF_TEXT) Then
								$i_Item = DllStructGetData($t_NMLVDI, 'Item')
								$i_SubItem = DllStructGetData($t_NMLVDI, 'SubItem')
								If BitAND($i_Mask, $LVIF_IMAGE) Then
									DllStructSetData($t_NMLVDI, 'Mask', BitOR($i_Mask, $LVIF_STATE))
									DllStructSetData($t_NMLVDI, 'StateMask', $LVIS_STATEIMAGEMASK)
									DllStructSetData($t_NMLVDI, 'State', $a__State[$aTxt[$i_Item][$iRows]])
								EndIf
								DllStructSetData($t__Text, 1, $aTxt[$i_Item][$i_SubItem])
								DllStructSetData($t_NMLVDI, 'Text', $p__Text)
							EndIf
						Case $LVN_ITEMCHANGED
							$t_NMLV = DllStructCreate($tagNMLISTVIEW, $i_lParam)
							$iSelected = -1
							If BitAND(DllStructGetData($t_NMLV, 'NewState'), $LVIS_SELECTED) Then $iSelected = DllStructGetData($t_NMLV, 'Item')
						Case $NM_CUSTOMDRAW
							Local $t_NMLVCD = DllStructCreate($tagNMLVCUSTOMDRAW, $i_lParam)

							Switch DllStructGetData($t_NMLVCD, 'dwDrawStage')
								Case $CDDS_PREPAINT
									Return $CDRF_NOTIFYITEMDRAW
								Case $CDDS_ITEMPREPAINT
									Return $CDRF_NOTIFYSUBITEMDRAW
								Case BitOR($CDDS_ITEMPREPAINT, $CDDS_SUBITEM)
									Local $a_Color[2][2] = [[0xFF0000, 0x0000FF],[0xFFFFFF, 0xEEEEAF]]

									$i_Item = DllStructGetData($t_NMLVCD, 'dwItemSpec')
									DllStructSetData($t_NMLVCD, 'clrText', $a_Color[0][$aTxt[$i_Item][$iRows]])
									DllStructSetData($t_NMLVCD, 'clrTextBk', $a_Color[1][$aTxt[$i_Item][$iRows]])
									Return $CDRF_NEWFONT
							EndSwitch
						Case $NM_CLICK
							$t_NMLV = DllStructCreate($tagNMLISTVIEW, $i_lParam)
							If Not DllStructGetData($t_NMLV, 'SubItem') Then
								Switch DllStructGetData($t_NMLV, 'ActionX')
									Case $iLeft To $iRight
										$i_Item = DllStructGetData($t_NMLV, 'Item')
										$aTxt[$i_Item][$iRows] = Not $aTxt[$i_Item][$iRows];BitXOR($aTxt[$i_Item][$iRows], 1)
										GUICtrlSendMsg($idLV, $LVM_REDRAWITEMS, $i_Item, $i_Item)
								EndSwitch
							EndIf
					EndSwitch
			EndSwitch
	EndSwitch
	Return $GUI_RUNDEFMSG
EndFunc   ;==>_WM_NOTIFY

;~ Проверял только на WinXP 32 и Win7 32 1366 x 768
Func __Get_Interval_NM_CLICK($id_LV, ByRef $i_Left, ByRef $i_Right)
	Local $h_ImageList, $a_Res, $t_Rect, $i_X

	$h_ImageList = _GUICtrlListView_GetImageList($id_LV, 2)
	If Not $h_ImageList Then Return 0
	$a_Res = DllCall('comctl32.dll', 'int', 'ImageList_GetIconSize', 'handle', $h_ImageList, 'int*', 0, 'int*', 0)
	If (@error) Or (Not $a_Res[0]) Then Return 0
	$t_Rect = _GUICtrlListView_GetItemRectEx($id_LV, 0, $LVIR_ICON)
	$i_X = DllStructGetData($t_Rect, 'Left')
	If Not $i_X Then Return 0
	$i_Left = 0
	If Not Mod($a_Res[2], 2) Then $i_Left += 1
	$i_Left += Ceiling(($i_X - $a_Res[2]) / 2)
	$i_Right = $i_Left + $a_Res[2] - 1
	Return 1
EndFunc   ;==>__Get_Interval_NM_CLICK

Func _CreateArrayMy($i_Items, $i_Rows)
	Local $a_Array[$i_Items][$i_Rows + 1]

	For $i = 0 To $i_Items - 1
		For $j = 0 To $i_Rows - 1
			$a_Array[$i][$j] = $i + 1 & '_Item-' & $j + 1 & '_Row'
		Next
	Next
	Return $a_Array
EndFunc   ;==>_CreateArrayMy

Func _GetSelecktedItemMy()
	Local $s_Txt = 'Seleckted item index: '

	If $iSelected > -1 Then
		_GUICtrlListView_EnsureVisible($idLV, $iSelected)
		$s_Txt &= $iSelected & @LF & 'Text: '
		For $i = 0 To $iRows - 1
			$s_Txt &= $aTxt[$iSelected][$i] & '|'
		Next
	Else
		$s_Txt &= 'not seleckted'
	EndIf
	Return $s_Txt
EndFunc   ;==>_GetSelecktedItemMy

Ошибка может быть в определении интервала Х-координат клика в функции __Get_Interval_NM_CLICK().
 
Автор
P

pvnn

Осваивающий
Сообщения
305
Репутация
32
madmasles спасибо за пример тема решена!
Я отказался от __Get_Interval_NM_CLICK().
Код:
Local $aRect=_GUICtrlListView_GetItemRect($hLV,0,2) ; Возвращает прямоугольник, обрамляющий текст пункта
$iLeft=1 				; Координата начала области CheckBox
$iRight=$aRect[0]		; Координата конца области CheckBox

Беру область до начала текста в Item
 
Верх