Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 16.04.2009, 13:51
одинадцатый одинадцатый вне форума
Новичок
 
Регистрация: 16.04.2009
Сообщения: 95
Репутация: 10
Сообщение подскажите как воздействовать на окна другой программы

Вот с чем надо помочь

1. Надо чтобы при нажатии button на моей проге открывались несколько других(одного типа, но разные копии) программы и при этом я знал хэндлы этих копий.
я их открываю через createprocess, но так я получаю хэндл процесса а не формы. Как получить из этого хэндла хэндл формы?
И как зная хэндл формы узнать какие окна в ней есть и какие у них хэндлы?

2. Чтобы при изменении данных в некоторых окнах
одной из этих копий, посредством моей проги передавались измененные данные в те же окна других копий поочередно.


проблема в том что я не знаю класс этой чужой программы , ну узнать - узнаю, только заголвки могут быть разные, потому что моя прога может стоять у других узеров. По-этому функция FindWindow в данном случае не помошник.

Или посоветуйте книжечку где про это написано.
Всем заранее спасибо.

Последний раз редактировалось одинадцатый, 16.04.2009 в 14:05.
Ответить с цитированием
  #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.
Насчет второго вопроса пока лень думать =) Может, у кого-нибудь другого будет желание...

Последний раз редактировалось Nyctos Kasignete, 16.04.2009 в 23:44.
Ответить с цитированием
  #3  
Старый 17.04.2009, 19:08
одинадцатый одинадцатый вне форума
Новичок
 
Регистрация: 16.04.2009
Сообщения: 95
Репутация: 10
По умолчанию

Что значит callback-функция?
что такое @EnumThrWndProc в строке EnumThreadWindows(_pi.dwThreadId, @EnumThrWndProc, i);? И что означает @?

По поводу задержки которая должна быть: нельзя ли как нибудь сделать чоб моя прога при этом не висла?


Попробовал ваш метод - работает, но возникло 2 проблемы:
1. При запуске той программы неск-ко копий которой я хочу открыть(кстати из разных папок и по большому счету они не связаны) появляется главное окно программы и еще окошечко(не модальное) так вот ваш метод мне выдает хэндл этого окошечка, а надо главной формы.
2. Как получить хэндл если эта программа уже запущена, не зная заголовка?
Ответить с цитированием
  #4  
Старый 17.04.2009, 20:19
Nyctos Kasignete Nyctos Kasignete вне форума
Активный
 
Регистрация: 29.03.2009
Сообщения: 300
Репутация: 94
По умолчанию

одинадцатый, объяснять подробно не буду: все ответы, как я уже говорила, можно найти в Windows SDK и в книжечках.

Поясняю коротко (по сути перевожу то, что написано в справке): функция EnumThreadWindows перебирает все окна, ассоциированные с потоком, дескриптор которого ей передается в первом параметре (у нас _pi.dwThreadId). Второй параметр — указатель на ту самую callback-функцию, которую мы объявили как EnumThrWndProc (символ @ как раз и означает, что это указатель). Функция EnumThreadWindows вызывает эту callback-функцию всякий раз, когда находит очередное окно, принадлежащее данному потоку. В свою очередь callback-функция получает дескриптор найденного окна... Последний параметр можно использовать по своему усмотрению, чем я и воспользовалась (передаю текущий индекс массива Handles).

Цитата:
Сообщение от одинадцатый
По поводу задержки которая должна быть: нельзя ли как нибудь сделать чоб моя прога при этом не висла?
Я не знаю, почему виснет ваша программа. Поясню еще раз, что задержка дает время запускаемой программе на создание ее окон и прочее. Если задержки не будет, наша функция-переборщик EnumThreadWindows быстро отработает, не дождавшись появления нужных нам окон, и ничего не найдет, что логично.
Если процедура Sleep, которую я использовала, слишком загружает вашу программу, есть альтернативный вариант создания задержки:
Код:
Hndl := CreateEvent(nil, False, False, nil);
WaitForSingleObject(Hndl, 1000);
CloseHandle(Hndl);
Переменная Hndl имеет тип THandle.

Цитата:
Сообщение от одинадцатый
ваш метод мне выдает хэндл этого окошечка, а надо главной формы.
Я подумаю на этот счет. Вообще, если верить справке, EnumThreadWindows перебирает лишь окна, не являющиеся дочерними, так что пока что кажется странным, что получен дескриптор дочернего...

Последний раз редактировалось Nyctos Kasignete, 17.04.2009 в 20:35.
Ответить с цитированием
  #5  
Старый 17.04.2009, 21:32
DungeonLords DungeonLords вне форума
Активный
 
Регистрация: 21.07.2008
Сообщения: 257
Репутация: 14
По умолчанию

Цитата:
Сообщение от одинадцатый
Что значит callback-функция?
В дополнение к тому, что сказала моя коллега, скажу callback функция - функция с обратным вызовом.
__________________
Делаем'c разные игры. Искать на glscene.ru
Ответить с цитированием
  #6  
Старый 17.04.2009, 22:15
Nyctos Kasignete Nyctos Kasignete вне форума
Активный
 
Регистрация: 29.03.2009
Сообщения: 300
Репутация: 94
По умолчанию

Есть на самом деле еще одно обстоятельство, о котором я не сказала. Тот код, который выше, я писала в предположении, что у запускаемого приложения будет единственное окно. А именно, функция EnumThrWndProc возвратит False сразу как только найдет первое окно, принадлежащее нити.
Цитата:
Сообщение от Nyctos Kasignete
Код:
Result := not IsWindow(hndl);
Когда callback-функция возвращает False, перебор прекращается, независимо от того, есть ли еще окна, принадлежащие потоку, или нет. Так вот, если не останавливать перебор, то можно получить дескрипторы всех окон в потоке... Для этого функция EnumThrWndProc всегда должна возвращать True. Но как из этой полученной кучи дескрипторов получить именно handle главной формы? Вот над этим пока и думаю сейчас...

__________________________________

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

Вся проблема состоит в том, чтобы по заданному набору дескрипторов, соответствующих окнам многооконного приложения, выбрать тот единственный, который принадлежит главному окну. Не понятно, по какому критерию можно опознать, что данное окно — главное. Хотела найти лазейку через стили (и расширенные стили) окна, считывая их функцией GetWindowLong. Понятное дело, можно отсеять те окна, которые, например, обладают расшренным стилем WS_EX_TOOLWINDOW. Но на самом деле не исключены такие окна в многооконном приложении, которые имеют в точности тот же стиль, что и главное... Так что, наверное, не выход.

Была идея воспользоваться тем обстоятельством, что обычно приложение создает лишь одну кнопку на панели задач, соответствующую главному окну, а дополнительные окна не светятся на панели задач. Здесь написано, как определить, какие окна видятся на панели задач. Но проблема в том, что и для главного окна многооконного приложения не выполняется условие GetWindowLong(Wnd, GWL_HWNDPARENT) = 0, т.е. главное, как и остальные окна, имеет родительское окно программы, общее для всех окон программы. Это не то окно, которое нужно нам.

