Потоки в консольном приложении

Вопросы использования сторонних (не входящих в состав FPC и Lazarus) утилит и библиотек.

Модератор: Модераторы

Потоки в консольном приложении

Сообщение Gorjatschew » 24.08.2008 21:23:56

Здравствуйте!
У меня к вам такой вопрос: пишу программу, которая должна пищать системным динамиком и одновременно проигрывать музыкальный файл.
Проблема в том, что попытавшись добиться одновременности, использовал потоки, но, наверное, я чего-то в них недопонимаю.
Программа писалась на делфях.
Вот код:
beep.dpr
Код: Выделить всё
uses
  Thread in 'Thread.pas',
  Windows, SysUtils, Classes, mmsystem;

var
  frequency, duration, count, delay: Integer;
  I: Integer;

procedure Play;
var
  so: TSyncObj;
begin
  so:=TSyncObj.Create(true);
  so.Resume;
  so.Priority:=tpNormal;
//  so.Terminate;
end;

begin
//Если есть флаги частоты и длительности
  if (FindCmdLineSwitch('f', ['-'], true) and FindCmdLineSwitch('d', ['-'], true)) then
    begin
      frequency:=StrToIntDef(ParamStr(2), 2400);
      duration:=StrToIntDef(ParamStr(4), 2500);
//если есть флаги числа повторений и задержки
      if (FindCmdLineSwitch('c', ['-'], true) and FindCmdLineSwitch('s', ['-'], true)) then
        begin
          count:=StrToIntDef(ParamStr(6), 1);
          delay:=StrToIntDef(ParamStr(8), 0);
            for I:=0 to count-1 do
              begin
                Windows.Beep(frequency, duration);
                Play;
                sleep(delay)
              end;
        end
      else
        begin
          Windows.Beep(frequency, duration);
          Play;
        end;
    end
  else
    begin
      if FindCmdLineSwitch('o', ['-'], true) then
        begin
          Play;
        end
      else
        if FindCmdLineSwitch('h', ['-'], true) then
          begin
            MessageBox(0, 'Beep ver. 0.1.5', 'About', MB_ICONINFORMATION);
          end
        else
          Windows.Beep(2400, 2500);
    end;
end.

Thread.pas
Код: Выделить всё
unit Thread;

interface

uses
  Classes;

type
  TSyncObj = class(TThread)
  private
    { Private declarations }
    procedure Play;
  protected
    procedure Execute; override;
  end;

implementation

uses
  Play;

{ Important: Methods and properties of objects in VCL can only be used in a
  method called using Synchronize, for example,

      Synchronize(UpdateCaption);

  and UpdateCaption could look like,

    procedure TSyncObj.UpdateCaption;
    begin
      Form1.Caption := 'Updated in a thread';
    end; }

{ TSyncObj }

procedure TSyncObj.Execute;
begin
  { Place thread code here }
  Synchronize(Play);
  if Terminated then exit;
end;

procedure TSyncObj.Play;
begin
  PlayAlarm;
end;

end.

и Play.pas
Код: Выделить всё
unit Play;

interface

uses
  SysUtils, mmsystem;

procedure PlayAlarm;

implementation

procedure PlayAlarm;
begin
//если есть флаг на проигрывание файла
  if FindCmdLineSwitch('o', ['-'], true) then
    begin
//если при этом есть флаги на пищалку
      if (FindCmdLineSwitch('-f', ['-'], true) and FindCmdLineSwitch('-d', ['-'], true)) then
        begin
//и на распределение длительности
          if (FindCmdLineSwitch('-c', ['-'], true) and FindCmdLineSwitch('-s', ['-'], true)) then
            PlaySound(PChar(ParamStr(10)),0,SND_FILENAME)
          else
//просто пищалка
            PlaySound(PChar(ParamStr(6)),0,SND_FILENAME)
        end
      else
//просто проиграть файл
        PlaySound(PChar(ParamStr(2)),0,SND_FILENAME)
    end;
end;

end.


Заранее спасибо!
И если кто предложит альтернативный, причём кроссплатформенный метод, буду благодарен.
З.Ы.
Писал на fpc, запускалось, но на время исполнения на экране появлялось окно командной строки, что не есть гут.
Аватара пользователя
Gorjatschew
новенький
 
Сообщения: 23
Зарегистрирован: 15.01.2008 18:57:06
Откуда: Санкт-Петербург

Re: Потоки в консольном приложении

Сообщение Deepthroat » 25.08.2008 23:57:53

Так а что конкретно не получается? Консольное окно? Ну так {$APPTYPE CONSOLE}. Или что-то еще не так?
Последний раз редактировалось Deepthroat 30.08.2008 00:37:02, всего редактировалось 1 раз.
Аватара пользователя
Deepthroat
постоялец
 
Сообщения: 144
Зарегистрирован: 06.09.2007 00:21:34
Откуда: Outer Heaven

Re: Потоки в консольном приложении

Сообщение Gorjatschew » 29.08.2008 14:48:47

Deepthroat писал(а):Так а что конкретно не получается? Консольное окно? Ну так {$APPTYPE GUI}. Или что-то еще не так?

Просто не пашет поток :)
Когда в отладке запускаю, вижу, как он проходит по потоку, но воспроизведения звука почему-то нет.
Аватара пользователя
Gorjatschew
новенький
 
Сообщения: 23
Зарегистрирован: 15.01.2008 18:57:06
Откуда: Санкт-Петербург

Re: Потоки в консольном приложении

Сообщение PublicJoke » 29.08.2008 15:19:27

1) Почитайте, для чего нужен и, главное, как работает Synchronize. Причем тут консольное приложение? Вызывайте PlayAlarm непосредственно из Execute
2) Play надо вызывать перед Beep, поскольку Beep - синхронный. Либо оформить его вызов из еще одного потока
3) Не увидел в beep.dpr строки {$APPTYPE CONSOLE}
4) После внесения вышеуказанных изменений у меня все работает (только с ключами Вы, на мой взгляд, намудрили)
5) Если не хотите следить за жизнью потока, рекомендую поставить у него FreeOnTerminate в True
PublicJoke
новенький
 
Сообщения: 41
Зарегистрирован: 04.07.2006 12:21:07


Вернуться в Сторонние средства

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 7

Рейтинг@Mail.ru