Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2008.08.03;
Скачать: [xml.tar.bz2];

Вниз

почему не срабатывает таймер?   Найти похожие ветки 

 
Сергей М. ©   (2007-11-01 08:30) [40]

Причем здесь другой поток ?

SleepEx у тебя сработал ? Сработал.
TimerAPCProc вызывается при этом ? Вызывается.
Ответ на вопрос ты получил ? Получил.

Так в чем же дело ?


 
Dmitry_177   (2007-11-01 15:37) [41]

Dmitry_177   (30.10.07 18:59) [35] и Dmitry_177   (30.10.07 19:07) [36]


 
Сергей М. ©   (2007-11-01 15:51) [42]


> Dmitry_177   (01.11.07 15:37) [41]



> SleepEx уже не спасает


А от чего он должен "спасти" ?

От "несрабатывания таймера" он тебя "спас", что ты еще от него хочешь ?


 
Dmitry_177   (2007-11-01 16:08) [43]

чтобы в такой "конструкции" событие срабатывало или может как-то подругому сделать..


 
Сергей М. ©   (2007-11-01 16:12) [44]

Каким боком SleepEx относится к "срабатыванию события" ?
Никаким.


 
Dmitry_177   (2007-11-01 16:16) [45]

странно почему тогда оно не срабатывает, приведу весь код:

первая программа, та которая устанавливает таймеры и реагирует на событие для считывания новых таймеров из файла(запущена постоянно):

program TimeServ;

uses
 Windows,
 Messages,
 ShFolder,
 Classes,
 IniFiles,
 SysUtils;

const
 EventName = "{58F4D8A4-CAD7-46DA-A3D1-238B95659E68}";

type
 PDataTimer = ^TDataTimer;

 TDataTimer = packed record   // структура, адрес переменной которой передается в TimerAPCProc
   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);   // период записывается в формате DateTime, перевожу в миллисекунды
           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);   // Close
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% дергается..


 
Сергей М. ©   (2007-11-01 16:26) [46]

Все понятно.
Но причем здесь SleepEx ? Она не имеет никакого отношения к потоку, выполняющему ф-цию ThreadEvent.


 
Dmitry_177   (2007-11-01 16:32) [47]

странно, но почему тогда событие не работает? останавливается на WaitForSingleObject в ThreadEvent и все..


 
Сергей М. ©   (2007-11-01 16:43) [48]

Значит константы EventName в этих проектах не совпадают.


 
Dmitry_177   (2007-11-01 16:48) [49]

смотрел, 100% совпадают.. еслиб даже не совпадали бы то в FormClose не сработало бы условие: if GetLastError = ERROR_ALREADY_EXISTS then  Значение EventName как вы наверно догадались я генерировал Ctl+Shift+G


 
Сергей М. ©   (2007-11-01 16:52) [50]

А нафига этот поток нужен вообще ?

Чем не устроила WaitForSingleObjectEx прямо в основном потоке ?
И почем в осн.потоке нет цикла вызова Ex-функции ? Ты вообще в [8] вник ?


 
Dmitry_177   (2007-11-01 21:58) [51]


> Чем не устроила WaitForSingleObjectEx прямо в основном потоке
> ?

А как ее применить в основном потоке? Вот так?


InstallTimers;

hEvent := CreateEvent(nil, false, false, EventName);
while true do
 begin
   if WaitForSingleObjectEx(hEvent, INFINITE, True) = WAIT_OBJECT_0 then
     begin
       UninstallTimers;
       InstallTimers;
     end;
 end;


 
Leonid Troyanovsky ©   (2007-11-01 22:11) [52]


> Dmitry_177   (01.11.07 21:58) [51]

RTFM бы ты, Джеф Рихтер: Windows для профи.
Ну, или, хотя б, msdn.

--
Regards, LVT.


 
Dmitry_177   (2007-11-01 23:33) [53]

а действительно так заработало, как я написал в Dmitry_177   (01.11.07 21:58) [51]

кстати мы создаем в InstallTimers, структуры TDataTimer: New(DataTimer); удаляем их в TimerAPCProc: Dispose(lpArgToCompletionRoutine);.. А если время срабатывания будет удалено в той второй программе, то получается DataTimer не удалится?


 
Dmitry_177   (2007-11-05 14:02) [54]

на самом деле как тогда удалять DataTimer? вот задам я таймер в той программе, в этой создастся DataTimer и установится таймер.. А потом в той программе удалю этот таймер.. то что будет с DataTimer? Как его удалять?



Страницы: 1 2 вся ветка

Форум: "WinAPI";
Текущий архив: 2008.08.03;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.56 MB
Время: 0.008 c
2-1215154601
JohnKorsh
2008-07-04 10:56
2008.08.03
Арабский формат ввода текста в Memo или RichEdit.


15-1213881136
Ega23
2008-06-19 17:12
2008.08.03
packed object - в какой версии Delphi появился?


2-1214976925
lewka-serdceed
2008-07-02 09:35
2008.08.03
ключ в реестре


6-1191559374
AndreyRu
2007-10-05 08:42
2008.08.03
TICQClient и HTTP proxy


2-1215254494
RealSwift
2008-07-05 14:41
2008.08.03
Перевести запрос к MDB из VB в DELPHI





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский