Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Отследить запуск внешней программы 
:(
    Опции темы
ВладимирЖуков
Дата 24.5.2006, 13:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 22.5.2006

Репутация: нет
Всего: нет



При запуске внешней программы процесс пошел, а окно еще не создалось и когда я пишу FindWindow(...), то оно не может найтись так как еще не создано. Я пробовал Sleep после запуска, но это не выход. Мне нужен Handle запускаемого окна. Подскажите, как это сделать?
PM MAIL   Вверх
Snowy
Дата 24.5.2006, 13:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 30
Всего: 484



Крути цикл с FindWindow, пока не найдется. 
PM MAIL   Вверх
Nickel
Дата 24.5.2006, 14:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 77
Регистрация: 7.2.2006

Репутация: 2
Всего: 4



Код

var Wnd:HWnd;
begin
  repeat
    Wnd:=FindWindow(nil,'Èìÿ îêîøêà');
    Application.ProcessMessages;
    if Application.Terminated then Halt;
    Sleep(50);
  until wnd<>0;
end;
 
PM   Вверх
ВладимирЖуков
Дата 24.5.2006, 15:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 22.5.2006

Репутация: нет
Всего: нет



Спасибо! Я подобное уже сделал. Но мне это как то не нравится, потомучто поиск окна происходит по заголовку или по классу. А можно какнибудь получить handle незная ни класса, ни заголовка. Имеется имя файла (запускаемой программы).
Может какнибудь через процессы или еще как-нибудь? Пожалуйста с кодом!
PM MAIL   Вверх
Romikgy
Дата 24.5.2006, 15:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 13
Всего: 146



GetModuleHandle+EnumThreadWindows 


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Yanis
Дата 24.5.2006, 22:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2937
Регистрация: 9.2.2004
Где: Москва

Репутация: 13
Всего: 111



Цитата(Nickel @ 24.5.2006,  15:01)
Код

var Wnd:HWnd;
begin
  repeat
    Wnd:=FindWindow(nil,'Èìÿ îêîøêà');
    Application.ProcessMessages;
    if Application.Terminated then Halt;
    Sleep(50);
  until wnd<>0;
end;

И не дай бог чужая программа не запустится smile  


--------------------
user posted image *щёлк*
PM MAIL WWW ICQ   Вверх
BUGOR
Дата 25.5.2006, 08:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 325
Регистрация: 12.3.2006

Репутация: 2
Всего: 16



В таблице открытых хендлов системы до того как окно не создано никаких записей об этом окне тоже не создано, поэтому пока окно не создано, то как ты его хендл-то узнаешь? Задача unreal)  


--------------------
Живу недоумевая, всё время хочу понять...
http://hunger.ru 
PM MAIL WWW ICQ   Вверх
Nickel
Дата 25.5.2006, 11:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 77
Регистрация: 7.2.2006

Репутация: 2
Всего: 4



Цитата(BUGOR @ 25.5.2006,  08:35)
В таблице открытых хендлов системы до того как окно не создано никаких записей об этом окне тоже не создано, поэтому пока окно не создано, то как ты его хендл-то узнаешь? Задача unreal)

А почему бы не подождать пока они не появятся?
Цитата(Yanis @ 24.5.2006,  22:54)
И не дай бог чужая программа не запустится smile

Ну что, я всё должен чтоли предусматривать?  smile 
Цитата(ВладимирЖуков @ 24.5.2006,  15:05)
Может какнибудь через процессы или еще как-нибудь? Пожалуйста с кодом!

Пожалуйста:
Код

uses TlHelp32;

function GetProcessName(PID: Cardinal): string;
var
 Snap: dword;
 Process: TPROCESSENTRY32;
begin
  Snap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  if Snap <> INVALID_HANDLE_VALUE then
     begin
      Process.dwSize := SizeOf(TPROCESSENTRY32);
      if Process32First(Snap, Process) then
         repeat
          if Process.th32ProcessID = PID then
             begin
              Result := Process.szExeFile;
              CloseHandle(Snap);
              Exit;
             end;
         until not Process32Next(Snap, Process);
      Result := '';
      CloseHandle(Snap);
     end;
end;

function FindWindowByExeName(ExeName: string): Hwnd;
var
  wnd: HWnd;
  PID : Cardinal;
begin
  wnd := GetWindow(Application.Handle, GW_HWNDFIRST);
  while wnd > 0 do
  begin
    GetWindowThreadProcessId(wnd, PID);
    if GetProcessName(PID) = ExeName then
    begin
      Result := wnd;
      Exit;
    end
    else
      wnd := GetWindow(wnd, GW_HWNDNEXT);
  end;
  Result := 0;
