相关疑难解决方法(0)

滚动条绘画问题与加厚的非客户端窗口边框

我试图在带有滚动条的自定义控件的客户区周围绘制彩色边框.为此,我设置BorderWidth为正整数并响应该WM_NCPAINT消息.这听起来像混合VCL和Win32,但该BorderWidth属性只是导致对WM_NCCALCSIZE消息的适当处理.

以下代码是SSCCE:

unit Unit6;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TSample = class(TCustomControl)
  protected
    procedure Paint; override;
    procedure CreateParams(var Params: TCreateParams); override;
    procedure WMNCPaint(var Message: TWMNCPaint); message WM_NCPAINT;
  published
    property BorderWidth;
  end;

  TForm6 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form6: TForm6;

implementation

{$R *.dfm}

{ TSample }

procedure TSample.CreateParams(var Params: TCreateParams);
begin
  inherited; …
Run Code Online (Sandbox Code Playgroud)

delphi controls border nonclient scrollbar

11
推荐指数
0
解决办法
398
查看次数

将非VCL窗口添加到VCL对齐队列中

一些背景(TLabel和TGroupbox Captions Flicker on Resize的延续):

  • 所以,我有一个应用程序加载不同的插件,并在TPageControl上为每个插件创建一个新选项卡.
  • 每个DLL都有一个与之关联的TForm.
  • 使用父hWnd创建表单作为新的TTabSheet.由于就VCL而言,TTabSheets不是表单的父级(不想使用动态RTL和其他语言的插件),我必须手动处理调整大小.

对于这种"插件"类型的应用程序,我似乎遇到了很多新问题(但很棒的学习经历).

因此,我目前的努力是尝试使用一个插件,该插件不会插入到TTabSheet中,但会在表单上直接调整大小并对齐.

由于这可以更容易用图片解释: 问题的视觉表示 现在我可以手动进行对齐和调整大小,但我宁愿让VCL对齐程序(alClient,alTop等)为我做.这样我就不必考虑在其表单上设置插件对齐.

在查看VCL源代码后,我开始逐步调整对齐代码及其调用方式.基本上,当TControl获得WM_RESIZE时,它将:

  1. 调用调用AlignControl()的Realign()
  2. AlignControl()将获取客户端rect并调用AlignControls()
  3. AlignControls()将按以下顺序为每个TAlignment类型调用DoAlign():alTop,alBottom,alLeft,alRight,alClient,alCustom,alNone
  4. DoAlign()将遍历FControls和FWinControls(它们是TLists)并将它们适当地对齐

所以我的思维过程是,如果我创建一个新的TWinControl,将它的句柄设置为插件窗体(窗口)句柄,并将其插入FControls列表中,并正确对齐它应该为我工作.

我当然在这里,所以它失败了.我甚至在退出应用程序时获得了一个关于无效窗口句柄的AV.我的猜测是我创建的TWinControl试图释放不再存在的插件窗体(窗口)的句柄.

我尝试过的:

procedure AddHandleToControlList(AHandle: DWORD; Align: TAlign);
var
  NewWinControl : TWinControl;
begin
  NewWinControl := TWinControl.Create(frmMain);
  NewWinControl.WindowHandle := AHandle;
  NewWinControl.Align := Align;
  NewWinControl.Width := frmMain.ClientWidth;
  NewWinControl.Height := 30;
  NewWinControl.Parent := frmMain;
end;

procedure AddHandleToControlList(AHandle: DWORD; Align: TAlign);
var
  NewWinControl : TWinControl;
begin
  NewWinControl := TWinControl.Create(frmMain);
  NewWinControl.WindowHandle …
Run Code Online (Sandbox Code Playgroud)

windows delphi winapi vcl delphi-xe

9
推荐指数
1
解决办法
668
查看次数

如何减少Delphi中的PageControl闪烁?

在Delphi 2009中,我发现PageControl的闪烁 - 在调整表单大小期间发生 - 可以通过将其DoubleBuffered属性设置为true 来减少.

但是,如果我向PageControl标签页添加控件,它们将闪烁,无论其DoubleBuffered属性设置如何.我也试过启用和不启用运行时主题.

delphi vcl flicker delphi-2009 tpagecontrol

8
推荐指数
1
解决办法
5102
查看次数

TToolbar与TForm.DoubleBuffered不兼容?

