Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2 3 4 5   вперед  Ctrl      все
 Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
Озадачился реализацией данного способа, а опыта работы с потоками вообще нету..(

Попробую словесно описать суть задачи

- Имеется форма и Основная процедура, которая производит какие-то вычисления
- на форме кроме разных полей, имеется Три кнопки: "Заменить", "Пропустить" и "Выход"
- в определенный момент Основной процедуре нужно передать определенные значения или пустить ее по одному из трех направлений, в зависимости от выбора пользователя из трех кнопок.

Сразу скажу - по определенным причинам, применение Диалоговых окон мне не подходит!

Реализацию алгоритмически вижу примерно так:
- внутри Основной процедуры в Осн.потоке пишем бесконечный цикл с анализом внутри трех Флаг-переменных - например Zamena, Propusk, Vihod: Boolean;
- перед этим бесконечным циклом запустить Доп.поток с тремя процедурами обработки клика на соответствующие клавиши, внутри каждой из которых будут меняться Флаг-переменные;
- т.о. получив нужные флаги внутри бесконечного цикла, Осн.поток останавливает Доп.поток и продолжает выполнение Основной процедуры.

По моему - сей алгоритм можно реализовать с помощью потоков!?
Может быть кто либо уже реализовывал его или есть похожие варианты кода?!

P.S. По случаю - поздравляю всех форумчан и Администрацию с наступающим 2018 годом!!!
31 дек 17, 17:09    [21076241]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 46361

Bellic
- внутри Основной процедуры в _Осн.потоке_ пишем бесконечный цикл с анализом внутри трех
Флаг-переменных - например *Zamena*, *Propusk*, *Vihod*: *Boolean*;
- перед этим бесконечным циклом запустить _Доп.поток_ с тремя процедурами обработки клика
на соответствующие клавиши, внутри каждой из которых будут меняться Флаг-переменные;

Наоборот. Всем GUI и в том числе кнопками должен заниматься исключительно основной поток.
Дополнительный поток - делает всю продолжительную работу, подчиняясь командам из основного.

Posted via ActualForum NNTP Server 1.5

31 дек 17, 17:45    [21076276]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
Dimitry Sibiryakov
Наоборот. Всем GUI и в том числе кнопками должен заниматься исключительно основной поток.
Дополнительный поток - делает всю продолжительную работу, подчиняясь командам из основного.

И что мешает Три процедуры обработки нажатия кнопок написать в отдельном модуле, запустить в Доп.потоке, а в Основном - закрутить в цикле анализ Флагов?
Т.е. как я описал - не получится сделать?
Я просто хочу отказаться от отдельного Диалогового окна в Осн.процедуре, а кнопки разместить на форме!
31 дек 17, 17:56    [21076285]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
Я видимо понял!
Создав Доп.поток нужно в нем запустить какую-либо процедуру, а в моем алго - лишь три обработчика нажатия клавиш!?
31 дек 17, 18:06    [21076296]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3631
Bellic
а в Основном - закрутить в цикле анализ Флагов?
В основном потоке и так беспрерывно крутится цикл обработки сообщений. Зачем еще один?
31 дек 17, 18:07    [21076298]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
YuRock
В основном потоке и так беспрерывно крутится цикл обработки сообщений. Зачем еще один?

Цикл анализа реакции выбора Юзера, цикл опроса Флаговых переменных...
31 дек 17, 18:14    [21076310]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
Ведь когда вызывается обычное Диалоговое окно - с момента его Вывода на экран и до нажатия кнопок - тоже ведь внутри идет цикл опроса клавиш, по сути!?
31 дек 17, 18:16    [21076314]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
YuRock
Зачем еще один?

YuRock, предложи тогда свой вариант - отказа Диалог.окон и переноса кнопок на основную форму!
31 дек 17, 18:19    [21076316]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3631
Bellic
Цикл анализа реакции выбора Юзера
Для этого существуют события баттонклики. По сути - орабатываются сообщения wm_command.


Bellic
цикл опроса Флаговых переменных...

Вот его и запихни в доппоток, и при изменении - кидай сообщение основному, что надо что-то изменить в отображении.
31 дек 17, 18:22    [21076321]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Vizit0r
Member

Откуда:
Сообщений: 563
какой-то поток сознания.

Работа делается в отдельном потоке.

Хоткеи срабатывают в основном окне, в обработчике делаются нужные действия с "рабочим" потоком.


Проблема-то в чем?
31 дек 17, 18:23    [21076322]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3631
Bellic
Ведь когда вызывается обычное Диалоговое окно - с момента его Вывода на экран и до нажатия кнопок - тоже ведь внутри идет цикл опроса клавиш, по сути!?
Это только в VCL такая костыльноглючная технология используется для модальности.
31 дек 17, 18:23    [21076323]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
YuRock
Вот его и запихни в доппоток, и при изменении - кидай сообщение основному, что надо что-то изменить в отображении.

Этого нельзя сделать!
В Основной процедуре открыта куча файлов, задействовано много циклов и переменных, процедура еще выполняется, просто в ОДИН момент нужен выбор юзера, и все!!! Все решается обычным Диалоговым окном!!!
Но мне Диалог не подходит!!!
Необходимо, что бы кнопки принятия решения были на самой форме!
31 дек 17, 18:29    [21076328]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3631
Bellic
Этого нельзя сделать!
В Основной процедуре открыта куча файлов, задействовано много циклов и переменных, процедура еще выполняется, просто в ОДИН момент нужен выбор юзера, и все!!!
Именно по этому и надо всё это перенести в доп поток, раз много работы.

А выбор юзера сделать перед началом этой работы. Ведь это же бред, когда юзер должен 10 минут сидеть ждать, пока программа его попросит сделать выбор.
31 дек 17, 18:33    [21076335]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
YuRock
Bellic
Этого нельзя сделать!
В Основной процедуре открыта куча файлов, задействовано много циклов и переменных, процедура еще выполняется, просто в ОДИН момент нужен выбор юзера, и все!!!
Именно по этому и надо всё это перенести в доп поток, раз много работы.

А выбор юзера сделать перед началом этой работы. Ведь это же бред, когда юзер должен 10 минут сидеть ждать, пока программа его попросит сделать выбор.

Юзер не будет ждать!
Даже наоборот - ему придется быстро оценивать промежуточные результаты в Эдитах и прочих полях, и нажимать нужную кнопку!
Именно по этому я хочу и отказаться от Диалогового окна, ибо оно закрывает собой часть осн.формы, передвинут его в сторону в ручную - потерять время! Программно разместить например в углу экрана - тоже не вариант - отвлечение внимания юзера и т.п.
31 дек 17, 18:44    [21076347]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3631
Bellic
Юзер не будет ждать!
Не понятно тогда, зачем другой поток.
31 дек 17, 20:03    [21076462]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Док
Member

Откуда: Казань
Сообщений: 5869
YuRock,

не убеждай его, бесполезно. Клиент должен дозреть.
31 дек 17, 22:35    [21076679]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
Парни, видимо меня сильно ругать кое-кто будет сейчас?!..))
Но весь код уместился в Основном модуле и без открытия дополнительных потоков:
+ Тестовый код (палками сильно не бить!..)))
unit Main_Module;

interface

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

type
  TMainForm = class(TForm)
    SButton: TButton;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    MLabel: TLabel;
    MMemo: TMemo;
    procedure SButtonClick(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
    Flag1, Flag2, Flag3: Boolean;
  public
    { Public declarations }
  end;

var
  MainForm: TMainForm;

implementation

{$R *.dfm}

//------------------------------------------------------------------------------
procedure TMainForm.Button1Click(Sender: TObject); // Кнопка "Продолжить" счет
begin
     Flag1:=True;
end;
//------------------------------------------------------------------------------
procedure TMainForm.Button2Click(Sender: TObject); // Кнопка "Пропустить" счет
begin
     Flag2:=True;
end;
//------------------------------------------------------------------------------
procedure TMainForm.Button3Click(Sender: TObject); // Кнопка "Остановить" счет
begin
     Flag3:=True;
end;
//------------------------------------------------------------------------------
procedure TMainForm.SButtonClick(Sender: TObject); // Кнопка "Запустить" счет
var
i: Integer;
label
Metka;
begin   MMemo.Lines.Add('Счет запущен');
     while True do
          begin
               for i := 0 to 10 do
                    begin
                         MLabel.Caption := IntToStr(i);
                         Application.ProcessMessages;
                         Sleep(500);
                         if i=5 then
                              begin
                                   MMemo.Lines.Add('Продолжаем цикл? Нажмите одну из Кнопок!');
Metka:                             Application.ProcessMessages; //==============
                                   if Flag1=True then begin
                                        MMemo.Lines.Add('Нажата кн."Продолжить"');
                                        Flag1:=False;
                                        Continue;
                                        end;
                                   if Flag2=True then begin
                                        MMemo.Lines.Add('Нажата кн."Пропустить"');
                                        Flag2:=False;
                                        Break;
                                        end;
                                   if Flag3=True then begin
                                        MMemo.Lines.Add('Нажата кн."Остановить"');
                                        Flag3:=False;
                                        MMemo.Lines.Add('Счет Остановлен!');
                                        Exit;
                                        end;
                                    goto Metka; //==============================
                              end;
                    end;
          end;
end;
//------------------------------------------------------------------------------
end.
Можете меня расстрелять, но Он прекрасно работает!..)))
Возможно будут замечания и к Тестовому коду, к циклам или же к "GOTO"-переходу, но тут важна сама суть - пока процедура "крутится" в цикле между МЕТКА-ми (выделено желтым цветом), анализируя три флага, пользователь приняв решение может нажать одну из 3-х кнопок.

