Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Drag & Drop para obtenr nombre y ruta de archivo (https://www.clubdelphi.com/foros/showthread.php?t=96661)

MAXIUM 31-03-2024 04:10:53

Drag & Drop para obtenr nombre y ruta de archivo
 
Hola. Nunca he realizado esto y no logro entenderlo :confused:

Quisiera arrastrar un archivo cualquiera, sea texto, video o imagen a un TImage y que la ruta de este, aparezca en un TEdit.

Ayuuuuuuda!!!

Casimiro Notevi 31-03-2024 12:56:56

¿Arrastrar texto o "lo que sea" a un TImage?

MAXIUM 31-03-2024 16:26:54

Cita:

Empezado por Casimiro Notevi (Mensaje 555176)
¿Arrastrar texto o "lo que sea" a un TImage?

Quise decir archivo de texto... es decir, cualquier archivo de cualquier extensión. No necesariamente a un TImage. Puede ser a un TPanel.

MAXIUM 31-03-2024 22:53:38

Add ShellAPI and Messages to your project's uses:
Código Delphi [-]
uses
    ShellAPI, Messages;
Add a method to your form that handles the WM_DROPFILES message.

For example, the following would be placed in the TForm1 declaration in the protected section:
Código Delphi [-]
protected
    procedure WMDropFiles(var Msg: TWMDropFiles); message WM_DROPFILES;
Drag 'n' drop are activated by calling:
Código Delphi [-]
DragAcceptFiles(Handle, true);
and deactivated by calling:

Código Delphi [-]
DragAcceptFiles(Handle, false);
It is normal to activate drag 'n' drop in the OnCreate event, and deactivate it in the OnClose or OnDestroy events:
Código Delphi [-]
procedure TForm1.FormCreate(Sender: TObject);
begin
  DragAcceptFiles(Handle, true);
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  DragAcceptFiles(Handle, false);
end;
This first procedure will enable you to drop files one at a time:
Código Delphi [-]
procedure TForm1.WMDropFiles(var Msg: TWMDropFiles);
var filename: PChar;
    length: LongWord;
begin
  length:= DragQueryFile(Msg.Drop, 0, NIL, 0);
  filename:= StrAlloc(length+1);
  DragQueryFile(Msg.Drop,0,filename,length+1);
  {do something with filename}
  Msg.Result:=0;
  inherited;
end;

escafandra 01-04-2024 08:20:48

Antes de usar DragAcceptFiles y DragQueryFile deberías deshabilitar el filtro para los mensajes WM_DROPFILES y WM_COPYGLOBALDATA con la API ChangeWindowMessageFilterEx.


Saludos.

Neftali [Germán.Estévez] 02-04-2024 10:41:05

Cita:

Empezado por MAXIUM (Mensaje 555173)
Hola. Nunca he realizado esto y no logro entenderlo :confused:
Quisiera arrastrar un archivo cualquiera, sea texto, video o imagen a un TImage y que la ruta de este, aparezca en un TEdit.


No es complicado.
Entendiendo los pasos, con unas pocas líneas se puede conseguir.
Necesitas un componente que reciba los ficheros; En este ejemplo he usado un panel, pero puede ser un TImage, el formulario completo,...
En este caso admite varios ficheros; En ese caso llamará varias veces al procedimiento AddFiles.

Añado el ejemplo completo al FTP del Club.

He colocado un panel en el formulario y le he llamado pnlArrastrar.




Y te adjunto el código necesario con los comentarios necesarios.

Código Delphi [-]
unit uMain;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls;

type
  TForm3 = class(TForm)
    pnlArrastrar: TPanel;  // componente que recibirá los ficheros
    procedure FormCreate(Sender: TObject);
  private
    // Mi procedimiento a ejecutar cuando llegue un mensaje al componente (panel)
    procedure LBWindowProc(var Message: TMessage);
    // Procedimiento cuando se reciba un fichero arrastrado
    procedure WMDROPFILES(var Msg: TMessage);
    // Procedimiento para definir qué quiero hacer con el fichero que se arrastre...
    procedure AddFile(AFileName:String);
  end;

var
  Form3: TForm3;
  OldLBWindowProc: TWndMethod; // apuntador para el procedimiento original

implementation

{$R *.dfm}

uses
    ShellAPI;

procedure TForm3.AddFile(AFileName: String);
begin
  Caption := 'Fichero: ' + AFileName;
end;

procedure TForm3.FormCreate(Sender: TObject);
begin
  // Nos quedamnos con la referencia al procedimniento original
  OldLBWindowProc := pnlArrastrar.WindowProc;
  // Asignamos nuestro procedimiento personalizado para el panel
  pnlArrastrar.WindowProc := LBWindowProc;
  // Marcamos que queremos que el panel acepte ficheros (los que vamos a arrastrar)
  DragAcceptFiles(pnlArrastrar.Handle, True);
end;

procedure TForm3.LBWindowProc(var Message: TMessage);
begin
  // sólo queremor "redefinir" el procedimiento de "arrastrar fichreos..."
  if Message.Msg = WM_DROPFILES then
    WMDROPFILES(Message); // ejecutamos el nuestro
  // Ejecutamos siempre lo que hubiera antes...
  OldLBWindowProc(Message);
end;

procedure TForm3.WMDROPFILES(var Msg: TMessage);
var
  pcFileName: PChar;
  i, iSize, iFileCount: integer;
begin
  pcFileName := '';
  // número de ficheros arrastrados
  iFileCount := DragQueryFile(Msg.wParam, $FFFFFFFF, pcFileName, 255);
  for i := 0 to iFileCount - 1 do  begin
    iSize := DragQueryFile(Msg.wParam, i, nil, 0) + 1;
    pcFileName := StrAlloc(iSize);
    DragQueryFile(Msg.wParam, i, pcFileName, iSize);
    if FileExists(pcFileName) then begin
      AddFile(pcFileName); // Llamada a AddFile (lo que queramos hacer con el fichero)
    end;
    StrDispose(pcFileName);
  end;
  DragFinish(Msg.wParam);
end;

end.

javipes 02-04-2024 10:42:58

Aunque ya se ha respondido, te amplio algo que yo utilizo, por si te esclarece más, que yo la primera vez me costó un poco:

Por ejemplo, para que el receptor del drag-and-drop sea un tmemo en tu form, puedes ampliar la clase TMemo con
Código Delphi [-]
type   
  //la clase TMemo sera receptora del drag-and-drop   
  TMemo = class(Vcl.StdCtrls.TMemo)   protected     
    procedure WMDropFiles(var Message: TWMDropFiles); message WM_DROPFILES;     
    procedure    CreateWnd; override;     
    procedure DestroyWnd; override;   
  end;

y estos metodos escribirlos:
Código Delphi [-]
{$REGION 'Memo'}  
procedure TMemo.CreateWnd; 
begin   
  inherited;   
  DragAcceptFiles(Handle, true); 
end;  

procedure TMemo.DestroyWnd; 
begin   
  DragAcceptFiles(Handle, false);   
  inherited; 
end;  

procedure TMemo.WMDropFiles(var Message: TWMDropFiles); 
var   
  numfichs: integer;   
  fn: array[0..MAX_PATH-1] of char;   
  nomfichero,extension:string; 
begin    
  numfichs := DragQueryFile(Message.Drop, $FFFFFFFF, fn, MAX_PATH);   
  if numfichs <> 1 then   
  begin     
    MessageBox(Handle, 'Solo un fichero.', 'Error descarga', MB_ICONERROR);     
    Exit;   
  end;    
  if DragQueryFile(Message.Drop, 0, fn, MAX_PATH) = 0 then 
    Exit;    
  nomfichero := fn;   //contiene el path completo    
 //hacer lo que se quiera con el fichero o con el nombre   
end; 
{$ENDREGION 'Memo'}

con esto, cualquier tmemo que incluyas en tu form podra ser receptor de drag and drop, por ejemplo para cargar en el el contenido del fichero si es de tipo texto.
Tambien podrías cambiarlo para aplicarlo sobre un tedit y que el receptor fuera el tedit....

javipes 02-04-2024 10:45:19

Neftali, hemos 'chocado'.
Pero ¿porque no se ve mi codigo bien? cuando he previsualizado lo veía bien antes de enviarlo.....

Neftali [Germán.Estévez] 02-04-2024 10:50:16

Cita:

Empezado por javipes (Mensaje 555186)
Neftali, hemos 'chocado'.

Si, nos hemos pisado los mensajes..

Cita:

Empezado por javipes (Mensaje 555186)
Pero ¿porque no se ve mi codigo bien? cuando he previsualizado lo veía bien antes de enviarlo.....

Ya está corregido.
Es un error antiguo de vBulletin. A veces cuando se usa la vista previa, se hace un lío con las etiquetas...

javipes 02-04-2024 10:57:08

Cita:

Empezado por Neftali [Germán.Estévez] (Mensaje 555187)
Si, nos hemos pisado los mensajes..

Ya está corregido.
Es un error antiguo de vBulletin. A veces cuando se usa la vista previa, se hace un lío con las etiquetas...

gracias, maestro.


La franja horaria es GMT +2. Ahora son las 01:22:23.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi