使用Windows API显示图像

发布于 2025-01-23 07:00:08 字数 1139 浏览 2 评论 0原文

我正在使用循环的原始代码来输出测试图像:

procedure TForm1.Button1Click(Sender: TObject);
var
  LP1, LP2: TLogPen;
  hp1, hp2: THandle;
  hdcv: Handle;
  i: integer;
begin
  LP1.lopnColor:=$FF0000;
  LP1.lopnStyle:=0;
  LP1.lopnWidth:=Classes.Point(1,0);
  LP2.lopnColor:=$FFFFFF;
  LP2.lopnStyle:=0;
  LP2.lopnWidth:=Classes.Point(1,0);
  hp1:=Windows.CreatePenIndirect(Windows.LOGPEN(LP1));
  hp2:=Windows.CreatePenIndirect(Windows.LOGPEN(LP2));

  hdcv:=Canvas.Handle;
  for i:=1 to 1000 do
    begin
      SelectObject(hdcv, hp1);
      Windows.MoveToEx(hdcv, 10+2*i, 10, nil);
      Windows.LineTo(hdcv, 50+2*i, 50);
      Sleep(100);
      Application.ProcessMessages;
      SelectObject(hdcv, hp2);
      Windows.MoveToEx(hdcv, 10+2*i+1, 10, nil);
      Windows.LineTo(hdcv, 50+2*i+1, 50);
      Sleep(100);
      Application.ProcessMessages;
    end;

  Windows.DeleteObject(hp1);
  Windows.DeleteObject(hp2);
end;

问题是,当鼠标在按钮上(按钮1)时,线路输出是间歇性的。好像绘图发生在某种缓冲区中,并且一段时间后显示在表单上。 我录制了一个视频。我正在使用Windows 7和Lazarus 1.6.4。有人可以解释这种图形行为吗?

I am using a looping primitive code to output a test image:

procedure TForm1.Button1Click(Sender: TObject);
var
  LP1, LP2: TLogPen;
  hp1, hp2: THandle;
  hdcv: Handle;
  i: integer;
begin
  LP1.lopnColor:=$FF0000;
  LP1.lopnStyle:=0;
  LP1.lopnWidth:=Classes.Point(1,0);
  LP2.lopnColor:=$FFFFFF;
  LP2.lopnStyle:=0;
  LP2.lopnWidth:=Classes.Point(1,0);
  hp1:=Windows.CreatePenIndirect(Windows.LOGPEN(LP1));
  hp2:=Windows.CreatePenIndirect(Windows.LOGPEN(LP2));

  hdcv:=Canvas.Handle;
  for i:=1 to 1000 do
    begin
      SelectObject(hdcv, hp1);
      Windows.MoveToEx(hdcv, 10+2*i, 10, nil);
      Windows.LineTo(hdcv, 50+2*i, 50);
      Sleep(100);
      Application.ProcessMessages;
      SelectObject(hdcv, hp2);
      Windows.MoveToEx(hdcv, 10+2*i+1, 10, nil);
      Windows.LineTo(hdcv, 50+2*i+1, 50);
      Sleep(100);
      Application.ProcessMessages;
    end;

  Windows.DeleteObject(hp1);
  Windows.DeleteObject(hp2);
end;

The problem is that when the mouse is on the button (Button1), lines output is intermittent. As if drawing takes place in some kind of buffer, and after some time it is displayed on the form. I recorded a video. I am using Windows 7 and Lazarus 1.6.4. Can someone explain this graphics behavior?

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

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

发布评论

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

评论(1

手长情犹 2025-01-30 07:00:08

在睡眠期间,Windows重新粉刷无法操作。因此,重新点可能仅发生在ProcessMessages阶段。

最好的解决方案是使用计时器将其异步重写。

要检验假设,您可以用更精细的谷物解决方案替换睡眠应用程序。

这样做的

 sleep(100);   
 Application.ProcessMessages;

方法

for y:=1 to 10 do
 begin
   sleep(10);
    Application.ProcessMessages;
 end;

是这样的解决方案(仅是假码):

 startticks:=gettickcount64; // startticks = int64
 while (gettickcount64-startticks)<100 do
    begin
      sleep(10);
      Application.ProcessMessages;
    end;

在应用程序中花费的时间更好。 。

During the sleep, windows repaint messages can't operate. So it is possible that the repaint only happens on the processmessages stage.

The best solution is to rewrite this asynchronously using a timer.

To test the hypothesis you could replace the sleep-application.processes with a more fine grained solution like

So instead of

 sleep(100);   
 Application.ProcessMessages;

we replace it with

for y:=1 to 10 do
 begin
   sleep(10);
    Application.ProcessMessages;
 end;

Somewhat nicer is a solution like this (pseudocode only):

 startticks:=gettickcount64; // startticks = int64
 while (gettickcount64-startticks)<100 do
    begin
      sleep(10);
      Application.ProcessMessages;
    end;

which accounts better for the time spent in Application.Processmessages.

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