Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 19.07.2009, 15:31   #1
VVM
Форумчанин
 
Аватар для VVM
 
Регистрация: 06.06.2007
Сообщений: 282
По умолчанию Error: "Canvas does not allow drawing", Delphi7

Доброе время суток!
Никак не пойму в чем дело. Поиск не помог, в сети на нашел Pls help!
Цель - создать цветную кнопочку именно на основе TButton =-)

Код:
unit Unit1;

interface

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

type
  TCanvasedButton = class(TButton)
  private
    FCanvas: TControlCanvas;
  public
    constructor Make(AOwner: TComponent);
    destructor Kill;
    property Canvas: TControlCanvas read FCanvas write FCanvas;   
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormClick(Sender: TObject);
  private
    Btn: TCanvasedButton;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormClick(Sender: TObject);
var
  Bmp: TBitmap;
begin
  Bmp := TBitmap.Create;
  Btn := TCanvasedButton.Make(Self);
  Btn.Canvas.FloodFill(0, 0, clRed, fsSurface); //Исключение вылетает здесь
  try
    Bmp.LoadFromFile('Fon.bmp');
    Form1.Canvas.Draw(0, 0, Bmp);
    Form1.OnPaint := Form1.OnClick;
  finally
    FreeAndNil(Bmp);
  end;
end;

{ TCanvasedButton }

destructor TCanvasedButton.Kill;
begin
  FreeAndNil(FCanvas);
  inherited Destroy;
end;

constructor TCanvasedButton.Make(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Canvas := TControlCanvas.Create;
end;

end.
Не важно, как часто вы падаете. Важно, как часто вы поднимаетесь. Винс Ломбарди.

Последний раз редактировалось VVM; 19.07.2009 в 15:37.
VVM вне форума Ответить с цитированием
Старый 19.07.2009, 16:25   #2
Daramant
Форумчанин
 
Регистрация: 06.01.2009
Сообщений: 340
По умолчанию

1. Исключение вылетает из-за того, что не определен контрол, на котором будет отрисовываться Canvas:

Код:
constructor TCanvasedButton.Make(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Canvas := TControlCanvas.Create;

  Canvas.Control := self; // <-- добавил
end;
2. Ты не правильно создаешь кнопку, если кнопка создается динамически, то и параметры ей необходимо устанавливать самому:

Код:
  Btn := TCanvasedButton.Make(Self);
  Btn.Top := 10;
  Btn.Left := 10;
  Btn.Parent := Form1; // кто будет родителем, т.е. на чем будет отображаться кнопка
  Btn.Caption := 'my button';
Я вынес загрузку картинки и создание копки в конструктор формы.
Будет как-то так:
Код:
unit Unit1;

interface

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

type
  TCanvasedButton = class(TButton)
  private
    FCanvas: TControlCanvas;
  public
    constructor Make(AOwner: TComponent);
    destructor Kill;
    property Canvas: TControlCanvas read FCanvas write FCanvas;
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    Btn: TCanvasedButton;
    Bmp: TBitmap;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormClick(Sender: TObject);
begin
  Canvas.Pen.Color := clWhite;
  Btn.Canvas.Brush.Color := clRed;
  Btn.Canvas.FillRect(Btn.ClientRect);

  Btn.Canvas.LineTo(10, 10);

  Form1.Canvas.Draw(0, 0, Bmp);
end;

{ TCanvasedButton }

destructor TCanvasedButton.Kill;
begin
  FreeAndNil(FCanvas);
  inherited Destroy;
end;

constructor TCanvasedButton.Make(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Canvas := TControlCanvas.Create;

  Canvas.Control := self; 
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Btn := TCanvasedButton.Make(Self);
  Btn.Top := 10;
  Btn.Left := 10;
  Btn.Parent := Form1;
  Btn.Caption := 'my button';

  Bmp := TBitmap.Create;
  Bmp.LoadFromFile('image.bmp');
  Form1.OnPaint := Form1.FormClick;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Btn.Free;
  Bmp.Free;
end;

end.
Но это не то.
Кнопка будет красной при клике не на нее (по форме и др.), но при клике на нее она перерисовывается и принимает стандартный вид.

Если хочешь создать свою кнопку, с собственной отрисовкой, то наследуй ее от TCustomControl.
Не буду пересказывать, вот статься:
http://svdpro.info/page.php?id=34
Истинный успех – это то, что Вы сделали в сравнении с тем, что могли бы сделать.
Никогда не бойся делать то, что ты не умеешь. Помни, ковчег был построен любителем. Профессионалы построили "Титаник".
Daramant вне форума Ответить с цитированием
Старый 19.07.2009, 16:38   #3
VVM
Форумчанин
 
Аватар для VVM
 
Регистрация: 06.06.2007
Сообщений: 282
По умолчанию

Цитата:
Canvas.Control := self; // <-- добавил
Ах вот где собака зарыта =)
Большое спасибо!
Не важно, как часто вы падаете. Важно, как часто вы поднимаетесь. Винс Ломбарди.
VVM вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Ошибка при работе с canvas "Неверный дескриптор" Алекс Ялта Gamedev - cоздание игр: Unity, OpenGL, DirectX 17 13.06.2011 22:32
1>Проект : error PRJ0003 : Ошибка при создании "cl.exe". ben95 Помощь студентам 1 14.05.2009 17:10
Проект : error PRJ0003 : Ошибка при создании "cl.exe". ben95 Общие вопросы C/C++ 0 14.05.2009 16:50
Как устранить ошибку "socket error #10060" Evgen1976 Работа с сетью в Delphi 11 20.03.2009 15:21
Нужен компонент для Delphi7 "WbemScripting_TLB" Air Компоненты Delphi 3 10.10.2007 01:15