- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个图形 TCustomControl
后代组件,其上有一个 TScrollBar
。问题是,当我按箭头键移动光标时,整个 Canvas 都被绘制为背景颜色,包括滚动条的区域,然后滚动条被重新绘制,这使得滚动条闪烁。我该如何解决这个问题?
这是代码。无需安装组件或在主窗体上放置任何内容,只需复制代码并分配 TForm1.FormCreate
事件:
Unit1.pas
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, SuperList;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
List: TSuperList;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
List:=TSuperList.Create(self);
List.Top:=50; List.Left:=50;
List.Visible:=true;
List.Parent:=Form1;
end;
end.
SuperList.pas
unit SuperList;
interface
uses Windows, Controls, Graphics, Classes, Messages, SysUtils, StdCtrls, Forms;
type
TSuperList = class(TCustomControl)
public
DX,DY: integer;
ScrollBar: TScrollBar;
procedure Paint; override;
constructor Create(AOwner: TComponent); override;
procedure WMKeyDown(var Message: TWMKeyDown); message WM_KEYDOWN;
procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
published
property OnMouseMove;
property OnKeyPress;
property OnKeyDown;
property Color default clWindow;
property TabStop default true;
property Align;
property DoubleBuffered default true;
property BevelEdges;
property BevelInner;
property BevelKind default bkFlat;
property BevelOuter;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Marus', [TSuperList]);
end;
procedure TSuperList.WMGetDlgCode(var Message: TWMGetDlgCode);
begin
inherited;
Message.Result:= Message.Result or DLGC_WANTARROWS;
end;
procedure TSuperList.WMKeyDown(var Message: TWMKeyDown);
begin
if Message.CharCode=VK_LEFT then begin dec(DX,3); Invalidate; exit; end;
if Message.CharCode=VK_RIGHT then begin inc(DX,3); Invalidate; exit; end;
if Message.CharCode=VK_UP then begin dec(DY,3); Invalidate; exit; end;
if Message.CharCode=VK_DOWN then begin inc(DY,3); Invalidate; exit; end;
inherited;
end;
procedure TSuperList.WMLButtonDown(var Message: TWMLButtonDown);
begin
DX:=Message.XPos;
DY:=Message.YPos;
SetFocus;
Invalidate;
inherited;
end;
constructor TSuperList.Create(AOwner: TComponent);
begin
inherited;
DoubleBuffered:=true;
TabStop:=true;
Color:=clNone; Color:=clWindow;
BevelKind:=bkFlat;
Width:=200;
Height:=100;
DX:=5; DY:=50;
ScrollBar:=TScrollBar.Create(self);
ScrollBar.Kind:=sbVertical;
ScrollBar.TabStop:=false;
ScrollBar.Align:=alRight;
ScrollBar.Visible:=true;
ScrollBar.Parent:=self;
end;
procedure TSuperList.Paint;
begin
Canvas.Brush.Color:=Color;
Canvas.FillRect(Canvas.ClipRect);
Canvas.TextOut(10,10,'Press arrow keys !');
Canvas.Brush.Color:=clRed;
Canvas.Pen.Color:=clBlue;
Canvas.Rectangle(DX,DY,DX+30,DY+20);
end;
end.
最佳答案
我认为我要做的第一件事就是删除滚动条控件。 Windows 带有现成的滚动条。您只需要启用它们即可。
因此,首先从组件中删除 ScrollBar
。然后添加 CreateParams
覆盖:
procedure CreateParams(var Params: TCreateParams); override;
像这样实现:
procedure TSuperList.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.Style := Params.Style or WS_VSCROLL;
end;
Yippee,您的控件现在有一个滚动条。
接下来您需要为 WM_VSCROLL
添加处理程序:
procedure WMVScroll(var Message: TWMVScroll); message WM_VSCROLL;
它是这样实现的:
procedure TSuperList.WMVScroll(var Message: TWMVScroll);
begin
case Message.ScrollCode of
SB_LINEUP:
begin
dec(DY, 3);
Invalidate;
end;
SB_LINEDOWN:
begin
inc(DY, 3);
Invalidate;
end;
...
end;
end;
您需要填写其余的滚动代码。
我还建议您不要在组件的构造函数中设置DoubleBuffered
。如果用户愿意,可以让他们设置。您的控件没有理由需要双缓冲。
关于delphi - 如何使我的 TCustomControl 后代组件停止闪烁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26130510/
有人可以解释一下哪个控件更适合创建自定义组件吗? twin control 和 tcustomcontrol 有什么区别? 先感谢您 最佳答案 Can someone please explain m
我正在编写一个基于 TCustomControl 的网格控件,这样我就可以自己处理所有结构、绘画和导航。我似乎无法弄清楚的是: 在我的构造函数中,我将 ControlStyle 设置为: Contro
我的 TCustomControl 后代使用线程,这涉及使用 InvalidateRect 进行无效化。我遇到这样的情况:当线程正在工作时关闭程序时,我不会停止 Destroy 中的线程,因为即使在进
很长一段时间,我在我的应用程序中使用了 TCustomPanel 类的后代,称为 MyContainer。我可以说是其他视觉控件的典型容器。一切都很好。有一天,我意识到我根本不使用面板功能,因此我可以
我有一个图形 TCustomControl 后代组件,其上有一个 TScrollBar。问题是,当我按箭头键移动光标时,整个 Canvas 都被绘制为背景颜色,包括滚动条的区域,然后滚动条被重新绘制,
如何创建一个行为类似于 Tpanel 的 TCustomControl?例如 MyCustomComponent,我可以将组件放入标签、图像等中。 最佳答案 诀窍是 TCustomPanel 中的这段
我创建了一个在 Canvas 上具有油漆覆盖的组件,我想设置最小宽度和高度的限制。当宽度或高度小于限制时,滚动条应该出现在侧面,就像滚动框一样,也可以滚动。 我选择 TCustomControl 是因
我创建了一个继承自TCustomControl的自定义控件,并发布了TControl的属性Align。但是,当我在 C++Builder 项目中使用此自定义控件时,它引发了异常 Project Lau
我创建了一个基于 TGraphicControl 的控件,该控件是透明的且大部分是空的。它实际上在线条艺术中实现了一个简单的符号。即TLFMagicControl = class(TGraphicCo
我正在使用一组现有的 TControl 设计一个新的 VCL 组件。控件放置在 TPanels 上,一些对齐到左侧位置,一个对齐到右侧位置,最后一个对齐到客户区。每个面板都有自定义组件作为其父级。 我
在 Delphi 5 中这曾经有效。我有一个源自 TCustomControl 的组件,并且我实现了 cmmouseleave 消息: procedure CMMouseLeave(var Messa
当我们创建一个组件作为自定义控件并将该控件放在面板上时,该控件始终显示在表单上而不是包含的控件上。如何在创建中设置自定义控件的父级,以便当按钮放在面板上时,按钮的父级就是面板? TGlassButto
如何创建 OnClick 事件?我需要有关 TCustomControl 的帮助。 最佳答案 OnClick 事件已在 TCustomControl 中定义。您所要做的就是让它可见。添加行 publi
我在 Delphi 2007 中让 TCustomControl 与透明度一起工作时遇到问题。我目前已将问题简化为下面的代码。问题是最初创建表单时,控件以相反的顺序绘制,它们被添加到表单中。当窗体被调
我创建了一个继承自 TCustomControl 的 Delphi 组件。该组件可以像从 TWinControl 继承一样获得焦点,但我需要在其获得焦点时“突出显示”,并在失去焦点时更改一些属性。正如
我是一名优秀的程序员,十分优秀!