Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
West Wind WebSurge - Rest Client and Http Load Testing for Windows

Drag and Drop from Explorer into a FoxPro TextBox


:P
On this page:

 

This might seem like a trivial thing to do, but as it turns out it’s not. My use case for this scenario is that somebody last week suggested it would be very nice if Help Builder supported the ability to drag and drop images directly from explorer into the Help Builder edit window. The nice thing about that is that you can leave explorer running and drag and drop multiple images easily.

 

FoxPro supports drag and drop easily enough via he Ole Drag & Drop features that have been in the product since 7.0 (I think). To manage drag and drop to a control from an external application you basically implement the OleDragOver method to essentially enable the control as a drop target by querying the drag data and then setting the OleDropHasData Property to a non-zero value. Then you can use the OleDragDrop event to actually do what you need to do on the drop action.

 

With files from Explorer you can check for a format type of 15 – file handles, which allows capturing an array of all the selected files dropped.

 

* OleDragOver

LPARAMETERS oDataObject, nEffect, nButton, nShift, nXCoord, nYCoord, nState

 

*** Check for files

IF odataobject.GETFORMAT(15)

   THIS.OLEDROPHASDATA = 1

ENDIF

 

* OleDragDrop

LPARAMETERS oDataObject, nEffect, nButton, nShift, nXCoord, nYCoord

LOCAL lcText, lcOldPath, lcImage

 

IF oDataObject.GetFormat(15)

   DIMENSION laFiles[1]

   oDataObject.GetData(15,@laFiles)

   IF ALEN(laFiles,1) > 0

      lcText = ""

      lcImage = laFiles[1]

      lcext = LOWER(JUSTEXT(lcImage))

      DO CASE

         CASE INLIST(lcExt,"png","gif","jpg","bmp","TIF")

            *** Drop an image

            lcOldPath = SYS(5) + CURDIR()

            CD (JUSTPATH(goHelp.oHelp.cFileName))

 

            lcRelImage = SYS(2014,lcImage)

            IF lcRelImage # ".."

               lcImage = lcRelImage

            ENDIF

 

            *** Convert to proper case

            lcImage = LongPath(lcImage)

 

            lcText = " " + THIS.cLTag + [img src="]+ lcImage +["]+THIS.cRTag

            CD (lcOldPath)

           

      ENDCASE

 

     this.SelLength = 0

     this.SelText = lcText

ENDIF

 

So far so good. But this code actually doesn’t quite do what I want. I want the text to be dropped into the textbox at the drop location. However, dragging and dropping files out of Explorer is not text (the only format that VFP will drop directly) so by default the drop operation doesn’t place the files anywhere. My code actually modifies the file formatting so that it’s turned into Help Builder’s markup code that gets embedded which is stored in lcText. My first thought was to use SelText to force the text into the document as shown above. Unfortunately this doesn’t quite do the trick as the text is pasted at the current cursor position, not the drop cursor position. Drag and Drop doesn’t actually change the cursor position of the text box.

 

So that’s a problem. Another thought here was to modify the DragAndDrop Data object that gets passed using SetData() and assigning my updated text to it and changing the format to 1. Unfortunately, that doesn’t work either because SetData() cannot be called from the DragOver or DragDrop events.

 

So, finally the solution turned out to be more of a nuisance and hack. The OleDragDrop event passes in a X and Y coordinate for the form. With that coordinate you can now force the mouse cursor to this position essentially forcing SelText focus to this location. So with this update the working code looks like this:

 

LPARAMETERS oDataObject, nEffect, nButton, nShift, nXCoord, nYCoord

LOCAL lcText, lcOldPath, lcImage

 

IF oDataObject.GetFormat(15)

   DIMENSION laFiles[1]

   oDataObject.GetData(15,@laFiles)

   IF ALEN(laFiles,1) > 0

      lcText = ""

      lcImage = laFiles[1]

      lcext = LOWER(JUSTEXT(lcImage))

      DO CASE

         CASE INLIST(lcExt,"png","gif","jpg","bmp","TIF")

            *** Drop an image

            lcOldPath = SYS(5) + CURDIR()

            CD (JUSTPATH(goHelp.oHelp.cFileName))

 

            lcRelImage = SYS(2014,lcImage)

            IF lcRelImage # ".."

               lcImage = lcRelImage

            ENDIF

 

            *** Convert to proper case

            lcImage = LongPath(lcImage)

 

            lcText = " " + THIS.cLTag + [img src="]+ lcImage +["]+THIS.cRTag

            CD (lcOldPath)

           

      ENDCASE

 

      IF !EMPTY(lcText)

         *** Pick up the Mouse Position of the drop location

         *** and force the mouse pointer to that position

         MOUSE CLICK AT nYCoord,nXCoord PIXELS WINDOW (THISFORM.Name)

         DOEVENTS

       

         *** Read ahead 1 char to check for spaces        

         this.SelLength = 1

         IF this.SelText != " "

            lcText = lcText + " "

         ENDIF

        

         *** Now paste at cursor

         SelLength = 0

         this.SelText = lcText

      ENDIF

   ENDIF

ENDIF

 

RETURN

 

Note the use of the MOUSE command to force the mouse to the location. The DOEVENTS is also significant to allow the form to refresh before changing the SelText location.

 

One thing that sucks about this is that VFP’s drag and drop behavior looks a little weird in a text box. You see the drag and drop cursor and you also see – a few characters below a caret cursor ‘dragging behind’. It looks a bit confusing. The cursor is where it actually drops which is the correct behavior, but the cursor caret is a visual nuisance.

 

Anyway there you have it – it works even if it’s not as straight forward as I would have expected.


The Voices of Reason


 

Alejandro A. Sosa
October 01, 2005

# re: Drag and Drop from Explorer into a FoxPro TextBox

Rick, I tried to do drag and drop into the RTF ActiveX control directly to the position that is tracked with no luck. It always dropped it at the beginning of the RTF box. I'll take another look using your tricks.

Thanks for sharing.

Alex

Rick Strahl
October 01, 2005

# re: Drag and Drop from Explorer into a FoxPro TextBox

Dropping into the RTF control will not work the same since the VFP MOUSE AT command can't be used.

However, the RTF control should accept any standard content directly - images, text etc. and embed it directly.


Ana María Bisbé York
November 25, 2005

# re: Drag and Drop from Explorer into a FoxPro TextBox

Thanks Rick!!

You can find the Spanish version of this article at (Puede encontrar la versión en Español de este artículo en:)

http://www.portalfox.com/modules.php?op=modload&name=Sections&file=index&req=viewarticle&artid=106

Regards / Saludos,

Ana
www.amby.net
www.PortalFox.com

# DotNetSlackers: Drag and Drop from Explorer into a FoxPro TextBox


West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2024