Что нового

Виртуальный ListView и контекстное меню

pvnn

Осваивающий
Сообщения
305
Репутация
32
Доброго времени суток.
Необходима помощь в следующем:
- При вызове правой клавишей контекстного меню в виртуальном ListView пропадает строка списка
- Если же сначала кликнуть левой клавишей, а потом правой, то иногда не пропадает
Может кто сталкивался? В обычном ListView таких проблем нет. Можно-ли как-то убрать эти глюки обрисовки?

Пример скрипта
Код:
; Виртуальный 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 $iItems = 10000, $aItems[$iItems]


; Create GUI
  $hGui = GUICreate( "Virtual ListView", 300, 230 )

; Контекстное Меню
$DummyMenu = GUICtrlCreateDummy()
$ContextMenu = GUICtrlCreateContextMenu($DummyMenu)
$OpenContextMenu=GUICtrlCreateMenuItem("Открыть файл", $ContextMenu)
GUICtrlCreateMenuItem("", $ContextMenu) ; Разделитель
$DeleteContextMenu=GUICtrlCreateMenuItem("Удалить файл(ы)", $ContextMenu)
GUICtrlCreateMenuItem("", $ContextMenu) ; Разделитель

  ; Create ListView
  $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))

  $hLV = GUICtrlGetHandle( $idLV ) ;    Virtual listview    Reduces flicker
  _GUICtrlListView_AddColumn( $hLV, "Column1",  100 )

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

; Указать количество строк для отображения в виртуальном ListView
  GUICtrlSendMsg( $idLV, $LVM_SETITEMCOUNT, $iItems, 0 )
; Заполнить структуру виртуального ListView
  GUIRegisterMsg( $WM_NOTIFY, "WM_NOTIFY" )

GUISetState(@SW_SHOW)


  ; Message loop
  While 1
    Switch GUIGetMsg()
     Case $GUI_EVENT_CLOSE
        Exit
    EndSwitch
  WEnd




; Функция Обновления Видимости Контролов
Func VisibleControls($Flag=1)
	If $Flag=-1 Then
		GUICtrlSetState($OpenContextMenu,$GUI_DISABLE)
	Else
		GUICtrlSetState($OpenContextMenu,$GUI_ENABLE)
	EndIf
EndFunc


; Серия Функций для Контекстного меню (ShowMenu, ClientToScreen, WM_NOTIFY  ... а в GUI добавить GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") )
Func ShowMenu($hWnd, $nContextID, $nContextControlID, $iMouse=0)
    Local $hMenu = GUICtrlGetHandle($nContextID)
    Local $iCtrlPos = ControlGetPos($hWnd, "", $nContextControlID)
    Local $X = $iCtrlPos[0]
    Local $Y = $iCtrlPos[1] + $iCtrlPos[3]
    ClientToScreen($hWnd, $X, $Y)
    If $iMouse Then
        $X = MouseGetPos(0)
        $Y = MouseGetPos(1)
    EndIf
    DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hMenu, "int", 0, "int", $X, "int", $Y, "hwnd", $hWnd, "ptr", 0)
EndFunc

; Convert the client (GUI) coordinates to screen (desktop) coordinates
Func ClientToScreen($hWnd, ByRef $x, ByRef $y)
    Local $stPoint = DllStructCreate("int;int")
    DllStructSetData($stPoint, 1, $x)
    DllStructSetData($stPoint, 2, $y)
    DllCall("user32.dll", "int", "ClientToScreen", "hwnd", $hWnd, "ptr", DllStructGetPtr($stPoint))
    $x = DllStructGetData($stPoint, 1)
    $y = DllStructGetData($stPoint, 2)
    ; release Struct not really needed as it is a local
    $stPoint = 0
EndFunc


