Posted: Fri May 26, 2006 4:06 pm
Hi schic.
I can't reproduce your first report, but as you indicate, it seems a minor deal.
The problem with the list view is to do with the way Windows sends notifications that a listview item is about to change. It sends it after you release the mouse button (which seems a little strange to me!)
This of course is a massive problem when enabling drag-and-drop since we will not be releasing the mouse button any time soon!
The way round it is to use EasyVent's #OnMouseDown() event instead as the following adaption to the above example shows:
NOTE that you will need to download the new version of EasyVENT (see post 1) which I have just uploaded for this to work.
To be honest, if you're making use of this library, it is probably best if you do not use PB's event loop for anything other than closing the program. I admit that any problems that arise are likely to do with drag-drop (as already shown!) but the two are really not designed to work together! This is not to say that they will not work together, but the two paradigms are quite dissimilar!
For example, my current app has nearly 50 events declared at the moment and all is working well. This is of course with the regular PB event loop only being used to close the program.
I can't reproduce your first report, but as you indicate, it seems a minor deal.
The problem with the list view is to do with the way Windows sends notifications that a listview item is about to change. It sends it after you release the mouse button (which seems a little strange to me!)
This of course is a massive problem when enabling drag-and-drop since we will not be releasing the mouse button any time soon!
The way round it is to use EasyVent's #OnMouseDown() event instead as the following adaption to the above example shows:
Code: Select all
XIncludeFile "EasyVENT.pbi"
;*********************************************************************************
Declare.l SelectItem(*sender.PB_Sender)
Declare.l DragOverWindow(*sender.PB_Sender)
Declare.l DragItem(*sender.PB_Sender)
Declare.l DropItem(*sender.PB_Sender)
Declare.l DragOver(*sender.PB_Sender)
Declare.l DragItemTree(*sender.PB_Sender)
Declare HighLightSelection(hwnd, state)
Define Event.l, i, WindowID, GadgetID, GadgetEvent
Global gTargetitem ;Denotes which item we are dropping on.
Global DragSource
OpenWindow(0, 100, 100, 330, 200, "EasyVENT drag and drop items demo 4.", #PB_Window_SystemMenu |#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget| #PB_Window_ScreenCentered)
CreateGadgetList(WindowID(0))
ListViewGadget(1, 0, 0, 150, 150)
ListIconGadget(2,170,10,150,150, "Drag to", 120)
For i = 1 To 10
AddGadgetItem(1, -1, "Gadget 1 - item " + Str(i))
; AddGadgetItem(0, -1, "Gadget 0 - item " + Str(i))
If i < 6
AddGadgetItem(2, -1, "Gadget 2 - item " + Str(i))
EndIf
Next
;Set event handlers.
SetEventHandler(GadgetID(1), #OnMouseDown, @SelectItem())
SetEventHandler(GadgetID(1), #OnDragItemStart, @DragItem())
SetEventHandler(GadgetID(2), #OnDragItemOver, @DragOver())
SetEventHandler(GadgetID(2), #OnDragItemEnd, @DropItem())
SetEventHandler(WindowID(0), #OnDragItemOver, @DragOverWindow())
SetActiveGadget(1)
Repeat
Event = WindowEvent()
Until Event = #PB_Event_CloseWindow
End
;*********************************************************************************
; EVENT HANDLERS
;*********************************************************************************
Procedure.l SelectItem(*sender.PB_Sender)
Debug GetGadgetState(1)
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
;The following ensures that any highlighted item in the target control is removed
;whenever the cursor leaves the control.
Procedure.l DragOverWindow(*sender.PB_Sender)
;Remove any selection highlight already in place.
HighLightSelection(GadgetID(2), 0)
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
;Here we simply return #PB_ProcessPureBasicEvents to enable the drag.
Procedure.l DragItem(*sender.PB_Sender)
If GetActiveGadget()=1 And GetGadgetState(1)>=0
DragSource = 1
*sender\Text$=GetGadgetText(1)
EndIf
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
;Since the following handles only one gadget, we need not check which control etc.
Procedure.l DropItem(*sender.PB_Sender)
;First remove any selection highlight already in place.
HighLightSelection(*sender\hwnd, 0)
If DragSource = 1
AddGadgetItem(2,gTargetitem, GetGadgetText(1)) ;Copy item to ListView.
RemoveGadgetItem(1,*sender\item) ;Remove item from ListIcon.
ElseIf DragSource = 0
AddGadgetItem(2,gTargetitem, GetGadgetText(0)) ;Copy item to ListView.
RemoveGadgetItem(1,*sender\item) ;Remove item from ListIcon.
EndIf
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
Procedure.l DragOver(*sender.PB_Sender)
Protected hittestinfo.LV_HITTESTINFO
;First remove any selection highlight already in place.
HighLightSelection(*sender\hwnd, 0)
;Find which item we are currently hovering over. We need an API call for this.
hittestinfo\pt\x = *sender\MouseX
hittestinfo\pt\y = *sender\MouseY
gTargetitem = SendMessage_(*sender\hwnd, #LVM_HITTEST, 0, @hittestinfo)
;Highlight the new item
If gTargetitem<>-1
HighLightSelection(*sender\hwnd, #LVIS_DROPHILITED)
EndIf
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
;*********************************************************************************
; END OF EVENT HANDLERS
;*********************************************************************************
;The following utility either highlights the target item or removes the highlight etc.
Procedure HighLightSelection(hwnd, state)
Protected pitem.LV_ITEM
pitem\mask = #LVIF_STATE
pitem\iItem = gTargetitem
pitem\state = state
pitem\stateMask = #LVIS_DROPHILITED
SendMessage_(hwnd, #LVM_SETITEM, 0, @pitem)
RedrawWindow_(hwnd, 0, 0, #RDW_UPDATENOW)
EndProcedure
To be honest, if you're making use of this library, it is probably best if you do not use PB's event loop for anything other than closing the program. I admit that any problems that arise are likely to do with drag-drop (as already shown!) but the two are really not designed to work together! This is not to say that they will not work together, but the two paradigms are quite dissimilar!

For example, my current app has nearly 50 events declared at the moment and all is working well. This is of course with the regular PB event loop only being used to close the program.