如何获取当前运行的实际窗口的标题?

发布于 2024-11-06 01:37:33 字数 2532 浏览 0 评论 0原文

我有一个问题:我只需要获取列表中所有窗口的标题,我所说的标题是指“记事本”、“总指挥官” - 只是窗口顶部边缘显示的文本。

到目前为止我已经到达这里

function EnumWindowProc(hHwnd: HWND; lParam : integer): boolean; stdcall;
var
  pPid : DWORD;
  title, ClassName : string;
begin
  if (hHwnd=NULL) then
  begin
    result := false;
  end
  else
  begin
    GetWindowThreadProcessId(hHwnd,pPid);
    SetLength(ClassName, 255);
    SetLength(ClassName,
              GetClassName(hHwnd,
                           PChar(className),
                           Length(className)));
    SetLength(title, 255);
    SetLength(title, GetWindowText(hHwnd, PChar(title), Length(title)));
    OptionsForm.ListBox1.Items.Add(title);
    OptionsForm.Memo1.Lines.Add
      ('Class Name = ' + className +
       '; Title = ' + title +
       '; HWND = ' + IntToStr(hHwnd) +
       '; Pid = ' + IntToStr(pPid));
    Result := true;
  end;
end;

但是,它返回各种“窗口”,不同的表单焦点等。我怎样才能只获得“主要”窗口?

以下是结果示例:

Class Name = Shell_TrayWnd; Title = ; HWND = 65898; Pid = 3776
Class Name = CiceroUIWndFrame; Title = CiceroUIWndFrame; HWND = 65976; Pid = 3776
Class Name = THelpInsightWindowImpl; Title = HelpInsightWindow; HWND = 1577734; Pid = 4852
Class Name = THelpInsightWindowImpl; Title = HelpInsightWindow; HWND = 591660; Pid = 4852
Class Name = TTokenWindow; Title = CodeParamWindow; HWND = 985436; Pid = 4852
Class Name = TaskSwitcherWnd; Title = Přepínání úloh; HWND = 66824; Pid = 3776
Class Name = tooltips_class32; Title = ; HWND = 198982; Pid = 1768
Class Name = tooltips_class32; Title = ; HWND = 66046; Pid = 3776
Class Name = _SearchEditBoxFakeWindow; Title = ; HWND = 66024; Pid = 3776
Class Name = tooltips_class32; Title = ; HWND = 66008; Pid = 3776
Class Name = tooltips_class32; Title = ; HWND = 131538; Pid = 3776
Class Name = Desktop User Picture; Title = Magicmaster; HWND = 65982; Pid = 3776
Class Name = DV2ControlHost; Title = Nabídka Start; HWND = 65978; Pid = 3776
Class Name = tooltips_class32; Title = ; HWND = 327840; Pid = 1768
Class Name = tooltips_class32; Title = ; HWND = 460808; Pid = 1768
Class Name = CTSCTooltip; Title = ; HWND = 266710; Pid = 2792
Class Name = Auto-Suggest Dropdown; Title = ; HWND = 69884; Pid = 4732
Class Name = Auto-Suggest Dropdown; Title = ; HWND = 69802; Pid = 4732
Class Name = TaskbarNotifierClass; Title = DAP Message Center; HWND = 68924; Pid = 4732
Class Name = tooltips_class32; Title = ; HWND = 134356; Pid = 1992
Class Name = ATKOSD; Title = ATKOSD; HWND = 65884; Pid = 3636

提前谢谢您!

I have a question: I simply need to get captions of all windows in a list, by captions I mean the "Notepad", "Total Commander" - simply the text shown in the top-edge of a window.

So far I've gotten here

function EnumWindowProc(hHwnd: HWND; lParam : integer): boolean; stdcall;
var
  pPid : DWORD;
  title, ClassName : string;
begin
  if (hHwnd=NULL) then
  begin
    result := false;
  end
  else
  begin
    GetWindowThreadProcessId(hHwnd,pPid);
    SetLength(ClassName, 255);
    SetLength(ClassName,
              GetClassName(hHwnd,
                           PChar(className),
                           Length(className)));
    SetLength(title, 255);
    SetLength(title, GetWindowText(hHwnd, PChar(title), Length(title)));
    OptionsForm.ListBox1.Items.Add(title);
    OptionsForm.Memo1.Lines.Add
      ('Class Name = ' + className +
       '; Title = ' + title +
       '; HWND = ' + IntToStr(hHwnd) +
       '; Pid = ' + IntToStr(pPid));
    Result := true;
  end;
end;

But well, it returns all kinds of "windows", different focuses of forms etc. How can I get only the "main" ones?

Here is a sample of the results:

Class Name = Shell_TrayWnd; Title = ; HWND = 65898; Pid = 3776
Class Name = CiceroUIWndFrame; Title = CiceroUIWndFrame; HWND = 65976; Pid = 3776
Class Name = THelpInsightWindowImpl; Title = HelpInsightWindow; HWND = 1577734; Pid = 4852
Class Name = THelpInsightWindowImpl; Title = HelpInsightWindow; HWND = 591660; Pid = 4852
Class Name = TTokenWindow; Title = CodeParamWindow; HWND = 985436; Pid = 4852
Class Name = TaskSwitcherWnd; Title = Přepínání úloh; HWND = 66824; Pid = 3776
Class Name = tooltips_class32; Title = ; HWND = 198982; Pid = 1768
Class Name = tooltips_class32; Title = ; HWND = 66046; Pid = 3776
Class Name = _SearchEditBoxFakeWindow; Title = ; HWND = 66024; Pid = 3776
Class Name = tooltips_class32; Title = ; HWND = 66008; Pid = 3776
Class Name = tooltips_class32; Title = ; HWND = 131538; Pid = 3776
Class Name = Desktop User Picture; Title = Magicmaster; HWND = 65982; Pid = 3776
Class Name = DV2ControlHost; Title = Nabídka Start; HWND = 65978; Pid = 3776
Class Name = tooltips_class32; Title = ; HWND = 327840; Pid = 1768
Class Name = tooltips_class32; Title = ; HWND = 460808; Pid = 1768
Class Name = CTSCTooltip; Title = ; HWND = 266710; Pid = 2792
Class Name = Auto-Suggest Dropdown; Title = ; HWND = 69884; Pid = 4732
Class Name = Auto-Suggest Dropdown; Title = ; HWND = 69802; Pid = 4732
Class Name = TaskbarNotifierClass; Title = DAP Message Center; HWND = 68924; Pid = 4732
Class Name = tooltips_class32; Title = ; HWND = 134356; Pid = 1992
Class Name = ATKOSD; Title = ATKOSD; HWND = 65884; Pid = 3636

Thank you in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

秉烛思 2024-11-13 01:37:34

重要信息包含在 MSDN 主题中,描述任务栏。本质上,您需要枚举顶级窗口并挑选出那些可见、无主且具有 WS_EX_APPWINDOW 窗口样式的窗口。

该程序向您展示了它是如何完成的:

program EnumTaskbarWindows;

{$APPTYPE CONSOLE}

uses
  SysUtils, Windows;

function EnumWindowsProc(hwnd: HWND; lParam: LPARAM): BOOL; stdcall;
var
  s: string;
  len: Integer;
  IsVisible, IsOwned, IsAppWindow: Boolean;
begin
  Result := True;//carry on enumerating

  IsVisible := IsWindowVisible(hwnd);
  if not IsVisible then
    exit;

  IsOwned := GetWindow(hwnd, GW_OWNER)<>0;
  if IsOwned then
    exit;

  IsAppWindow := GetWindowLongPtr(hwnd, GWL_STYLE) and WS_EX_APPWINDOW<>0;
  if not IsAppWindow then
    exit;
  
  len := GetWindowTextLength(hwnd);
  if len = 0 then
    exit;
  SetLength(s, len);
  GetWindowText(hwnd, PChar(s), len+1);
  Writeln(s);
end;

begin
  EnumWindows(@EnumWindowsProc, 0);
end.

The important information is contained in the MSDN topic describing the taskbar. Essentially you need to enumerate the top-level windows and pick out those that are visible, unowned and have the WS_EX_APPWINDOW window style.

This program shows you how it is done:

program EnumTaskbarWindows;

{$APPTYPE CONSOLE}

uses
  SysUtils, Windows;

function EnumWindowsProc(hwnd: HWND; lParam: LPARAM): BOOL; stdcall;
var
  s: string;
  len: Integer;
  IsVisible, IsOwned, IsAppWindow: Boolean;
begin
  Result := True;//carry on enumerating

  IsVisible := IsWindowVisible(hwnd);
  if not IsVisible then
    exit;

  IsOwned := GetWindow(hwnd, GW_OWNER)<>0;
  if IsOwned then
    exit;

  IsAppWindow := GetWindowLongPtr(hwnd, GWL_STYLE) and WS_EX_APPWINDOW<>0;
  if not IsAppWindow then
    exit;
  
  len := GetWindowTextLength(hwnd);
  if len = 0 then
    exit;
  SetLength(s, len);
  GetWindowText(hwnd, PChar(s), len+1);
  Writeln(s);
end;

begin
  EnumWindows(@EnumWindowsProc, 0);
end.
云雾 2024-11-13 01:37:34

您想要检查这些窗口的属性。例如,排除任何不可见的窗口。您可以使用 GetWindowInfo 来执行此操作。要查找的属性:无标题(dwStyle 中缺少 WS_CAPTION),或不可见(WS_VISIBLE 标志)。您可能还想检查移出屏幕的窗口,但这有点棘手(可能有多个监视器,即使偏移量为负)

You want to check the properties of these windows. For instance, exclude any window that's not visible. You do this with GetWindowInfo. The properties to look for: no caption (missing WS_CAPTION in dwStyle), or not visible (WS_VISIBLE flag). You might also want to check for windows that are moved off screen, but that's slightly tricky (there could be multiple monitors, even at negative offsets)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文