Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   AutoIt (http://forum.oszone.net/forumdisplay.php?f=103)
-   -   [решено] Как переместить выделенную строку ListView (http://forum.oszone.net/showthread.php?t=157059)

malev 14-11-2009 20:11 1270354

Как переместить выделенную строку ListView
 
Как переместить выделенную строку ListView вверх или вниз

Creat0R 15-11-2009 00:49 1270540

При перетаскиваний, или по кнопке?

Вот пример по кнопке:
Код:

;Demo for _GUICtrlListView_MoveItems() function.
;Just select one (or more) item, and press one of the buttons (Up or Down).


#include <GUIConstants.au3>
#include <WindowsConstants.au3>
#include <ButtonConstants.au3>
#include <GuiListView.au3>
#include <GuiImageList.au3>
#include <SendMessage.au3>
;

$GUI = GUICreate('Demo for _GUICtrlListView_MoveItems()', 300, 320)

$Up_Button = GUICtrlCreateButton("Up", 20, 20, 24, 24, $BS_ICON)
GUICtrlSetImage(-1, "netcfgx.dll", 1, 0)

$Down_Button = GUICtrlCreateButton("Down", 70, 20, 24, 24, $BS_ICON)
GUICtrlSetImage(-1, "netcfgx.dll", -2, 0)

$ListView = _GUICtrlListView_Create($GUI, "Column1|Column2", 20, 50, 260, 250, _
    BitOR($LVS_SHOWSELALWAYS, $LVS_REPORT), $WS_EX_CLIENTEDGE)

_GUICtrlListView_SetExtendedListViewStyle($ListView, BitOR($LVS_EX_CHECKBOXES, $LVS_EX_FULLROWSELECT, $LVS_EX_SUBITEMIMAGES))

$iImage_Size = 14

$hImage = _GUIImageList_Create($iImage_Size, $iImage_Size)

_GUIImageList_Add($hImage, _WinAPI_CreateSolidBitmap($ListView, 0xFF0000, $iImage_Size, $iImage_Size))
_GUIImageList_Add($hImage, _WinAPI_CreateSolidBitmap($ListView, 0x00FF00, $iImage_Size, $iImage_Size))
_GUIImageList_Add($hImage, _WinAPI_CreateSolidBitmap($ListView, 0x0000FF, $iImage_Size, $iImage_Size))

_GUICtrlListView_SetImageList($ListView, $hImage, 1)

For $i = 0 To 9
    _GUICtrlListView_AddItem($ListView, "Item " & $i+1, Random(0, 2, 1))
    _GUICtrlListView_AddSubItem($ListView, $i, "SubItem " & $i+1, 1, Random(0, 2, 1))
Next

$iRandom_1 = Random(0, 9, 1)
$iRandom_2 = Random(0, 9, 1)

_GUICtrlListView_SetItemChecked($ListView, $iRandom_1, 1)
_GUICtrlListView_SetItemSelected($ListView, $iRandom_1, 1)

_GUICtrlListView_SetItemChecked($ListView, $iRandom_2, 1)
_GUICtrlListView_SetItemSelected($ListView, $iRandom_2, 1)

_SendMessage($ListView, $LVM_SETCOLUMNWIDTH, 0, -1)
_SendMessage($ListView, $LVM_SETCOLUMNWIDTH, 1, -1)

ControlFocus($GUI, "", $ListView)

GUISetState()

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $Up_Button
            _GUICtrlListView_MoveItems($ListView, -1)
            ControlFocus($GUI, "", $ListView)
        Case $Down_Button
            _GUICtrlListView_MoveItems($ListView, 1)
            ControlFocus($GUI, "", $ListView)
    EndSwitch
WEnd

;===============================================================================
; Function Name:    _GUICtrlListView_MoveItems()
; Description:      Moves Up or Down selected item(s) in ListView.
;
; Parameter(s):    $hListView          - ControlID or Handle of ListView control.
;                  $iDirection        - Define in what direction item(s) will move:
;                                          -1 - Move Up.
;                                            1 - Move Down.
;
; Requirement(s):  AutoIt 3.3.0.0
;
; Return Value(s):  On seccess - Move selected item(s) Up/Down and return 1.
;                  On failure - Return "" (empty string) and set @error as following:
;                                                                  1 - No selected item(s).
;                                                                  2 - $iDirection is wrong value (not 1 and not -1).
;                                                                  3 - Item(s) can not be moved, reached last/first item.
;
; Note(s):          * If you select like 15-20 (or more) items, moving them can take a while :( (second or two).
;
; Author(s):        G.Sandler a.k.a CreatoR
;===============================================================================

Func _GUICtrlListView_MoveItems($hListView, $iDirection)
    Local $aSelected_Indices = _GUICtrlListView_GetSelectedIndices($hListView, 1)

    If UBound($aSelected_Indices) < 2 Then Return SetError(1, 0, "")
    If $iDirection <> 1 And $iDirection <> -1 Then Return SetError(2, 0, "")

    Local $iTotal_Items = _GUICtrlListView_GetItemCount($hListView)
    Local $iTotal_Columns = _GUICtrlListView_GetColumnCount($hListView)

    Local $iUbound = UBound($aSelected_Indices)-1, $iNum = 1, $iStep = 1

    Local $iCurrent_Index, $iUpDown_Index, $sCurrent_ItemText, $sUpDown_ItemText
    Local $iCurrent_Index, $iCurrent_CheckedState, $iUpDown_CheckedState
    Local $iImage_Current_Index, $iImage_UpDown_Index

    If ($iDirection = -1 And $aSelected_Indices[1] = 0) Or _
        (
$iDirection = 1 And $aSelected_Indices[$iUbound] = $iTotal_Items-1) Then Return SetError(3, 0, "")

    ControlListView($hListView, "", "", "SelectClear")

    If $iDirection = 1 Then
        $iNum = $iUbound
        $iUbound
= 1
        $iStep = -1
    EndIf

    For $i = $iNum To $iUbound Step $iStep
        $iCurrent_Index
= $aSelected_Indices[$i]
        $iUpDown_Index = $aSelected_Indices[$i]+1
        If $iDirection = -1 Then $iUpDown_Index = $aSelected_Indices[$i]-1

        $iCurrent_CheckedState = _GUICtrlListView_GetItemChecked($hListView, $iCurrent_Index)
        $iUpDown_CheckedState = _GUICtrlListView_GetItemChecked($hListView, $iUpDown_Index)

        _GUICtrlListView_SetItemSelected($hListView, $iUpDown_Index)

        For $j = 0 To $iTotal_Columns-1
            $sCurrent_ItemText = _GUICtrlListView_GetItemText($hListView, $iCurrent_Index, $j)
            $sUpDown_ItemText = _GUICtrlListView_GetItemText($hListView, $iUpDown_Index, $j)

            If _GUICtrlListView_GetImageList($hListView, 1) <> 0 Then
                $iImage_Current_Index = _GUICtrlListView_GetItemImage($hListView, $iCurrent_Index, $j)
                $iImage_UpDown_Index = _GUICtrlListView_GetItemImage($hListView, $iUpDown_Index, $j)

                _GUICtrlListView_SetItemImage($hListView, $iCurrent_Index, $iImage_UpDown_Index, $j)
                _GUICtrlListView_SetItemImage($hListView, $iUpDown_Index, $iImage_Current_Index, $j)
            EndIf

            _GUICtrlListView_SetItemText($hListView, $iUpDown_Index, $sCurrent_ItemText, $j)
            _GUICtrlListView_SetItemText($hListView, $iCurrent_Index, $sUpDown_ItemText, $j)
        Next

        _GUICtrlListView_SetItemChecked($hListView, $iUpDown_Index, $iCurrent_CheckedState)
        _GUICtrlListView_SetItemChecked($hListView, $iCurrent_Index, $iUpDown_CheckedState)

        _GUICtrlListView_SetItemSelected($hListView, $iUpDown_Index, 0)
    Next

    For $i = 1 To UBound($aSelected_Indices)-1
        $iUpDown_Index = $aSelected_Indices[$i]+1
        If $iDirection = -1 Then $iUpDown_Index = $aSelected_Indices[$i]-1
        _GUICtrlListView_SetItemSelected($hListView, $iUpDown_Index)
    Next

    Return 1
EndFunc


Creat0R 15-11-2009 01:09 1270557

А вот пример по перетаскиванию:

Код:

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GUIListView.au3>
#include <GUIImageList.au3>
;

Global $iLast_Index = -1
Global $a_Index[2] ;From and to
Global $iLastLineTop, $iLastLineLeft

Global $iDragging = False
Global $iDrawing = False ;To ensure mousemove doesn't cause more than one line to be drawn
Global $iLButtonIsUp = False ;To ensure a correct redraw of ListView

$Main_GUI = GUICreate("Drag & Drop LV Item", 225, 400, -1, -1, BitOR($WS_THICKFRAME, $WS_SIZEBOX))

$ListView = GUICtrlCreateListView("Entry Name|Category", 5, 75, 195, 280, $LVS_SINGLESEL)
$h_ListView = GUICtrlGetHandle($ListView)

_GUICtrlListView_SetColumnWidth($ListView, 0, 100)
_GUICtrlListView_SetColumnWidth($ListView, 1, 100)

GUICtrlSendMsg($ListView, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_GRIDLINES, $LVS_EX_GRIDLINES)
GUICtrlSendMsg($ListView, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_FULLROWSELECT, $LVS_EX_FULLROWSELECT)
GUICtrlSendMsg($ListView, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_CHECKBOXES, $LVS_EX_CHECKBOXES)

GUICtrlSendMsg($ListView, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_SUBITEMIMAGES, $LVS_EX_SUBITEMIMAGES)

$h_ImageList = _GUIImageList_Create(20, 20, 5, 0, 4, $LVSIL_SMALL)

For $i = 0 To 10
        _GUIImageList_AddIcon($h_ImageList, @SystemDir & "\shell32.dll", $i)
Next

_GUICtrlListView_SetImageList($h_ListView, $h_ImageList, $LVSIL_SMALL)

For $i = 0 To 9
        GUICtrlCreateListViewItem("Name " & $i & "|Category " & $i, $ListView)
        _GUICtrlListView_SetItemImage($h_ListView, $i, $i, 0); listview handle, index, subitem, image index
Next

GUISetState()

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY_EVENTS")
GUIRegisterMsg($WM_LBUTTONUP, "WM_LBUTTONUP_EVENTS")
GUIRegisterMsg($WM_MOUSEMOVE, "WM_MOUSEMOVE_EVENTS")

While 1
        Switch GUIGetMsg()
                Case $GUI_EVENT_CLOSE
                        _GUIImageList_Destroy($h_ImageList)
                        Exit
        EndSwitch
       
        If $iLButtonIsUp Then
                $iLButtonIsUp = False
                DllCall("User32.dll", "int", "RedrawWindow", "hwnd", $h_ListView, "ptr", 0, "int", 0, "int", 5)
        EndIf
WEnd

Func WM_LBUTTONUP_EVENTS($hWndGUI, $MsgID, $wParam, $lParam)
        $iLButtonIsUp = True
        $iDragging = False
        $iDrawing = False
       
        $iLast_Index = -1
       
        Local $aLV_Pos = ControlGetPos($hWndGUI, "", $ListView)
       
        Local $iX = BitAND($lParam, 0xFFFF) - $aLV_Pos[0]
        Local $iY = BitShift($lParam, 16) - $aLV_Pos[1]
       
        Local $struct_LVHITTESTINFO = DllStructCreate("int;int;uint;int;int;int")
       
        DllStructSetData($struct_LVHITTESTINFO, 1, $iX)
        DllStructSetData($struct_LVHITTESTINFO, 2, $iY)

        $a_Index[1] = GUICtrlSendMsg($ListView, $LVM_HITTEST, 0, DllStructGetPtr($struct_LVHITTESTINFO))
        Local $iFlags = DllStructGetData($struct_LVHITTESTINFO, 2)

        ;// Out of the ListView?
        If $a_Index[1] == -1 Then Return $GUI_RUNDEFMSG
       
        ;// Not in an item?
        If BitAND($iFlags, $LVHT_ONITEMLABEL) == 0 And BitAND($iFlags, $LVHT_ONITEMSTATEICON) == 0 Then Return $GUI_RUNDEFMSG
       
        If $a_Index[0] <> $a_Index[1] Then
                ;ConsoleWrite($a_Index[0] & " ==> " & $a_Index[1] & @CRLF)
                _GUICtrlListView_CopyItem($h_ListView, $h_ListView, $a_Index[0], $a_Index[1], 1)
        EndIf
       
        Return $GUI_RUNDEFMSG
EndFunc  ;==>WM_LBUTTONUP_EVENTS

Func WM_MOUSEMOVE_EVENTS($hWndGUI, $MsgID, $wParam, $lParam)
        If Not $iDragging Or $iDrawing Then Return $GUI_RUNDEFMSG
       
        Local $aLV_Pos = ControlGetPos($hWndGUI, "", $ListView)
       
        Local $iX = BitAND($lParam, 0xFFFF) - $aLV_Pos[0]
        Local $iY = BitShift($lParam, 16) - $aLV_Pos[1]
       
        Local $struct_LVHITTESTINFO = DllStructCreate("int;int;uint;int;int;int")
       
        DllStructSetData($struct_LVHITTESTINFO, 1, $iX)
        DllStructSetData($struct_LVHITTESTINFO, 2, $iY)
       
        Local $iItem = GUICtrlSendMsg($ListView, $LVM_HITTEST, 0, DllStructGetPtr($struct_LVHITTESTINFO))
        If $iItem = -1 Then Return $GUI_RUNDEFMSG
       
        If $iLast_Index = $iItem Then Return $GUI_RUNDEFMSG
       
        If $iLast_Index > $iItem Then ;Move up
                _GUICtrlListView_RedrawItems($ListView, $iItem, $iLast_Index)
        Else
                _GUICtrlListView_RedrawItems($ListView, $iLast_Index, $iItem - 1)
        EndIf
       
        $iLast_Index = $iItem
       
        Local $aLV_Pos = ControlGetPos($hWndGUI, "", $ListView)
        Local $iY = _GUICtrlListView_GetItemPositionY($ListView, $iItem)
       
        If $iY <= 0 Then Return $GUI_RUNDEFMSG
       
        _DrawLine($aLV_Pos[0], $iY, $aLV_Pos[2], 2, 0x0000FF, $h_ListView)
EndFunc  ;==>WM_MOUSEMOVE_EVENTS

Func WM_NOTIFY_EVENTS($hWndGUI, $MsgID, $wParam, $lParam)
        Local $tagNMHDR, $iEvent, $hwndFrom, $iCode, $iItem
       
        $tagNMHDR = DllStructCreate("int;int;int;int", $lParam) ;NMHDR (hwndFrom, idFrom, code, Item)
        If @error Then Return $GUI_RUNDEFMSG
       
        $iCode = DllStructGetData($tagNMHDR, 3)
        $iItem = DllStructGetData($tagNMHDR, 4)
       
        Switch $wParam
                Case $ListView
                        Switch $iCode
                                Case $LVN_BEGINDRAG
                                        $a_Index[0] = $iItem
                                        $iDragging = True
                                       
                                        ;_GUICtrlListView_SetItemSelected($ListView, $iItem, False)
                        EndSwitch
        EndSwitch
       
        Return $GUI_RUNDEFMSG
EndFunc  ;==>WM_NOTIFY_EVENTS

Func _GUICtrlListView_CopyItem($hWnd_Source, $hWnd_Destination, $iSrcIndex, $iDstIndex, $fDelFlag = False)
        Local $iInsert_Index
        Local $tItem = DllStructCreate($tagLVITEM)
       
        Local $iCols = _GUICtrlListView_GetColumnCount($hWnd_Source)
        Local $iItems = _GUICtrlListView_GetItemCount($hWnd_Source)
        Local $iDest_Items = _GUICtrlListView_GetItemCount($hWnd_Destination)
       
        _GUICtrlListView_BeginUpdate($hWnd_Source)
        If $hWnd_Destination <> $hWnd_Source Then _GUICtrlListView_BeginUpdate($hWnd_Destination)
       
        DllStructSetData($tItem, "Mask", BitOR($LVIF_GROUPID, $LVIF_IMAGE, $LVIF_INDENT, $LVIF_PARAM, $LVIF_STATE))
        DllStructSetData($tItem, "Item", $iSrcIndex)
        DllStructSetData($tItem, "SubItem", 0)
        DllStructSetData($tItem, "StateMask", -1)
       
        _GUICtrlListView_GetItemEx($hWnd_Source, $tItem)
       
        If $iDstIndex > $iSrcIndex Then
                $iDstIndex += 1
        ElseIf $iSrcIndex > $iDstIndex Then
                $iSrcIndex += 1
        EndIf
       
        $iInsert_Index = _GUICtrlListView_InsertItem($hWnd_Destination, _
                        _GUICtrlListView_GetItemText($hWnd_Source, $iSrcIndex, 0), $iDstIndex, DllStructGetData($tItem, "Image"))
       
        If BitAND(_GUICtrlListView_GetExtendedListViewStyle($hWnd_Source), $LVS_EX_CHECKBOXES) == $LVS_EX_CHECKBOXES Then
                If _GUICtrlListView_GetItemChecked($hWnd_Source, $iSrcIndex) Then _
                                _GUICtrlListView_SetItemChecked($hWnd_Destination, $iInsert_Index)
        EndIf
       
        For $i = 0 To $iCols - 1
                DllStructSetData($tItem, "Item", $iInsert_Index)
                DllStructSetData($tItem, "SubItem", $i)
               
                _GUICtrlListView_GetItemEx($hWnd_Source, $tItem)
               
                _GUICtrlListView_AddSubItem($hWnd_Destination, $iInsert_Index, _
                                _GUICtrlListView_GetItemText($hWnd_Source, $iSrcIndex, $i), $i, DllStructGetData($tItem, "Image"))
        Next
       
        If $fDelFlag Then _GUICtrlListView_DeleteItem($hWnd_Source, $iSrcIndex)
       
        If $iDstIndex > $iSrcIndex Then $iDstIndex -= 1
        _GUICtrlListView_SetItemSelected($hWnd_Source, $iDstIndex)
       
        _GUICtrlListView_EndUpdate($hWnd_Source)
        If $hWnd_Destination <> $hWnd_Source Then _GUICtrlListView_EndUpdate($hWnd_Destination)
       
        _GUICtrlListView_RedrawItems($hWnd_Destination, $iSrcIndex, $iDstIndex)
        ;DllCall("User32.dll", "int", "RedrawWindow", "hwnd", $hWnd_Destination, "ptr", 0, "int", 0, "int", 5)
EndFunc  ;==>_GUICtrlListView_CopyItem

Func _DrawLine($iLeft, $iTop, $iWidth, $iHeight, $sColor, $hWnd = 0)
        $iDrawing = True
        $sColor = Hex("0x" & BitAND(BitShift(String(Binary($sColor)), 8), 0xFFFFFF)) ;RGB2BGR
       
        Local $hDC = DllCall("User32.dll", "int", "GetDC", "hwnd", $hWnd)
        Local $aPen = DllCall("GDI32.dll", "int", "CreatePen", "int", 0, "int", $iHeight, "int", $sColor)
       
        DllCall("GDI32.dll", "int", "SelectObject", "int", $hDC[0], "int", $aPen[0])
       
        If $iLastLineTop > -1 And $iLastLineLeft > -1 Then
                If $iLastLineTop <> $iTop Then ; or $iLastLineLeft <> $iLeft Then
                        ;Local $strRect = DllStructCreate("int[4]")
                       
                        ;DllStructSetData($strRect, 1, 5)
                        ;DllStructSetData($strRect, 2, 75)
                        ;DllStructSetData($strRect, 3, 198 + 5)
                        ;DllStructSetData($strRect, 4, 280 + 75)
                       
                        ;Local $pRect = DllStructGetPtr($strRect)
                       
                        $iLastLineLeft = $iLeft
                        $iLastLineTop = $iTop
                       
                        DllCall("user32.dll", "int", "InvalidateRect", "hwnd", $hWnd, "int", 0, "int", 1)
                        Sleep(50) ;seems to be needed to ensure redrawn before line is drawn
                EndIf
        EndIf
       
        DllCall("GDI32.dll", "int", "MoveToEx", "hwnd", $hDC[0], "int", $iLeft, "int", $iTop, "int", 0)
        DllCall("GDI32.dll", "int", "LineTo", "hwnd", $hDC[0], "int", $iLeft + $iWidth, "int", $iTop)
       
        DllCall("user32.dll", "int", "ReleaseDC", "hwnd", $hWnd, "int", $hDC[0])
        DllCall("GDI32.dll", "int", "DeleteObject", "int", $aPen[0])
       
        $iDrawing = False
EndFunc  ;==>_DrawLine


malev 15-11-2009 12:29 1270763

Спасибо 1 вариант нужен был, почему так все сложно с ListView вроде простые и необходимые функции.


Время: 14:21.

Время: 14:21.
© OSzone.net 2001-