如题!
问题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.   


    2
    那两个不是窗口控件,是自绘出来的,没有窗口。所以没窗口类。你可以用spy++试试看。
      

  2.   

    问题一:你可以先用ExtractFileExt函数对拖入的文件进行扩展名过滤,得到你要的文件即可。例如
    if ExtractFileExt(StrPas(Buffer))='.txt' then 这里处理TXT文件。如果不是你要的类型,则拖放上去也无效。“直接不充许拖放,光标显示为禁止状态”没必要啊。WMDROPFILES事件只有在拖放后鼠标松开了才激发,你要先得到文件名可能有些困难,或者有其它方法吧,关注!问题二:你的取类名方法也是我用的方法。至于Image无法用此法获取类名。其实可以这样得到:先遍历窗口所有控件,然后分别判断鼠标的所在位置是否在某个控件的位置对应的矩形框内。
    判断一个坐标是否在一个矩形区域内可以用函数来实现:PtInRect(矩形,坐标点)
      

  3.   


    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.
      

  4.   

    谢谢各位!问题1:
      我感觉有必要。这样,用户拖放到界面上,如果显示为禁止的图标,他就明白,不充许接受这样的文件。
      不需要这样的提示。像上面的,我也是这样做,但感觉不是很好。问题2:
      我现在也是用这样的方法判断。PtInRect.但是,如果两个Image有重叠的部分。而我又放到重叠的那一块。则无法
    判断是哪一个。我查下资料,根据Components[Index]的Index值大小来判断。但当我把下面一个Image,用BringToFront
    时,这个Index还是原来的那个。根据没有变化。还是程序刚运行时的值。有没有函数,当我使用BringToFront或
    SendToBack时,能让这个Index值,重新更新一下呢?或都有什么更好的方法,知道当前重叠的,哪一个在上面呢? 
        
      

  5.   

    像金山词霸,他是怎么取Label上的Caption呢?
      

  6.   

    两个Image重叠,不管是谁,它们的类名都一样。用BringToFront的时候在后面也要加一句Update。
    重叠是一种特殊情况,因为你限止必须是鼠标获取,所以重叠的问题解决不了。你的问题一,WMDROPFILES事件只有在拖放后鼠标松开了才激发,所以你先做出响应光标状态有些困难,除非你找到与此类似的事件,比如鼠标拖着文件移动(释放之前)就可以触发。再帮你顶下贴子。
      

  7.   

    第二个问题:
    没有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;
      

  8.   

    金山词霸是Hook的DrawText这样的API,或许还用了驱动吧。
      

  9.   

    取其他程序的当然只能针对有Handle的,没Handle的,如果已知目标进程是Delphi写的话那就只能注入后获取了
    看楼主在用Components遍历,似乎不是想查其他进程中的啊
    其他程序的图片?其他程序有可能不是用的Image类啊,想VC中,人家一般就是用GDI画上去的,都没特定的窗体还有什么对应的类名?
      

  10.   

    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;