Jump to content

Possible ListView Item Copy bug


Recommended Posts

Hello,

I've been doing some fairly hefty exploration with listviews and no matter what I try, I can't get this copy to work. Attached is a chunk of code. When you run it, you'll notice that you can drag items from the left to the right. However, when you drag items from right to left - it copies them but doesn't remove them.

Is this an AutoIT bug? I'm using version 3.3.2.0.

If this isn't a bug, I'd sure appreciate it if someone could tell me what I'm doing wrong here.

Cheers,

JT

UPDATE: I've just tried it with v3.3.6.0 and it's the same!

; Includes first! Must must must!
#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#Include <GuiListView.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <Array.au3>
#include <Misc.au3>


; Switch on the 'onEvent' notifications
Opt ("GUIOnEventMode", 1)


; Generate the GUI! Ahoy there.
Global $MainForm, $list_source, $list_target
$MainForm = GUICreate(" TEST! ", 517, 178)


; Source list box
$list_source = GUICtrlCreateListView("Title|Details", 13, 16, 240, 136, BitOR($LVS_REPORT,$LVS_SHOWSELALWAYS,$LVS_SORTASCENDING))


; Target list box
$list_target = GUICtrlCreateListView("Title|Details", 261, 16, 240, 136, BitOR($LVS_REPORT,$LVS_SHOWSELALWAYS,$LVS_SORTASCENDING))


; Populate box with some test stuff
For $x = 1 to 6
    GUICtrlCreateListViewItem( _makeJunkName() & "|" & _makeJunkName(), $list_source)
Next


; Handle GUI events
GUISetOnEvent($GUI_EVENT_PRIMARYDOWN, "_dragHandler")
GUISetOnEvent($GUI_EVENT_CLOSE,       "_formEvents")
GUISetOnEvent($GUI_EVENT_MINIMIZE,    "_formEvents")
GUISetOnEvent($GUI_EVENT_RESTORE,     "_formEvents")


; Show the form
GUISetState(@SW_SHOW)


; Main program loop
While 1
    ; Don't really do much in here at all...
WEnd


; Create a junk name for testing
Func _makeJunkName()
    Local $labelout = ''
    For $i = 1 to 10
        $labelout &= chr(Random(65,90,1))
    Next
    Return $labelout
EndFunc


; Function to handle drag and drop
Func _dragHandler()
    
    ; Define some stuff
    Local $source, $desc
    Local $cinfo =  GUIGetCursorInfo (WinGetHandle($MainForm))
    Local $direction = 0
    
    ; Check we are dragging from one or the other boxes
    If $cinfo[4] = $list_source OR $cinfo[4] = $list_target Then
        
        ; Are we moving from source to destination
        If $cinfo[4] = $list_source Then
            $direction = 1
        EndIf
        
        ; Or are we moving from destination to source
        If $cinfo[4] = $list_target Then
            $direction = 2
        EndIf

        ; Doublecheck we're pressing mouse button
        If _IsPressed(1) Then
            if $direction = 1 Then
                $selecteditems = _GUICtrlListView_GetSelectedCount($list_source);
            Else
                $selecteditems = _GUICtrlListView_GetSelectedCount($list_target);
            EndIf
            
            ; Check we actually have selected an item
            If $selecteditems >= 1 Then
                
                ; Wait for keypress!
                While _IsPressed(1)
                WEnd
                
                ; Get new position
                Local $newcinfo =  GUIGetCursorInfo (WinGetHandle($MainForm))
                
                ; If we were moving from source to destination and we ARE in the destination box
                If $direction = 1 And $newcinfo[4] = $list_target Then
                    ConsoleWrite("Moved " & $selecteditems & " items from source to destination" & @CRLF)
                    _GUICtrlListView_CopyItems ($list_source, $list_target, 1)
                EndIf
                
                ; If we are moving from destination to source and we ARE in source box
                If $direction = 2 And $newcinfo[4] = $list_source Then
                    ConsoleWrite("Moved " & $selecteditems & " items from destination to source" & @CRLF)
                    _GUICtrlListView_CopyItems ($list_target, $list_source, 1)
                EndIf

            EndIf

        EndIf
        
    EndIf
    
