Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Трабла Tpanel+TPaintBox+TEdit

3.2K
17 марта 2008 года
Гудвин
186 / / 22.12.2007
Суть такая на пэинтбоксе изображение объектов с подписями, при нажатии на подпись на её месте появляется Эдит, пользователь вводит текст клацает по пэинтбоксу в другом месте и подпись меняется на то что он ввёл, а эдит исчезает.
Данный пример работает без проблем если пэинтбокс лежит на форме. если же он лежит на панели, то, после исчезновения эдита, изображение перерисовывается полностью но на месте эдита остается белый прямоугольник
onPaint в данном случае использовать нельзя
Из-за чего это, и как тут быть?

Код:
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.
303
18 марта 2008 года
makbeth
1.0K / / 25.11.2004
Рисуй в обработчике PaintBox.OnPaint, а вместо прямых вызовов drawfon вызывай Invalidate PaintBox'а.
3.2K
18 марта 2008 года
Гудвин
186 / / 22.12.2007
Цитата: makbeth
Рисуй в обработчике PaintBox.OnPaint, а вместо прямых вызовов drawfon вызывай Invalidate PaintBox'а.



я бы с радостью, но тогда изображение мерцает, даже если предварительно рисовать на битмап и выводить на канву одной функцией типа драв или битблт. может можно какнибудь перехватывать лишние сообщения перерисовки paintbox-а?
з.ы. изображение формируется большое с GDI+

303
18 марта 2008 года
makbeth
1.0K / / 25.11.2004
Вообще, мерцание происходит из-за перерисовки фона. Тут есть несколько вариантов:
1. Прибить обработку сообщения WM_ERASEBKGND. Для этого нужно будет переопределить свойство WndProc у панели.
2. Установить свойство DoubleBuffered в true. А поскольку оно находится в секции protected, то тут необходим небольшой хакерский прием:
 
Код:
type
    TDoubleBufPaintProp = class (TControl)
    public
        property DoubleBuffered;
    end;

и далее использовать так:
 
Код:
TDoubleBufPaintProp(Panel1).DoubleBuffered:=true;
3.2K
18 марта 2008 года
Гудвин
186 / / 22.12.2007
пасибо. прогуглил на счёт WM_ERASEBKGND, лишняя перерисовка фона исчезает если:
PaintBox.ControlStyle := PaintBox.ControlStyle + [ csOpaque ] ;
терь всё работает более менее норм)
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог