Доброго времени суток.
Необходима помощь в следующем:
- При вызове правой клавишей контекстного меню в виртуальном ListView пропадает строка списка
- Если же сначала кликнуть левой клавишей, а потом правой, то иногда не пропадает
Может кто сталкивался? В обычном ListView таких проблем нет. Можно-ли как-то убрать эти глюки обрисовки?
Пример скрипта
Необходима помощь в следующем:
- При вызове правой клавишей контекстного меню в виртуальном 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