P.S. Поиски в Интернете показали другой вариант - с анализом WM_LBUTTONDOWN, или WM_COMMAND, а потом чтением и анализом Хэндла кнопки... но у меня пока так и не получилось его реализовать.
В этом случае по моему можно было вообще обойтись без отдельных процедур - обработчиков нажатия кнопок!?
3 янв 18, 01:07    [21079598]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Няшик
Member

Откуда: Екатеринбург
Сообщений: 885
Может кто нибудь мне - умственно отсталому человеку объяснить....

На кой чёрт потоки и бесконечные циклы????

Можно же было всем объектам назначить коллбэк один, или вызов доп коллбэка.

И уже там творить все делишки.
3 янв 18, 01:45    [21079614]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
Няшик
На кой чёрт потоки и бесконечные циклы????
Можно же было всем объектам назначить коллбэк один, или вызов доп коллбэка.
И уже там творить все делишки.

Дополнительного потока в крайнем коде - как видите нету!
А бесконечный цикл (тот что выделен цветом) - в ожидании изменения флагов...

Лучше напишите реально работающий свой вариант с "одним коллбэком"..))
3 янв 18, 01:55    [21079619]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Няшик
Member

Откуда: Екатеринбург
Сообщений: 885
Bellic,

+
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    SButton: TButton;
    Memo1: TMemo;
    procedure AllButtonClick(Sender: TObject);
  private
    SButtonEnebled: Boolean;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.AllButtonClick(Sender: TObject);
  function IndexIArray(const str: string; const arr: TArray<string>): Integer;
  var
    I: Integer;
  begin
    for I := Low(arr) to High(arr) do
      if str.ToLower = arr[I].ToLower then
        exit(I);
  end;

var
  obj: TButton;
begin
  obj := TButton(Sender);
  if not SButtonEnebled then
  begin
    if obj.Name = 'SButton' then
      SButtonEnebled := true
    else
      Memo1.Lines.Add('Кряя. Надо нажать на SButton');
    exit;
  end;

  case IndexIArray(obj.Name, ['Button1', 'Button2', 'Button3']) of
    0:
      begin
        Memo1.Lines.Add('Нажата кн."Продолжить"');
      end;
    1:
      begin
        Memo1.Lines.Add('Нажата кн."Пропустить"');
      end;
    2:
      begin
        Memo1.Lines.Add('Счет Остановлен!');
      end;
  end;
  SButtonEnebled := False;
end;

end.
3 янв 18, 02:07    [21079625]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
alekcvp
Member

Откуда:
Сообщений: 1201
Bellic,

Вообще, судя по Sleep(500) - там запланировано выполнение чего-то длительного, поэтому почти всё что в процедуре ".SButtonClick()" нужно вынести в отдельный поток и уже из него анализировать состояние этих флагов.

А вообще, бесконечные циклы, да ещё и со Sleep() в ГУИ потоке - не надо так, пользователи вас за подвисающий интерфейс будут очень долго любить... часто вспоминать... малым загибом... ну и так далее.
3 янв 18, 02:07    [21079626]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
alekcvp
Вообще, судя по Sleep(500) - там запланировано выполнение чего-то длительного
Sleep(500) - это задержка, чисто в тестовом коде, чтоб счет был не таким быстрым!.)))

поэтому почти всё что в процедуре ".SButtonClick()" нужно вынести в отдельный поток и уже из него анализировать состояние этих флагов.
Зачем еще поток? И так ведь все работает?

А вообще, бесконечные циклы, да ещё и со Sleep() в ГУИ потоке - не надо так, пользователи вас за подвисающий интерфейс будут очень долго любить... часто вспоминать... малым загибом... ну и так далее.
Тестовая программа - не зависает, а Пользователи - исключительно только я, ну может с друзьями поделюсь!..))
3 янв 18, 02:32    [21079639]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
Няшик, уточните плизз код вот тут:
procedure TForm1.AllButtonClick(Sender: TObject);
  function IndexIArray(const str: string; const arr: TArray<string>): Integer;
  var
    I: Integer;
  begin
    for I := Low(arr) to High(arr) do
      if str.ToLower = arr[I].ToLower then
        exit(I);
        ....

Начинается процедура, затем Функция... а вот
if str.ToLower = arr[I].ToLower then
моя DX вообще не поняла!
У Вас ваш код работает?
3 янв 18, 02:42    [21079644]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Няшик
Member

Откуда: Екатеринбург
Сообщений: 885
Эта функция нужна, что бы найти в массиве индекс элемента. Дабы, что бы по этому индексу обратится к коллекцию case по нужному адресу.


Код полностью рабочий, и никаких задержек не надо.

Хотя я кое что не дописал. Надо ещё в case добавить 3 пункт (3: exit;), дабы при нажатии второй раз кнопки SButton не вылетал флаг в false
3 янв 18, 02:48    [21079648]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Няшик
Member

Откуда: Екатеринбург
Сообщений: 885
Хотя. Ты используешь модуль System.SysUtils ????
3 янв 18, 02:51    [21079649]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2 3 4 5   вперед  Ctrl      все
Все форумы / Delphi Ответить