не запускается таймер

Вопросы программирования и использования среды Lazarus.

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

не запускается таймер

Сообщение der_win » 20.03.2011 17:05:39

Пишу программу-звонилку
Создаю на форме таймер ShowNews: TTimer, изначально выключен
Есть процедура callback, которая отображает ход подключения
Код: Выделить всё
procedure Callback(hrasconn: HRasConn; msg: integer; state: RASCONNSTATE;
  error, dwExtendedError: integer); stdcall;           
var
  ErrTitle, ErrHint: string;
  WErrHint: WideString;
  s: array [0..512] of widechar;
  e: integer;   
begin   
try
  ...много кода....
    case state of
      RASCS_Connected:
      begin
        // активируем таймер новостей
        ConfigForm.ShowNews.Enabled:=true;  // здесь запускаем таймер
        // закончили работу с таймером новостей
        Connected := True;
        Connecting := False;
        ConfigForm.ConnImg.Picture.LoadFromLazarusResource('button_disconnect');
       end;
    end;
  except
    ConfigForm.disconnect();
  end;           

вызывается он вот так
Код: Выделить всё
function TConfigForm.connect(): DWORD;   
var
  a, dwSize: longint;
  lpfPassword: longbool;
  RE: RASENTRY;
  RD: RASDIALPARAMSW;
  Conn: TConnectionType;       
begin 
...много кода....
// тут мы загоняем параметры соединения в dll
Result := RasDialW(nil, nil, RD, 1, @Callback, hConn);


вопрос такой. Почему таймер не активируется?
Пробовал сделать через public функцию - всё равно не активируется...
Я понимаю что звучит бредово - но я уже 3й день бьюсь и не могу понять почему именно с этого места именно таймер не активируется.
Лазарь 0.9.31 дата 2011-02-25
fpc 2.5.1
win XP
der_win
новенький
 
Сообщения: 19
Зарегистрирован: 10.02.2011 18:44:18

Re: не запускается таймер

Сообщение Ism » 20.03.2011 18:03:20

Как вариант, вы выполняете какуюто функцию, а пока она не отработает таймер будет стоять, так как не может срабатывать во время выполнения другого кода (но это теоретически)
Ism
энтузиаст
 
Сообщения: 908
Зарегистрирован: 06.04.2007 17:36:08

Re: не запускается таймер

Сообщение der_win » 20.03.2011 18:33:24

свои варианты я знаю, но нужно именно так и именно отсюда
нашёл похожую проблему http://forum.vingrad.ru/forum/topic-319 ... D0%BA.html
http://forum.sources.ru/index.php?showtopic=6807&hl=
мне нужен способ как это сделать. Может быть я забыл указать какую нить синхронизацию.....
А лучше всего хочется услышать объяснение почему так происходит
der_win
новенький
 
Сообщения: 19
Зарегистрирован: 10.02.2011 18:44:18

Re: не запускается таймер

Сообщение Padre_Mortius » 20.03.2011 18:50:43

без кода вашего проекта получается гадание на кофейной гуще
Padre_Mortius
энтузиаст
 
Сообщения: 1265
Зарегистрирован: 29.05.2007 17:38:07
Откуда: Спб

Re: не запускается таймер

Сообщение Maxizar » 20.03.2011 19:15:16

1 - Где гарантия, того, что до включение таймера вообще доходит дело?..., по этому без кода ничего не ясно…(По этому Padre_Mortius получает +1 В башню). Вы скажите все доходит и все такое, и ошибка в другом… чтобы этого не было набросал такую же ситуацию… Форма, на которой есть таймер, есть процедура, которая включает этот таймер… но запускаем мы его очень хитро, при нажатии кнопки, вызываем процедуру из Dll, в которой и вызывается эта процедура….
Код DLL:
Код: Выделить всё
library project1;

{$mode objfpc}{$H+}

uses
  Classes
  { you can add units after this };
type
   TStartTimerProc = procedure; register;

procedure RunTimer(P:TStartTimerProc);register;
begin
if P<>Nil then
  P;

end;

{$R *.res}

Exports

RunTimer    index 1 name 'RunTimer';
begin
end.

Код формы:
Код: Выделить всё
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls;

type
TStartTimerProc = procedure;register;
  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Timer1: TTimer;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

procedure StartTimer;

var
  Form1: TForm1;
  I:Integer;
implementation

