Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

drag and drop from a grid 2

Status
Not open for further replies.

herbstgy

Programmer
Jan 30, 2018
54
HU
Greetings, Everyone...

there's a rather complicated formatted readonly grid used only for output.
it looks like this:
2_uqjpa0.png

inside the column cells there are container classes with uniquely formatted text fields.
how could I detect the beginning of a drag event from the grid to copy the contents of a cell?
 
The short answer to your question is that the OLEStartDrag event fires at the beginning of a drag operation. Both the grid itself and the container within the column have OLEStartDrag events. You might need to experiment to see which one would be most appropriate in this case.

I assume you know that you also have to set the same object's OleDragMode to 1 to enable drag and drop.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
thanks for your answer, Mike.

I'm going to start experimenting with it, and I'm sure I'll be back with more questions. :)
 
here's what I've found out so far:

- the grid object's OLEDragMode property is readonly, I can't set it to 1
- I've set container object's OLEDragMode property to 1 in the 2nd column and wrote a WAIT WINDOW "cntcim olestartdrag fired" statement in the OLEStartDrag event but it didn't fire
- tried the same with one of the fields inside the container but also no.

how could I get the form or the grid to notice that I started dragging? all the rest of the questions (what to grag, how to build up the dragged data) only come after this...
 
I wouldn't pay too much attention to the fact that the Wait window didn't fire. There are several things that don't happen - or which happen differently - while a drag is in progress. I'm not sure if a Wait is one of them, but it might well be.

It might be better to use the Event Tracker (on the debugger's Tools menu) to check for the firing of the OLEStartDrag. Or, better still, go ahead and write yuor code to do the drop, so that you can test the whole process in one go.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Dear Mike,

yes, I tried Event Tracker before I posted my question here. It didn't get me anywhere. :)
I only see the grid's MouseDown/MouseUp and the container's MouseDown event to fire. (besides of course the MouseEnter/MouseMove/MouseLeave events.)
 
Sorry, Herbstgy. I might have misled you. In my tests, OLEStartDrag does fire for a container, but it seems not to fire if the container is inside a grid. At least, that's what I am seeing.

I checked this by putting this code in the OLEStartDrag:

Code:
LPARAMETERS oDataObject, nEffect
lcText = oDataObject.GetData(1)
WAIT WINDOW lcText NOWAIT

For a container placed directly on the form, I could see the Wait window with the relevant text in it (also the mouse pointer changes to the default NoDrop icon). But that didn't happen for a container placed in a grid.

If I get any more information, I will let you know.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Step 1 - In the mousedown of the container save the top and left to 2 form properties as follows: Thisform.contstartingtop = This.Top
Thisform.contstartingleft = This.Left

Step 2 - In the mousemove of the container save off two more form properties Thisform.xoffset = nXCoord - This.Left
Thisform.yoffset = nYCoord - This.Top

Step 3 - In the dragdrop event of the form use the following code: lnContTop = nYCoord - Thisform.yoffset (This will give you Top of Container after user has finished the drop)
lnContLeft = nXCoord - Thisform.xoffset (This will give you Left of Container after user has finished the drop)

Sure you have Step 4 Now which is compare results of Step 1 against Step 3 and this will tell you if user has in fact moved the container. We are using the dragdrop as a simulated mouseup of the container. So my thinking is if you store off the uniquely formatted text fields in the mouse down of the container and then only write the text fields to wherever if Step1 <> Step3.
 
Another option is to use api which I got from another post on Tek-Tips. See this "drag detected" option. I have not had time to test it fully but it's another idea.

PUBLIC objForm
objForm = CreateObject("TForm")
objForm.Visible = .T.

DEFINE CLASS TForm As Form
Width=400
Height=200
Autocenter=.T.

PROCEDURE Load
THIS.decl

PROCEDURE MouseDown
LPARAMETERS nButton, nShift, nXCoord, nYCoord

* testing the mouse key state
IF nButton <> 1
RETURN
ENDIF

LOCAL lcCursorPos, hWindow

* window handle for this form
hWindow = GetFocus()

* reading cursor position
lcCursorPos = Repli(Chr(0), 8)
= GetCursorPos(lcCursorPos)

* Attention: at the next line the execution is stopped until
* the mouse button released or the cursor moved out
* the drag-free rectangle centered on the current cursor position
* with sides defined by the system

* the width and height of this rectangle returned by the GetSystemMetrics
* function called with the correspondent SM_CXDRAG or SM_CYDRAG parameters

IF DragDetect(hWindow, @lcCursorPos) <> 0
* user moved the mouse outside of the drag rectangle
* while holding down the left button
ACTI SCREEN
? "Drag detected"
ELSE
ACTI SCREEN
? "Mouse key released without dragging"
ENDIF

PROCEDURE decl
DECLARE INTEGER GetFocus IN user32
DECLARE INTEGER GetCursorPos IN user32 STRING @lpPoint

DECLARE INTEGER DragDetect IN user32;
INTEGER hwnd, STRING @pt
ENDDEFINE
 
generalac said:
* the width and height of this rectangle returned by the GetSystemMetrics
* function called with the correspondent SM_CXDRAG or SM_CYDRAG parameters

could you elaborate on this?
 
Dear Generalac,

thank you for your example.
I tried it and it works if I put it in the container's MouseDown event in the grid column, but I don't know how to move forward from here.
I suppose I should call the container's OLEStartDrag event and build up the dragged data from the contents of the container (plain text would do), but I didn't find any relevant sample between the Foxpro samples. most of them shows how handle the dropped data and differentiate the data types, but never shows how to START a drag... :(
 
okay, I think I got it.

I can initiate the drag with

this.OLEDrag(.f.)

where ?"Drag detected" message was, then I can build the dragged data in the container's OLEStartDrag method like this:

Code:
IF oDataObject.GetFormat("VFP Source Object")
    oDataObject.SetFormat(1)
    oDataObject.SetData("dragged text comes here",1)
ENDIF
 
something still not right.

I managed to handle the drag from inside grid container, and whether the drag is successful or not, the grid containing form becomes unclosable, like the oledraganddrop was still in progress. the controls on the form remain active, but I can't close it.

any advice?
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top