EndFunc


; Function to handle other form events
Func _formEvents()
    Select
        Case @GUI_CtrlId = $GUI_EVENT_CLOSE
            Exit
    EndSelect
EndFunc
Edited by JonnyThunder
Link to comment
Share on other sites

  • 2 weeks later...
  • Moderators

JohnnyThunder,

There does appear to be a bug, but not quite as you have stated. :(

Try using this as your "list filler":

; Populate boxes with some test stuff
For $x = 1 to 2
    GUICtrlCreateListViewItem( "Source|" & _makeJunkName(), $list_source)
    GUICtrlCreateListViewItem( "Target|" & _makeJunkName(), $list_target)
Next

When I test now, I can "move" items from one box to another (in both directions), but only "copy" them if I try to move them back to their original position!

I will keep playing about and see if I can find out any more, but nothing is jumping out at me for the moment. :)

M23

P.S. You really need to put some Sleep(10) statements in your While...WEnd loops or your CPU will explode one day! :)

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

If you take a look into _GUICtrlListView_CopyItems() and replace the line

_GUICtrlListView_DeleteItem($hWnd_Source, $a_indices[$i])

with

_GUICtrlListView_DeleteItem(GUICtrlGetHandle($hWnd_Source), $a_indices[$i])

it works fine.

Replacing

_GUICtrlListView_CopyItems($list_source, $list_target, 1)

with

_GUICtrlListView_CopyItems(GUICtrlGetHandle($list_source), $list_target, 1)

in your source will also do the trick.

Link to comment
Share on other sites

  • Moderators

KaFu,

You take all the fun out of life. :(

I have just wasted an hour coding this - so I will post it anyway: :)

; Includes first! Must must must!
#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#Include <GuiListView.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <Array.au3>
#include <Misc.au3>

; Switch on the 'onEvent' notifications
Opt ("GUIOnEventMode", 1)

; Generate the GUI! Ahoy there.
Global $MainForm, $list_source, $list_target
$MainForm = GUICreate(" TEST! ", 517, 178)

Global $aWinPos = WinGetPos($MainForm)

; Source list box
GUICtrlCreateListView("Title|Details", 13, 16, 240, 136, -1, $LVS_EX_FULLROWSELECT)
$list_source = GUICtrlGetHandle(-1)
Global $aSource_Coords[4] = [$aWinPos[0] + 13, $aWinPos[1] + 16, $aWinPos[0] + 13 + 240, $aWinPos[1] + 16 + 136]

; Target list box
GUICtrlCreateListView("Title|Details", 261, 16, 240, 136, -1, $LVS_EX_FULLROWSELECT)
$list_target = GUICtrlGetHandle(-1)
Global $aTarget_Coords[4] = [$aWinPos[0] + 261, $aWinPos[1] + 16, $aWinPos[0] + 261 + 240, $aWinPos[1] + 16 + 136]

; Populate box with some test stuff
For $x = 0 to 1
    _GUICtrlListView_AddItem($list_source, "Source")
    _GUICtrlListView_AddSubItem($list_Source, $x, $x + 1, 1)
    _GUICtrlListView_AddItem($list_target, "Target")
    _GUICtrlListView_AddSubItem($list_target, $x, $x + 1, 1)
Next

; Handle GUI events
GUISetOnEvent($GUI_EVENT_CLOSE,       "_formEvents")
GUISetOnEvent($GUI_EVENT_MINIMIZE,    "_formEvents")
GUISetOnEvent($GUI_EVENT_RESTORE,     "_formEvents")

; Show the form
GUISetState(@SW_SHOW)

$dll = DllOpen("user32.dll")
; Main program loop
While 1
    Sleep(10)
    If _IsPressed("01", $dll) Then _dragHandler()
WEnd

