Pregunta

Veo mi versión de delphi, no tiene eventos de eventos clave (OnKeyDown, OnKeyUp, OnKeyPress) para TPaintBox.Me gustaría procesar algo así.¿Alguien tenía una caja de pinturas con estos eventos?

¿Fue útil?

Solución

Como dijo TLama, deberá heredar de TCustomControl. Pero necesitará un código adicional para publicar todos los eventos de teclado. Puede elegir la forma más fácil y heredar de TPanel, ya que TPanel ya expone un Canvas y una serie de eventos de teclado.

Pero aquí hay un código para mostrar cómo crear y registrar un nuevo control que publicó las propiedades de TCustomControl e introduce un nuevo evento OnPaint:

Si crea un nuevo paquete, agrega esta unidad y la instala, tendrá un nuevo control TGTPaintBox que puede tener el foco (aunque no lo vea). También puede recuperar la entrada del teclado.

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.

He agregado algunas funciones en un intento de hacer que el control sea transparente, porque un PaintBox también lo es. Una desventaja es que debe volver a pintar el elemento principal para borrar el contenido dibujado anteriormente. En la aplicación de demostración, esto es bastante fácil. Solo invalido el formulario en lugar del control. : p
Si no lo necesita, puede eliminar WMEraseBkGnd, CreateParams y SetParent del control.

Pequeña demostración: Ponga una etiqueta en un formulario. Pon un TGTPaintBox encima y hazlo un poco más grande. Luego agregue un temporizador y tal vez algunos otros controles.

Asegúrese de establecer la propiedad TabStop de GTPaintBox en True.

Luego, implemente los siguientes eventos;

// 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;

Otros consejos

También puede crear un marco con la caja de pinturas (alineado con alClient) y reutilizar el marco según sea necesario.TFrame es un control en ventana por lo que tiene todos los eventos de teclado.No están publicados pero puede asignarlos en código.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top