end;

...


procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(IntToStr(FindWindowByExeName(ExtractFileName
           (Application.ExeName)))+' - '+IntToStr(Handle));
end;


Зацикли FindWindowByExeName по аналогии с FindWindow. Если есть вероятность, что программа может не запуститься, то, во-первых, проверь что возвратил WinExec (если используешь его), если значение больше 31, то всё окей, иначе - ошибка. Во-вторых, ограничь по времени поиск окна, ну например секунд 5 (сгодится даже TTimer с закладки System). 
PM   Вверх
аЛексус
Дата 26.5.2006, 06:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 20.3.2006
Где: Алматы

Репутация: нет
Всего: 1



Что-то не выходит!!! :-(
Может еще что-то есть?! 
PM MAIL WWW ICQ   Вверх
Nickel
Дата 26.5.2006, 06:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 77
Регистрация: 7.2.2006

Репутация: 2
Всего: 4



А что не выходит? Каков результат? Как делаешь? 
PM   Вверх
аЛексус
Дата 26.5.2006, 11:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 20.3.2006
Где: Алматы

Репутация: нет
Всего: 1



Интерфейс второй программы, то встраивается то не встраивается. 
1. Интерфейс визуально не встраивается(выходит за рамки окна), хотя относится к окну главной программы. и при этом в панели задач нет  кнопки для второй программы, хотя окно есть.
2. Интерфейс втраивается и в панели задач появляется кнопка.

Вот код проги:

Код

function FindWindowByExeName(ExeName: string): Hwnd;
var
  Wnd: HWnd;
  PID : Cardinal;
begin
  Wnd := GetWindow(Application.Handle, GW_HWNDFIRST);
  Result := 0;
  while Wnd <> 0 do
  begin
    GetWindowThreadProcessId(Wnd, PID);
    if GetProcessName(PID) = ExeName then
    begin
      Result := Wnd;
      Exit;
    end
    else
      Wnd := GetWindow(Wnd, GW_HWNDNEXT);
  end;
end;

function GetProcessName(PID: Cardinal): string;
var
  Snap: DWORD;
  Process: TProcessEntry32;
begin
  Snap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  if Snap <> INVALID_HANDLE_VALUE then
  begin
    Process.dwSize := SizeOf(TPROCESSENTRY32);
    if Process32First(Snap, Process) then
      repeat
        if Process.th32ProcessID = PID then
        begin
          Result := Process.szExeFile;
          CloseHandle(Snap);
          Exit;
        end;
      until not Process32Next(Snap, Process);
    Result := '';
    CloseHandle(Snap);
  end;
end;

procedure TfrmMain.Button2Click(Sender: TObject);
var
  Wnd: HWND;
begin
  Wnd := 0;
  if odFile.Execute then
    if ShellExecute(Handle, nil, PAnsiChar(odFile.FileName), nil, nil, SW_SHOW) > 32 then
      if ExtractFileName(odFile.FileName) <> ExtractFileName(Application.ExeName) then
      begin
        repeat
          if Application.Terminated then Halt;

          Wnd := FindWindowByExeName(ExtractFileName(odFile.FileName));

          if Wnd <> 0 then
          begin
            if Windows.SetParent(Wnd, Handle) = 0 then
            begin
              SendMessage(Wnd, WM_CLOSE, 0, 0);
              ShowMessage('Невозможно встроить окно!');
              Exit;
            end;
          end;
          Sleep(10);
        until Wnd <> 0;
      end;
end;

 
PM MAIL WWW ICQ   Вверх
Nickel
Дата 26.5.2006, 12:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 77
Регистрация: 7.2.2006

Репутация: 2
Всего: 4



Понятно, мой код не очень надёжный, поскольку ищет первое попавшееся окошко данного процесса, а у процесса может быть много всяких невидимых окошек, поэтому нужно как минимум отфильтровать в функции FindWindowByExeName невидимые окошки, окошки с нулевым размером и, наверно показанные за пределом экрана (можно ещё ввести ограничения по стилям типа WS_POPUP...). 
PM   Вверх
Демо
Дата 26.5.2006, 14:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 3.11.2005

Репутация: 6
Всего: 50



Цитата(ВладимирЖуков @  24.5.2006,  13:45 Найти цитируемый пост)
Подскажите, как это сделать?


См. WaitForInputIdle 


--------------------
    
PM MAIL ICQ Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0741 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.