; Function to handle drag and drop
Func _dragHandler()

    Local $direction = 0

    $aMousePos = MouseGetPos()

    ; Check we are dragging from one or the other boxes
    ; Check Y pos
    If $aMousePos[1] > $aSource_Coords[1] And $aMousePos[1] < $aSource_Coords[3] Then
        ; Check X pos
        If $aMousePos[0] > $aSource_Coords[0] And $aMousePos[0] < $aSource_Coords[2] Then
            ; We are in Source list
            ConsoleWrite("Source" & @CRLF)
            $direction = 1
        ElseIf $aMousePos[0] > $aTarget_Coords[0] And $aMousePos[0] < $aTarget_Coords[2] Then
            ; We are in Target list
            ConsoleWrite("Target" & @CRLF)
            $direction = 2
        EndIf
    EndIf

    if $direction = 1 Then
        $selecteditems = _GUICtrlListView_GetSelectedCount($list_source);
    Else
        $selecteditems = _GUICtrlListView_GetSelectedCount($list_target);
    EndIf

    ; Check we actually have selected an item
    If $selecteditems >= 1 Then

        While _IsPressed("01", $dll)
            Sleep(10)
        WEnd

        $aMousePos = MouseGetPos()
        ; Check we are dragging to the other boxes
        ; Check Y pos
        If $aMousePos[1] > $aSource_Coords[1] And $aMousePos[1] < $aSource_Coords[3] Then
            ; Check direction
            Switch $direction
                Case 1
                    If $aMousePos[0] > $aTarget_Coords[0] And $aMousePos[0] < $aTarget_Coords[2] Then
                        ; We are in Target list
                        _GUICtrlListView_CopyItems ($list_source, $list_target, 1)
                        ConsoleWrite("Moved " & $selecteditems & " items from source to destination" & @CRLF)
                    Endif

                Case 2
                    If $aMousePos[0] > $aSource_Coords[0] And $aMousePos[0] < $aSource_Coords[2] Then
                        ; We are in Source list
                        _GUICtrlListView_CopyItems ($list_target, $list_source, 1)
                        ConsoleWrite("Moved " & $selecteditems & " items from destination to source" & @CRLF)
                    EndIf
            EndSwitch
        EndIf
    EndIf

EndFunc

; Create a junk name for testing
Func _makeJunkName()
    Local $labelout = ''
    For $i = 1 to 10
        $labelout &= chr(Random(65,90,1))
    Next
    Return $labelout
EndFunc

; Function to handle other form events
Func _formEvents()
    Select
        Case @GUI_CtrlId = $GUI_EVENT_CLOSE
            DllClose($dll)
            Exit
    EndSelect
EndFunc

M23

Edit: Small code change - see below.

Edited by Melba23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

You take all the fun out of life. :)

Sorry about that :(...

... and in your code I guess

Case @GUI_CtrlId = $GUI_EVENT_CLOSE
            DllOpen("user32.dll")
            Exit

should be more like this...

Case @GUI_CtrlId = $GUI_EVENT_CLOSE
            dllclose($dll)
            Exit
Link to comment
Share on other sites

  • Moderators

KaFu,

:(

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Thanks very much for your time and effort guys. The post that KaFu made does seem to work - but I don't fully understand why the original example I posted only worked in one direction but not both?

Just for completeness, can you fill in the missing details for me?

Thanks again though. I'm up and running with drag'n'drop goodness! :-) Oh, thanks for the pointer about sleeping my loop. Am I mistaken, but I also seem to remember something in a previous version history which said that tight loops like this were more CPU friendly now than in older versions of AutoIT?

p.s. Should I now close the bug ticket? Or is there still an issue here?

Edited by JonnyThunder
Link to comment
Share on other sites

ControlID is different from Control handle. ID is an enumarted INT during GUI creation and specific to the GUI. Handle is valid system-wide.

On a low level handle is necessary to perfom control manipulation (I think :().

Most au3 functions and UDFs perform the controlID <> handle conversion internally.

The functions used to add a new entry do so...

The function used to delete an entry does not...

Link to comment
Share on other sites

  • Moderators

JonnyThunder,

p.s. Should I now close the bug ticket? Or is there still an issue here?

I would add to the ticket explaining what KaFu found and linking to this thread. Then the Devs can decide to alter the UDF if they wish. :(

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...