Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2005.02.06;
Скачать: [xml.tar.bz2];

Вниз

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

 
-=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.



Страницы: 1 2 вся ветка

Форум: "WinAPI";
Текущий архив: 2005.02.06;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.57 MB
Время: 0.039 c
3-1104733993
SnapIn
2005-01-03 09:33
2005.02.06
Создание Oracle Listener...


1-1106542851
romal
2005-01-24 08:00
2005.02.06
Delphi .Net и железо


9-1098162851
RRAIN
2004-10-19 09:14
2005.02.06
Совместное написание игр


1-1106078553
Aleks
2005-01-18 23:02
2005.02.06
Передать фокус на компонент


14-1105981206
мазербо)
2005-01-17 20:00
2005.02.06
простой пример на с++





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский