Frage

Ich sehe meine Version von Delphi und habe keine Schlüsselereignisse (OnKeyDown, OnKeyUp, OnKeyPress) für TPaintBox.Ich würde so etwas gerne verarbeiten.Hatte jemand einen Paintbox mit diesen Ereignissen?

War es hilfreich?

Lösung

Wie TLama sagte, müssen Sie von TCustomControl erben. Sie benötigen jedoch zusätzlichen Code, um alle Tastaturereignisse zu veröffentlichen. Sie können den einfachen Weg wählen und von TPanel erben, da TPanel bereits einen Canvas und eine Reihe von Tastaturereignissen verfügbar macht.

Hier ist jedoch ein Code, der zeigt, wie ein neues Steuerelement erstellt und registriert wird, das die Eigenschaften von TCustomControl veröffentlicht und ein neues OnPaint-Ereignis einführt:

Wenn Sie ein neues Paket erstellen, dieses Gerät hinzufügen und installieren, verfügen Sie über ein neues TGTPaintBox-Steuerelement, das den Fokus haben kann (obwohl Sie es nicht sehen). Es kann auch Tastatureingaben abrufen.

unit uBigPaintbox;

interface

uses Windows, Classes, Messages, Controls;

type
  TGTPaintBox = class(TCustomControl)
  private
    FOnPaint: TNotifyEvent;
  protected
    // Three methods below are for transparent background. This may not work that great,
    // and if you don't care about it, you can remove them.
    procedure WMEraseBkGnd(var Msg: TWMEraseBkGnd); message WM_ERASEBKGND;
    procedure CreateParams(var Params: TCreateParams); override;
    procedure SetParent(AParent: TWinControl); override;
  protected
    procedure Paint; override;
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
  public
    property Canvas;
  published
    // Introduce OnPaint event
    property OnPaint: TNotifyEvent read FOnPaint write FOnPaint;
    // Publish keyboard and mouse events.
    property OnKeyPress;
    property OnKeyDown;
    property OnKeyUp;
    property OnClick;
    property OnDblClick;
    property OnMouseUp;
    property OnMouseDown;
    property OnMouseMove;
    // And some other behavioral property that relate to keyboard input.
    property TabOrder;
    property TabStop;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('GolezTrol', [TGTPaintBox]);
end;

{ TGTPaintBox }

procedure TGTPaintBox.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  Params.ExStyle := Params.ExStyle or WS_EX_TRANSPARENT;
end;

procedure TGTPaintBox.MouseDown(Button: TMouseButton; Shift: TShiftState; X,
  Y: Integer);
begin
  inherited;

  // Focus the control when it is clicked.
  if not (csDesigning in ComponentState) and CanFocus then
    SetFocus;
end;

procedure TGTPaintBox.Paint;
begin
  inherited;
  // Call paint even if it is assigned.
  if Assigned(FOnPaint) then
    FOnPaint(Self);
end;

procedure TGTPaintBox.SetParent(AParent: TWinControl);
var
  NewStyle: Integer;
begin
  inherited;
  if AParent = nil then
    Exit;

  // Make sure the parent is updated too behind the control.
  NewStyle := GetWindowLong(AParent.Handle, GWL_STYLE) and not WS_CLIPCHILDREN;
  SetWindowLong(AParent.Handle, GWL_STYLE, NewStyle);
end;

procedure TGTPaintBox.WMEraseBkGnd(var Msg: TWMEraseBkGnd);
begin
  SetBkMode(Msg.DC, TRANSPARENT);
  Msg.Result := 1;
end;

end.

Ich habe einige Funktionen hinzugefügt, um das Steuerelement transparent zu machen, da dies auch eine PaintBox ist. Ein Nachteil ist, dass Sie das übergeordnete Element neu streichen müssen, um den zuvor gezeichneten Inhalt zu löschen. In der Demo-Anwendung ist dies einfach genug. Ich mache nur das Formular anstelle des Steuerelements ungültig. : p
Wenn Sie es nicht benötigen, können Sie WMEraseBkGnd, CreateParams und SetParent aus dem Steuerelement entfernen.

Kleine Demo: Bringen Sie ein Etikett auf einem Formular an. Legen Sie eine TGTPaintBox darauf und vergrößern Sie sie etwas. Fügen Sie dann einen Timer und möglicherweise einige andere Steuerelemente hinzu.

Stellen Sie sicher, dass Sie die TabStop-Eigenschaft der GTPaintBox auf True setzen.

Implementieren Sie dann die folgenden Ereignisse:

// To repaint the lot.
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Invalidate;
end;

// Capture key input and save the last entered letter in the tag.
procedure TForm1.GTPaintBox1KeyPress(Sender: TObject; var Key: Char);
begin
  if Key in ['a'..'z'] then
    TGTPaintBox(Sender).Tag := Integer(Key);
end;

// Paint the control (this is called every second, when the timer invalidates the form
procedure TForm1.GTPaintBox1Paint(Sender: TObject);
var
  PaintBox: TGTPaintBox;
begin
  PaintBox := TGTPaintBox(Sender);

  // Draw a focus rect too. If you want the control to do this, you would normally
  // implement it in the control itself, and make sure it invalides as soon as it 
  // receives or loses focus.
  if PaintBox.Focused then
    PaintBox.Canvas.DrawFocusRect(PaintBox.Canvas.ClipRect);

  // It just draws the character that we forced into the Tag in the KeyPress event.
  PaintBox.Canvas.TextOut(Random(200), Random(200), Char(PaintBox.Tag));
end;

Andere Tipps

Sie können auch einen Rahmen mit dem Farbkasten erstellen (ausgerichtet auf alClient) und den Rahmen nach Bedarf wiederverwenden.TFrame ist ein Fenstersteuerelement, das alle Tastaturereignisse enthält.Sie werden nicht veröffentlicht, aber Sie können sie im Code zuweisen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top