procedure RunTimer(P:TStartTimerProc); register;  External 'project1.dll';

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin
  RunTimer(@StartTimer);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  I:=0;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Caption:=IntToStr(I);
  Timer1.Enabled:=False;
  inc(I);
end;

procedure StartTimer;
begin
   Form1.Timer1.Enabled:=True;
end;
end.

Вот исходники всего проекта: http://zalil.ru/30704910

У меня все вкл и все работает…Каждое нажатие, кнопки будет сопровождаться запуском таймера через процедуру в ДЛЛ. Каждый запуск инкрементирует переменную I….

2 – По этому либо протрассируйте код по шагам.
3 – И почему вообще возникла такая необходимость?... зачем все так усложнять и делать через Париж…. Совет который предложил Ism боле простой, и более правильный.
Я бы переделал логику работы именно в этом куске кода.. а то вызывать (вкл) таймер через функцию (метод) формы, но вызывать ее в процедуре из длл… Не ну честно, это из жанра, пускай все думают почему так…
Я бы переделал так:
Вызываем функцию из Длл, которая вернет значение, которое будет говорить нам, о том, что нужно сделать дальше, в том числе и вкл\выкл таймер…
Если же вы упертый, и сделать нужно именно так: то я Вам показал, что если дело доходит до вкл или до вызова из ДЛЛ, то все хорошо...
Maxizar
постоялец
 
Сообщения: 385
Зарегистрирован: 20.03.2010 19:48:14

Re: не запускается таймер

Сообщение der_win » 21.03.2011 14:12:40

код в месте вызова выполняется :) это и обновление переменных, и замена рисунка кнопки....
Пошёл дальше и сделал ещё более интересную вещь.
Под строкой ConfigForm.ShowNews.Enabled:=true; сделал простую проверку
if ConfigForm.ShowNews.Enabled=true then begin .... end
else begin .... end
И о чудо! Проверка говорит что Enabled=true :) НО таймер не срабатывает!!!! я вообще в растерянности.....
Ещё вчера была идея что косяк где то в самом событии таймера, но если активировать его после нажатия кнопки на гланой форме - всё работает.......
И всё таки, остался нерешёный вопрос, я уже говорил что сделал процедуру в public у класса ConfigForm
Код: Выделить всё
procedure  ConfigForm.SetActiveTimer();
begin
  ConfigForm.ShowNews.Enabled:=true;
end;


Почему если делать вызов этой функции из того же самого места - результат нулевой? я всё таки думаю тут какая то проблема с потоками...
Собственно, понимаю что вопрос риторический, так что пофиг, сделаю костыль, иначе не успею сдать проект.... всё таки хочется узнать, баг это или просто я чего то не знаю
der_win
новенький
 
Сообщения: 19
Зарегистрирован: 10.02.2011 18:44:18

Re: не запускается таймер

Сообщение stikriz » 21.03.2011 23:14:36

Application.ProcessMessages в Ваш код вставьте.
Аватара пользователя
stikriz
энтузиаст
 
Сообщения: 612
Зарегистрирован: 15.03.2006 09:37:47

Re: не запускается таймер

Сообщение dunin » 22.03.2011 09:09:32

Как версия... Если я правильно понял, то что-то похожее у мну было, только не с таймером. Процедура от события отваливалась. Принудительно попробуйте привязать. Как-то так:
Код: Выделить всё
ConfigForm.ShowNews.OnTimer:= @ConfigForm.ShowNewsTimer;
...
ConfigForm.ShowNews.Enabled:=true;  // здесь запускаем таймер
...
Аватара пользователя
dunin
энтузиаст
 
Сообщения: 634
Зарегистрирован: 02.05.2007 13:18:11
Откуда: Тољя††и

Re: не запускается таймер

Сообщение der_win » 06.04.2011 17:46:18

процедура не отваливается. Проблема с тем, что таймер можно ВЫКЛЮЧИТЬ, но нельзя включить из другого потока (коим является функция обратного вызова callback).
И дебаггер показывает что в таймер включен после этого кода.
Думаю проблема связана с синхронизацией, но т.к. поток явно не задан - придётся делать синхронизацию через другой поток и эвенты.........
der_win
новенький
 
Сообщения: 19
Зарегистрирован: 10.02.2011 18:44:18


Вернуться в Lazarus

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

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

Рейтинг@Mail.ru