How to get captions of actual windows currently running?

11,707

Solution 1

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;
  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;

  SetLength(s, GetWindowTextLength(hwnd));
  GetWindowText(hwnd, PChar(s), Length(s)+1);
  Writeln(s);
end;

begin
  EnumWindows(@EnumWindowsProc, 0);
end.

Solution 2

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)

Share:
11,707
Martin Melka
Author by

Martin Melka

Updated on June 09, 2022

Comments

  • Martin Melka
    Martin Melka about 2 years

    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!

  • Martin Melka
    Martin Melka about 13 years
    This is it. Thank you for the MSDN link too. I didn't know the criteria for the windows.
  • Server Overflow
    Server Overflow almost 11 years
    @David Heffernan - After a quick look I realized that unfortunately your code does not show some windows such as BSPlayer and Kaspersky KIS and Delphi.
  • David Heffernan
    David Heffernan almost 11 years
    Why not? What does the debugger tell you?
  • user30478
    user30478 over 5 years
    It missed Windows calculator.