通过delphi获取活动窗口中所选文件的名称和扩展名

时间:2016-12-11 08:43:35

标签: delphi

我想通过delphi7在explorer中显示所选文件的名称和扩展名。

我使用下面的代码显示活动窗口的显示标题,但我需要在活动窗口中选择文件名。

function ActiveCaption: string;

var
  Handle: THandle;
  Len: LongInt;
  Title: string;

begin
  Result := '';
  Handle := GetForegroundWindow;
  if Handle <> 0 then
  begin
    Len := GetWindowTextLength(Handle) + 1;
    SetLength(Title, Len);
    GetWindowText(Handle, PChar(Title), Len);
    ActiveCaption := TrimRight(Title);
  end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Label1.Caption := ActiveCaption;
end;

1 个答案:

答案 0 :(得分:0)

我知道的唯一方法是使用Active-X IShellWindows和IWebBrowser接口。

首先,您必须导入“Microsoft Internet Controls”Active-X(通过组件菜单)。通过这个你将获得一个名为“SHDocVW_TLB”的单位。将此单元和ActiveX单元放在uses子句中。

您可以使用以下两个函数从提供的窗口句柄中检索所选文件:

如果给定句柄属于资源管理器窗口,则第一个函数会进行粗略测试

function isexplorerwindow(exwnd: hwnd): boolean;
var
  p: array[0..max_path] of Char;
begin
  GetClassName(exwnd, p, SizeOf(p));
  result := ((strcomp(p, 'CabinetWClass') = 0) or (strcomp(p, 'ExploreWClass') = 0));
end;

第二个函数检索第n个选定文件的名称:

function getexplorerselectedfile(exwnd: hwnd; nr: integer): string;
var
  pvShell: IShellWindows;
  pvWeb2: IWebBrowser2;
  ovIE: OleVariant;
  psp: IServiceProvider;
  psb: IShellBrowser;
  isw: IShellView;
  ido: IDataObject;
  FmtEtc: TFormatEtc;
  Medium: TStgMedium;
  dwcount: integer;
  n: integer;
  p: array[0..max_path] of Char;
  s: string;
  found: boolean;
begin
  found := false;
  result := '';
  s :='';
  try
    pvShell := CoShellWindows.Create;
    for dwcount := 0 to Pred(pvShell.count) do
    begin
      ovIE := pvShell.Item(dwcount);
      if (ovIE.hwnd = exwnd) or ((exwnd = 0) and isexplorerwindow(ovIE.hwnd)) then
      begin
        found := true;
        if (IDispatch(ovIE).QueryInterface(IWebBrowser2, pvWeb2) = S_OK) then
        begin
          psp := (pvWeb2 as IServiceProvider);
          psp.QueryService(IID_IShellBrowser, IID_IShellBrowser, psb);
          psb.QueryActiveShellView(isw);
          if isw.GetItemObject(SVGIO_SELECTION, IDataObject, pointer(ido)) = S_OK then
          begin
            try
              FmtEtc.cfFormat := CF_HDROP;
              FmtEtc.ptd := nil;
              FmtEtc.dwAspect := DVASPECT_CONTENT;
              FmtEtc.lindex := -1;
              FmtEtc.tymed := TYMED_HGLOBAL;
              ido.GetData(FmtEtc, Medium);
              GlobalLock(Medium.hGlobal);
              try
                n := DragQueryFile(Medium.hGlobal, $FFFFFFFF, nil, 0);
                if nr < n then
                begin
                  DragQueryFile(Medium.hGlobal, nr, p, max_path);
                  s := strpas(p);
                end;
              finally
                DragFinish(Medium.hGlobal);
                GlobalUnLock(Medium.hGlobal);
              end;
            finally
              ReleaseStgMedium(Medium);
            end;
          end;
          pvWeb2 := nil;
        end;
      end;
      ovIE := Unassigned;
      if found then
        break;
    end;
    pvShell := nil;
  finally
    result := s;
  end;
end;

要测试此代码,请创建一个新项目并在表单上放置一个按钮和一个备忘录。

将以下单位添加到uses子句中:

USES SHDocVW_TLB, ShlObj, activex, shellapi;

并将此代码添加到按钮事件处理程序:

PROCEDURE TForm2.Button1Click(Sender: TObject);
VAR
  wnd, exwnd: hwnd;
  n: integer;
  s: STRING;
BEGIN
  exwnd := 0;
  wnd := getwindow(getdesktopwindow, gw_child);
  REPEAT
    IF isexplorerwindow(wnd) THEN
    BEGIN
      exwnd := wnd;
      break;
    END;
    wnd := getwindow(wnd, gw_hwndnext);
  UNTIL (wnd = 0) OR (exwnd <> 0);
  IF exwnd <> 0 THEN
  BEGIN
    n := 0;
    REPEAT
      s := getexplorerselectedfile(exwnd, n);
      memo1.Lines.Add(s);
      inc(n);
    UNTIL s = '';
  END;
END;

如果按下按钮,备忘录将包含它找到的第一个打开资源管理器窗口的选定文件。当然,您应该打开一个资源管理器窗口,至少选择一个文件。