Короче, уже надоело писать. X( Скажу только, что на данный момент вижу один способ дальнейших действий. Все-таки надо забрать дескрипторы всех окон нити, а потом на основании каких-то отличительных признаков главного окна той самой, конкретной программы выбрать из имеющихся окон нужное. Ну ведь чем-то отличается все-таки главное окно от остальных??
Код немного переделала. Теперь не нужно каждый раз перед запуском очередной копии делать задержку. Делается одна-единственная общая задержка после того как все нужные копии программы отправлены на запуск с помощью CreateProcess. После этого проходимся по всем запущенным нитям и собираем дескрипторы окон.
Код:
type
  THandles = array of HWND;

  { новый тип — структура, в которой хранится идентификатор процесса
    и набор дескрипторов ассоциированных с ним окон}
  TThreadIdHandles = record
    ThreadId: Cardinal;
    Handles: THandles;
  end;

  TForm1 = class(TForm)
    StartProgramBtn: TButton;
    procedure StartProgramBtnClick(Sender: TObject);
  private
    { Private declarations }
    procedure GetAllWndHandlesFromThreads; // новая общая процедура перебора
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  ThreadIdHandles: array[0..3] of TThreadIdHandles; // допустим, будем запускать четыре копии программы
  function EnumThrWndProc(hndl: HWND; lprm: LPARAM): BOOL; stdcall;

implementation

{$R *.dfm}

function EnumThrWndProc(hndl: HWND; lprm: LPARAM): BOOL; stdcall;
var
  ToolWndStyle: Integer;
  PrevHandlesLen: Integer;
begin
  Result := True;
  ToolWndStyle := GetWindowLong(hndl, GWL_EXSTYLE) and WS_EX_TOOLWINDOW;
  { убираем ненужные окна, имеющие стиль WS_EX_TOOLWINDOW }
  if ToolWndStyle = 0 then
     with ThreadIdHandles[lprm] do
     begin
       PrevHandlesLen := Length(Handles);
       SetLength(Handles, PrevHandlesLen + 1);
       Handles[PrevHandlesLen] := hndl;
     end;
end;

procedure TForm1.StartProgramBtnClick(Sender: TObject);
const
  WinDirPath = 'D:\Path_to_program_directory';
  NPadPath = 'D:\Path_to_program_directory\Program.exe';
var
  i: Byte;
  _si: STARTUPINFO;
  _pi: PROCESS_INFORMATION;
  Evnt: THandle;
begin
  for i := 0 to 3 do
  begin
    ThreadIdHandles[i].Handles := nil;
    FillChar(_si, SizeOf(_si), 0);
    _si.cb := SizeOf(_si);
    _si.dwFlags := STARTF_USESHOWWINDOW;
    _si.wShowWindow := SW_SHOWNORMAL;

    CreateProcess(@NPadPath[1], nil, nil, nil, False, NORMAL_PRIORITY_CLASS, nil,
                  @WinDirPath[1], _si, _pi);
    ThreadIdHandles[i].ThreadId := _pi.dwThreadId;
  end;

  // делаем лишь однократную задержку перед вызовом общей процедуры перебора
  Evnt := CreateEvent(nil, False, False, nil);
  WaitForSingleObject(Evnt, 1500);
  CloseHandle(Evnt);
  Form1.GetAllWndHandlesFromThreads();
end;

procedure TForm1.GetAllWndHandlesFromThreads;
var
  i: Byte;
begin
  for i := 0 to 3 do
    EnumThreadWindows(ThreadIdHandles[i].ThreadId, @EnumThrWndProc, i);
end;

Последний раз редактировалось Nyctos Kasignete, 18.04.2009 в 23:09.
Ответить с цитированием
  #7  
Старый 20.04.2009, 07:02
одинадцатый одинадцатый вне форума
Новичок
 
Регистрация: 16.04.2009
Сообщения: 95
Репутация: 10
По умолчанию

По поводу
Цитата:
Уж не знаю, продолжает ли работать над проблемой сам автор темы...
Да! Конечно!!! Я вниметельно слежу за развитием темы. Для меня этот вопрос сейчас очень важен. По этому буду рад любой помощи...

А вообще про SDK я не знал, но все равно теперь вряд ли быстро найду решение, потому что на англ. да и толком не знаю что искать...

Есть некоторые изменения:
допустим что при запуске пары копий нужной мне проги открывается лишь главная форма. значит получить дескрипторы всех окон на ней я могу так же через функцию EnumThrWndProc правильно?
Я попробовал так:

function EnumThrWndProc(hndl: HWND; lprm: LPARAM): BOOL; stdcall;
var
ToolWndStyle: Integer;
PrevHandlesLen: Integer;
begin
getwindowtext(hndl,w,200);
form1.Memo1.Lines.Add(w);
Result := True;
...

Но в мемо у меня оказалось только 7 пустых строк, caption этой самой формы и еще 19 пустых строк. В чем дело?

И еще я не совсем понял что такое callback функция и не ясно почему в строке
EnumThreadWindows(_pi.dwThreadId, @EnumThrWndProc, i);
мы не передаем параметры для ф-ии EnumThrWndProc, их же там нет поумолчанию.

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

одинадцатый, я в процессе отладки заголовки окон считывала немного по-другому. Поскольку имеется постоянно доступный массив, где хранятся дескрипторы всех найденных окон, то необязательно загромождать функцию EnumThrWndProc. Просто делала Memo и еще одну кнопку с вот таким обработчиком события OnClick:
Код:
procedure TForm1.GetTextBtnClick(Sender: TObject);
var
  i: Byte;
  j: Integer;
  wndtxt: PChar;
begin
  GetMem(wndtxt, 200);
  try
    Memo1.Lines.Clear;
    for i := 0 to 3 do
      for j := 0 to High(ThreadIdHandles[i].Handles) do
      begin
        GetWindowText(ThreadIdHandles[i].Handles[j], wndtxt, 200);
        Memo1.Lines.Add(StrPas(wndtxt));
      end;
  finally
    FreeMem(wndtxt, 200);
  end;
end;
В результате у меня в Memo было по три записи для каждой из запущенных копий программ:
  1. заголовок главной формы;
  2. заголовок еще одной (дополнительной) формы, которая тоже появляется при запуске программы;
  3. заголовок кнопки самой программы на панели задач.
На самом деле, всё ведь зависит от того приложения, которое вы запускаете. Значит, если у вас в Memo оказывается куча пустых строчек, то у программы столько открытых окон, имеющих пустой заголовок...
Цитата:
Сообщение от одинадцатый
допустим что при запуске пары копий нужной мне проги открывается лишь главная форма. значит получить дескрипторы всех окон на ней я могу так же через функцию EnumThrWndProc правильно?
Заметьте: так можно получить дескрипторы лишь окон, не являющихся дочерними. Например, вы таким образом не получите handle какой-нибудь кнопки или поля ввода на форме (это тоже окна!). В посте #2 я говорила, что нужно сделать, чтобы перебирать еще и дочерние окна.
Цитата:
Сообщение от одинадцатый
не ясно почему в строке EnumThreadWindows(_pi.dwThreadId, @EnumThrWndProc, i); мы не передаем параметры для ф-ии EnumThrWndProc
Здесь в этой строчке не происходит вызова функции EnumThrWndProc! Мы просто передаем функции EnumThreadWindows адрес callback функции. Вызывать же ее будет функция EnumThreadWindows самостоятельно, и параметры определять тоже.

Последний раз редактировалось Nyctos Kasignete, 20.04.2009 в 14:56.
Ответить с цитированием
  #9  
Старый 21.04.2009, 11:01
одинадцатый одинадцатый вне форума
Новичок
 
Регистрация: 16.04.2009
Сообщения: 95
Репутация: 10
По умолчанию

Цитата:
В посте #2 я говорила, что нужно сделать, чтобы перебирать еще и дочерние окна.

Что-то не могу ни как разобраться. Я ввел попробовал вот так:
Код:
   Handles: array[0..0] of HWND; // например, запускаются четыре копии приложения...
  function EnumThrWndProc(hndl: HWND; lprm: LPARAM): BOOL; stdcall;
implementation

{$R *.dfm}

function EnumThrWndProc(hndl: HWND; lprm: LPARAM): BOOL; stdcall;
var w:array[0..200] of char;
begin
    getwindowtext(hndl,w,200);
    form1.Memo1.Lines.Add(w);
  Result := not IsWindow(hndl);
  if not Result then
  begin

    Handles[lprm] := hndl;
  end;
end;

function EnumThrWndProc2(hndl: HWND; lprm: LPARAM): BOOL; stdcall;
var w:array[0..200] of char;
begin
    getwindowtext(hndl,w,200);
    form1.Memo1.Lines.Add(w);
  Result := not IsWindow(hndl);
  if not Result then
  begin
    Handles[lprm] := hndl;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  WinDirPath, NPadPath: PChar;
  i: Byte;
  _si: STARTUPINFO;
  _pi: PROCESS_INFORMATION;
begin
  try
    for i := 0 to 0 do
    begin
      FillChar(_si, SizeOf(_si), 0);
      _si.cb := SizeOf(_si);
      _si.dwFlags := STARTF_USESHOWWINDOW;
      _si.wShowWindow := SW_SHOWNORMAL;

      CreateProcess('g:\programs\forex\mt4\terminal.exe', nil, nil, nil,
      False, NORMAL_PRIORITY_CLASS, nil, nil, _si, _pi);
      Sleep(5000);
      EnumThreadWindows(_pi.dwThreadId, @EnumThrWndProc, i);
      EnumChildWindows(Handles[0], @EnumThrWndProc2,i);
    end;
  finally
  end;
end;
Admin: Пользуемся тегами!

и в мемо оказались только caption формы и пустая строка, хотя через WinSight там видно что есть еще неск-ко Label, кнопок и т.д.
Подскажите пожалуйста что не так.
И еще такая проблема: если я открываю свою прогу через ярлык(параметров ни каких не прописано) то программа запускается только с одним, главным окном, а если через свою прогу, через createprocess, прога уже открывает 2 окна: главная форма и окошко для авторизации. Почему?

Последний раз редактировалось Admin, 21.04.2009 в 12:48.
Ответить с цитированием
  #10  
Старый 21.04.2009, 11:51
Nyctos Kasignete Nyctos Kasignete вне форума
Активный
 
Регистрация: 29.03.2009
Сообщения: 300
Репутация: 94
По умолчанию

одинадцатый, функцию EnumChildWindows необходимо вызывать из самой callback функции EnumThrWndProc! Я теперь уже забросила первый вариант, который вы привели. Использую тот, который в посте #6. Поэтому буду показывать на примере именно его.
Да простят меня модераторы, но приведу код полностью (в который раз!), чтобы не оставалось никаких неясностей, в конце концов...
Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  THandles = array of HWND;

  TThreadIdHandles = record
    ThreadId: Cardinal;
    Handles: THandles;
  end;

  TForm1 = class(TForm)
    StartProgramBtn: TButton;
    GetTextBtn: TButton;
    Memo1: TMemo;
    procedure StartProgramBtnClick(Sender: TObject);
    procedure GetTextBtnClick(Sender: TObject);
  private
    { Private declarations }
    procedure GetAllWndHandlesFromThreads;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  ThreadIdHandles: array[0..3] of TThreadIdHandles;
  function EnumThrWndProc(hndl: HWND; lprm: LPARAM): BOOL; stdcall;
  function EnumChildWndProc(hndl: HWND; lprm: LPARAM): BOOL; stdcall;

implementation

{$R *.dfm}

function EnumChildWndProc(hndl: HWND; lprm: LPARAM): BOOL; stdcall;
var
  WndTxt: PChar;
begin
  Result := True;
  GetMem(WndTxt, 255);
  try
    GetWindowText(hndl, WndTxt, 255);
    Form1.Memo1.Lines.Add(StrPas(WndTxt));
  finally
    FreeMem(WndTxt, 255);
  end;
end;

function EnumThrWndProc(hndl: HWND; lprm: LPARAM): BOOL; stdcall;
var
  ToolWndStyle: Integer;
  PrevHandlesLen: Integer;
begin
  Result := True;
  ToolWndStyle := GetWindowLong(hndl, GWL_EXSTYLE) and WS_EX_TOOLWINDOW;
  { take into account only non-tool windows from the thread }
  if ToolWndStyle = 0 then
     with ThreadIdHandles[lprm] do
     begin
       PrevHandlesLen := Length(Handles);
       SetLength(Handles, PrevHandlesLen + 1);
       Handles[PrevHandlesLen] := hndl;
     end;
  EnumChildWindows(hndl, @EnumChildWndProc, 0);
end;

procedure TForm1.GetAllWndHandlesFromThreads;
var
  i: Byte;
begin
  for i := 0 to 3 do
    EnumThreadWindows(ThreadIdHandles[i].ThreadId, @EnumThrWndProc, i);
end;

procedure TForm1.StartProgramBtnClick(Sender: TObject);
const
  WinDirPath = 'g:\programs\forex\mt4';
  ProgPath = 'g:\programs\forex\mt4\terminal.exe';
var
  i: Byte;
  _si: STARTUPINFO;
  _pi: PROCESS_INFORMATION;
  Evnt: THandle;
begin
  for i := 0 to 3 do
  begin
    ThreadIdHandles[i].Handles := nil;
    FillChar(_si, SizeOf(_si), 0);
    _si.cb := SizeOf(_si);
    _si.dwFlags := STARTF_USESHOWWINDOW;
    _si.wShowWindow := SW_SHOWNORMAL;

    CreateProcess(@ProgPath[1], nil, nil, nil, False, NORMAL_PRIORITY_CLASS, nil,
                  @WinDirPath[1], _si, _pi);
    ThreadIdHandles[i].ThreadId := _pi.dwThreadId;
  end;

  // do a delay only once before calling GetAllWndHandlesFromThreads proc.
  Evnt := CreateEvent(nil, False, False, nil);
  WaitForSingleObject(Evnt, 1500);
  CloseHandle(Evnt);
  Form1.GetAllWndHandlesFromThreads();
end;

procedure TForm1.GetTextBtnClick(Sender: TObject);
var
  i: Byte;
  j: Integer;
  wndtxt: PChar;
begin
  GetMem(wndtxt, 200);
  try
    Memo1.Lines.Clear;
    for i := 0 to 3 do
      for j := 0 to High(ThreadIdHandles[i].Handles) do
      begin
        GetWindowText(ThreadIdHandles[i].Handles[j], wndtxt, 200);
        Memo1.Lines.Add(StrPas(wndtxt));
      end;
  finally
    FreeMem(wndtxt, 200);
  end;
end;

end.
При переборе дочерних теперь выводятся в Memo заголовки кнопок и прочего.

P.S. одинадцатый, уже давайте что-ли пользоваться BB-кодами, а то схватите предупреждение от Admin'а или модератора...
Код оформляется так: [code]Сюда вставляется код[/code]

P.P.S. По поводу различий при запуске с ярлыка и с CreateProcess. Раскопайте в справке описание функции CreateProcess. Возможно, что дело в том, что вы не используете атрибуты безопасности при запуске приложения. Вместо некоторых nil, которые вы передаете в параметрах функции CreateProcess, в общем случае должны стоять указатели на структуру SECURITY_ATTRIBUTES. Хотя я не утверждаю, что дело именно в этом. И атрибутами безопасности я никогда не пользовалась...

Последний раз редактировалось Nyctos Kasignete, 21.04.2009 в 12:21.
Ответить с цитированием
  #11  
Старый 22.04.2009, 16:37
одинадцатый одинадцатый вне форума
Новичок
 
Регистрация: 16.04.2009
Сообщения: 95
Репутация: 10
По умолчанию

Спасибо Nyctos Kasignete.
Похоже вы одна здесь отвечаете на вопросы)
Ваш метод попробовал - дескрипторы получил.
Тока понимаю что тема эта для меня нова и пока непонятна так что cразу от общего к частному перейду. в общем надо для начала извлечь информацию из окна(что то типа stringgrid-а).
Дескриптор его я вашим методом получил. А можно ли как нибудь из этого окна выдернуть всю таблицу данных? Как?
Выглядет оно вот так:
http://www.delphisources.ru/forum/at...1&d=1240403753

Я так понимаю: само окно с вертикальным Caption "Терминал" - это что то типа GroupBox(Который в winsight имеет клас SysListView32), а в него воткнут этот самый компонент похожий на StirngGrid(Который в winsight имеет клас SysHeader32).
Изображения
Тип файла: jpg 2412412.JPG (26.3 Кбайт, 18 просмотров)
Ответить с цитированием
  #12  
Старый 22.04.2009, 18:18
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,721
Репутация: 52347
По умолчанию

А зачем влезать в чужой разговор без надобности?
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.
Ответить с цитированием
  #13  
Старый 22.04.2009, 19:08
одинадцатый одинадцатый вне форума
Новичок
 
Регистрация: 16.04.2009
Сообщения: 95
Репутация: 10
По умолчанию

А от куда вам знать с надобностью или без?
Ответить с цитированием
  #14  
Старый 22.04.2009, 19:10
Nyctos Kasignete Nyctos Kasignete вне форума
Активный
 
Регистрация: 29.03.2009
Сообщения: 300
Репутация: 94
По умолчанию

Цитата:
Сообщение от Страдалецъ
А зачем влезать в чужой разговор без надобности?
Наоборот, авторитетное мнение в дополнение никогда не помешает! =) Если бы не было надобности, тема не разрасталась до таких размеров, как сейчас...
одинадцатый, я тоже такими вещами не каждый день занимаюсь. Поэтому обучаюсь на ходу. В Win32 API навалом всяких макросов и всяких сообщений, которые можно отсылать таким окнам, как ListView. Класс SysListView32 — это класс таких окон, как список файлов в Explorer'е (в режиме отображения "Таблица") или в программе WinRAR...
Получить содержимое любой "ячейки" можно с помощью отсылки сообщения LVM_GETITEMTEXT. При этом происходит заполнение структуры LV_ITEM, у которой есть поле pszText, в которое и будет записано содержимое "ячейки".
Я сейчас горю по времени, пример написать просто не успеваю. Свободное время появится, скорее всего, в субботу, так что лучше всего начинайте пока самостоятельно копать в этом направлении. Если будут затруднения, попробую что-нибудь набросать в качестве примера при первой же возможности. Но, скорее всего, не раньше субботы...
Ответить с цитированием
  #15  
Старый 22.04.2009, 19:24
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,721
Репутация: 52347
По умолчанию

Ну как откуда? Я вот топик почитал, вижу что потихонечку все движеться, зачем же мешать? А если нужно много быстрых советов "зубров", задайте это вопрос на sql.ru в разделе Delphi.
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.

Последний раз редактировалось Страдалецъ, 22.04.2009 в 19:27.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 07:25.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter