Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 02.08.2017, 06:26   #1
devzik111
 
Регистрация: 02.08.2017
Сообщений: 5
По умолчанию Многопоточное приложение

Доброго! Вот и моя очередь пришла просить помощи, не хватает моих знаний.

Есть программа для работы с определенными окнами, при запуске смотрит все запущенные окна и отсеевает по классу окна и добавляет их в ComboBox.
Код:
i:=0;
Wnd:=FindWindow(nil,nil);
while Wnd<>0 do
begin
GetClassName(Wnd,Cl,100);
if Cl='ElementClient Window' then
begin
GetWindowText(Wnd,Hndl,SizeOf(Hndl));
GetWindowThreadProcessId(Wnd,@window[i]);
hProcess:=OpenProcess(PROCESS_ALL_ACCESS,False,window[i]);
ReadProcessMemory(hProcess,ptr(BA),@ibuf,sizeof(ibuf),BC);
ReadProcessMemory(hProcess,ptr(ibuf+$1C),@ibuf,sizeof(ibuf),BC);
ReadProcessMemory(hProcess,ptr(ibuf+$28),@ibuf,sizeof(ibuf),BC);
ReadProcessMemory(hProcess,ptr(ibuf+$6F4),@ibuf,sizeof(ibuf),BC);
ReadProcessMemory(hProcess,ptr(ibuf),@Nick,sizeof( Nick),BC);
Form1.ComboBox1.Items.Add(Nick);
window[i] := Wnd;
inc(i);
end;
Handle всех нужных окон попадает в массив:
Код:
window: array[0..20] of THandle;
Раньше программа работала только с одним окном и обращалась к тому окну, которое было выбрано в ComboBox:
Код:

Wnd:=window[Form1.ComboBox1.ItemIndex];
GetWindowThreadProcessid(Wnd,@hProcess);
hProcess:=OpenProcess(PROCESS_ALL_ACCESS,False,hProcess);
Далее запускался поток в котором все крутилось и вертелось. А теперь подскажите как сделать так: Все нужные окна вместо ComboBox добавляются в CheckListBox, далее я сам чекаю нужные окна в CheckListBox и, соответственно, сколько окон я выбрал столько и запускается потоков. Каждый поток обращается к своему "чекнутому" окну. Уже неделю голову ломаю, выручайте!
devzik111 вне форума Ответить с цитированием
Старый 02.08.2017, 07:21   #2
Sciv
Старожил
 
Аватар для Sciv
 
Регистрация: 16.05.2012
Сообщений: 3,211
По умолчанию

Делаете наследника от TThread с приватным свойством WindowID, которое передаёте в поток при инициализации экземпляра класса (переопределив метод Create):

Код:
TMyThread = class (TThread)
private
  WindowID: HWND; // или какой там у Вас тип используется
public
  constructor Create(WinID: HWND); overload;
end;

constructor TMyThread.Create(WinID: HWND); 
begin
  WindowID := WinID;
  inherited Create();
end;
Соответственно в Execute потока находите нужное по WindowID и работаете с ним.

Главное - не забыть про Synchronize.
Начал решать проблему с помощью регулярных выражений. Теперь решаю две проблемы...
Sciv вне форума Ответить с цитированием
Старый 02.08.2017, 10:52   #3
devzik111
 
Регистрация: 02.08.2017
Сообщений: 5
По умолчанию

Спасибо! Я уже почти у цели)
И еще такой вот вопрос: Как в Execute потока указать именно на нужное окно? Получается, что чекаю 2 окна в CheckListBox, запускаются 2 потока, но оба в одном окне, которое последнее в CheckListBox.
devzik111 вне форума Ответить с цитированием
Старый 02.08.2017, 13:12   #4
Sciv
Старожил
 
Аватар для Sciv
 
Регистрация: 16.05.2012
Сообщений: 3,211
По умолчанию

Цитата:
Сообщение от devzik111 Посмотреть сообщение
Как в Execute потока указать именно на нужное окно?
Можно просто пробегать по всем открытым на экране окнам в поисках нужного хендла. Того самого, который передаёте в поток при создании оного. Нашёл - обработал.

Цитата:
Сообщение от devzik111 Посмотреть сообщение
запускаются 2 потока, но оба в одном окне
Что это значит - я не очень понял. Я так понимаю, 2 потока обрабатывают только последнее окно из списка?
Начал решать проблему с помощью регулярных выражений. Теперь решаю две проблемы...

Последний раз редактировалось Вадим Мошев; 03.08.2017 в 00:12.
Sciv вне форума Ответить с цитированием
Старый 02.08.2017, 14:56   #5
devzik111
 
Регистрация: 02.08.2017
Сообщений: 5
По умолчанию

