gpt4 book ai didi

delphi - 当拖动窗口或单击下拉菜单时,VCL TTimer 停止

转载 作者:行者123 更新时间:2023-12-03 15:26:07 29 4
gpt4 key购买 nike

我有TTimer启用并且应该永远不间断地运行,直到用户停止它。然而,事实并非如此。在 OnTimer 事件中,它以毫秒为单位一遍又一遍地处理窗口消息。

例如,这是我的代码片段。

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。如果我错了请纠正我。

最佳答案

在这两种情况下(开始调整窗口大小/移动窗口或打开菜单),从 TApplication.ProcessMessage 分派(dispatch)的最后一条消息是 WM_NCLBUTTONDOWN (或 WM_NCRBUTTONDOWN 如果标题和系统菜单存在并单击标题..或 WM_RBUTTONUP 如果打开上下文菜单等..)。所有人的共同点是他们正在启动模式消息循环。

例如,以下内容来自 WM_ENTERSIZEMOVE 文档:

The WM_ENTERSIZEMOVE message is sent one time to a window after it enters the moving or sizing modal loop. [....] The operation is complete when DefWindowProc returns.

模式消息循环启动后,TApplication.Run 中的 HandleMessage 调用将不会返回,直到相关窗口的 DefWindowProc 返回(在例如,在 WM_NCLBUTTONDOWN 情况下,分派(dispatch)的消息将导致将 WM_SYSCOMMAND 发送到窗口,该窗口将启动模式消息循环,并且在移动/调整大小完成之前不会返回)。因此,在此期间您将无法使用应用程序的 OnMessage 处理程序(在 TApplication.ProcessMessage 中调用)。

您的解决方案很简单。不要使用 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, 1234, 5678);
end;

procedure TForm1.WmUser10(var Msg: TMsg);
begin
//
end;


或者,将您的代码放入 OnTimer 事件中,因为 WM_TIMER 本身已发布

关于delphi - 当拖动窗口或单击下拉菜单时,VCL TTimer 停止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5155742/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com