Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > Кнопка START и кнопка STOP


Автор: Alexzz 9.7.2008, 21:04
Предположим, есть форма и на ней две кнопки, одна старт, другая стоп. Вторая изначально не видна (.Visible выставлен в false). По нажатию первой кнопки начинается процесс чтения данных через ком-порт. На время выполнения кнопка старт становится неактивной, а вторая появляется.
Код

begin
  Button1.Enabled:=false;
  Button2.Visible:=true;
  
  // ******* открытие порта, чтение данных, закрытие порта

  Button1.Enabled:=true;
  Button2.Visible:=false;
end;

Процесс заканчивается когда все данные считаны.  Но может возникнуть ошибка при считывании, или устройство может оказаться не включенным к ком-порту, и при этом в алгоритме считывания данных предусмотрены повторные попытки считать данные увеличив интервалы. Но есть желание чтобы процесс можно было бы прервать в любой момент, кликнув на кнопку STOP, коей является Button2. Ну предположим, задав некую глобальную переменную типа boolean, могу выставить её в true в начале процесса и постоянно проверять в условии цикла, а по клику на буттон2 просто присвоить ей значение false.
Проблема в том, что пока выполняется алгоритм чтения, кнопка2 хоть и выглядит активной, но кликай на неё сколько хочешь, это ни к чему не приводит пока процесс не выполнится до конца.
Внутри цикла процесса чтения стоит application.processmessages, но толку никакого.

Вопрос: Как сделать чтобы кнопка 2 была кликаемой во время выполнения процесса прописанного в онклике кнопки 1?

Автор: Данкинг 9.7.2008, 22:12
Если данные читаются в цикле, то как-то так: завести глобальную переменную... По клику на кнопке "стоп" изменить её значение... В цикле же проверять значение этой переменной после каждой итерации... Если изменилось, то из цикла выходить... И не забываем про application.Processmessages.

Автор: Alexzz 9.7.2008, 22:58
Данкинг, это всё уже есть, вопрос не об этом. Вопрос о том, как кнопку "стоп" сделать активной.

Автор: Данкинг 9.7.2008, 23:25
Цитата(Alexzz @  9.7.2008,  23:58 Найти цитируемый пост)
это всё уже есть

Код

application.Processmessages

тоже есть?..

Автор: THandle 10.7.2008, 05:34
Ну вот работающий пример:
Код


unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  b : boolean = false;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Button1.Enabled := false;
  Button2.Enabled := true;
  Button2.Visible := true;
  while not b do
    begin
      Application.ProcessMessages;
      //Some Code
    end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  b := not b;
  Button1.Enabled := true;
end;

end.




А вообще мне кажется, что тут лучше отдельный поток сделать...

Автор: morpheyushka 10.7.2008, 11:07
Цитата(THandle @  10.7.2008,  05:34 Найти цитируемый пост)
А вообще мне кажется, что тут лучше отдельный поток сделать... 

 и попробывать прикрутить Антифриз к нему. Должно все получиться!

Автор: Rennigth 10.7.2008, 11:32
Цитата(THandle @  10.7.2008,  05:34 Найти цитируемый пост)
А вообще мне кажется, что тут лучше отдельный поток сделать... 

Единственное правильное решение.  smile 
ProcessMessages все-равно коряво работает, плюс не будет возмодности во время выполнения закрыть программу.

Добавлено через 45 секунд
Цитата(morpheyushka @  10.7.2008,  11:07 Найти цитируемый пост)
 и попробывать прикрутить Антифриз к нему. 

Причем он сдесь? В индейцев вроде автор не грает...  smile 

Автор: Alexzz 13.7.2008, 23:15
Цитата(Данкинг @ 9.7.2008,  23:25)
Цитата(Alexzz @  9.7.2008,  23:58 Найти цитируемый пост)
это всё уже есть

Код

application.Processmessages

тоже есть?..

Наверное нынче в моде давать ответ не читая вопрос. Я ещё в первом сообщении написал, что процессмессаджес есть, выполняется внутри цикла. Кнопка стоп выглядит активной, но она мёртвая до окончания чтения.

По поводу отдельного потока, можно поподробней, пожалуйста?

Автор: THandle 14.7.2008, 06:02
Alexzz, по нажатию кнопки START создаешь отдельный поток, он читает данные. По нажатию кнопки STOP останавливаем этот поток.

Подробнее о потоках тут:
http://forum.vingrad.ru/forum/topic-60076.html

Автор: MetalFan 14.7.2008, 15:31
Цитата(morpheyushka @  10.7.2008,  11:07 Найти цитируемый пост)
и попробывать прикрутить Антифриз к нему. Должно все получиться! 

какой такой антифриз?! из индей? и при чем он тут?

Автор: Alexzz 20.7.2008, 16:24
Вынужден просить прощения. Оказывается это я сам лоханулся и не обратил внимания, что в случае отсутствия поступающих данных программа выполняет совсем другой цикл, в котором то и не было никакого application.processmessages. Всунул его и в тот цикл ожидания данных, точнее прямо в процедуру чтения, туда где начисляется таймаут, и кнопка "стоп" ожила!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)