Tôi có một thành phần hậu duệ TCustomControl
đồ họa với một số TScrollBar
trên đó. Vấn đề là khi tôi nhấn phím mũi tên để di chuyển con trỏ, toàn bộ canvas được tô màu nền, bao gồm cả vùng của thanh cuộn, sau đó thanh cuộn được sơn lại và làm cho thanh cuộn nhấp nháy. Làm sao tôi có thể giải quyết việc này ?Làm sao để thành phần hậu duệ TCustomControl của tôi ngừng nhấp nháy?
Đây là mã. Không cần phải cài đặt các thành phần hoặc đặt một cái gì đó về hình thức chính, chỉ cần sao chép mã và gán TForm1.FormCreate
sự kiện:
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.
Bạn đã thử bitmap đệm trung gian chưa? Ý tưởng là, làm tất cả các bản vẽ của bạn trên một khung hình vô hình, sau đó khi hoàn thành, vẽ hình ảnh đó để kiểm soát của bạn. –
Tôi đã nói rằng việc nuôi dạy con cái một thanh cuộn sẽ là một vấn đề. Tôi nghĩ rằng bạn sẽ được tốt hơn nhận được xử lý bởi hệ thống. Và đặt 'DoubleBuffered' thành' True' trong điều khiển có vẻ không rõ ràng. Bạn không cần phải tăng gấp đôi bộ đệm. 1 cho một câu hỏi rất hay, với tất cả các mã chúng ta cần, cắt giảm rất tốt. –
@JerryDodge Có. Thuộc tính 'DoubleBuffered' được kích hoạt và tất cả các bản vẽ được tạo trên bitmap vô hình trước tiên. –