GaryC Posted June 6, 2011 Posted June 6, 2011 (edited) Hi all, I have a list view in which I delete items and move items to the end. When items are moved or deleted I want the focused item to be the one following the moved or deleted item. So I delete the item, create one at the end, and use _GUICtrlListView_SetItemState to set selected and focused state on the item following the one that was moved. When I move using the button, it works as desired. However, when I use the CTRL+End key, when I read back the status after setting it it is set, and the state on the last item is clear, but the last item is still highlighted. What do I need to do so that I don't lose my place in the list view when I use the CTRL+END key? Below is a test script that I hope illustrates what I mean. The script initially sets the focus on the second item. Then push the move button. The second item moves to the end and what was the 3rd item is selected as desired. Then restart the script but use the CTRL+END key while focused on the list view. The second item moves to the end of the list and what was the 3rd item should be selected (and focused), but instead the last item is selected. I'm using WINXP SP3. [update: I added code (updated below) to allow underline to also move to the end. It does not have the same problem as CTRL+END. It does emit a ding, which CTRL+END does not. Any idea why the ding? I assume CTRL+END is behaving the way it is because the list view processes arrow keys even though I'm catching LVN_KEYDOWN. Is there any way to get it to not do that processing when I catch the key?] [Okay, I got rid of the references to LbC.au3. (Layout by Code is a library designed to assist blind programmers with GUI layout. It can generate code to make the UI so that it doesn't have to be included.)] Thanks. GaryC expandcollapse popup; 6/5/11 Test changing selection in a list view. #include <GUIConstantsEx.au3> #include <ListviewConstants.au3> #include <GuiListview.au3> #include <WindowsConstants.au3> Global Const $VK_SHIFT = 16 Global Const $VK_CONTROL = 17 Global Const $VK_MENU = 18 Global Const $VK_SPACE = 0x20 Global Const $VK_PRIOR = 33 Global Const $VK_NEXT = 34 Global Const $VK_END = 35 Global Const $VK_HOME = 36 Global Const $VK_LEFT = 37 Global Const $VK_UP = 38 Global Const $VK_RIGHT = 39 Global Const $VK_DOWN = 40 Global Const $VK_DELETE = 46 Global $ghForm, $gIdLV, $ghLV, $gIdMsg Global $giMask = BitOR($LVIS_FOCUSED, $LVIS_SELECTED) Main() Func Main() $ghForm = GUICreate("Test list view focus and selection change", 531, 372, 246, 181) $gIdLV = GUICtrlCreateListView("Item text", 14, 14, 300, 120) $ghLV = GUICtrlGetHandle($gIdLV) For $i = 0 To 4 GUICtrlCreateListViewItem("Item " & $i, $gIdLV) Next ; $i GUICtrlCreateLabel("This tests whether the display changes as a result of programatically setting focus and selected item state.", 14, 148, 497, 16, 0x50020100, 0x00000000) GUICtrlCreateLabel("When I delete or move an item to the end I want the focus and selection to be on the item following it.", 14, 172, 478, 16, 0x50000100, 0x00000000) Local $IdMoveBtn = GUICtrlCreateButton("Move to end", 14, 196, 100, 16, 0x50010F00, 0x00000000) Local $IdDeleteBtn = GUICtrlCreateButton("Delete", 122, 196, 100, 16, 0x50010F00, 0x00000000) GUICtrlCreateLabel("Msg", 14, 226, 20, 16, 0x50020100, 0x00000000) $gIdMsg = GUICtrlCreateEdit("", 40, 226, 300, 100, 0x503110C4, 0x00000000) GUISetState(@SW_SHOW) GUIRegisterMsg($WM_NOTIFY, "WMNotify") SelItem(1) Msg("Item 1 should have focus and be selected") While 1 Local $iMsg = GUIGetMsg() Switch $iMsg Case 0 ContinueLoop Case $GUI_EVENT_CLOSE ExitLoop Case $IdMoveBtn Msg("Move button pressed.") Move() Case $IdDeleteBtn Msg("Delete button pressed.") Delete() EndSwitch WEnd GUIDelete() EndFunc ;==>Main Func Msg($s) GUICtrlSetData($gIdMsg, $s & @CRLF, 1) EndFunc ;==>Msg Func SelItem($iItem, $fFlag = True) Local $iState If $fFlag Then $iState = $giMask Else $iState = 0 EndIf Msg("Setting state of item " & $iItem & " to " & $iState) _GUICtrlListView_SetItemState($ghLV, $iItem, $iState, $giMask) EndFunc ;==>SelItem Func Move() Local $iFirst = _GUICtrlListView_GetNextItem($ghLV) Local $sItm = _GUICtrlListView_GetItemTextString($ghLV, $iFirst) _GUICtrlListView_DeleteItemsSelected($ghLV) Local $iLast = _GUICtrlListView_GetItemCount($ghLV) ; get index of next added item. GUICtrlCreateListViewItem($sItm, $gIdLV) SelItem($iFirst) Msg("After selecting item " & $iFirst & ", its state is " & _GUICtrlListView_GetItemState($ghLV, $iFirst, $giMask)) Msg(" State of item " & $iLast & ", is " & _GUICtrlListView_GetItemState($ghLV, $iLast, $giMask)) EndFunc ;==>Move Func Delete() Local $iFirst = _GUICtrlListView_GetNextItem($ghLV) _GUICtrlListView_DeleteItemsSelected($ghLV) SelItem($iFirst) Msg("After selecting item " & $iFirst & ", its state is " & _GUICtrlListView_GetItemState($ghLV, $iFirst, $giMask)) EndFunc ;==>Delete Func WmNotify($hWnd, $iMsg, $iWParam, $iLParam) Local $tagNM = DllStructCreate($tagNMHDR, $iLParam) If DllStructGetData($tagNM, "IdFrom") = $gIdLV Then Switch DllStructGetData($tagNM, "Code") Case $LVN_KEYDOWN ;Dbg("LVN_KEYDOWN") ; debug $tagNM = DllStructCreate($tagNMLVKEYDOWN, $iLParam) Local $iKey = DllStructGetData($tagNM, "VKey") Local $fControl = BitAND(GetKeyState($VK_CONTROL), 0x8000) Local $fShift = BitAND(GetKeyState($VK_SHIFT), 0x8000) Local $fAlt = BitAND(GetKeyState($VK_MENU), 0x8000) If Not $fControl And Not $fAlt And Not $fShift Then Msg($iKey) Switch $iKey Case $VK_DELETE Msg("Delete key") Delete() Return 0 Case Else Return $GUI_RUNDEFMSG EndSwitch EndIf ; no modifiers If Not $fControl And Not $fAlt And $fShift Then Msg("Shift+" & $iKey) Switch $iKey Case 189 Msg("_ key") Move() Return 0 Case Else Return $GUI_RUNDEFMSG EndSwitch EndIf ; Shift If $fControl And Not $fShift And Not $fAlt Then Msg("CTRL+" & $iKey) Switch $iKey Case $VK_END ; CTRL+END Msg("CTRL+END") Move() Return 0 #cs Case $VK_UP ; CTRL+UP Return 0 Case $VK_DOWN ; CTRL+DOWN Return 0 #ce Case Else Return $GUI_RUNDEFMSG EndSwitch ; $iKey EndIf ; $fControl EndSwitch ; code EndIf Return $GUI_RUNDEFMSG EndFunc ;==>WmNotify ; Adapted from WINApi.au3 function _WinAPI_GetAsyncKeyState. ; Return is a short; if MSB (bit 15, 0x8000) is set the key is down, if bit 0 is 1 a toggle key (like caps lock) is toggled (on). Func GetKeyState($iKey) Local $aResult = DllCall("user32.dll", "short", "GetKeyState", "int", $iKey) If @error Then Return SetError(@error, @extended, 0) Return $aResult[0] EndFunc ;==>GetKeyState Edited June 8, 2011 by GaryC
PsaltyDS Posted June 8, 2011 Posted June 8, 2011 (edited) Put your demo script in SciTE4AutoIt3 and hit Ctrl-F5 to do syntax check. Re-post it after eliminating the errors. Edit: Sorry, I missed that you were already going to update it. Edited June 8, 2011 by PsaltyDS Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now