我正在使用Delphi XE3.
当我创建一个新的VCL项目并删除TToolbar它时,一切正常 - 除非我激活Form1.DoubleBuffered.
从那一刻起,工具栏的绘制就被打破了 - 在设计时,它是黑色,透明或IDE的一部分(状态栏,工具栏等)被复制到其中.当我点击它时以及当我更改为源代码(F12)并返回时,它会在这些选项之间发生变化.
在运行时,它总是黑色的.

随着DrawingStyle=dsGradient,一切正常.切换回dsNormal再次打破它.

停用Form1.DoubleBuffered修理它.

任何提示如何解决该问题?

delphi vcl doublebuffered toolbar delphi-xe3

7
推荐指数
1
解决办法
1134
查看次数

何时使用TPanel FullRepaint?

我注意到,resize flicker获得当我设置好很多TPanel.FullRepaintFalse.由于该属性存在且True默认情况下,因此必须有一些原因.

如何决定是否应该设置?

帮助只是声明:

FullRepaint控制面板调整大小时的响应方式.当FullRepaint为true时,整个面板(包括斜面边框)会在尺寸更改时重新绘制.当FullRepaint为false时,只有斜面边框内的区域重新绘制.

http://docwiki.embarcadero.com/Libraries/XE3/en/Vcl.ExtCtrls.TPanel.FullRepaint

该文本说它做了什么,但不是为什么......

delphi resize tpanel

6
推荐指数
1
解决办法
1963
查看次数

Delphi TSplitter闪烁问题

我正在使用启用了VCL样式的Delphi,我想为我的表单更改TSplitter的颜色.我在内TSplitter.Paint插器类中重写以绘制比默认VCL样式cBtnFace颜色更暗的颜色,但在调整大小时窗体上会出现明显的闪烁.有没有办法消除这种闪烁?

我试过这些东西来尝试减少闪烁,但没有一个有效:

  1. 禁用VCL样式(TSplitter.StyleElements := []).

  2. 更改VCL样式位图样式设计器的"分割器"对象元素,但修改此对象元素不会更改分割器的外观.

  3. 试图处理对象WM_ERASEBKGND上的消息TControl,但我无法在我的插入器类中调用该过程.

    procedure WMEraseBkgnd(var Msg: TWMEraseBkgnd); message WM_ERASEBKGND;
    ...
    procedure TSplitter.WMEraseBkgnd(var Msg: TWMEraseBkgnd);
    begin
        // this is never invoked by the TSplitter
        Msg.Result := 1;
    end;
    
    Run Code Online (Sandbox Code Playgroud)

任何其他想法摆脱闪烁的TSplitterTSplitter根据我所知,没有DoubleBuffer属性或类似的东西.

UPDATE

不幸的是,我不能共享代码库,但我可以告诉你,这是TSplitter闪烁时应用程序UI设置的方式:

TForm (DoubleBuffered = False)
-> BackgroundPanel (DoubleBuffered = True, ParentBackground = False)
-> -> A TGradient, image and label to fill the BackgroundPanel
-> LeftPanel (ParentBackground = False`, no flickering) …
Run Code Online (Sandbox Code Playgroud)

delphi flicker vcl-styles

5
推荐指数
1
解决办法
1570
查看次数

停止标签标题闪烁

我有一个标签,指示文件大小

FormatFloat('##.## KB',BytesIn/OneKB);
Run Code Online (Sandbox Code Playgroud)

当文件都低于2MB时,一切正常.现在我有时使用2GB及以上的文件.

FormatFloat('##.##### MB',BytesIn/OneMB);
Run Code Online (Sandbox Code Playgroud)

标题正在每1 KB更新一次,闪烁非常激烈.

有什么方法可以阻止或最小化它?

delphi flicker delphi-7

5
推荐指数
1
解决办法
3715
查看次数

德尔福:透明或渐变框架

我有一个表单,并在Paint事件上使用渐变绘制它.我也在那张表格上有框架.我希望框架将是透明的,以查看窗体的渐变或使用渐变绘制帧,如果透明度不可用.

表格和框架一定不要闪烁:)

何去做?谢谢.

编辑:

正如我所见,帧的透明度有些闪烁.因此,对我来说最好的解决方案是覆盖TFrame1.PaintWindow(DC:HDC)并使用渐变绘制框架的背景.

forms delphi transparency gradient frame

2
推荐指数
1
解决办法
3480
查看次数