http://west-wind.com/weblog/posts/3135.aspx
Autor: Rick Strahl
Traducido por: Ana María Bisbé York
Esto parece ser algo muy trivial de hacer; pero no lo es. Mi caso de uso para este escenario es que alguien la semana pasada sugirió que sería muy bueno que el Help Builder (http://www.west-wind.com/wwHelp/) tuviera la capacidad de arrastrar imágenes directamente del explorador a la ventana de edición del Help Builder. Lo bueno en este caso es que puede dejar que el explorador siga funcionando mientras arrastra y suelta varias imágenes simultáneamente.
FoxPro admite arrastrar y soltar fácilmente mediante sus características Ole Drag & Drop que están en el producto desde 7.0 (Creo). Para controlar las acciones de arrastrar y soltar en un control desde una aplicación externa implemente el método OleDragOver que permite el control como un destino para soltar al consultar el dato arrastrado y luego establecer la propiedad OleDropHasData a un valor diferente de cero. Entonces, puede utilizar el evento OleDragDrop para hacer realmente lo que necesita en la acción Soltar.
Con archivos desde el explorador puede verificar un tipo de formato de 15 - controlador de archivos, que permite capturar una matriz de todos los archivos seleccionados para soltar.
* OleDragOver LPARAMETERS oDataObject, nEffect, nButton, nShift, nXCoord, nYCoord, nState *** Verificar los archivos 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") *** Soltar una imagen lcOldPath = SYS(5) + CURDIR() CD (JUSTPATH(goHelp.oHelp.cFileName)) lcRelImage = SYS(2014,lcImage) IF lcRelImage # ".." lcImage = lcRelImage ENDIF *** Convertir a mayúsculas lcImage = LongPath(lcImage) lcText = " " + THIS.cLTag + [img src="]+ lcImage +["]+THIS.cRTag CD (lcOldPath) ENDCASE this.SelLength = 0 this.SelText = lcText ENDIF ENDIF RETURNHasta aquí todo bien. Pero este código, en realidad no hace lo que yo quiero. Yo quiero que sea arrastrado hasta la ubicación de un cuadro de texto. Sin embargo, arrastrar y soltar archivos fuera del Explorador no tiene texto, sólo el formato que VFP va a soltar directamente, por lo que de forma predeterminada la operación Soltar no va a colocar los archivos en ningún lugar. Mi código modifica el formato de archivo de tal forma que lo convierte en formato de marcado del Help Builder que está embebido y es almacenado en lcText. Lo primero que pensé fue utilizar SelText para obligar al texto dentro del documento como se muestra arriba. Desafortunadamente no es fácil hacer este truco debido a que el texto es pegado en la posición actual del cursor, no a la posición del cursor al soltar. En realidad arrastrar y soltar no cambian la posición del cursor del cuadro de texto.
Entonces, hay un problema. Otra idea fue modificar el objeto DragAndDrop Data que se pasa utilizando SetData() y asignarle mi texto actualizado y cambiar el formato a 1.
Desafortunadamente, no trabaja, porque SetData() no puede ser llamado desde los eventos DragOver o DragDrop.
Entonces, finalmente la solución ha sido un poco más molesta y rebuscada. El evento OleDragDrop pasa unas coordenadas X y Y desde el formulario. Con esas coordenadas puede forzar el movimiento del cursor a esta posición forzando esencialmente el foco a la localización de SelText. Entonces, el código que funciona correctamente tiene el aspecto siguiente.
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") *** Soltar una imagen lcOldPath = SYS(5) + CURDIR() CD (JUSTPATH(goHelp.oHelp.cFileName)) lcRelImage = SYS(2014,lcImage) IF lcRelImage # ".." lcImage = lcRelImage ENDIF *** Convertir a letra mayúscula lcImage = LongPath(lcImage) lcText = " " + THIS.cLTag + [img src="]+ lcImage +["]+THIS.cRTag CD (lcOldPath) ENDCASE IF !EMPTY(lcText) *** Tomar la posición del ratón en la localización al soltar *** y obligar al puntero del ratón a esa posición MOUSE CLICK AT nYCoord,nXCoord PIXELS WINDOW (THISFORM.Name) DOEVENTS *** Leer un carácter para verificar los espacios this.SelLength = 1 IF this.SelText != " " lcText = lcText + " " ENDIF *** Ahora pegar al cursor SelLength = 0 this.SelText = lcText ENDIF ENDIF ENDIF RETURNVea que se utiliza el comando MOUSE para forzar la localización del ratón. También es significativo el DOEVENTS que hace que el formulario se refresque antes de cambiar la localización SelText.
Esta forma de arrastrar y soltar en VFP es un poco raro en el TextBox. Puede arrastrar y soltar el cursor y luego verá - unos caracteres debajo, un acento circunflejo (`´) dibujado después. Esto parece un poco confuso. El cursor está donde ha sido soltado en realidad con el comportamiento correcto; pero el cursor muestra una molestia visual.
De cualquier manera aquí lo tiene - trabaja incluso si no es tan claro como yo hubiera esperado.