Solved

Drag and drop on an icon

Posted on 1998-05-09
23
203 Views
Last Modified: 2010-04-03
With Win 3.1 and Delphi 1, how can you drop a file on a minimized application and have it automatically load?
0
Comment
Question by:swright243
  • 12
  • 6
  • 2
  • +3
23 Comments
 
LVL 8

Expert Comment

by:ZifNab
ID: 1343939
hi swright243,

maybe these things make you a little bit wiser :

sunsite.icm.edu.pl/delphi/ftp/d10free/copyfile.zip
sunsite.icm.edu.pl/delphi/ftp/d10free/dragger.zip
sunsite.icm.edu.pl/delphi/ftp/d10free/dropfile.zip

Regards, ZiF.
0
 

Author Comment

by:swright243
ID: 1343940
I have those already. It is not drag and drop that's a problem. It's dropping on a minimize app that is a problem. I never had this problem with Borland Pascal 7.0 and I don't with Delphi 3.

If you know how to drop a file on a minimized app and have it load I would be very grateful.

Stephen

0
 
LVL 1

Expert Comment

by:Greedy
ID: 1343941
humm...What do you mean by drop a file on a minimized app.  If the app is minimized isn't it already loaded...or do you mean you want it to load with the file that you just dropped on it?  In that case you'll have to provide me with a bit more information of what the minimized program is. and the interfaces that you have for it.

0
 

Author Comment

by:swright243
ID: 1343942
Imagine a text editor with the following function for loading a file:

procedure TFrameForm.WMDropFiles(var Msg: TMessage);
var
   N : Word;
   Num : Word;
   buff : array[0..80] of char;
   FName: string;
begin
   Drop := Msg.wParam;
   Msg.Result := 0;                
   Num := DragQueryFile(Msg.wParam, $FFFF, NIL, 0);
   if Num <> 0 then
   for N := 0 to pred(Num) do begin
     DragQueryFile(Msg.wParam, N, @buff, pred(sizeof(buff)));
     FName := strpas(buff);
     OpenEditor(FName);
   end;
end;

procedure TFrameForm.OpenEditor(AFileName: string);
var EditForm: TEditForm;
begin
    EditForm := TEditForm.Create(Application);
    EditForm.Open(AFileName);
    EditForm.Show;
end;

A similar function with Borland Pascal 7.0 would also enable drag and drop on the minimized application (remember this is for Windows 3.1), but Delphi 1 doesn't automatically enable this.
With Win95 and Delphi 3 you have to add a function like this to get it to work, but this same trick doesn't work with Delphi 1:

procedure TForm1.FormCreate(Sender: TObject);
begin
   DragAcceptFiles(Handle, True);
   If ParamCount <> 0 then               Memo1.Lines.LoadFromFile(ParamStr(1));
   Memo1.Modified := False;
end;


0
 

Author Comment

by:swright243
ID: 1343943
Adjusted points to 300
0
 

Author Comment

by:swright243
ID: 1343944
Adjusted points to 400
0
 

Expert Comment

by:dr_gonzo
ID: 1343945
I'm not sure about 3.1 but in win95 it is not possible to drop on a minimized program. If this is the case in 3.1 as well I think it should be covered in the api help files under DropFiles.
0
 

Expert Comment

by:hyperion66
ID: 1343946
What kind of documents, text files?
0
 

Author Comment

by:swright243
ID: 1343947
Yes, text files in the example I have described here, but any kind of file for any reason.  Hyperion66, do you think you may know how to do this?

By the way, with Win95 it is possible to drop a file on a minimized application or on a Desktop shortcut.


0
 

Author Comment

by:swright243
ID: 1343948
Come on experts! Show me your stuff! I have to know the answer to this question. I have tried everything and looked everywhere.
Help! Help! Help! Help! Help! Help! Help! Help! Help! Help!
0
 
LVL 1

Expert Comment

by:Greedy
ID: 1343949
Dude, when did this thing go to 1000 points...ok fine, I will try to find some way to make this work. I think I have somthing here in this Undocumented feature of Win 3.xx It reads as follows...

------ Microsoft Internal Document

Install Windows 95 to correct the horid oversites of win 3.1

------ End Microsoft Document

Damn, I don't think that helps us much does it?

I would bet the main reason that no one can help you is that for the past 3 years we've been working with 95 and NT.  But I think I still have a 486 at home that's running workgroups so I'll give it a wack...I guess it's worth it now.

0
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 

Author Comment

by:swright243
ID: 1343950
No need to preach to the converted! I was a beta tester for Win 95 back in '94. Nevertheless, I need to know this thing since I have clients still using Windows 3.1 and will probably continue to do so for quite awhile.

0
 
LVL 3

Expert Comment

by:rickpet
ID: 1343951
Okay the problem is that drag drop message is not going to the application but to the form, and since the form is not active it never gets the message...

You need to set an application message...

Application.OnMessage := DragMessage;

procedure TForm1.DragMessage(Var msg: TMsg;Var handled: boolean);
begin
  If Msg. message = WM_DropFiles then
  begin
    standard drag drop code here...
    handled := true;
  end;
end;
0
 
LVL 3

Expert Comment

by:rickpet
ID: 1343952
Rickpet: I don't get it. What is wrong with this?
type
  TForm1 = class(TForm)
    Label1: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
    procedure WMDropFiles(var Msg: TMessage);{d&d}
    message wm_Dropfiles;{d&d}
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Drop: longint;
implementation
uses ShellAPI{d&d};

{$R *.DFM}

{d&d}
procedure TForm1.WMDropFiles(var Msg: TMessage);
var
   buff : array[0..80] of char;
begin
   Msg.Result := 0;
   Drop := Msg.wParam;
   DragQueryFile(Msg.wParam, 0, buff, pred(sizeof(buff)));
   Label1.caption := strpas(buff);
   BringToFront;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
   DragAcceptFiles(Handle, True);
end;



0
 

Author Comment

by:swright243
ID: 1343953
This returns the name of a dropped file as a label caption.
0
 

Author Comment

by:swright243
ID: 1343954
Remember in Delphi their is a hidden window the application.  For the application needs to know that it is handeling the message.  Windows sends the WMDropFile to the application window.  The application has no code to handle the WMDropFile message, there is no active forms so it just swallows the message and goes on.  Now in your code the form is handeling the message.  If the form is visible, when the application receives the WMDropFile it passes the message down to the form.  The form has tied in to WMDropfile and handles it.  But if the form is minimized (which means the app is minimized), the application never passes the message down to the form because it is not active.  So the form never receives the message to accept the drag drop.

So add an Applicaion message and tie into it. This tells your application to call DragMessage everytime it gets a message, and of course DragMessage is going to only check for WMDropFile messages.
 
Application.OnMessage := DropMessage;//drop message a better name

procedure TForm1.DropMessage(Var msg: TMsg;Var handled: boolean);


Rick Peterson
0
 
LVL 3

Expert Comment

by:rickpet
ID: 1343955
I don't get it. The following is a very simple unit accepting drag and drop, but not when minimized.
unit Unit1;

interface

uses
  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
    procedure WMDropFiles(var Msg: TMessage);{d&d}
    message wm_Dropfiles;{d&d}
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Drop: longint;
implementation
uses ShellAPI{d&d};

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
   DragAcceptFiles(Handle, True);
end;

{d&d}
procedure TForm1.WMDropFiles(var Msg: TMessage);
var
   buff : array[0..80] of char;
begin
   Msg.Result := 0;
   Drop := Msg.wParam;
   DragQueryFile(Msg.wParam, 0, buff, pred(sizeof(buff)));
   Label1.caption := strpas(buff);
   BringToFront;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
   DragFinish(Drop);
end;

end.
unit Unit1;

interface

uses
  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
    procedure WMDropFiles(var Msg: TMessage);{d&d}
    message wm_Dropfiles;{d&d}
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Drop: longint;
implementation
uses ShellAPI{d&d};

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
   DragAcceptFiles(Handle, True);
end;

{d&d}
procedure TForm1.WMDropFiles(var Msg: TMessage);
var
   buff : array[0..80] of char;
begin
   Msg.Result := 0;
   Drop := Msg.wParam;
   DragQueryFile(Msg.wParam, 0, buff, pred(sizeof(buff)));
   Label1.caption := strpas(buff);
   BringToFront;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
   DragFinish(Drop);
end;

end.

0
 

Author Comment

by:swright243
ID: 1343956
Try this...I havn't tested in Win 3.1 but it should work...again...you tie into OnMessage of TApplication

Rick


unit Unit1;
interface

uses
  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Label1: TLabel;
     procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure DropFiles(Var msg: TMsg;Var handled: boolean);
  end;

var
  Form1: TForm1;
  Drop: longint;
implementation
uses ShellAPI{d&d};

{$R *.DFM}

procedure TForm1.DropFiles(Var msg: TMsg;Var handled: boolean);
var
   buff : array[0..80] of char;

begin
  If Msg. message = WM_DropFiles then
  begin
   Drop := Msg.wParam;
   DragQueryFile(Msg.wParam, 0, buff, pred(sizeof(buff)));
   Label1.caption := strpas(buff);
   BringToFront;
   handled := true;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
   Application.OnMessage := DropFiles;
   DragAcceptFiles(Handle, True);
end;

{d&d}


procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
   DragFinish(Drop);
end;

end.

0
 
LVL 3

Expert Comment

by:rickpet
ID: 1343957
Your proposed solution does not compile. I tried a few variations on it without success. It fails at this line:
 If Msg. message = WM_DropFiles then

with error 5 syntax error

The problem I think is that wm_dropfiles is not a TMsg but a field in the TMessage object.

0
 

Author Comment

by:swright243
ID: 1343958
You have included WinTypes and messages???Did you change the parameters of procedure TForm1.DropFiles(Var msg: TMsg;Var handled: boolean).  This should be of type TMsg, to be compatible with Application.OnMessage,  not TMessage.

Taken from Delphi 1 (identical in Delphi 3)
From messages.pas

  wm_DropFiles        = $0233;
{ Generic window message record }


  PMessage = ^TMessage;
  TMessage = record
    Msg: Cardinal;
    case Integer of
      0: (
        WParam: Word;
        LParam: Longint;
        Result: Longint);
      1: (
        WParamLo: Byte;
        WParamHi: Byte;
        LParamLo: Word;
        LParamHi: Word;
        ResultLo: Word;
        ResultHi: Word);
  end;

from wintypes.pas

type
  PMsg = ^TMsg;
  TMsg = record
    hwnd: HWnd;
    message: Word;
    wParam: Word;
    lParam: LongInt;
    time: Longint;
    pt: TPoint;
  end;

0
 
LVL 3

Expert Comment

by:rickpet
ID: 1343959
This compiles under Delphi 1...
unit Udrop16;

interface

uses
  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure DropFiles(Var msg: TMsg;Var handled: boolean);

  end;

var
  Form1: TForm1;

implementation
uses ShellAPI{d&d};
var
  Drop: longint;

{$R *.DFM}

procedure TForm1.DropFiles(Var msg: TMsg;Var handled: boolean);
var
   buff : array[0..80] of char;
begin
  If Msg. message = WM_DropFiles then
  begin
   Drop := Msg.wParam;
   DragQueryFile(Msg.wParam, 0, buff, pred(sizeof(buff)));
   Label1.caption := strpas(buff);
   BringToFront;
   handled := true;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Application.OnMessage := DropFiles;
  DragAcceptFiles(Handle, True);

end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  DragFinish(Drop);
end;

end.
 
0
 
LVL 3

Accepted Solution

by:
rickpet earned 1000 total points
ID: 1343960
Your solution worked after I added these two lines:

procedure TForm1.FormCreate(Sender: TObject);
begin
  Application.OnMessage := DropFiles;
  DragAcceptFiles(Application.Handle, True);
  DragAcceptFiles(Form1.Handle, True);
end;

The OnMessage was the key and your explanation of how it works helped me a lot. Good job--you deserve a A+!

swright243@aol.com

0
 

Author Comment

by:swright243
ID: 1343961
Glad you where able to get it to work...
thought I was going crazy... =)-~

Wow...4000pts???

Rick
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
This video discusses moving either the default database or any database to a new volume.
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now