【发布时间】:2011-03-01 14:21:00
【问题描述】:
我启用了TTimer,并且应该永远不间断地运行,直到用户停止它。但是,它不是那样工作的。在OnTimerevent 中,它以毫秒为单位一遍又一遍地处理窗口消息。
例如,这是我的代码的 sn-p。
procedure TDXCommDlg.Timer2Timer(Sender: TObject);
begin
inherited;
if Scanning then
begin
Timer1.Enabled := false;
Timer2.Enabled := false;
while not PostMessage(Handle,WM_USER + 10,1234,5678) do;
Timer1.Enabled := true;
end;
end;
发生的事情是这样的。当 TTimer 启用并运行时,您拖动应用程序的任何窗口或单击下拉菜单,TTimer 事件完全停止工作,即使我在代码的其他部分采取了预防措施来防止这种情况发生。但是,它似乎没有帮助。
重启OnTimer事件的唯一方法是用户通过TButton事件停止并重启Timer。
相同的代码或程序在使用 Delphi 7 编译的 Windows XP 下运行良好。目前,我正在使用 Windows 7 和 Delphi 2010 来重建我的系统。
我会尽力为您提供更多信息。我正在开发的是一个受版权保护的软件。
有一个名为 HandleMsg 的用户定义过程。它实际上处理串行端口消息。 HandleMsg设置为Application事件onMessage;
Application.onMessage:=HandleMsg();
PostMessage 与应用程序的 onMessage 事件相关联。
每当调用 PostMessage 时,它都会触发设置为 HandleMsg() 的 onMessage 事件。
这里有更多我的代码:
procedure TDXCommDlg.HandleMsg(var
Msg: TMsg; var Handled: Boolean);
begin
Handled := false;
case Msg.message of
WM_USER + 10:
begin
if (Msg.wParam = 1111) and (Msg.lParam = 2222) then
begin
SendLanMessage;
Handled := true;
end
else if (Msg.wParam = 1234) and (Msg.lParam = 5678) then
begin
SendMessage;
Handled := true;
end
else
begin
if (Msg.wParam = 4321) then
begin
MainFrm.CloseWindow(TViewFrm(Msg.lParam).WinCap);
end;
end;
end;
end; { case } end;
HandleMsg() 响应 PostMessage。如果我错了,请纠正我。
【问题讨论】:
-
这段代码应该做什么?
while not PostMessage(Handle,WM_USER + 10,1234,5678) do;为什么你认为你需要它? -
我在表单中添加了计时器、标签和菜单。我实现了一个计时器事件处理程序,它增加了一个计数器并将其显示在标签中。当我的菜单被下拉和表单拖动时,标签不断变化。我不知道你的问题是什么。您需要使其更清晰,但添加足够的代码以便我们能够理解和重现您的问题。
-
此代码以毫秒为单位反复处理串行通信。它通过 DB9 串口与外部硬件通信。串行消息在作为窗口消息发送出去时被处理。因此,应用程序本身不需要直接处理它们并使应用程序的其他部分超载或更糟的是减慢速度。
-
那个 PostMessage 循环是一个非常糟糕的主意。如果 PostMessage 失败,你有什么合理的理由期望立即再次尝试它会成功?如果失败,请按照文档告诉您的操作并调用 GetLastError 以找出问题所在。 (但如果您报告的问题即使在该行不存在的情况下仍然存在,那么请将其从问题中删除,因为它无关紧要。)
-
也不能复制。但请注意“WM_TIMER 消息是低优先级消息。GetMessage 和 PeekMessage 函数仅在线程的消息队列中没有其他高优先级消息时才发布此消息。”来自msdn跨度>
标签: delphi events delphi-2010