Показать сообщение отдельно
  #2  
Старый 16.04.2009, 23:38
Nyctos Kasignete Nyctos Kasignete вне форума
Активный
 
Регистрация: 29.03.2009
Сообщения: 300
Репутация: 94
По умолчанию

Пока что только по поводу первого вопроса.
Вот вам мой вариант реализации... Искомые дескрипторы запущенных окон записываются в массив Handles.
Код:
var
  Form1: TForm1;
  Handles: array[0..3] of HWND; // например, запускаются четыре копии приложения...
  function EnumThrWndProc(hndl: HWND; lprm: LPARAM): BOOL; stdcall;

........................

{ Эта callback-функция вызывается при переборе окон,
 принадлежащих нити, запускаемой через CreateProcess }
function EnumThrWndProc(hndl: HWND; lprm: LPARAM): BOOL; stdcall;
begin
  Result := not IsWindow(hndl);
  if not Result then Handles[lprm] := hndl;
end;

// нажатие на кнопку вызывает запуск четырех копий Блокнота  =)
procedure TForm1.Button1Click(Sender: TObject);
var
  WinDirPath, NPadPath: PChar;
  i: Byte;
  _si: STARTUPINFO;
  _pi: PROCESS_INFORMATION;
begin
  GetMem(WinDirPath, MAX_PATH);
  GetMem(NPadPath, MAX_PATH);
  try
    GetWindowsDirectory(WinDirPath, MAX_PATH);
    StrPCopy(NPadPath, StrPas(WinDirPath) + '\Notepad.exe');
    for i := 0 to 3 do
    begin
      FillChar(_si, SizeOf(_si), 0);
      _si.cb := SizeOf(_si);
      _si.dwFlags := STARTF_USESHOWWINDOW;
      _si.wShowWindow := SW_SHOWNORMAL;

      CreateProcess(NPadPath, nil, nil, nil, False, NORMAL_PRIORITY_CLASS, nil,
                    WinDirPath, _si, _pi);
      Sleep(1000); 
      { какая-то задержка принципиально необходима перед тем как
        начинать перебор! Нужно дать приложению время запуститься.
        Возможно, что секунда — это даже много, но смотрите сами. }
      EnumThreadWindows(_pi.dwThreadId, @EnumThrWndProc, i);
    end;
  finally
    FreeMem(WinDirPath, MAX_PATH);
    FreeMem(NPadPath, MAX_PATH);
  end;
end;

{ это просто проверка того, что получены дескрипторы 
  всех запущенных окон. Например, изменим их заголовки =) }
procedure TForm1.Button2Click(Sender: TObject);
const
  WndTexts: array[0..3] of string = ('Wnd#1', 'Wnd#2', 'Wnd#3', 'Wnd#4');
var
  i: Byte;
begin
  for i := 0 to 3 do
    SendMessage(Handles[i], WM_SETTEXT, 0, Integer(@WndTexts[i][1]));
end;
По поводу поиска дочерних окон, исходя из дескриптора родительского — тоже придется написать callback-функцию типа EnumChildProc и при переборе передавать ее адрес функции EnumChildWindows. Об этом всё написано в Windows SDK.
Насчет второго вопроса пока лень думать =) Может, у кого-нибудь другого будет желание...
Ответить с цитированием