Как найти все окна процесса

I need to capture particular windows of 3rd party process. I can find main window handle as Process.MainWindowHandle, but what I can use to list other windows?

I am using C# / .NET

asked Feb 17, 2010 at 14:30

st78's user avatar

Community's user avatar

answered Feb 17, 2010 at 14:34

Svetlozar Angelov's user avatar

3rd party aplication launched other windows not as child windows.

It is possible to find out what is structure using Spy++ tool which comes with Visual Studio.

After this, I was able to find necessary window using FindWindowEx function using WindowClassName (taken from Spy++):
lastWindows = FindWindowEx(IntPtr.Zero, lastWindows, m.WindowClassName, null);

answered Feb 24, 2010 at 17:28

st78's user avatar

st78st78

7,95811 gold badges49 silver badges68 bronze badges

Use the Win32 API EnumWindows (and if you want EnumChildWindows)

[DllImport("user32.dll", CharSet=CharSet.Auto, SetLastError=true)]
public static extern bool EnumWindows(EnumThreadWindowsCallback callback, IntPtr extraData);

Then check which process each window belongs to by using the Win32 API GetWindowThreadProcessId

[DllImport("user32.dll", CharSet=CharSet.Auto, SetLastError=true)]
public static extern int GetWindowThreadProcessId(HandleRef handle, out int processId);

answered Mar 28, 2010 at 3:59

Brian R. Bondy's user avatar

Brian R. BondyBrian R. Bondy

337k124 gold badges592 silver badges635 bronze badges

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
namespace WindowsFormsApplication1
{
    using System;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Windows.Forms;
 
    public partial class Form1 : Form
    {
        delegate bool EnumWindowsProc ( IntPtr hWnd, IntPtr lParam );
 
        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool EnumWindows ( EnumWindowsProc lpEnumFunc, IntPtr lParam );
 
        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool EnumChildWindows ( IntPtr hWndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam );
 
        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool IsWindowVisible ( IntPtr hWnd );
 
        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr GetParent ( IntPtr hWnd );
 
        [DllImport("user32.dll", SetLastError = true)]
        static extern int GetWindowText ( IntPtr hWnd, StringBuilder lpString, int nMaxCount );
 
        [DllImport("user32.dll", SetLastError = true)]
        static extern int GetClassName ( IntPtr hWnd, StringBuilder lpString, int nMaxCount );
 
        [DllImport("user32.dll", SetLastError = true)]
        static extern int GetWindowTextLength ( IntPtr hWnd );
 
        public Form1()
        {
            InitializeComponent();
        }
 
        private void button1_Click ( object sender, EventArgs e ) {
            TreeNode node;
            treeView1.BeginUpdate();
            {
                treeView1.Nodes.Clear();
                checkBox1.Enabled = false;
                EnumWindows(new EnumWindowsProc(( hWnd, lParam ) => {
                    if (!checkBox1.Checked || IsWindowVisible(hWnd)) {
                        node = new TreeNode(string.Format("{0:X8} "{1}" {2}",
                            hWnd.ToInt32(), GetWindowText(hWnd), GetWindowClass(hWnd)));
                        AddChildWindow(hWnd, node);
                        treeView1.Nodes.Add(node);
                    }
                    return true;
                }), IntPtr.Zero);
                checkBox1.Enabled = true;
            }
            treeView1.EndUpdate();
        }
 
        void AddChildWindow ( IntPtr hWndParent, TreeNode node ) {
            EnumChildWindows(hWndParent, new EnumWindowsProc(( hWnd, lParam ) => {
                if (GetParent(hWnd) != hWndParent)
                    return true;
 
                if (!checkBox1.Checked || IsWindowVisible(hWnd)) {
                    // Информация выводится ввиде: HANDLE [HEX] "ЗАГОЛОВОК" КЛАСС
                    AddChildWindow(hWnd, node.Nodes.Add(string.Format("{0:X8} "{1}" {2}",
                        hWnd.ToInt32(), GetWindowText(hWnd), GetWindowClass(hWnd))));
                }
                return true;
            }), IntPtr.Zero);
        }
        // Получаем заголовок окна
        string GetWindowText ( IntPtr hWnd ) {
            int len = GetWindowTextLength(hWnd) + 1;
            StringBuilder sb = new StringBuilder(len);
            len = GetWindowText(hWnd, sb, len);
            
            return sb.ToString(0, len);
        }
        // Получаем класс окна
        string GetWindowClass ( IntPtr hWnd ) {
            int len = 260;  // В принципе можно и побольше взять,
                            // но я ещё не видел классы с именем
                            // длиннее 260 символов.
            StringBuilder sb = new StringBuilder(len);
            len = GetClassName(hWnd, sb, len);
            
            return sb.ToString(0, len);
        }
    }
}

 
-=SS=- ©
 
