如何支持自定义类型的文件拖放

wywry 2008-04-11 11:41:26
如题!
问题1:

要求在文件拖放到窗体上,能进行判断。如果不是我要的类型,则不充许拖放,光标显示为禁止状态。

我现在实现文件拖放是用如下方法,但是无法做到类型判断。



procedure TDesignFrm.FormCreate(Sender: TObject);
begin
DragAcceptFiles(Handle, True); //充许拖放
end;


procedure TDesignFrm.WMDropFiles(var Msg: Tmessage);
var
N,Count : Integer;
buffer : ARRAY[0..1024] OF Char;
Curwindow,PrevWindow,ParentWnd :THANDLE; //取得的窗口句柄
MousePoint:TPOINT;
bufClassName,bufClassCaption:array[0..255] of Char;

begin
WITH Msg DO
BEGIN
Count:=DragQueryFile(WParam, $FFFFFFFF, Nil,256);
FOR N := 0 TO Count-1 DO
BEGIN
DragQueryFile(WParam, N, Buffer, SizeOf(buffer));
ShowMessage(StrPas(Buffer)); //显示文件名称
END;
DragFinish(WParam); //拖放结束
END;
end;



问题2:

如何到到光标下控件的类名等(主要是Label,Image类),
其他类,我使用如下可以得到:

//得到光标处的控件
GetCursorPos(MousePoint);{获取光标的位置}
Curwindow:=WindowFromPoint(MousePoint);
GetClassName(Curwindow,bufClassName,255);
HandleEdit.Text:=IntToStr(Curwindow); {当前句柄}
ShowMessage(StrPas(bufClassName)); {类名}


谢谢!
...全文
115 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
genispan 2008-04-14
  • 打赏
  • 举报
回复
MARK
lake_cx 2008-04-14
  • 打赏
  • 举报
回复
对,那个是只能获取窗体的子控件的对象,而不能获取下级子控件的
wywry 2008-04-14
  • 打赏
  • 举报
回复
To 10楼:

这个办法获取自己的不错。但有个BUG,修改如下:


procedure TForm1.Button1Click(Sender: TObject);
begin
SetCaptureControl(Self);
end;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
AControl: TControl;
begin
ReleaseCapture;
// AControl := ControlAtPos(Point(X, Y), True, True);
AControl := ControlAtPos(ScreenToClient(Mouse.CursorPos), True, True); //修改后
if (AControl = nil) then Exit;
Text := AControl.Name;
end;
gingerlee 2008-04-14
  • 打赏
  • 举报
回复
帮顶
无条件为你 2008-04-12
  • 打赏
  • 举报
回复
10楼,你的代码只能取自己的程序,能不能取其它程序上面的图片对应的类名?
UndefinedCoder 2008-04-12
  • 打赏
  • 举报
回复
金山词霸是Hook的DrawText这样的API,或许还用了驱动吧。
lake_cx 2008-04-12
  • 打赏
  • 举报
回复
第二个问题:
没有Handle的窗体是没有Z序的,BringToFront对它无效。。。
要遍历的是遍历树,用Controls属性,而不是组件Components属性
就这样就行了,给你参考
procedure TForm1.Button1Click(Sender: TObject);
begin
SetCaptureControl(Self);
end;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
AControl: TControl;
begin
ReleaseCapture;
AControl := ControlAtPos(Point(X, Y), True, True);
if (AControl = nil) then Exit;
Text := AControl.Name;
end;
wywry 2008-04-12
  • 打赏
  • 举报
回复
我也想了想:如果用户一次性托动好多文件,
在其中有我想要的类型,也没有我想要的类型,
你不可能禁止吧,呵,自己过滤处理。

2.第二个问题还没有想到很好的办法!
无条件为你 2008-04-12
  • 打赏
  • 举报
回复
关于你的问题一,我换了个思路想了想,用钩子可以解决,不过麻烦的多,我认为实际功能并不值得花费如此代价。
lake_cx 2008-04-12
  • 打赏
  • 举报
回复
取其他程序的当然只能针对有Handle的,没Handle的,如果已知目标进程是Delphi写的话那就只能注入后获取了。。。
看楼主在用Components遍历,似乎不是想查其他进程中的啊。。。
其他程序的图片?其他程序有可能不是用的Image类啊,想VC中,人家一般就是用GDI画上去的,都没特定的窗体还有什么对应的类名?
  • 打赏
  • 举报
回复

2
那两个不是窗口控件,是自绘出来的,没有窗口。所以没窗口类。你可以用spy++试试看。
wywry 2008-04-11
  • 打赏
  • 举报
回复
置顶
无条件为你 2008-04-11
  • 打赏
  • 举报
回复
两个Image重叠,不管是谁,它们的类名都一样。用BringToFront的时候在后面也要加一句Update。
重叠是一种特殊情况,因为你限止必须是鼠标获取,所以重叠的问题解决不了。

你的问题一,WMDROPFILES事件只有在拖放后鼠标松开了才激发,所以你先做出响应光标状态有些困难,除非你找到与此类似的事件,比如鼠标拖着文件移动(释放之前)就可以触发。

再帮你顶下贴子。
wywry 2008-04-11
  • 打赏
  • 举报
回复
像金山词霸,他是怎么取Label上的Caption呢?
wywry 2008-04-11
  • 打赏
  • 举报
回复
谢谢各位!

问题1:
我感觉有必要。这样,用户拖放到界面上,如果显示为禁止的图标,他就明白,不充许接受这样的文件。
不需要这样的提示。像上面的,我也是这样做,但感觉不是很好。

问题2:
我现在也是用这样的方法判断。PtInRect.但是,如果两个Image有重叠的部分。而我又放到重叠的那一块。则无法
判断是哪一个。我查下资料,根据Components[Index]的Index值大小来判断。但当我把下面一个Image,用BringToFront
时,这个Index还是原来的那个。根据没有变化。还是程序刚运行时的值。有没有函数,当我使用BringToFront或
SendToBack时,能让这个Index值,重新更新一下呢?或都有什么更好的方法,知道当前重叠的,哪一个在上面呢?


pengxuan 2008-04-11
  • 打赏
  • 举报
回复

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, shellapi;

type
TForm1 = class(TForm)
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
private
procedure DropFiles(var Msg: TMessage); message WM_DropFILES;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.DropFiles(var Msg: TMessage);
var i, Count: integer;
buffer: array[0..1024] of Char;
begin
inherited;
Count := DragQueryFile(Msg.WParam, $FFFFFFFF, nil, 256); // 第一次调用得到拖放文件的个数
for i := 0 to Count - 1 do
begin
buffer[0] := #0;
DragQueryFile(Msg.WParam, i, buffer, sizeof(buffer)); // 第二次调用得到文件名称
if LowerCase(ExtractFileExt(buffer))='.txt' then
Memo1.Lines.Add(buffer)
else
ShowMessage('文件类型不对');
end;
end;

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

end.

无条件为你 2008-04-11
  • 打赏
  • 举报
回复
问题一:

你可以先用ExtractFileExt函数对拖入的文件进行扩展名过滤,得到你要的文件即可。例如
if ExtractFileExt(StrPas(Buffer))='.txt' then 这里处理TXT文件。

如果不是你要的类型,则拖放上去也无效。“直接不充许拖放,光标显示为禁止状态”没必要啊。WMDROPFILES事件只有在拖放后鼠标松开了才激发,你要先得到文件名可能有些困难,或者有其它方法吧,关注!

问题二:

你的取类名方法也是我用的方法。至于Image无法用此法获取类名。其实可以这样得到:先遍历窗口所有控件,然后分别判断鼠标的所在位置是否在某个控件的位置对应的矩形框内。
判断一个坐标是否在一个矩形区域内可以用函数来实现:PtInRect(矩形,坐标点)
NTKO附件管理控件(多文件上传下载在线编辑扫描控件)是拥有完全独立知识产权的多附件上传控件.使用NTKO附件管理控件[多文件上传控件],能够在浏览器中启动原始文件对应的应用程序,对图像文件,OFFICE文件,文本文件,AUTOCAD等任何文件进行编辑,打印,扫描,阅读,并保存到Web服务器。实现文档的方便编辑和统一管理。支持拖放,修改提示保存,多线程下载上传,多种视图模式,智能提交等多种特性。 http://www.ntko.com在线演示展示了NTKO 附件管理控件常用功能。该技术能让您更简单快速的将控件集成到您的产品中。 NTKO附件管理控件支持包括DOMINO在内的IIS,Websphere,Apache等所有后台WEB服务器和支持PHP,ASP,JSP,C#,VB.NET,DOMINO等各种web编程语言。并且可以在浏览器中通过JScript或者VBScrip使用控件提供的属性和方法控制文档操作。在DOMINO中,比INOTES使用更加方便快捷。集成程度更好。 详细功能列表: 1、 平台支持功能 ★ 支持多种后台web服务器和开发语言 支持DOMINO,IIS,WebLogic,Apache等多种后台web服务器和ASP,JSP,C#,VB.NET,PHP等多种后台开发语言。在任何后台web服务器都无需后台安装特别的组件或者软件。 ★ 与DOMINO服务器无缝集成 无需后台组件,和DOMINO服务器可无缝集成。比INOTES使用更加方便,开发更加快捷。 2、 网络及协议功能支持支持智能提交 控件使用我们独创的智能提交技术,支持将附件文件和开发者指定的FORM中的数据一次性上传到服务器。 ★ 多线程上传下载,性能更高 控件完全采用多线程方式上传下载,可以更好的改善用户体验,达到更高性能。 ★ 支持UTF-8网页编码 通过IsUseUTF8Data属性,可以支持UTF-8编码网页的智能提交 ★ 支持网络缓冲大小自定义 自适应的网络传输速度,并且在特殊网络中允许用户自定义网络传输缓冲的大小 ★ 支持HTTP协议,HTTPS OVER SSL协议 对HTTPS协议的支持使得可以创建更加安全的应用。并且自动支持Session Cookie。使用当前页面的Session Cookie和服务器进行交互。 3、 界面行为支持支持鼠标拖放 用户可以通过拖放增加本地文件到控件中,或者通过拖放从控件中拖放文件到本地资源管理器或者其他支持拖放的应用程序。 ★ 支持多种视图模式 支持大图标,小图标,详细信息显示等多种模式。支持多种排序方式。 ★ 支持自定义工具栏 通过附件提供的事件和方法,用户可以自定义工具栏执行调用。 ★ 支持直接编辑文件 用户可双击附件直接打开编辑,或者使用右键菜单选择打开或者打印,系统自动下载到临时目录并执行相关操作。 ★ 支持提示文件修改 如果下载到本地的文件被修改,控件自动提示并可以保存回服务器。 ★ 支持编辑,打开,打印等多种操作方式L 可对附件进行编辑,打开,打印,打开文件夹,查看属性等多种操作。 4、 编程支持支持简洁高效的编程接口 可使用Javascript和VBScript对控件进行编程。 ★ 支持自定义列,并且可以隐藏预定义的某些列 控件支持最多5个自定义列。让开发者能够有更多的控制。 ★ 支持设定自定义用户数据并显示 控件可以为自定义列设定自定义的用户数据并显示。并且能够自动排序。 ★ 支持过滤文件大小,文件总数量,以及文件类型 通过控件的BeforeFileAdded事件,用户可以限定允许添加到控件的文件类型,大小,以及数量。 ★ 支持多个事件 通过控件选择文件,添加文件之前,选择数量变化等多个事件,用户可以对控件实施更多控制 5、 安全及其他支持 ★ 安全可靠 系统不会自动增加未经用户授权的文件。在打开可执行文件时会自动提示警告。 ★ 支持直接从扫描仪输入文件[需要购买扫描支持模块] 通过AddFromScanner方法,控件支持从扫描仪中直接扫描图片到控件中。[需要购买扫描支持模块]

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