Код:
for i := 0 to Form1.CheckListBox1.Count - 1 do
if CheckListBox1.Checked[i]
then begin
Wnd := window [i];
TMyThread.Create(wnd);
Form1.Memo1.Lines.Add('Handle ' + IntToStr(wnd));
Вот таким циклом запускаю потоки, но... В Мемо он записывает хендлы всех чекнутых в CheckListBox окон, то есть: если отметил 3 окна, то в мемо запишет:
handle 1
handle 2
handle 3
А вот потоки запускаются только с последним хендлом, то есть с 3. И получается запускается 3 потока и все 3 обращаются к 3му окну. Вот такая беда
devzik111 вне форума Ответить с цитированием
Старый 02.08.2017, 15:08   #6
Sciv
Старожил
 
Аватар для Sciv
 
Регистрация: 16.05.2012
Сообщений: 3,211
По умолчанию

Покажите код Execute потока.
Начал решать проблему с помощью регулярных выражений. Теперь решаю две проблемы...
Sciv вне форума Ответить с цитированием
Старый 02.08.2017, 16:29   #7
devzik111
 
Регистрация: 02.08.2017
Сообщений: 5
По умолчанию

Код:
procedure TMyThread.Execute;

begin

  GetWindowThreadProcessId(Wnd, @hProcess);
  hProcess := OpenProcess(PROCESS_ALL_ACCESS, False, hProcess); 
  Name := Form1.CheckListBox1.Items[v]; 
  ...
// Читаем информацию с окна
  ...
  Synchronize(Info);
  Synchronize(WND);

end;
Код:
procedure TMyThread.Info; 
 begin
   Form1.Memo1.Lines.Add(' [' + Name + '] Инфо: ' + Info);
 end;

procedure TMyThread.WND; 
 begin
   Form1.Memo1.Lines.Add(' [' + Name + '] Хендл в потоке: ' + IntToStr(Wnd));
 end;
Результат в Мемо:

[Name3] Инфо: 10 // Name всегда последнего окна
[Name3] Инфо: 10 // Вся информация взята из 3 окна.
[Name3] Инфо: 10 //
[Name3] Хендл в потоке: 3147182 //
[Name3] Хендл в потоке: 525912 // А вот хендлы какие надо.
[Name3] Хендл в потоке: 6620686 //
devzik111 вне форума Ответить с цитированием
Старый 02.08.2017, 19:27   #8
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию

Цитата:
Сообщение от devzik111 Посмотреть сообщение
[CODE]
procedure TMyThread.Execute;
begin
GetWindowThreadProcessId(Wnd, @hProcess);
hProcess := OpenProcess(PROCESS_ALL_ACCESS, False, hProcess);
Name := Form1.CheckListBox1.Items[v]; <<<<ТАК НЕЛЬЗЯ
...
// Читаем информацию с окна
...
Synchronize(Info);<<<<Synchronize вероятно лишний
Synchronize(WND);<<<<Synchronize вероятно лишний
end;
Synchronize налепил там где ненадо... а где надо его нет
тебе в первом же посте показали один из способов передать параметры в поток
Не стесняемся, плюсуем!
Slym вне форума Ответить с цитированием
Старый 02.08.2017, 19:36   #9
Sciv
Старожил
 
Аватар для Sciv
 
Регистрация: 16.05.2012
Сообщений: 3,211
По умолчанию

Код:
GetWindowThreadProcessId(Wnd, @hProcess);
hProcess := OpenProcess(PROCESS_ALL_ACCESS, False, hProcess); 
Name := Form1.CheckListBox1.Items[v]; <<<<ТАК НЕЛЬЗЯ
...
// Читаем информацию с окна
...
Вот это всё в отдельную private-процедуру, например DoWork. А в теле Execute так:

Код:
while not terminated do
  Synchronize(DoWork);
Начал решать проблему с помощью регулярных выражений. Теперь решаю две проблемы...
Sciv вне форума Ответить с цитированием
Старый 02.08.2017, 22:52   #10
eoln
Старожил
 
Аватар для eoln
 
Регистрация: 26.04.2008
Сообщений: 2,645
По умолчанию

Цитата:
Сообщение от Sciv Посмотреть сообщение
Вот это всё в отдельную private-процедуру, например DoWork. А в теле Execute так:

Код:
while not terminated do
  Synchronize(DoWork);
Тогда нет смысла в многопоточности, всё будет выполнятся в родительском потоке
eoln вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Многопоточное приложение Usov Работа с сетью в Delphi 5 10.02.2014 17:32
многопоточное приложение Vistar Общие вопросы .NET 1 26.08.2011 16:25
многопоточное приложение favorite Общие вопросы Delphi 0 26.05.2011 19:47
Многопоточное приложение MaXoN66613 Помощь студентам 0 07.06.2010 12:36
Многопоточное приложение на Indy Core2Duo Работа с сетью в Delphi 15 08.04.2009 16:45