如何同时更改控件而不重新绘制每个控件?

发布于 2024-08-25 01:38:07 字数 181 浏览 8 评论 0原文

例如,我需要在运行时禁用两个按钮。在我禁用第一个按钮后,它变成灰色,第二个按钮也变成灰色。但我不知道如何使重画同时进行!

我需要类似的东西:

  1. 冻结表单(禁用重画)
  2. 禁用第一个按钮
  3. 禁用第二个按钮
  4. 启用表单重画

如何实现?

For example I need to disable two buttons in runtime. After I disabled first button it bacame gray, the second - it also became gray. But I do not know how to make the repainting simultaneous!

I need something like that:

  1. freeze the Form (disable repainting)
  2. disable first button
  3. disable second button
  4. Enable Form repainting

How to implement that?

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

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

发布评论

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

评论(5

懵少女 2024-09-01 01:38:07

查看 Win32 API WM_SETREDRAW 消息。例如:

SendMessage(Handle, WM_SETREDRAW, False, 0);
Button1.Enabled := False;
Button2.Enabled := False;
SendMessage(Handle, WM_SETREDRAW, True, 0);
InvalidateRect(Handle, nil, True);

Look at the Win32 API WM_SETREDRAW message. For example:

SendMessage(Handle, WM_SETREDRAW, False, 0);
Button1.Enabled := False;
Button2.Enabled := False;
SendMessage(Handle, WM_SETREDRAW, True, 0);
InvalidateRect(Handle, nil, True);
眼前雾蒙蒙 2024-09-01 01:38:07

在应用程序重新进入消息循环之前,无法处理消息,因此任何修改/更新依赖于消息处理的控制状态的尝试都不会在不“泵送”消息的单个代码序列中起作用。

幸运的是,VCL 控件通常提供一种通过 Update 方法强制重新绘制的方法,而无需等待消息被处理:

Button1.Enabled := False;
Button2.Enabled := False;
Button1.Update;
Button2.Update;

这与禁用表单重新绘制无关。无论如何,在您的应用程序进入消息循环之前,表单不会重新绘制,因此在本身不会导致消息处理的单个过程中禁用表单绘制并重新启用是浪费时间。

这可能不是完全同时重新绘制两个按钮,但是如果不进入多线程 GUI 绘制代码,真正同时绘制两个单独的控件是不可能的,我认为这远远超出了这个问题的范围。然而,以这种方式在两个按钮上调用 Update 将根据您的需要几乎同时生效。

Messages cannot be processed until your application re-enters a message loop, so any attempt to modify/update control state that relies on message processing will not work within a single sequence of code that does not "pump" messages.

Fortunately the VCL controls typically provide a means for force repainting without waiting for messages to be processed, via the Update method:

Button1.Enabled := False;
Button2.Enabled := False;
Button1.Update;
Button2.Update;

This works independently of having to disable form repainting. The form will not repaint until your application goes into a message loop anyway, so disabling form painting and re-enabling within a single procedure that does not itself cause message processing is a waste of time.

This may not be exactly simultaneous repainting of the two buttons, but truly simultaneous painting of two separate control is impossible without getting into multithreaded GUI painting code which I think is way beyond the scope of this problem. Calling Update on two buttons in this way will be as near simultaneous in effect as you need however.

话少情深 2024-09-01 01:38:07

致 Elias551:

LockWindowUpdate 可能不是处理此问题的最佳方法,因为它旨在用于拖放操作,并且在误用时可能会引入微妙的错误。

请参阅 http://blogs.msdn.com/b/ oldnewthing/archive/2007/02/22/1742084.aspx

而是使用 SendMessage(hwnd, WM_SETREDRAW, FALSE, 0)

To Elias551:

LockWindowUpdate is probably not the best way to handle this since it is intended for drag and drop operations and can introduce subtle bugs when misused.

See http://blogs.msdn.com/b/oldnewthing/archive/2007/02/22/1742084.aspx

Instead use SendMessage(hwnd, WM_SETREDRAW, FALSE, 0)

幸福还没到 2024-09-01 01:38:07

上述 WM_SETREDRAW 决定不会更新子窗口。

相反,我推荐 RedrawWindow:

RedrawWindow(Handle, nil, 0, RDW_INVALIDATE or RDW_ALLCHILDREN);

The above decision with WM_SETREDRAW does not update child windows.

Instead, i recommend RedrawWindow:

RedrawWindow(Handle, nil, 0, RDW_INVALIDATE or RDW_ALLCHILDREN);
醉城メ夜风 2024-09-01 01:38:07

这可能会有所帮助:API LockWindowUpdate(Handle: HWND) 将绘图锁定到句柄和子级。

例如:

procedure TForm1.ColorButtons();
begin
  LockWindowUpdate(Self.Handle);
  // Make some stuff
  LockWindowUpdate(0);
end;

一旦锁定的手柄被重置,组件就会被重新绘制

This could help: the API LockWindowUpdate(Handle: HWND) locks drawing to the handle and children.

ex:

procedure TForm1.ColorButtons();
begin
  LockWindowUpdate(Self.Handle);
  // Make some stuff
  LockWindowUpdate(0);
end;

Once the locked handle is reset, the component is repainted

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