![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
почему не срабатывает таймер? [D7, WinXP]
Dmitry_177 © (2007-10-29 13:44:00)Есть ini-файл, из него считывается время срабатывания таймеров(их несколько) но почему то не срабатывает таймер.. Приведу весь кусок кода:
program TimeServ;
uses
Windows,
Messages,
Classes,
IniFiles,
SysUtils;
var
AMessage: TMsg;
hTimers: array of THandle;
procedure TimerAPCProc(lpArgToCompletionRoutine: PChar; dwTimerLowValue: DWORD; dwTimerHighValue: DWORD); stdcall;
begin
MessageBox(0, '1', '1', 0); // не срабатывает почему то..
end;
function InstallTimers: BOOL;
var
Sections: TStrings;
iTimer: integer;
sysTime: SYSTEMTIME;
fTime: FILETIME;
begin
try
Sections := TStringList.Create;
with TIniFile.Create('TimeManager.ini') do
try
ReadSections(Sections);
if Sections.Count > 0 then
begin
SetLength(hTimers, Sections.Count);
for iTimer := 0 to Sections.Count - 1 do
begin
hTimers[iTimer] := CreateWaitableTimer(nil, false, nil);
DateTimeToSystemTime(StrToDateTime(Sections[iTimer]), sysTime); // запись происходит функцией DateTimeToStr, в переменной sysTime смотрел дата с временем правильно считывается..
SystemTimeToFileTime(sysTime, fTime);
LocalFileTimeToFileTime(fTime, fTime);
SetWaitableTimer(hTimers[iTimer], TLargeInteger(fTime), 0, @TimerAPCProc, nil, false);
end;
end;
finally
Free;
end;
finally
Sections.Free;
end;
end;
function UninstallTimers: BOOL;
var
iTimer: integer;
begin
for iTimer := 0 to Length(hTimers) - 1 do
begin
CancelWaitableTimer(hTimers[iTimer]);
CloseHandle(hTimers[iTimer]);
end;
SetLength(hTimers, 0);
end;
begin
InstallTimers;
while GetMessage(AMessage, 0, 0, 0) do
DispatchMessage(AMessage);
UninstallTimers;
end.
Подскажите пожалуйста..
Dmitry_177 (2007-10-30 17:18:00) [21]я так и понял :) спасибо!
Сергей М. (2007-10-30 17:15:00) [22]Только ведь в теле TimerAPCProc у тебя не будет никаких pdt, а будет 1-й параметр указательного типа, его и указывай в кач-ве параметра для Dispose
Сергей М. (2007-10-30 17:13:00) [23]разумеется !
Dmitry_177 (2007-10-30 17:09:00) [24]Спасибо! соответственно и удалято тогда Dispose(pdt) ?
Сергей М. (2007-10-30 16:52:00) [25]например, так:
PDataTimer = ^TDataTimer;
TDataTimer = packed record
..
end;
..
pdt: PDataTimer;
..
New(pdt);
Dmitry_177 (2007-10-30 16:20:00) [26]а как их тогда создавать?
Сергей М. (2007-10-30 16:13:00) [27]
> она разве не создана?
>
Создана.
В единственном экз-ре.
А у тебя куча объектов-таймеров, и каждый из них при таком решении нуждается в собственномэкз-ре.
Dmitry_177 (2007-10-30 16:08:00) [28]
> - Перед вызовом SetWaitableTimer создать экз-р структуры
> TDataTimer
если она объявлена в разделе описания переменных:
var
DataTimer: TDataTimer;
она разве не создана?
Сергей М. (2007-10-30 15:57:00) [29]- Перед вызовом SetWaitableTimer создать экз-р структуры TDataTimer
- Заполнить поле hTimer этой структуры хэндлом соотв.таймера
- Вызвать SetWaitableTimer, передав параметром указательна этот экз-р
- В теле TimerAPCProc при необходимости уничтожить этот экз-р, ибо ссылка на него передана 1-м параметром и доступна.
Dmitry_177 (2007-10-30 15:52:00) [30]
> Нафига ?
а что тогда можно сделать?
Сергей М. (2007-10-30 15:51:00) [31]
> придется еще и массив этих структур создавать?
>
Нафига ?
> Вот так ошибка: Invalid typecast
Почему бы и нет, если ты тип, несовместимый с указательным, пытаешься привести к указательному ?
Dmitry_177 (2007-10-30 15:41:00) [32]
function InstallTimers: BOOL;
var
DataTimer: TDataTimer;
begin
...
DataTimer.hTimer := hTimers[iTimer];
DataTimer.StrDateTime := PChar(Sections[iTimer]);
SetWaitableTimer(hTimers[iTimer], TLargeInteger(fTime), 60000, @TimerAPCProc, Pointer(DataTimer), false);
...
end;
Вот так ошибка: Invalid typecast
Dmitry_177 (2007-10-30 15:12:00) [33]свою структуру? в принципе да.. т.е. если сделать как-нибудь так:
type
TDataTimer = packed record
hTimer: THandle;
Str: PChar;
end;
то придется еще и массив этих структур создавать?
Сергей М. (2007-10-30 15:06:00) [34]
> мне нужно еще и строку передавать
А про record'ы ты что-нить слышал ?)
Dmitry_177 (2007-10-30 14:59:00) [35]мне нужно еще и строку передавать..
Сергей М. (2007-10-30 14:56:00) [36]
> можно ли в TimerAPCProc определить какой таймер сработал?
На то у TimerAPCProc и существует 1-й параметр - передавай через него хоть хэндл, хоть черта лысого)
Dmitry_177 (2007-10-30 14:29:00) [37]Еще маленький вопросик, можно ли в TimerAPCProc определить какой таймер сработал? Ведь если таймер с периодом он так и будет дергать TimerAPCProc, так вот если уже больше он не понадобится, чтоб можно его было хлопнуть в этой же TimerAPCProc..
Dmitry_177 (2007-10-30 13:51:00) [38]блин, торможу сорри.. сделал Sections глобальной переменной и все ок
Dmitry_177 (2007-10-30 13:34:00) [39]да уж.. а как тогда? Может так тогда?
var
str: string;
function InstallTimers: BOOL;
begin
...
str := PChar(Sections[iTimer]);
SetWaitableTimer(hTimers[iTimer], TLargeInteger(fTime), 0, @TimerAPCProc, PChar(str), false);
...
end;
Сергей М. (2007-10-30 08:15:00) [40]
> Dmitry_177 (29.10.07 22:30) [13]
Так делать нельзя вообще.
Выражением
PChar(Sections[iTimer])
ты передал адрес строки, время жизни которой равно времени жизни объекта Sections, который уничтожается тобой сразу же по возврату из InstallTimers.