(2004-12-15 18:17)
[0]

Собственно ИМХО может кто знает какие – то апишные функции
зараннее благодарен


 
Суслик ©
 
(2004-12-15 18:19)
[1]

можно по хандлу окна узнать принадлежит ли он процесу

The GetWindowThreadProcessId function retrieves the identifier of the thread that created the specified window and, optionally, the identifier of the process that created the window.

т.е. можно все окна пребрать.

Может иначе можно, я не знаю.


 
Юрий Зотов ©
 
(2004-12-15 18:31)
[2]

> -=SS=- ©   (15.12.04 18:17)

> Можно ли по ID просесса узнать хендл окна этого просесса?

Задумайтесь на минутку – а что, если процесс породил несколько окон? Какое из них Вам нужно? А ведь такое бывает очень часто.

Как сказано в [1], можно перебрать все окна процесса. Но для того, чтобы выделить из них нужное Вы должны знать об этом окне еще что-то, кроме того, что оно принажлежит данномк процессу.


 
-=SS=- ©
 
(2004-12-15 19:18)
[3]

Огромное спасибо за направление но всё же
DWORD GetWindowThreadProcessId(

   HWND hWnd, // handle of window
   LPDWORD lpdwProcessId  // address of variable for process identifier
  );

что опередавать в hWnd если у меня никакого окна нету предаю 0 ноль и возвращает 🙁


 
Суслик ©
 
(2004-12-15 19:21)
[4]

Ну напрагись, задай вопрос нормально :)) С знаком вопроса, с запятыми и пр.
Я не издеваюсь, я вопроса не понял. Честно. 🙂


 
-=SS=- ©
 
(2004-12-15 19:36)
[5]

Функция GetWindowThreadProcessId требует handle окна.
Что туда передавать ? если я не знаю handl-ов окон мне их нужно получить.
Для теста передаю туда 0 на выходе получаю 0.
Что делать ?
  Зараннее спасибо!


 
Суслик ©
 
(2004-12-15 19:49)
[6]

1. Ты знаешь id процесса.
2. Для того, чтобы найти все окна, принадлежащие данному процессу, нужно перебрать все окна в системе. Т.е. получить последовательно handle всех окон.
3. Получив handle очередного окна ты используя указанную мной функцию проверяешь принадлежит ли окно процессу (заметь, что нужно передавать указатель на id процесса, а не брать результат функции – это стандратная ошибка).

Теперь о том, как перебрать окна. Ответ – не знаю, т.к. никогда не делал этого. Но уверен, что если начать копать, начиная с функции win api enumwindows, то обязательно добъешься успеха.


 
-=SS=- ©
 
(2004-12-15 20:09)
[7]

Теперь понял … Большое спасибо за наводку


 
Leonid Troyanovsky ©
 
(2004-12-15 21:20)
[8]


> -=SS=- ©   (15.12.04 19:36) [5]
> Функция GetWindowThreadProcessId требует handle окна.
> Что туда передавать ? если я не знаю handl-ов окон мне их
> нужно получить.


var
 h: HWND;
 pid: DWord;

h := FindWindowEx(0, 0, nil, nil);
while (h <> 0) do
  begin
     GetWindowThreadProcessId(h, @pid);
     if (pid = pi.dwProcessId) then
       {окно принадлежит потоку запущенного процесса}
     h := FindWindowEx(0, h, nil, nil); // ищем следующее окно
  end;


С уважением, LVT.


 
GuAV ©
 
(2004-12-15 21:56)
[9]

IMHO лучше найти все потоки процесса и искать окно в потоках с помощью EnumThreadWindows. Тем более что не всегда у процесса больше одного потока и не всегда во вторичных потоках есть окна – задача может упростися.


 
Piter ©
 
(2004-12-15 22:14)
[10]

procedure SearchHandle(ProcessId: DWORD; CallbackFunction: TFNWndEnumProc;
   UnicID: LPARAM);
var
 HSnapShot: THandle;
 te: TThreadEntry32;
begin
 //нам нужен снимок потоков
 HSnapShot:=CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
 try
   //перед использованием TThreadEntry32 нужно заполнить поле dwSize
   te.dwSize := sizeof(TThreadEntry32);
   // если первая запись о потоках получена - продолжаем
   if Thread32First(HSnapShot, te) then
     repeat
       // если этот поток относится к интересующему нас процессу, то
       // перечисляем все окна, созданные этим потоком
       if te.th32OwnerProcessID = ProcessId then
         EnumThreadWindows(te.th32ThreadID, CallbackFunction, UnicID);
// получаем запись о следующем потоке, если не получаем - выходим из цикла
     until ( not Thread32Next(HSnapShot,te) );
 finally
   closehandle(HSnapShot); // закрываем описатель снимка
 end;
end;

function EnumWnd(Handle: hwnd; UnicID: LPARAM): boolean; stdcall;
begin
 Result := True;
 PostMessage(Handle, WM_CLOSE, 0, 0);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 SearchHandle(GetCurrentProcessId, @EnumWnd, 0);
end;

————————————————————-

SearchHandle ищет все окна заданного процесса. При нахождении очередного окна вызывается функция CallbackFunction, которой в данном случае является  EnumWnd. Она посылает WM_CLOSE всем окнам.

Так как вызывается:
SearchHandle(GetCurrentProcessId, @EnumWnd, 0);
то код приводит к посылке сообщений WM_CLOSE всем окнам данного процесса…


 
Leonid Troyanovsky ©
 
(2004-12-15 23:03)
[11]


> Piter ©   (15.12.04 22:14) [10]

> function EnumWnd(Handle: hwnd; UnicID: LPARAM): boolean;
> stdcall;

 BOOL CALLBACK EnumThreadWndProc
 Хотя, в данном случае это, возможно, не принципиально,
 но, вообще-то, надо поаккуратней с хидерами.


С уважением, LVT.

PS  Кстати, Toolhelp32 отсутствует в NT4.


 
Piter ©
 
(2004-12-16 00:42)
[12]

Leonid Troyanovsky ©   (15.12.04 23:03) [11]
BOOL CALLBACK EnumThreadWndProc
Хотя, в данном случае это, возможно, не принципиально,
но, вообще-то, надо поаккуратней с хидерами.

а что не так? Я не понял…


 
Игорь Шевченко ©
 
(2004-12-16 10:43)
[13]

Piter ©   (16.12.04 00:42) [12]


> а что не так? Я не понял…

Я бы написал вместо


> function EnumWnd(Handle: hwnd; UnicID: LPARAM): boolean;
> stdcall;

function EnumWnd(Handle: hwnd; UnicID: LPARAM): BOOL; stdcall;

С уважением,


 
-=SS=- ©
 
(2004-12-16 10:46)
[14]


> Piter ©   (15.12.04 22:14) [10]

Толково…. спасибо…
Осталась маленькая проблемка … ну это я думаю что порывшись в хелпе найду что – то подходящее … Теперь надо будет определять если процесс имеет окна, то как определить главное окно ?


 
Piter ©
 
(2004-12-16 20:16)
[15]

Ах да, для моего примера [10] нужно подключить юнит TLHelp32

Leonid Troyanovsky ©   (15.12.04 23:03) [11]
Игорь Шевченко ©   (16.12.04 10:43) [13]

понял

-=SS=- ©   (16.12.04 10:46) [14]
Теперь надо будет определять если процесс имеет окна, то как определить главное окно ?

не знаю. И вообще сомневаюсь, что в WinApi есть понятие “главное окно”.

Лучше объясни задачу – зачем тебе главное окно? Видимо, ты что-то не так понимаешь…


 
Leonid Troyanovsky ©
 
(2004-12-16 21:17)
[16]


> Piter ©   (16.12.04 20:16) [15]
> Ах да, для моего примера [10] нужно подключить юнит TLHelp32

Это само собой. Но, этим ты не отвертишься 😉
Формально, NT4 еще имеет право на жизнь, а там такого
понятия, как ToolHelp functions, нет.
Т.е., включаешь ремарку “исключая NT4”.


С уважением, LVT


 
-=SS=- ©
 
(2004-12-16 22:34)
[17]

Незнаю почему но под DELPHI 7 TollHelp32 не работает … а вот на 5 Delphi работает … и даже неизвестно почему


 
Piter ©
 
(2004-12-16 23:09)
[18]

-=SS=- ©   (16.12.04 22:34) [17]
Незнаю почему но под DELPHI 7 TollHelp32 не работает

все работает…


 
Piter ©
 
(2004-12-16 23:12)
[19]

И вместо абстрактного “не работает” почему бы не сказать где именно затык?

P.S. Так как у меня уровень телепатии уже второго уровня, попробую сказать – ты точно в function EnumWnd поставил директиву stdcall;


 
-=SS=- ©
 
(2004-12-17 10:37)
[20]

Я конечно извеняюсь но причем тут EnumWnd.

begin
 H := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
 Memo1.Clear;
 If Process32First(H, P) then
   Memo1.Lines.Add(P.szExeFile)
 until Process32Next(H, P) = False;

Этот код на D5 работает т.е показывает всё процессы, а на D7 не работает т.е не показывает ни одной записи (WIN XP)
кстати Директива stdcall стоит но она используется пожже, но всё равно все работает (Под D5)


 
Piter ©
 
(2004-12-17 19:30)
[21]

Ну и какой смысл в молчанку играть? Почему информацию надо вытягивать, как будто это мне нужно? 🙂

ЧТО возвращает CreateToolhelp32Snapshot? Если ошибочный Handle – что возвращает GetLastError?

а-а-а-а-а-а-а-а…. гы гы.

begin
H := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
Memo1.Clear;
If Process32First(H, P) then
  Memo1.Lines.Add(P.szExeFile)
until Process32Next(H, P) = False;

Нда, я плакаль. Предлагаю найти самому ошибку.

P.S. А также неплохо было бы узнать – откуда ты это собственно взял, если в [10] я привел рабочий код? Из моего FAQ”а что ли?

Тупой Copy-Paste приводит к ошибкам 🙂


 
Piter ©
 
(2004-12-17 20:50)
[22]

Сори, это я уже лажанулся. Ты просто переделал пример для поиска процессов. Ок, тогда остаются вопросы:

Piter ©   (17.12.04 19:30) [21]
Ну и какой смысл в молчанку играть? Почему информацию надо вытягивать, как будто это мне нужно? 🙂

ЧТО возвращает CreateToolhelp32Snapshot? Если ошибочный Handle – что возвращает GetLastError?


 
GuAV ©
 
(2004-12-17 23:22)
[23]

-=SS=- ©   (16.12.04 10:46) [14]
Теперь надо будет определять если процесс имеет окна, то как определить главное окно ?

Если под “главным окном” понимать окно для которого создаётся кнопка на панели задач, то можно проверить (с пом GetWindowLong) extended style на наличие признака кнопки на панели задач (WS_EX_APPWINDOW).


 
Игорь Шевченко ©
 
(2004-12-17 23:53)
[24]

GuAV ©   (17.12.04 23:22) [23]

У окон, отображаемых на Taskbar не обязательно имеется стиль  WS_EX_APPWINDOW. Точнее, большинство отображаемых на таскбаре окон этого стиля не имеет 🙂

С уважением,


 
Piter ©
 
(2004-12-18 00:44)
[25]

GuAV ©   (17.12.04 23:22) [23]

имхо, первое окно, созданное приложением и есть “главное”, то есть отображается на Панели Задач


 
GuAV ©
 
(2004-12-18 00:44)
[26]

Игорь Шевченко ©   (17.12.04 23:53) [24]

Да..

А как тогда определить отображается окно на taskbar ?

WS_EX_APPWINDOW
Forces a top-level window onto the taskbar when the window is visible.


 
Игорь Шевченко ©
 
(2004-12-18 00:54)
[27]

GuAV ©   (18.12.04 00:44) [26]


> А как тогда определить отображается окно на taskbar ?

http://www.schevchenko.net.ru/SRC/EnumFunctions_60.zip

(Только сделал апгрейд, файлы черт знает где, прошу прощения, что приходится ссылку на сайт давать)

С уважением,


 
GuAV ©
 
(2004-12-18 01:28)
[28]


> http://www.schevchenko.net.ru/SRC/EnumFunctions_60.zip

Мой склероз. Я это смотрел несколько дней назад.

Кстати, Ваш критерий тоже неточен 🙂

Проверку из EnumFunctions_60
if (WindowOwner = 0) AND
    ((ExStyle AND WS_EX_TOOLWINDOW) = 0) AND
    ((WinStyle AND WS_VISIBLE) <> 0) then

не проходит такое окно

 CreateWindowEx(WS_EX_APPWINDOW or WS_EX_TOOLWINDOW,
   "BUTTON", "I""m on taskbar", WS_VISIBLE, 0, 0, 0, 0, HWND_DESKTOP, 0, 0, 0);


 
Игорь Шевченко ©
 
(2004-12-18 01:56)
[29]

GuAV ©   (18.12.04 01:28) [28]

Спасибо. К сожалению, я практически не обновляю сайт.

Проверка, очевидно должна выглядеть так (надо проверить):

if (WindowOwner = 0) and ((WinStyle and WS_VISIBLE) <> 0) and
  (((ExStyle and WS_EX_TOOLWINDOW) = 0) or ((ExStyle and WS_EX_APPWINDOW) <> 0)) then

С уважением,


 
Piter ©
 
(2004-12-18 02:21)
[30]

GuAV ©   (18.12.04 1:28) [28]

а что ты скажешь на:

Piter ©   (18.12.04 0:44) [25]
имхо, первое окно, созданное приложением и есть “главное”, то есть отображается на Панели Задач


 
Leonid Troyanovsky ©
 
(2004-12-18 13:56)
[31]


> Игорь Шевченко ©   (18.12.04 01:56) [29]

> Проверка, очевидно должна выглядеть так (надо проверить):
>
> if (WindowOwner = 0) and ((WinStyle and WS_VISIBLE) <> 0)
> and
>   (((ExStyle and WS_EX_TOOLWINDOW) = 0) or ((ExStyle and
> WS_EX_APPWINDOW) <> 0)) then

Проверка должна выглядеть так (можешь проверить):


function IsTaskbarBtnExist(h: HWND): Boolean;
var
 exstyle: Longint;
begin
 Result:= IsWindowVisible(h);
 if Result then
   begin
     exstyle := GetWindowLong(h, GWL_EXSTYLE);
     Result := exstyle and WS_EX_APPWINDOW <> 0;
     if not Result and
        (exstyle and WS_EX_TOOLWINDOW = 0) then
       Result := GetWindowLong(h, GWL_HWNDPARENT) = 0;
    end;
end;


С уважением, LVT.


 
Leonid Troyanovsky ©
 
(2004-12-18 14:04)
[32]


> Piter ©   (18.12.04 02:21) [30]
> GuAV ©   (18.12.04 1:28) [28]
>
> а что ты скажешь на:
>
> Piter ©   (18.12.04 0:44) [25]
> имхо, первое окно, созданное приложением и есть “главное”,
> то есть отображается на Панели Задач

В отсутствии определения “главное окно” любое высказывание
может быть представлено как истинное.


С уважением, LVT.

PS Собс-но, проще руководстваться целью: “что нужно от
этого окна”.


 
GuAV ©
 
(2004-12-18 17:45)
[33]

Piter ©   (18.12.04 2:21) [30]
а что ты скажешь на:

Piter ©   (18.12.04 0:44) [25]
имхо, первое окно, созданное приложением и есть “главное”, то есть отображается на Панели Задач

То что имеет значение не порядок, а стили и владалец.
В VCL приложении обычно ни одна форма не видна на TaskBar, для этого исспользуется окно Application.Handle.

type
 TForm1 = class(TForm)
 private
   { Private declarations }
 protected
   procedure CreateParams(var Params: TCreateParams); override;
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.CreateParams(var Params: TCreateParams);
begin
 inherited;
 // любая из нижеследуючих строк приводит к появлению формы на taskbar
 Params.WndParent := HWND_DESKTOP;
 Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
end;

Немного поэксперементировав пришел к выводу, что проверка должна выглядеть так:
if (WindowOwner = 0) and ((WinStyle and WS_VISIBLE) <> 0) and ((WinStyle and WS_CHILD) = 0) and
 (((ExStyle and WS_EX_TOOLWINDOW) = 0) or ((ExStyle and WS_EX_APPWINDOW) <> 0)) then


 
GuAV ©
 
(2004-12-18 18:06)
[34]

GuAV ©   (18.12.04 17:45) [33]
, что проверка должна выглядеть так:

Хотя нет, правильно в [29]


 
Leonid Troyanovsky ©
 
(2004-12-18 18:31)
[35]


> GuAV ©   (18.12.04 17:45) [33]
..
> Немного поэксперементировав пришел к выводу, что проверка
> должна выглядеть так:

От:Tomas Restrepo (winder@bigfoot.com)
Тема:Re: How to EnumWindows…
Группы новостей:microsoft.public.win32.programmer.kernel
Дата:1999/04/06

Maurizio,

You have to do some test on each of the windows returned by EnumWindows() to
decide wheter to show it or not. The test were described by Jeffrey Richter in
the Nov “97 issue of MSJ. Quoting:

“The rules the taskbar uses to decide whether a button should be shown
for a window are really quite simple, but are not well documented.
When you create a window, the taskbar examines the window”s extended
style to see if either the WS_EX_APPWINDOW (defined as 0x00040000) or
WS_EX_TOOLWINDOW (defined as 0x00000080) style is turned on. If
WS_EX_APPWINDOW is turned on, the taskbar shows a button for the
window, and if WS_EX_ TOOLWINDOW is turned on, the taskbar does not
show a button for the window. You should never create a window that
has both of these extended styles.

You can create a window that doesn”t have either of these styles. If a
window has neither style, the taskbar decides to create a button if
the window is unowned and does not create a button if the window is
owned.

One final note: before making any of the above tests, the taskbar
first checks to see if a window has the standard WS_VISIBLE window
style turned on. If this style bit is off, the window is hidden; the
taskbar never shows a button for a hidden window. Only if the
WS_VISIBLE style bit is on will the taskbar check the WS_EX_APPWINDOW,
WS_ EX_TOOLWINDOW, and window ownership information.”

Which, BTW,  David Lowndes has posted in this group several times in the past


Tomas Restrepo


С уважением, LVT.


 
GuAV ©
 
(2004-12-18 18:43)
[36]

Leonid Troyanovsky ©   (18.12.04 18:31) [35]

Неточность в том, что если окно WS_CHILD, то никакие  WS_EX_APPWINDOW не помогут – можете проверить.

PS: интересный спор ни о чём.


 
Piter ©
 
(2004-12-18 18:51)
[37]

Leonid Troyanovsky ©   (18.12.04 14:04) [32]
В отсутствии определения “главное окно” любое высказывание
может быть представлено как истинное

не в этом суть:


> > имхо, первое окно, созданное приложением и есть
>”главное”,
> > то есть отображается на Панели Задач


 
GuAV ©
 
(2004-12-18 19:01)
[38]

2 Piter ©   (18.12.04 18:51) [37]
GuAV ©   (18.12.04 17:45) [33]


 
GuAV ©
 
(2004-12-18 19:02)
[39]

GuAV ©   (18.12.04 17:45) [33]
То что имеет значение не порядок, а стили и владалец.


 
Leonid Troyanovsky ©
 
(2004-12-18 19:05)
[40]


> GuAV ©   (18.12.04 18:43) [36]

> Неточность в том, что если окно WS_CHILD, то никакие  WS_EX_APPWINDOW
> не помогут – можете проверить.

А причем тут WS_CHILD?
Речь шла про EnumWindows & top-level windows.


> PS: интересный спор ни о чём.

Это называется обсуждением, IMHO.


С уважением, LVT.


Как посмотреть запущенные процессы

