期刊弹出表单

发布于 2024-09-25 06:57:52 字数 429 浏览 0 评论 0原文

我应该以其他形式定期实施弹出表单。此弹出表单不是常见设计,因此我无法使用标准消息。我需要实现平滑地显示\隐藏此弹出表单。

现在我使用计时器来隐藏\显示此表单,但遇到了奇怪的问题。 如果我只运行 Show\Hide 弹出表单进程,一切都可以,但是当我尝试在基本表单上运行其他线程时,这些线程正在编组到 vcl 线程(数学绘画),弹出表单的行为变得很奇怪。

我应该如何在多线程应用程序中实现线程安全的弹出表单?谢谢

编辑

奇怪的事情:我的计时器设置显示显示隐藏形式与周期 5 秒。 当进程启动时一切正常。弹出窗体的显示和隐藏时间与预期一致,超过 5 秒。 但后来我得到了一些弹出窗口(显示弹出窗口)的循环,没有暂停。 然后再次弹出时间就可以了(5s)。
然后我的计时器间隔无法正常工作。 我同意 ~4,6s 周期。但有时弹出窗口之间没有句点。

I should implement periodically popup form at other form. This popup form isn't common design, so I couldn't use standard messages. I need implement smoothly showing\hiding of this popup form.

Now I use timers for hide\show this form, but have strange problems.
If I run only Show\Hide popup form process all is OK, but when I try run other threads at base form,which are marshling to vcl thread (math painting) behaviour of popup form become strange.

How should I imlement thread-safe popup form at multi-thread app? Thanks

EDIT

Strange thing: My timers setup show show hide form with period 5s.
When process starts all is ok. Popup form is show and hide over 5s as expecting.
But then I got some cycles of popup(show popup from) withous pause.
Then again period of popup is OK(5s).
Then my timer intervals don't work correctly.
I agree with ~4,6s period. But sometimes there is no periods between popup.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

爱冒险 2024-10-02 06:57:52

因为您遗漏了很多重要信息(“表单行为奇怪”可以以无数种方式解释,并且有同样多的解决方案),我将猜测您的问题是什么,并尝试给你一个解决方案。如有错误,请提供相关信息!

关于 TTimer:

当您需要一些定时信号但不应该非常精确时,TTimer 是一个简单的解决方案。您将计时器设置为以给定的时间间隔“触发”,Windows 将按照配置的周期向您的应用程序发送 WM_TIMER 消息。这里的技巧是,应用程序的队列上永远不会同时有两个 WM_TIMER 消息。

如果你要制作一个时钟,并使用 TTimer 给你 1 秒的心跳,那么当你的计算机空闲时,你的时钟会大部分准时,但如果你的计算机繁忙,它就会运行缓慢。如果运行时钟的进程很忙,时钟运行速度会更慢。

关于你的问题:

你是说:

如果我只运行 Show\Hide 弹出表单进程,一切都正常,但是当我尝试在基本表单上运行其他线程时,这些线程会编组到 vcl 线程(数学绘画),弹出表单的行为变得很奇怪。

解释:我假设线程数学绘制发生在VCL线程中的某个地方,并且这会阻塞应用程序的消息队列。这反过来会导致您的应用程序跳过 WM_TIMER 消息,导致弹出表单的行为变得奇怪

可能的解决方案:

在没有真正了解问题的情况下,这显然很困难(再次,奇怪 - 怎么办?),但我无论如何都会给你一些想法。首先让我告诉你,我不认为你可以使用更好的计时器来解决你的问题。您的问题与 GUI 相关,并且 GUI 是单线程的。虽然您确实有一些后台线程在做一些事情,但它们需要编组到 vcl 线程 - 无论您的计时器有多精确,它都无法阻止主 VCL 线程执行编组 事情,因此计时器需要等待 marshall 完成才能执行需要完成的操作。

我需要实现平滑显示\隐藏此弹出表单中获取提示,我假设您需要一些步骤来实现平滑显示\隐藏,这就是您正在使用的TTimer 的。

如果你有这样的代码:
(警告,这是伪代码,我怀疑它是否可以编译)

procedure Timer1OnTimer(Sender:TObject);
begin
  SomeCounter := SomeCounter + 1;
  if SomeCounter > 10 then
    HidePopupForm
  else
    SetPopupFormTransparencyTo((SomeCounter * 255) div 10);
end;

将其替换为以下内容:

var HideAtTime:TDateTime;
    ShownAtTime:TDateTime;

procedure Timer1OnTimer(Sender:TObject);
var ExpectedVisibleTime:TDateTime;
    ElapsedVisibleTime:TDateTime;
begin
  if Now > HideAtTime then
    HidePopupForm
  else
    begin
      ExpectedVisibleTime := HideAtTime - ShownAtTime;
      ElapsedVisibleTime := Now - ShownAtTime;
      SetPopupFormTransparencyTo(ElapsedVisibleTime/ExpectedVisibleTime*255);
    end;
end;

此解决方案的总体思路是计算截止日期,将它们存储在 TDateTime 变量中,与 进行比较现在来自你的TTimer.OnTimer;这样,即使计时器事件没有按要求的时间间隔到达也没关系,您基本上可以准时完成其他所有事情。当然,显示表单可能不像预期的那么顺利,但它可以完成工作。

Because you left out a lot of important information ("form is behaving strange" can be interpreted in about a zillion ways, with just as many solutions), I'm going to GUESS what your problem is, and attempt giving you a solution. Please provide relevant information if I'm wrong!

About the TTimer:

The TTimer is a simple solution when you need some timing signals but it's not supposed to be very precise. You set up the timer to "fire" at the given Interval, and Windows will send your application WM_TIMER messages with the configured periodicity. The trick here is, there will never be two WM_TIMER messages on your application's queue at the same time.

If you were to make an clock, and used an TTimer to give you a 1 second heart-beat, your clock would be mostly on time when your computer is idle but it will run slow if your computer is busy. If the processes running the clock is busy the clock would run even slower.

About your problem:

You're saying:

If I run only Show\Hide popup form process all is OK, but when I try run other threads at base form,which are marshling to vcl thread (math painting) behaviour of popup form become strange.

Interpretation: I assume the thread math painting is happening somewhere in the VCL thread, and that's blocking your application's message queue. This is turn is causing your application to skip WM_TIMER messages, causing the behaviour of popup form become strange.

Possible solutions:

This is obviously tough without actually knowing the problem (again, strange - how?), but I'm going to give you some ideas any way. First of all let me tell you, I don't think you can fix your problem using a better timer. Your problem is GUI related, and the GUI is single-threaded. While you do have some background threads doing some stuff, they need to marshall to vcl thread - no matter how precise your timer is, it can't stop the main VCL thread from doing the marshall thing, so the timer will need to wait for the marshall to finish in order to do what needs to be done.

Taking hint from I need implement smoothly showing\hiding of this popup form I assume you need an number of steps for your smooth showing\hiding, and that's what you're using the TTimer for.

If you got code like this:
(warning, this is pseudo-code, I doubt it compiles)

procedure Timer1OnTimer(Sender:TObject);
begin
  SomeCounter := SomeCounter + 1;
  if SomeCounter > 10 then
    HidePopupForm
  else
    SetPopupFormTransparencyTo((SomeCounter * 255) div 10);
end;

Replace it with something like this:

var HideAtTime:TDateTime;
    ShownAtTime:TDateTime;

procedure Timer1OnTimer(Sender:TObject);
var ExpectedVisibleTime:TDateTime;
    ElapsedVisibleTime:TDateTime;
begin
  if Now > HideAtTime then
    HidePopupForm
  else
    begin
      ExpectedVisibleTime := HideAtTime - ShownAtTime;
      ElapsedVisibleTime := Now - ShownAtTime;
      SetPopupFormTransparencyTo(ElapsedVisibleTime/ExpectedVisibleTime*255);
    end;
end;

The general idea with this solution is to compute deadlines, store them in TDateTime variables, compare with Now from your TTimer.OnTimer; That way it doesn't matter if the timer events don't arrive at the requested intervals, you'd be mostly on time with everything else. Sure, showing up a form might not be as smooth as desired, but it'll get the job done.

反差帅 2024-10-02 06:57:52

您是否尝试过使用备用计时器?
库存VCL计时器使用主消息队列,这意味着如果您的消息队列被发布无数消息的其他线程堵塞,则实际计时完全偏离实时。

Have you tried to use alternate timers?
The stock VCL Timers use the main message queue which means that if your message queue gets clogged by the other threads posting zillions of messages, the actual timing is completely off from real time.

那小子欠揍 2024-10-02 06:57:52

感谢 Cosmin Prund 的精彩帖子,我解决了我的问题。问题是:后台线程的数学处理量很小,并且经常(在循环中)编组到 VCL 线程。因此,几乎在执行后台线程的所有时间中,它都会以线程安全的方式绘制其结果。

因为 vcl 线程非常“繁忙”,

background threads it can't stop the main VCL thread from doing the marshall thing, 
so the timer will need to wait for the marshall to finish in order to do what
needs to be done.

所以我决定让我的 bacjground 线程更加独立于 vcl 并粘贴

 Sleep(50);

到我的执行方法中。
好吧,我的计时器行为“正常”:)。

但我对新的 vcl 线程反应并不满意。所以我决定在线程中构建位图,并在同步时将其分配给 gui,而不是在同步时进行画布操作。这样我就可以期待 vcl 反应和弹出行为。谢谢大家。

Thanks to nice Cosmin Prund post, I resolve my issue. The problem was: background thread has small math procession and frequently(in loop) marshalled to VCL thread. So almoast all the time of executing background thread it paints of its result thread-safe way.

Because vcl thread was very "busy" and

background threads it can't stop the main VCL thread from doing the marshall thing, 
so the timer will need to wait for the marshall to finish in order to do what
needs to be done.

Ok I decide make my bacjground thread more vcl independent and paste

 Sleep(50);

at my execute method.
Ok I get "normal" :) behaviour of my timers.

But I don't be satisfied new vcl thread reaction. So I decide build bitmap at thread and assign it to gui at synchronize instead canvas manipulation at synchronize. This way I get expecting vcl reaction and popup behaviuor. Thanks for all.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文