向各位高手请教,我想在程序里加上这样一个功能,从外部脱拽文件到程序里,如果文件是预期的,程序将自动打开该文件,并运行.(类似于,媒体播放软件,从外边脱拽影音文件,将自动被播放)
解决方案 »
- 你们都不用TSqlConnection吗?是不是都用ADO呀
- 求Delphi制作和调用COM组件的一个例子和思想
- 复杂SQL问题,求救!!!
- 怎么样将自定义的xml文件导入到数据库中?
- 如何判断鼠标左键是否按下(或者右键)。
- 请问哪里有delphi开发人事工资管理的论文
- 谁知道怎样编程实现远程控制另外一台计算机?(在线)
- 请问怎么从Tdatetimepicker控件中提取出对应的年、月、日?
- 明天去一家通讯公司应聘delphi程序员!
- 如何调用EXE或DLL程序,使被调用程序是调用程序的MDI中的一个子窗口?
- 简单问题多送分!关于dbtext,在线等。
- 在ExpressQuantumGrid4.2中如何设置能在底部显示统计数据之类的东东,如合计、平均值等,同时如何汉化出现的英文。
1 、使程序能接收 WM_DROPFILES 消息 ;
2 、在 WM_DROPFILES 消息的响应程序中取得被拖放的文件名,然后进行相应处理。
使程序能接收 WM_DROPFILES 消息
首先,需要调用 WINAPI DragAcceptFiles(handle,True); 其中的 handle 为要接收 WM_DROPFILES 消息的控件的 handle 。例如,我们要让 Memo1 接收该消息,则调用形式为 DragAcceptFiles(Form1.Memo1.handle,True);
其次,要在收到 WM_DROPFILES 消息时做处理,需要用自己的代码替换该控件的 WindowProc 方法。在替换前,要保存原来的 WindowProc 方法以便处理其他消息。为此,我们定义一个全程变量 OldWndProc:TWndMethod 保存原来的 WindowProc 方法 ; 再在窗体定义的 Public 段定义了一个方法 procedure DragFileProc(var Message: TMessage); 作为新的 WindowProc 方法。在 Unit 的 implementation 段内写下 DragFileProc 的完整代码,当消息为其他消息地调用 OldWndProc 来处理,当消息为 WM_DROPFILES 时,作相应处理。
取得被拖放的文件名,然后进行相应处理
在 WM_DROPFILES 消息的响应程序中,先调用 DragQueryFile(Message.wParam,$FFFFFFFF,nil,0) 返回值为拖放的文件总数。再循环调用 DragQueryFile(Message.wParam,i,buf,len); 取得拖放文件全名。 i 为 0 到拖放的文件总数减 1 的值,buf 为 Pchar 型,是存放文件名的缓冲区,len 为文件名缓冲区长度。至于取得文件名后的处理,就悉听尊便了。一定要注意 Pchar 和 String 的转换!
以下为程序片段
type
TForm1 = class(TForm)
.
.
.
btnEnableDragFile: TButton;
.
.
.
procedure btnEnableDragFileClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure DragFileProc(var Message: TMessage);
end;
implementation
var OLDWndProc:TWndMethod;
.
.
.
procedure TForm1.btnEnableDragFileClick(Sender: TObject);
begin
DragAcceptFiles(self.MemoDrag.Handle,true);
OLDWndProc:=self.MemoDrag.WindowProc;
// 保存原来的 WindowProc
self.MemoDrag.WindowProc:=self.DragFileProc;
// 设置新的 WindowProc
end;
procedure TForm1.DragFileProc(var Message:TMessage) ;
var i:word;
p:array[0..254]of char;
begin
if Message.Msg=WM_DropFiles
then
begin
self.MemoDrag.Clear;
i:=DragQueryFile(Message.WParam,$FFFFFFFF,nil,0);
// 取得拖放文件总数
for i:=0 to i-1 do
begin
DragQueryFile(Message.WParam,i,p,255);
// 取得拖放文件名
self.MemoDrag.Lines.add(StrPas(p));
// 对文件的处理
end;
end
else // 其他消息,调用原来的处理程序
OLDWndProc(Message);
end;
.
.
.
begin
Dragacceptfiles(form1.handle,true);
end;procedure tform1.wmdropfiles(var message:tmessage);
var
p:array[0..254] of char;
i:word;
begin
inherited;
memo1.lines.clear;
{$IFDEF WIN32}
I:=dragqueryfile(message.wparam,$ffffffff,nil,0);
{$ELSE}
I:=dragqueryfile(message.wparam,$ffff,nil,0);
{$ENDIF}
caption:=inttostr(i);
for i:=0 to i-1 do
begin
dragqueryfile(message.wparam,i,p,255);
memo1.lines.add(strpas(p));
end;
end;
end.
使用C 语言格式, 1. VOID DragAcceptFiles(
HWND hWnd,
BOOL fAccept );
---- DragAcceptFiles 函数是用来为拖放文件作初始化, 它的第一个参
数hWnd 指明目标窗体的句柄, 第二个参数fAccept 是一个布尔型变
量, 为True 时则hWnd 所指向的窗体可以接受拖放的文件.
2. UINT DragQueryFile(
HDROP hDrop,
UINT iFile,
LPTSTR lpszFile,
UINT cch )
---- DragQueryFile 函数用来查询拖放文件的文件名, 其本身的返回值
是一个无符号整数, 参数hDrop 是一个存放所拖放文件名称的数
据结构的句柄, 也就是文件名缓冲区的句柄, 需要从Windows 消息
WM_DROPFILES 中获得.iFile 指明所要查询文件的序号, 它有两种取
值方式,1. 值为十六进制数FFFFFFFF 时,DragQueryFile 的返回值为所拖
放文件的数目;2. 值在0 到拖放文件总数之间时, DragQueryFile 函数将
相应序号的文件名放入参数lpszFile 所指向的缓冲区内, 若此时
lpszFile 的值为NULL, 则DragQueryFile 会返回相应文件名的长度. 参数
cch 决定缓冲区的长度, 由于Windows95 支持长文件名, 它的值不能
设得太小.
3.VOID DragFinish( HDROP hDrop );
---- 使用DragFinish 函数告诉Windows 拖放操作结束, 使其释放文件名
缓冲区, 它的参数hDrop 与DragQueryFiles 函数中的一样, 也由Windows 消
息WM_DROPFILES 的hDrop 参数获得.
---- 下面将结合一个我编写的例子来说明具体的编程步骤. 本例
中窗体上放置了一个Memo 控件memo1, 在Windows 中选取数个文件拖
至程序窗体放下, 则memo1 中便会显示所选文件的总数及每个文
件的各自名称. 程序代码如下: unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
procedure Label3Click(Sender: TObject);
procedure Label4Click(Sender: TObject);
private
PROCEDURE FinishDropped ( VAR Msg : TMessage );
Message WM_DropFiles ;
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses shellapi;
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
//initialize the drag process;
DragAcceptFiles(Handle,True);
end;
Procedure TForm1.FinishDropped ( VAR Msg : TMessage ) ;
Var
hDrop : THandle ;
iFile:Uint;
lpszFile :pchar;
CountOfFiles : integer ;
FileIndex : integer ;
ReSults : string ;
begin
hDrop := Msg.WParam ;
getmem(pchar,255);
iFile:=$FFFFFFFF;
CountOfFiles := DragQueryFile(hDrop,iFile,lpszFile,254);
ReSults := '' ;
for FileIndex := 0 CountOfFiles-1 do
begin
iFile:=FileIndex;
DragQueryFile(hDrop,iFile,lpszFile,254);
// Get the File names by order;
ReSults := ReSults + #13#10 + lpszFile ;
end ;
Dispose(lpszFile);
memo1.Clear;
memo1.lines.add(' 拖放了'+IntToStr
(CountOfFiles) + ' 个文件:' + ReSults );
DragFinish ( hDrop);
end ;
end.
---- 从以上代码可以看出, 首先应该在窗体的OnCreate 事件中用
DragAccepteFiles 来说明程序窗体支持文件的拖放.
---- 另外, 除了调用以上3 个API 函数, 在Delphi 中还应编写针对
WM_DROPFILES 的消息处理过程FinishDropped, 截取了WM_DROPFILES, 由
其wParam 才能够得到文件名缓冲区的句柄. ---- 在FinishDropped 过程里, 有两处DragQueryFile 函数, 第一处其iFile 参数
为$FFFFFFFF, 得到拖放文件的总数; 第二处iFile 参数为每个文件的
序号, 则可在lpszFile 中可得到相应的文件名. 当然, 为了明显的对比
iFile 的值对DragQueryFile 函数的影响, 这里的代码不够简练. 有一点
需要注意的是,lpszFile 是Pchar 型的变量, 为了程序运行安全, 它使用
前需用getmem 过程为其分配内存, 使用后再用dispose 过程将其释放.
在FinishDropped 过程的最后, 用DragFinish 函数释放文件名缓冲区