unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Panel1: TPanel;
PaintBox1: TPaintBox;
Edit1: TEdit;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
procedure drawfon;
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
fRect:Trect;
str:string;
implementation
uses Types;
{$R *.dfm}
procedure TForm1.drawfon;
begin
with PaintBox1 do
begin
Canvas.Brush.Color:=clgreen;
Canvas.pen.Color:=clgreen;
Canvas.Rectangle(0,0,Width,Height);
Canvas.pen.Color:=clRed;
Canvas.Rectangle(frect);
canvas.TextOut(frect.Left+2,frect.Top+2,str);
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
frect.Left:=200;
frect.top:=200;
frect.right:=250;
frect.bottom:=220;
str:='Текст';
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
drawfon;
end;
procedure TForm1.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Edit1.Visible then
begin
str:=Edit1.Text;
Edit1.Visible:=false;
drawfon;
end else
if (x>frect.Left)and(x<fRect.Right)and(y>frect.Top)and(y<fRect.Bottom)then
begin
Edit1.Left:=fRect.Left;
Edit1.top:=fRect.top;
Edit1.width:=fRect.Right-fRect.Left;
Edit1.Height:=fRect.Bottom-fRect.Top;
Edit1.Visible:=true;
Edit1.SetFocus;
end;
end;
end.
Трабла Tpanel+TPaintBox+TEdit
Данный пример работает без проблем если пэинтбокс лежит на форме. если же он лежит на панели, то, после исчезновения эдита, изображение перерисовывается полностью но на месте эдита остается белый прямоугольник
onPaint в данном случае использовать нельзя
Из-за чего это, и как тут быть?
Код:
Рисуй в обработчике PaintBox.OnPaint, а вместо прямых вызовов drawfon вызывай Invalidate PaintBox'а.
Цитата: makbeth
Рисуй в обработчике PaintBox.OnPaint, а вместо прямых вызовов drawfon вызывай Invalidate PaintBox'а.
я бы с радостью, но тогда изображение мерцает, даже если предварительно рисовать на битмап и выводить на канву одной функцией типа драв или битблт. может можно какнибудь перехватывать лишние сообщения перерисовки paintbox-а?
з.ы. изображение формируется большое с GDI+
1. Прибить обработку сообщения WM_ERASEBKGND. Для этого нужно будет переопределить свойство WndProc у панели.
2. Установить свойство DoubleBuffered в true. А поскольку оно находится в секции protected, то тут необходим небольшой хакерский прием:
Код:
type
TDoubleBufPaintProp = class (TControl)
public
property DoubleBuffered;
end;
TDoubleBufPaintProp = class (TControl)
public
property DoubleBuffered;
end;
и далее использовать так:
Код:
TDoubleBufPaintProp(Panel1).DoubleBuffered:=true;
PaintBox.ControlStyle := PaintBox.ControlStyle + [ csOpaque ] ;
терь всё работает более менее норм)