delphi – VCL TTimer在单击窗口拖动或下拉菜单时停止
我已启用
TTimer 并且应该永久运行直到用户停止它.但是,它不起作用.在OnTimerevent中,它以毫秒为单位一遍又一遍地处理窗口消息.
例如,这是我的代码片段. 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设置为onMessage的Application事件; Application.onMessage:= HandleMsg(); PostMessage与应用程序的onMessage事件相关联. 每当调用PostMessage时,它都会触发onMessage事件,该事件设置为HandleMsg(). 这里有更多我的代码: 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.如果我错了,请纠正我. 解决方法
在这两种情况下(开始调整大小/移动窗口或打开菜单),从TApplication.ProcessMessage调度的最后一条消息是WM_NCLBUTTONDOWN(如果字幕和系统菜单存在并且单击标题,则为WM_NCRBUTTONDOWN ..如果打开上下文菜单,则为WM_RBUTTONUP等等.).众所周知,他们正在开始一个模态消息循环.
例如,以下内容来自WM_ENTERSIZEMOVE文档:
在启动模态消息循环后,TApplication.Run中的HandleMessage调用将不会返回,直到相关窗口的DefWindowProc返回为止(例如,在WM_NCLBUTTONDOWN情况下,调度的消息将导致WM_SYSCOMMAND被发送到窗口,这将启动模式消息循环,并且在移动/调整大小完成之前不会返回).因此,您将无法在TApplication.ProcessMessage中调用的此期间使用应用程序的OnMessage处理程序. 你的解决方案很简单.而不是使用OnMessage处理程序,使用表单的消息处理程序处理消息: const WMUSER_10 = WM_USER + 10; type TForm1 = class(TForm) Timer1: TTimer; procedure Timer1Timer(Sender: TObject); private procedure WmUser10(var Msg: TMsg); message WMUSER_10; public end; procedure TForm1.Timer1Timer(Sender: TObject); begin PostMessage(Handle,WMUSER_10,5678); end; procedure TForm1.WmUser10(var Msg: TMsg); begin // end; 或者,将您的代码放在OnTimer事件中,因为WM_TIMER本身已发布. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |