Форум: "KOL";
Текущий архив: 2007.06.03;
Скачать: [xml.tar.bz2];
ВнизTimer & Messages BUG !!! Найти похожие ветки
← →
AndreyRus (2006-09-11 04:55) [0]Я обнаружил, что сообщение (возможно не только WM_POWERBROADCAST) обрабатывается дважды, если в программе используется таймер.
function TForm1.KOLForm1Message(var Msg: tagMSG; var Rslt: Integer): Boolean;
begin
Result:= false;
if Msg.message = WM_POWERBROADCAST then
begin
MsgOk("APM Event detected - " + UInt2Str(Msg.wParam));
result:= true;
end;
end;
← →
AndreyRus (2006-09-14 10:56) [1]Уважаемый Владимир Кладов, пожалуйста, обратите внимание на эту тему.
← →
Unknown Mystic © (2006-09-14 11:01) [2]А ты уверен, что это сообщение идет не двум разным объектам, а одному?
Если не ошибаюсь, то, например, форма получает и все сообщения идущие объектам на ней...
← →
AndreyRus (2006-09-15 00:31) [3]
> А ты уверен, что это сообщение идет не двум разным объектам,
> а одному?
Вы хотите сказать, что Windows посылает сообщения как окну, так и таймеру? :)
← →
homm © (2006-09-15 06:13) [4]
> MsgOk("APM Event detected - " + UInt2Str(Msg.wParam));
Замени на запись лога в файл, если все равно 2 записи будет, тогда есть о чем говорить.
← →
AndreyRus (2006-09-15 14:27) [5]Делал, конечно. Все равно приходит два события.
← →
AndreyRus (2006-09-25 22:03) [6]Люди добрые, да помогите! Подскажите, где копать?
← →
Vladimir Kladov (2006-09-26 15:14) [7]в VCL смотрели?
Вообще-то, это широковещательное оповещение. Не факт, что оно должно приходить ровно 1 раз. А вы его на форме ловите? Может, лучше на Applet"е.
← →
AndreyRus (2006-09-27 04:40) [8]
> в VCL смотрели?type
TForm1 = class(TForm)
Timer1: TTimer;
procedure PWRSUSPENDRESUME (var Message: TMessage); message WM_POWERBROADCAST;
procedure Timer1Timer(Sender: TObject);
end;
procedure TForm1.PWRSUSPENDRESUME (var Message: TMessage);
begin
ShowMessage("APM Event detected - " + IntToStr(Message.wParam));
end;
Попробовал.... Ошибки нет.
> Вообще-то, это широковещательное оповещение. Не факт, что
> оно должно приходить ровно 1 раз.
Несогласен.
> А вы его на форме ловите? Может, лучше на Applet"е.
Попробовал... Вообще прикол - сообщение приходит 3 раза.
← →
Vladimir Kladov (2006-09-27 15:59) [9]Тогда проверьте отправителя в Msg.hwnd. Видимо, оно приходит нескольким окнам в приложении, но у нас Applet ловит все сообщения, от всех окон.
← →
AndreyRus (2006-09-27 22:09) [10]
if Msg.message = WM_POWERBROADCAST then
begin
MsgOk("APM Event detected - " + UInt2Str(Msg.wParam) + ". hWnd - " + UInt2Str(Msg.hwnd));
result:= true;
end;
Msg.hwnd отличается.
Владимир, не могли бы Вы описать диспечеризацию событий в КОЛ?
← →
AndreyRus (2006-09-30 04:51) [11]
> Владимир, не могли бы Вы описать диспечеризацию событий
> в КОЛ?
И какое отношение к нему имеет таймер?
← →
Vladimir Kladov (2006-09-30 08:56) [12]существуют таймеры с callback ом и таймеры посылающие сообщения окну. Мы используем вторые вроде. Так что особо никакого отношения нет, просто сообщение WM_TIMER должно проходить по тому же маршруту, что и все прочие.
← →
Unknown Mystic © (2006-10-01 00:28) [13]
> Msg.hwnd отличается.
А то сразу на меня напустились вместо того, чтоб проверить... ;)
← →
AndreyRus (2006-10-04 02:16) [14]Так почему же, если на форме расположен активный таймер, то приходят два сообщения, а если таймера нет, то одно?
← →
Unknown Mystic © (2006-10-04 12:24) [15]А какому все таки каждое из сообщений идет? И что происходит, если таймер не активный?
← →
AndreyRus (2006-10-04 19:47) [16]
> что происходит, если таймер не активный?
Если таймер не активный, то все работает так как и должно - сообщение приходит однократно. Причем, если MultiMedia:= true, то глюк исчезает.
← →
AndreyRus (2006-10-06 22:23) [17]
procedure TTimer.SetEnabled(const Value: Boolean);
begin
if Value then
begin
if TimerOwnerWnd = nil then
begin
TimerOwnerWnd := _NewWindowed( nil, "", TRUE ); // !!!
TimerOwnerWnd.fStyle := 0;
TimerOwnerWnd.fIsControl := TRUE;
end;
end;
Уважаемый Владимир Кладов, а зачем создается дополнительно окно при использовании таймера?
← →
Vladimir Kladov (2006-10-07 06:39) [18]Да, я совсем забыл. В начальных версиях для этого использовался апплет. Потом выяснилось, что есть люди, которые хотят иметь возможность работать с таймером даже при отсутствии в приложении окон. В принципе, несложно сделать IFDEF"ом, чтобы снова использовалось окно апплета. Так всяко лучше для размера, чем проверять наличие присвоенного, и ветвить код.
← →
AndreyRus (2006-10-07 11:15) [19]А как быть, если в приложении не используется Applet, а его роль выполняет обычная форма (TKOLForm)?
← →
Vladimir Kladov (2006-10-07 11:41) [20]Тогда Applet = этой форме.
← →
AndreyRus (2006-10-07 12:49) [21]Логично :)
IMHO. В таком случае лучше использовать не директивы условной компиляции, а код размером несколько байт
if Applet = nil then {} else {}
← →
Vladimir Kladov (2006-10-08 07:49) [22]несколько байт будет if. А вот то, чот будет в {} будет больше, и потребует еще кое-чего вне {}.
← →
AndreyRus (2006-10-08 09:45) [23]Я вот, что подумал. Те, кому нужно использование таймера без единого окна, могут реализовать его и на API, т.к. ничего особо сложного в этом нет. Большенство других программ используют хотя бы одно окно. Поэтому, условная директива компиляции должна именно исключать код создающий дополнительно окно. К тому же это позволит сэкономить несколько байт. Предлагаю назвать директиву - TimerWithWindow.
← →
Vladimir Kladov (2006-10-08 12:17) [24]в проектах mck были проблемы с созданием таймера, потому вариант с отдельным окном и пришелся ко двору. Вообще непонятно, чем плохо иметь единственное окно для всех простых таймеров. Для нас главное, что требует мало кода. Я так и не проверил возможность работы вообще без окна, вроде в msdn что-то мельком написано.
← →
AndreyRus (2006-10-08 14:58) [25]Если вообще без окна, то лучше использовать CallBack функцию указываемую при создании таймера. Либо путем создания бесполезного окна, которому будет приходить сообщение WM_TIMER, в очереди сообщений которого нужно отлавливать и обрабатывать срабатывание таймера.
← →
Vladimir Kladov (2006-10-08 15:40) [26]вообще без окна не получается узнать от какого объекта пришло событие. От апплета не получается правильно уничтожить таймер, потому что в этот момент Aplet уже nil. Проще оставить как есть.
← →
AndreyRus (2006-10-10 17:24) [27]> От апплета не получается правильно уничтожить таймер, потому что в этот момент Aplet уже nil.
А как раньше то работало?
> Проще оставить как есть.
Проще то оно проще, но в этом случае необходимо задокументировать эту особенность в реализации таймера, т.к. на эти "грабли" будут периодически наступать.
function NewForm( AParent: PControl; const Caption: String ): PControl;
{* |<#control>
Creates form window object and returns pointer to it. If You use only one form,
and You are not going to do applet button on task bar invisible, it is not
necessary to create also special applet button window - just pass
your (main) form object to Run procedure. In that case, it is a good
idea to assign pointer to your main form object to Applet variable
immediately following creating it - because some objects (e.g. TTimer)
want to have Applet assigned to something.
TTimer = object( TObj )
{* Easy timer incapsulation object. Uses applet window to
receive timer events. So, either assign your main form
to Applet variable or create applet button object (and
assign it to Applet) before enabling timer. }
property Enabled : Boolean read fEnabled write SetEnabled;
{* True, is timer is on. Initially, always False. Before assigning True,
make sure, that Applet global variable is assigned to applet object
(NewApplet) or to form (NewForm). }
← →
Vladimir Kladov (2006-10-10 19:43) [28]оставить как есть - я имею в виду как сейчас. С отдельным окном. Окно на все таймеры одно. А не через апплет.
← →
AndreyRus (2006-10-11 10:13) [29]
> Да, я совсем забыл. В начальных версиях для этого использовался
> апплет.В принципе, несложно сделать IFDEF"ом, чтобы снова
> использовалось окно апплета.
> От апплета не получается правильно уничтожить таймер, потому
> что в этот момент Aplet уже nil.
Уважаемый Владимир! Вы пишите прямо противоположные вещи.
P.S. В посте [27] я указал места в KOL, которые не соответствую реальному положению дел.
← →
Vladimir Kladov (2006-10-11 20:03) [30]это комментарий остался неисправленный с тех времен. Правильнее исправить комментарии, что я и сделаю.
← →
AndreyRus (2006-10-12 16:57) [31]Вот в таком, случае вот код, позволяющий корректно обрабатывать широковещательные сообщения:
function TForm1.KOLForm1Message(var Msg: tagMSG; var Rslt: Integer): Boolean;
begin
Result:= false;
if (Msg.message = WM_POWERBROADCAST) and (Msg.hwnd = Form.Handle) then
begin
MsgOk("APM Event detected - " + UInt2Str(Msg.wParam));
result:= true;
end;
end;
Страницы: 1 вся ветка
Форум: "KOL";
Текущий архив: 2007.06.03;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.042 c