在德尔福的无边界窗体中平滑调整大小 [英] Smooth resizing in a borderless form/window in Delphi

查看:260
本文介绍了在德尔福的无边界窗体中平滑调整大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试调整无边界形式的大小,但是当我使用右侧/底部增加尺寸时,我会根据移动鼠标的速度在边框和旧客户端之间找到一个差距。

I am trying to resize a borderless form but when I increase the size using the right/bottom side, I get a gap between the border and the old client area that depends of the speed you move the mouse.

当您从左侧边框或从底部边缘重新调整大小时,效果更为明显,这是非常糟糕的(我尝试使用其他商业应用程序,同时也发生)。当我更改为相当大的边框时,这种效果也会发生,但是当我删除表单边框时,这并不那么糟糕。

The effect is more noticeable when you resize from the left border or even from the bottomleft corner, it's horrible everywhere (I tried with other commercial apps and it happens as well). This effect happens as well when I change to sizable border, but it's not as awful as when I remove form borders

表单布局包含一个顶部的标题栏功能(有一些tImages和按钮),还有一些其他面板显示其他信息(如备忘录,其他控件等)

The form layout consists in a top panel doing the title bar function (with some tImages and buttons), and some other panels showing other info (like a memo, other controls, etc)

我的代码中有一个剪辑,我捕获鼠标按钮并向Windows发送消息,但是我也尝试用类似的结果手动执行

There's a snip of my code where I capture the mouse button and send a message to windows, but I also tried to do it manually with the similar results

激活顶部面板的双缓冲区可避免闪烁,但调整大小面板与表单大小不同步,因此出现空白,或面板的一部分消失。

Activating the double buffer for the top panel avoids flickering, but resizing the panel is not synchronized with form resizing, thus appearing a gap, or part of the panel disapearing

 procedure TOutputForm.ApplicationEvents1Message( var Msg: tagMSG;
  var Handled: Boolean );
const
  BorderBuffer = 5;
var
  X, Y: Integer;
  ClientPoint: TPoint;
  direction: integer;
begin
  Handled := false;
  case Msg.message of
    WM_LBUTTONDOWN:
      begin
        if fResizable then
        begin
          if fSides = [sTop] then
            direction := 3
          else if fSides = [sLeft] then
            direction := 1
          else if fSides = [sBottom] then
            direction := 6
          else if fSides = [sRight] then
            direction := 2
          else if fSides = [sRight, sTop] then
            direction := 5
          else if fSides = [sLeft, sTop] then
            direction := 4
          else if fSides = [sLeft, sBottom] then
            direction := 7
          else if fSides = [sRight, sBottom] then
            direction := 8;
          ReleaseCapture;
          SendMessage( Handle, WM_SYSCOMMAND, ( 61440 + direction ), 0 );
          Handled := true;
        end;
      end;
    WM_MOUSEMOVE:
      begin
        // Checks the borders and sets fResizable to true if it's in a "border" 
        // ...
      end; // mousemove
  end; // case
end;

如何避免该区域和/或强制重新绘制窗口?我使用的是Delphi,但通用的解决方案(或其他语言)甚至是向前推进的方向对我来说都是不错的。

How could I avoid that area and/or force windows to be redrawn? I am using Delphi but a generic solution (or in other language) or even a direction to go forward would be fine for me

提前谢谢你

推荐答案

上次我试图通过WM_SYSCOMMAND和鼠标拖动手动创建一个调整大小的窗口,无论涉及任何嵌套面板还是否,我发现问题并不仅限于闪烁。

Last time I attempted to manually make a top level window that resizes via WM_SYSCOMMAND and mouse drag, whether involving any nested panels or no, I found the problems were not limited only to flicker.

即使在没有可重新调整大小的边框的情况下,也可以添加自己的可重新调整大小的边框,同时处理鼠标,鼠标移动和鼠标向上消息直接证明太有问题了。我放弃了你在这里展示的代码方法,而我发现了两种可行的方法:

Even with a bare-TForm without a resizeable border, adding my own resizeable border and handling the mouse down and mouse move and mouse up messages directly proved too problematic. I gave up on the code-approach you are showing here, and instead I found two workable approaches:


  1. 我接手非客户区的画面。这是Google Chrome和许多其他全面定制的窗口。您仍然拥有一个非客户端区域,由您自己绘制并处理非客户端和边框绘图。换句话说,它不是真正的无边界,但如果你想要的话,它们都可以是单一的颜色。阅读此有关WM_NCPAINT消息的帮助,开始使用

使用一个仍然可以被识别的无边框可调整窗口(即使没有将其非客户区域设置为可调整大小的窗口) -applet。这里是一个我刚才问的问题,在我的问题的底部是一个完整的演示,提供了一个平滑的无闪烁的方式来有一个无边界的可调整大小的窗口。答案的底层技术由David H.

Use a borderless resizeable window that still gets recognized (even without its nonclient area as a resizeable window. Think of a post-it-note-applet. Here is a question I asked a while ago, at the bottom of my question is a fully working demo that provides a smooth flicker free way to have a borderless resizeable window. The underlying technique for the answer was provided by David H.

这篇关于在德尔福的无边界窗体中平滑调整大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