Func WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam )
  Local Static $tText = DllStructCreate( "wchar[100]" )	; Размерность данных в столбцах
  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 )
			; Если valid text buffer
			If BitAND( DllStructGetData( $tNMLVDISPINFO, "Mask" ), $LVIF_TEXT ) Then
				; Опрос всего массива
				$nRow = DllStructGetData($tNMLVDISPINFO, "item")	; Номер строки
				$nCol = DllStructGetData($tNMLVDISPINFO, "subitem")	; Номер столбца
				  Local $sItem = $aItems[$nRow]	; Данные в столбце
				; Заполняем структуру
				DllStructSetData( $tText, 1, $sItem )								; Текст
				DllStructSetData( $tNMLVDISPINFO, "Text", $pText )					; Указатель структуры
				DllStructSetData( $tNMLVDISPINFO, "TextMax", StringLen( $sItem ) )	; Длина строки
			EndIf

        Case $NM_RCLICK ; Sent by a list-view control when the user clicks an item with the right mouse button
             Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $lParam)
             Local $iIndex = DllStructGetData($tInfo, "Index")
             If $iIndex = -1 Then ; Если вызов меню не на пустой строке
				VisibleControls(-1)
			 Else
				VisibleControls()
			 EndIf
               ShowMenu($hWnd, $ContextMenu, $hLV, 1)
      EndSwitch
 EndSwitch
  Return $GUI_RUNDEFMSG
EndFunc
 

MaximK

Знающий
Сообщения
33
Репутация
5
Закоментируйте
Код:
If $iIndex = -1 Then ; Если вызов меню не на пустой строке
                VisibleControls(-1)
             Else
                VisibleControls()
             EndIf
в $NM_RCLICK
 
Автор
P

pvnn

Осваивающий
Сообщения
305
Репутация
32
Закоментируйте
MaximK, а как тогда обработать видимость пунктов контекстного меню?
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
pvnn,
Код:
;~ ...
Global $iIndexCM
;~ ...

Код:
;~ ...
While 1
	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE
			Exit
		Case $OpenContextMenu
			MsgBox(64, 'Info', 'Открыть файл: ' & $aItems[$iIndexCM], 0, $hGui)
		Case $DeleteContextMenu
			MsgBox(64, 'Info', 'Удалить файл(ы): ' & $aItems[$iIndexCM], 0, $hGui)
	EndSwitch
WEnd
;~ ...

Код:
;~ ...
				Case $NM_RCLICK ; Sent by a list-view control when the user clicks an item with the right mouse button
					Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $lParam)
					Local $iIndex = DllStructGetData($tInfo, "Index")
					If $iIndex > -1 Then ; Если вызов меню не на пустой строке
						$iIndexCM = $iIndex
						ShowMenu($hWnd, $ContextMenu, $hLV, 1)
					EndIf
;~ ...
 
Автор
P

pvnn

Осваивающий
Сообщения
305
Репутация
32
madmasles Сделал как вы написали - заработало, но после добавления новых записей в массив (Кнопка Добавить) вызов контекстного меню первый раз опять скрывает строку списка

Код:
; Виртуальный 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 $iItems = 10000, $aItems[$iItems]
Global $iIndexCM

; Create GUI
  $hGui = GUICreate( "Virtual ListView", 300, 230 )

; Контекстное Меню
$DummyMenu = GUICtrlCreateDummy()
$ContextMenu = GUICtrlCreateContextMenu($DummyMenu)
$OpenContextMenu=GUICtrlCreateMenuItem("Открыть файл", $ContextMenu)
GUICtrlCreateMenuItem("", $ContextMenu) ; Разделитель
$DeleteContextMenu=GUICtrlCreateMenuItem("Удалить файл(ы)", $ContextMenu)
GUICtrlCreateMenuItem("", $ContextMenu) ; Разделитель




  ; Create ListView
  $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))

  $hLV = GUICtrlGetHandle( $idLV ) ;    Virtual listview    Reduces flicker
  _GUICtrlListView_AddColumn( $hLV, "Column1",  100 )


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

  Next

$Button1 = GUICtrlCreateButton("Добавить", 10, 8, 75, 25)

; Указать количество строк для отображения в виртуальном ListView
  GUICtrlSendMsg( $idLV, $LVM_SETITEMCOUNT, $iItems, 0 )
; Заполнить структуру виртуального ListView
  GUIRegisterMsg( $WM_NOTIFY, "WM_NOTIFY" )

GUISetState(@SW_SHOW)


  ; Message loop
  While 1
    Switch GUIGetMsg()
     Case $GUI_EVENT_CLOSE
        Exit

        Case $Button1
        ; Добавить записи в массив
          _ArrayAdd($aItems,'test')
          $iItems=$iItems+1 ; Новое количество записей в массиве
        ; Обновить виртуальный ListView, указав новое количесто записей в массиве
         GUICtrlSendMsg( $idLV, $LVM_SETITEMCOUNT, $iItems, 0 )
        ; Выделить добавленную запись
        _GUICtrlListView_SetItemSelected($hLV,-1,False)         ; Снять все выделения
        _GUICtrlListView_SetItemSelected($hLV,$iItems-1,True)   ; Выделить добавленный пункт
        _GUICtrlListView_EnsureVisible($hLV,$iItems-1)          ; Гарантирует, чтобы пункт был полностью или частично видим
    EndSwitch
  WEnd




;~ ; Функция Обновления Видимости Контролов
;~ Func VisibleControls($Flag=1)
;~     If $Flag=-1 Then
;~         GUICtrlSetState($OpenContextMenu,$GUI_DISABLE)
;~     Else
;~         GUICtrlSetState($OpenContextMenu,$GUI_ENABLE)
;~     EndIf
;~ EndFunc


; Серия Функций для Контекстного меню (ShowMenu, ClientToScreen, WM_NOTIFY  ... а в GUI добавить GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") )
Func ShowMenu($hWnd, $nContextID, $nContextControlID, $iMouse=0)
    Local $hMenu = GUICtrlGetHandle($nContextID)
    Local $iCtrlPos = ControlGetPos($hWnd, "", $nContextControlID)
    Local $X = $iCtrlPos[0]
    Local $Y = $iCtrlPos[1] + $iCtrlPos[3]
    ClientToScreen($hWnd, $X, $Y)
    If $iMouse Then
        $X = MouseGetPos(0)
        $Y = MouseGetPos(1)
    EndIf
    DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hMenu, "int", 0, "int", $X, "int", $Y, "hwnd", $hWnd, "ptr", 0)
EndFunc

; Convert the client (GUI) coordinates to screen (desktop) coordinates
Func ClientToScreen($hWnd, ByRef $x, ByRef $y)
    Local $stPoint = DllStructCreate("int;int")
    DllStructSetData($stPoint, 1, $x)
    DllStructSetData($stPoint, 2, $y)
    DllCall("user32.dll", "int", "ClientToScreen", "hwnd", $hWnd, "ptr", DllStructGetPtr($stPoint))
    $x = DllStructGetData($stPoint, 1)
    $y = DllStructGetData($stPoint, 2)
    ; release Struct not really needed as it is a local
    $stPoint = 0
EndFunc


Func WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam )
  Local Static $tText = DllStructCreate( "wchar[100]" ) ; Размерность данных в столбцах
  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 )
            ; Если valid text buffer
            If BitAND( DllStructGetData( $tNMLVDISPINFO, "Mask" ), $LVIF_TEXT ) Then
                ; Опрос всего массива
                $nRow = DllStructGetData($tNMLVDISPINFO, "item")    ; Номер строки
                $nCol = DllStructGetData($tNMLVDISPINFO, "subitem") ; Номер столбца
                  Local $sItem = $aItems[$nRow] ; Данные в столбце
                ; Заполняем структуру
                DllStructSetData( $tText, 1, $sItem )                               ; Текст
                DllStructSetData( $tNMLVDISPINFO, "Text", $pText )                  ; Указатель структуры
                DllStructSetData( $tNMLVDISPINFO, "TextMax", StringLen( $sItem ) )  ; Длина строки
            EndIf

                Case $NM_RCLICK ; Sent by a list-view control when the user clicks an item with the right mouse button
                    Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $lParam)
                    Local $iIndex = DllStructGetData($tInfo, "Index")
                    If $iIndex > -1 Then ; Если вызов меню не на пустой строке
                        $iIndexCM = $iIndex
                        ShowMenu($hWnd, $ContextMenu, $hLV, 1)
                    EndIf

      EndSwitch
 EndSwitch
  Return $GUI_RUNDEFMSG
EndFunc
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
pvnn,
Так у меня все работает.
Код:
#include <GUIConstants.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
;~ #include <Array.au3>
;~ #include <ButtonConstants.au3>
;~ #include <GuiListView.au3>

;~ #include <APIConstants.au3>
;~ #include <WinAPIEx.au3>

Opt('MustDeclareVars', 1)

Global $iItems = 10000, $aItems[$iItems], $hMenu, $hGui, $idDummyMenu, $idContextMenu, $idOpenContextMenu, $idDeleteContextMenu, $idLV, $idButton

; Create GUI
$hGui = GUICreate('Virtual ListView', 300, 230)

; Контекстное Меню
$idDummyMenu = GUICtrlCreateDummy()
$idContextMenu = GUICtrlCreateContextMenu($idDummyMenu)
$hMenu = GUICtrlGetHandle($idContextMenu)
$idOpenContextMenu = GUICtrlCreateMenuItem('Открыть файл', $idContextMenu)
GUICtrlCreateMenuItem('', $idContextMenu) ; Разделитель
$idDeleteContextMenu = GUICtrlCreateMenuItem('Удалить файл(ы)', $idContextMenu)
GUICtrlCreateMenuItem('', $idContextMenu) ; Разделитель

; Create ListView
$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))
_GUICtrlListView_AddColumn($idLV, 'Column1', 100)
_GUICtrlListView_SetUnicodeFormat($idLV, 1)

$idButton = GUICtrlCreateButton('Добавить', 10, 8, 75, 25)

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

; Указать количество строк для отображения в виртуальном ListView
GUICtrlSendMsg($idLV, $LVM_SETITEMCOUNT, $iItems, 0)
; Заполнить структуру виртуального ListView
GUIRegisterMsg($WM_NOTIFY, 'WM_NOTIFY')

GUISetState()

While 1
	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE
			Exit
		Case $idButton
			$iItems += 1
			ReDim $aItems[$iItems]
			$aItems[$iItems - 1] = 'test ' & $iItems
			GUICtrlSendMsg($idLV, $LVM_SETITEMCOUNT, $iItems, 0)
			GUICtrlSetState($idLV, $GUI_FOCUS)
			_GUICtrlListView_SetItemSelected($idLV, -1, False)
			_GUICtrlListView_SetItemSelected($idLV, $iItems - 1)
			_GUICtrlListView_EnsureVisible($idLV, $iItems - 1)
	EndSwitch
WEnd

Func _ShowMenuMy($h_Wnd, $h_Menu, $i_Index)
	Local Const $__TPM_RETURNCMD = 0x0100
	Local $a_Res = DllCall('user32.dll', 'uint', 'TrackPopupMenuEx', 'hwnd', $h_Menu, 'uint', $__TPM_RETURNCMD, 'int', MouseGetPos(0), _
			'int', MouseGetPos(1), 'hwnd', $h_Wnd, 'ptr', 0)
	If (@error) Or (Not $a_Res[0]) Then Return
	Switch $a_Res[0]
		Case $idOpenContextMenu
			_OpenMy($i_Index)
		Case $idDeleteContextMenu
			_DeleteMy($i_Index)
	EndSwitch
EndFunc   ;==>_ShowMenuMy

Func _OpenMy($i_Index)
	MsgBox(64, 'Info', 'Открыть файл: ' & $aItems[$i_Index], 0, $hGui)
EndFunc   ;==>_OpenMy

Func _DeleteMy($i_Index)
	MsgBox(64, 'Info', 'Удалить файл(ы): ' & $aItems[$i_Index], 0, $hGui)
EndFunc   ;==>_DeleteMy

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

	Local $tNMHDR, $idFrom, $iCode
	$tNMHDR = DllStructCreate($tagNMHDR, $lParam)
	$idFrom = DllStructGetData($tNMHDR, 'IDFrom')
	$iCode = DllStructGetData($tNMHDR, 'Code')

	Switch $idFrom
		Case $idLV
			Switch $iCode
				; Отобразить виртуальный ListView
				Case $LVN_GETDISPINFOW
					Local $tNMLVDISPINFO = DllStructCreate($tagNMLVDISPINFO, $lParam)
					; Если valid text buffer
					If BitAND(DllStructGetData($tNMLVDISPINFO, 'Mask'), $LVIF_TEXT) Then
						; Опрос всего массива
						Local $iRow = DllStructGetData($tNMLVDISPINFO, 'item') ; Номер строки
;~ 						Local $iCol = DllStructGetData($tNMLVDISPINFO, 'subitem') ; Номер столбца
						Local $sItem = $aItems[$iRow] ; Данные в столбце
						; Заполняем структуру
						DllStructSetData($tText, 1, $sItem) ; Текст
						DllStructSetData($tNMLVDISPINFO, 'Text', $pText) ; Указатель структуры
;~ 						DllStructSetData($tNMLVDISPINFO, 'TextMax', StringLen($sItem)) ; Длина строки
					EndIf
				Case $NM_RCLICK ; Sent by a list-view control when the user clicks an item with the right mouse button
					Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $lParam)
					Local $iIndex = DllStructGetData($tInfo, 'Index')
					If $iIndex > -1 Then ; Если вызов меню не на пустой строке
						_ShowMenuMy($hWnd, $hMenu, $iIndex)
					EndIf
			EndSwitch
	EndSwitch
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY
 
Автор
P

pvnn

Осваивающий
Сообщения
305
Репутация
32
madmasles - тоже добавил фокус на ListView
Код:
GUICtrlSetState($idLV, $GUI_FOCUS)

строка исчезать перестала, спасибо
Но есть проблема

Конструкция
Код:
If $iIndex > -1 Then
                        $iIndexCM = $iIndex
                        ShowMenu($hWnd, $ContextMenu, $hLV, 1)
                    EndIf


Вызывает вызов контекстного меню только не на пустой строке
А мне нужно, чтобы вызывалось всегда, но если на пустой строке, то определенные пункты контекстного меню были бы недоступны (обесцвеченные), т.е. как сделать работоспособным вот это:
Код:
If $iIndex = -1 Then
                GUICtrlSetState($OpenContextMenu,$GUI_DISABLE)
             Else
				GUICtrlSetState($OpenContextMenu,$GUI_ENABLE)
             EndIf
			ShowMenu($hWnd, $ContextMenu, $hLV, 1)


Здесь опять исчезания
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
pvnn [?]
Здесь опять исчезания
Не знаю, как это побороть. Попробуйте сделать два меню, одно для $iIndex > -1, другое $iIndex = -1.

Два меню не решают проблему. Если вызывать меню не на выделенной ячейке, то, если была выделенная ячейка, она исчезает. ИМХО, TrackPopupMenuEx на время своей работы блокирует WM_NOTIFY и данные в ячейке не обновляются.
 
Автор
P

pvnn

Осваивающий
Сообщения
305
Репутация
32
Когда-то Creator выкладывал ModernMenu - Расширенное создание меню GUI и Tray
http://autoit-script.ru/index.php/topic,12136.0.html
Настроил ModernMenuRaw.au3 для Autoit 3.3.12.0 (Добавил #include <APIShellExConstants.au3>)
Пример:
Код:
; Виртуальный 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 <ModernMenuRaw.au3> ; Для контекстного меню

Global $iItems = 10000, $aItems[$iItems][2]


; Create GUI
  $hGui = GUICreate( "Virtual ListView", 300, 230 )

; Контекстное Меню
$DummyMenu = GUICtrlCreateDummy()
$ContextMenu = GUICtrlCreateContextMenu($DummyMenu)

$OpenContextMenu=_GUICtrlCreateODMenuItem("Открыть файл", $ContextMenu)
_GUICtrlCreateODMenuItem("", $ContextMenu) ; Разделитель
$DeleteContextMenu=_GUICtrlCreateODMenu("Удалить файл(ы)", $ContextMenu)
_GUICtrlCreateODMenuItem("", $ContextMenu) ; Разделитель

  ; Create ListView
  $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))

  $hLV = GUICtrlGetHandle( $idLV ) ;    Virtual listview    Reduces flicker
  _GUICtrlListView_AddColumn( $hLV, "Column1",  100 )
  _GUICtrlListView_AddColumn( $hLV, "Column2",  100 )

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

$idButton = GUICtrlCreateButton('Добавить', 10, 8, 75, 25)

; Указать количество строк для отображения в виртуальном ListView
  GUICtrlSendMsg( $idLV, $LVM_SETITEMCOUNT, $iItems, 0 )
; Заполнить структуру виртуального ListView
  GUIRegisterMsg( $WM_NOTIFY, "WM_NOTIFY" )

GUISetState(@SW_SHOW)


  ; Message loop
  While 1
    Switch GUIGetMsg()
     Case $GUI_EVENT_CLOSE
        Exit
	 Case $idButton
          $iItems=$iItems+1 	; Новое количество записей в массиве
          _ArrayAdd($aItems,'test'&$iItems&'|'&'test'&$iItems)	; Добавить записи в массив
        ; Обновить виртуальный ListView, указав новое количесто записей в массиве
         GUICtrlSendMsg( $idLV, $LVM_SETITEMCOUNT, $iItems, 0 )
        ; Выделить добавленную запись
        _GUICtrlListView_SetItemSelected($hLV,-1,False)         ; Снять все выделения
        _GUICtrlListView_SetItemSelected($hLV,$iItems-1,True)   ; Выделить добавленный пункт
        _GUICtrlListView_EnsureVisible($hLV,$iItems-1)          ; Гарантирует, чтобы пункт был полностью или
    EndSwitch
  WEnd







; для Контекстного меню
Func ShowMenu($hWnd, $nContextID, $nContextControlID, $iMouse=0)
    Local $hMenu = GUICtrlGetHandle($nContextID)
    Local $iCtrlPos = ControlGetPos($hWnd, "", $nContextControlID)
    Local $X = $iCtrlPos[0]
    Local $Y = $iCtrlPos[1] + $iCtrlPos[3]
    ClientToScreen($hWnd, $X, $Y)
    If $iMouse Then
        $X = MouseGetPos(0)
        $Y = MouseGetPos(1)
    EndIf
    DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hMenu, "int", 0, "int", $X, "int", $Y, "hwnd", $hWnd, "ptr", 0)
EndFunc

; Convert the client (GUI) coordinates to screen (desktop) coordinates
Func ClientToScreen($hWnd, ByRef $x, ByRef $y)
    Local $stPoint = DllStructCreate("int;int")
    DllStructSetData($stPoint, 1, $x)
    DllStructSetData($stPoint, 2, $y)
    DllCall("user32.dll", "int", "ClientToScreen", "hwnd", $hWnd, "ptr", DllStructGetPtr($stPoint))
    $x = DllStructGetData($stPoint, 1)
    $y = DllStructGetData($stPoint, 2)
    ; release Struct not really needed as it is a local
    $stPoint = 0
EndFunc


Func WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam )
  Local Static $tText = DllStructCreate( "wchar[100]" ) ; Размерность данных в столбцах
  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 )
            ; Если valid text buffer
            If BitAND( DllStructGetData( $tNMLVDISPINFO, "Mask" ), $LVIF_TEXT ) Then
                ; Опрос всего массива
                $nRow = DllStructGetData($tNMLVDISPINFO, "item")    ; Номер строки
                $nCol = DllStructGetData($tNMLVDISPINFO, "subitem") ; Номер столбца
                  Local $sItem = $aItems[$nRow][$nCol] ; Данные в столбце
                ; Заполняем структуру
                DllStructSetData( $tText, 1, $sItem )                               ; Текст
                DllStructSetData( $tNMLVDISPINFO, "Text", $pText )                  ; Указатель структуры
                DllStructSetData( $tNMLVDISPINFO, "TextMax", StringLen( $sItem ) )  ; Длина строки
            EndIf

        Case $NM_RCLICK ; Sent by a list-view control when the user clicks an item with the right mouse button
             Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $lParam)
             Local $iIndex = DllStructGetData($tInfo, "Index")

             If $iIndex = -1 Then
                VisibleControls(-1)	; Если вызов меню на пустой строке
             Else
                VisibleControls()	; Если вызов меню не на пустой строке
             EndIf
               ShowMenu($hWnd, $ContextMenu, $hLV, 1)


      EndSwitch
 EndSwitch
  Return $GUI_RUNDEFMSG
EndFunc


; Функция Обновления Видимости Контролов
Func VisibleControls($Flag=1)
    If $Flag=-1 Then
        GUICtrlSetState($OpenContextMenu,$GUI_DISABLE)
    Else
        GUICtrlSetState($OpenContextMenu,$GUI_ENABLE)
    EndIf
EndFunc

... если по-другому никак не получается организовать контекстное меню, то с данной UDF в принципе все заработало.
Тема решена.
madmasles спасибо что помогали найти решение!
 
Верх