Если ваш компьютер вдруг стал тяжело работать и долго думать, того и гляди зависнет, значит, в вашей операционной системе выполняется одновременно слишком много процессов. Для того чтобы контролировать текущие исполняемые процессы, в операционную систему встроена полезная программа «Диспетчер задач», или Task Manager.

Как посмотреть запущенные процессы

Вам понадобится

  • – компьютер;
  • – доступ к диспетчеру задач.

Инструкция

Нажимаете правой кнопкой мыши по нижней панели инструментов, на которой обычно группируются минимизированные окна ваших программ. В появившемся меню выбираете опцию «Запустить диспетчер задач». Также можете нажать комбинацию клавиш ALT+CTRL+DELETE. Это стандартный способ вызова службы «Диспетчера задач». Вы можете в любое время вызвать данную службу и закрыть любые программы, процессы, увеличить приоритет.

Ищете вкладку «Процессы» и переходите на нее. Здесь отображается список всех процессов, выполняющихся в вашей системе в момент работы. Это могут быть специальные службы для работы по сети, процессы приложений, системные процессы и, конечно, вирусы. В столбцах по вертикали ведется учет, сколько памяти и производительности процессора они используют. Нажмите на вкладку «Имя образа» и весь список перестроится по алфавиту.

Выбираете знакомые процессы. Это будут сокращенные названия ваших программ. Если сомневаетесь, в крайнем правом столбце указывается полное название программы текущего процесса.

Выполняете нужное действие над процессом в диспетчере. Чаще всего, нам нужно завершить исполнение какой-либо программы и освободить поглощаемые ей системные ресурсы. Учтите, что программа, запустившая данный процесс, будет закрыта аварийно и данные (или документы) не будут сохранены.

Диспетчер задач предоставляет полную картину происходящего на вашем компьютере. Если вы научитесь разбираться в исполняемых процессах, вы научитесь контролировать системные ресурсы вашей операционной системы. Однако не стоит особо копаться в данном разделе, так как можно отключить важные процессы, которые необходимы для полноценной работы компьютера.

Войти на сайт

или

Забыли пароль?
Еще не зарегистрированы?

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Для получения списка окон вам придется прибегнуть к WinApi функции EnumWindows. Описание к этой функции вы можете найти здесь.

Полагаю вы хотите найти конкретное окошко, по этому прилагаю пример:

[DllImport("user32.dll")]
private static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam);

// Delegate to filter which windows to include 
public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);

/// <summary> Get the text for the window pointed to by hWnd </summary>
public static string GetWindowText(IntPtr hWnd)
{
    int size = GetWindowTextLength(hWnd);
    if (size > 0)
    {
        var builder = new StringBuilder(size + 1);
        GetWindowText(hWnd, builder, builder.Capacity);
        return builder.ToString();
    }

    return String.Empty;
}

/// <summary> Find all windows that match the given filter </summary>
/// <param name="filter"> A delegate that returns true for windows
///    that should be returned and false for windows that should
///    not be returned </param>
public static IEnumerable<IntPtr> FindWindows(EnumWindowsProc filter)
{
  IntPtr found = IntPtr.Zero;
  List<IntPtr> windows = new List<IntPtr>();

  EnumWindows(delegate(IntPtr wnd, IntPtr param)
  {
      if (filter(wnd, param))
      {
          // only add the windows that pass the filter
          windows.Add(wnd);
      }

      // but return true here so that we iterate all windows
      return true;
  }, IntPtr.Zero);

  return windows;
}

/// <summary> Find all windows that contain the given title text </summary>
/// <param name="titleText"> The text that the window title must contain. </param>
public static IEnumerable<IntPtr> FindWindowsWithText(string titleText)
{
    return FindWindows((wnd, param) => GetWindowText(wnd).Contains(titleText));
}

Применение:

var windows = FindWindowsWithText("Notepad");

Для получения позиции курсора можно использовать WinAPI функцию GetCursorPos

Использование:

POINT p;
if (GetCursorPos(&p))
{
    //позиция курсора: p.x  p.y
}

Что бы определить позицию курсора внутри окна можно воспользоваться этой функцией:

if (ScreenToClient(hwnd, &p))
{
    //p.x и p.y относительны вашего окна
}

Документация

Добавить комментарий