如题!
问题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)); {类名}
谢谢!
问题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)); {类名}
谢谢!
2
那两个不是窗口控件,是自绘出来的,没有窗口。所以没窗口类。你可以用spy++试试看。
if ExtractFileExt(StrPas(Buffer))='.txt' then 这里处理TXT文件。如果不是你要的类型,则拖放上去也无效。“直接不充许拖放,光标显示为禁止状态”没必要啊。WMDROPFILES事件只有在拖放后鼠标松开了才激发,你要先得到文件名可能有些困难,或者有其它方法吧,关注!问题二:你的取类名方法也是我用的方法。至于Image无法用此法获取类名。其实可以这样得到:先遍历窗口所有控件,然后分别判断鼠标的所在位置是否在某个控件的位置对应的矩形框内。
判断一个坐标是否在一个矩形区域内可以用函数来实现:PtInRect(矩形,坐标点)
unit Unit1;interfaceuses
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.
我感觉有必要。这样,用户拖放到界面上,如果显示为禁止的图标,他就明白,不充许接受这样的文件。
不需要这样的提示。像上面的,我也是这样做,但感觉不是很好。问题2:
我现在也是用这样的方法判断。PtInRect.但是,如果两个Image有重叠的部分。而我又放到重叠的那一块。则无法
判断是哪一个。我查下资料,根据Components[Index]的Index值大小来判断。但当我把下面一个Image,用BringToFront
时,这个Index还是原来的那个。根据没有变化。还是程序刚运行时的值。有没有函数,当我使用BringToFront或
SendToBack时,能让这个Index值,重新更新一下呢?或都有什么更好的方法,知道当前重叠的,哪一个在上面呢?
重叠是一种特殊情况,因为你限止必须是鼠标获取,所以重叠的问题解决不了。你的问题一,WMDROPFILES事件只有在拖放后鼠标松开了才激发,所以你先做出响应光标状态有些困难,除非你找到与此类似的事件,比如鼠标拖着文件移动(释放之前)就可以触发。再帮你顶下贴子。
没有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;
看楼主在用Components遍历,似乎不是想查其他进程中的啊
其他程序的图片?其他程序有可能不是用的Image类啊,想VC中,人家一般就是用GDI画上去的,都没特定的窗体还有什么对应的类名?
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;