странно почему тогда оно не срабатывает, приведу весь код:
первая программа, та которая устанавливает таймеры и реагирует на событие для считывания новых таймеров из файла(запущена постоянно):program TimeServ;
uses
Windows,
Messages,
ShFolder,
Classes,
IniFiles,
SysUtils;
const
EventName = '';
type
PDataTimer = ^TDataTimer;
TDataTimer = packed record
hTimer: THandle;
StrDateTime: PChar;
end;
var
hEvent: THandle;
idThread: DWORD;
hTimers: array of THandle;
StrFilePath: string;
Sections: TStrings;
function GetStrFilePath: string;
var
StrBuffer: array [0 .. MAX_PATH - 1] of Char;
StrAppDataFolder: string;
begin
ShGetFolderPath(0, CSIDL_APPDATA, 0, 0, StrBuffer);
StrAppDataFolder := StrBuffer + '\TimeManager';
if not DirectoryExists(StrAppDataFolder) then
ForceDirectories(StrAppDataFolder);
Result := StrAppDataFolder + '\TimeManager.ini';
end;
procedure TimerAPCProc(lpArgToCompletionRoutine: PDataTimer; dwTimerLowValue: DWORD; dwTimerHighValue: DWORD); stdcall;
begin
with TIniFile.Create(StrFilePath) do
try
if MessageBox(0, PChar(ReadString(lpArgToCompletionRoutine.StrDateTime, 'Note', '') + #13#10#13#10 + 'Удалить это напоминание?'), 'Напоминание', MB_ICONQUESTION or MB_YESNO) = idYes then
begin
CancelWaitableTimer(lpArgToCompletionRoutine.hTimer);
CloseHandle(lpArgToCompletionRoutine.hTimer);
EraseSection(lpArgToCompletionRoutine.StrDateTime);
Dispose(lpArgToCompletionRoutine);
end;
finally
Free;
end;
end;
procedure InstallTimers;
var
iTimer: integer;
sysTime: SYSTEMTIME;
fTime: FILETIME;
DataTimer: PDataTimer;
begin
with TIniFile.Create(StrFilePath) 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);
SystemTimeToFileTime(sysTime, fTime);
LocalFileTimeToFileTime(fTime, fTime);
New(DataTimer);
DataTimer.hTimer := hTimers[iTimer];
DataTimer.StrDateTime := PChar(Sections[iTimer]);
SetWaitableTimer(hTimers[iTimer], TLargeInteger(fTime), Round(Frac(StrToDateTime(ReadString(Sections[iTimer], 'Period', '0'))) * 86400) * 1000, @TimerAPCProc, DataTimer, false);
end;
end;
finally
Free;
end;
end;
procedure UninstallTimers;
var
iTimer: integer;
begin
for iTimer := 0 to Length(hTimers) - 1 do
begin
CancelWaitableTimer(hTimers[iTimer]);
CloseHandle(hTimers[iTimer]);
end;
SetLength(hTimers, 0);
Sections.Clear;
end;
function ThreadEvent(Param: Pointer): DWORD; stdcall;
begin
while true do
begin
if WaitForSingleObject(hEvent, INFINITE) = WAIT_OBJECT_0 then
begin
UninstallTimers;
InstallTimers;
end;
end;
Result := 0;
end;
begin
StrFilePath := GetStrFilePath;
Sections := TStringList.Create;
InstallTimers;
hEvent := CreateEvent(nil, false, false, EventName);
CloseHandle(CreateThread(nil, 0, @ThreadEvent, nil, 0, idThread));
while true do
SleepEx(INFINITE, True);
UninstallTimers;
Sections.Free;
end.
теперь вторая, та которая записывает таймеры и дергает событие(запускается нерегулярно):в ней в принципе ничего сложного нету, она записывает в файл таймеры, которые вводятся с использованием форм и по завершению дергает событие.. Я думаю саму запись ненужно показывать, приведу FormClose, который собственно и дергает событие:
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
hEvent: THandle;
begin
hEvent := CreateEvent(nil, false, false, EventName);
if hEvent = INVALID_HANDLE_VALUE then
Exit;
if GetLastError = ERROR_ALREADY_EXISTS then
SetEvent(hEvent);
CloseHandle(hEvent);
end;
Код трассировал, SetEvent срабатывает, т.е. само событие 100% дергается..