Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 4 501

/ вопрос открыт /

Здравствуйте!
Моя проблема в том что я создаю регион и после этого пытаюсь отрисовать у этого региона рамку.
Регион создается, но когда пытаюсь отрисовать рамку с помощью Canvas.Brush программа ругается что canvas'у не разрешено рисовать.
Возможно ктонибудь знает как это преодолеть

Приложение:
  1. SetWindowRgn(Form1.Handle,Rect,true);
  2. Canvas:=TCanvas.Create;
  3. Canvas.Brush.Color:=ClBlack;
  4. FrameRgn(Canvas.Handle,Rect,Canvas.Brush.Handle,Form1.Width,Form1.Height);


SOA Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: SOA (статус: Посетитель)
Вопрос отправлен: 14 августа 2010, 12:00
Состояние вопроса: открыт, ответов: 0.


Мини-форум вопроса

Всего сообщений: 10; последнее сообщение — 17 августа 2010, 09:42; участников в обсуждении: 3.
Вадим К

Вадим К (статус: Академик), 14 августа 2010, 12:24 [#1]:

а если использовать Bitmap, который собственно для рисования и созданный?

К тому же я заметил, что в Вашем коде для канваса не выставляются размеры.

И ещё, если выше переменная Canvas не объявлена, то код очень плохой, так как используется канвас формы (утечки памяти и разнообразные глюки гарантированы).
Если же переменная Canvas используется, то лучше использовать более "мирное имя", например cnv.
Галочка "подтверждения прочтения" - вселенское зло.
SOA

SOA (статус: Посетитель), 14 августа 2010, 13:14 [#2]:

Насчет bitmap не знаю может и можно, но я не представляю как.

Размеры для канваса не выставляются потому что он используется в качестве устройства вывода, а также используются его кисти.

Переменная объявлена.

примерный код:

 Procedure SetForm();
 
 var
 cnv: TCanvas;
 Rect:hRgn;
 
implementation
 
{$R *.dfm}
 
Procedure SetForm();
Begin
Rect:=CreateRoundRectRgn(Form1.Left,Form1.Top,Form1.Left+Form1.Width,Form1.Top+Form1.Height,20,20);
  SetWindowRgn(Form1.Handle,Rect,true);
 
  cnv:=TCanvas.Create;
  cnv.Brush.Color:=ClBlack;
  FrameRgn(cnv.Handle,Rect,cnv.Brush.Handle,Form1.Width,Form1.Height);
End;
 
End.

Все компелируется, но при запуске процедуры программа ругается на
FrameRgn(cnv.Handle,Rect,cnv.Brush.Handle,Form1.Width,Form1.Height);

"Canvas does not allow to drawing"

Если сделать так

cnv:=Form1.Canvas;
  cnv.Brush.Color:=ClBlue;
  FrameRgn(cnv.Handle,Rect,cnv.Brush.Handle,Form1.Width,Form1.Height);

то программа не ругается, но и граница не прорисовывается.
Вадим К

Вадим К (статус: Академик), 14 августа 2010, 16:18 [#3]:

без указания размеров - это точно плохо.
Если просто создать канвас и рисовать на нем, то нигде ничего и не отобразиться - он то в памяти.

С другой стороны рамка может быть и не видна - если рисовать за пределами региона. попробуйте координаты изменить так, что бы они оказались точно внутри. На пикселей 5-10.
Галочка "подтверждения прочтения" - вселенское зло.
SOA

SOA (статус: Посетитель), 14 августа 2010, 20:40 [#4]:

Попробывал сделать так

Procedure SetForm();
 
 var
 cnv: TCanvas;
 Rect:hRgn;
 Rect1: TRect;
 
implementation
 
{$R *.dfm}
 
Procedure SetForm();
Begin
Rect:=CreateRoundRectRgn(Form1.Left,Form1.Top,Form1.Left+Form1.Width,Form1.Top+Form1.Height,20,20);
 
  Rect1:=Form1.ClientRect;
 
  cnv:=TCanvas.Create;
  cnv:=Form1.Canvas;
  Rect1.Left:=Rect1.Left+10; // отступ от границы в 10 пикселов
  Rect1.Right:=Rect1.Right-10;
  cnv.CopyRect(cnv.ClipRect,cnv,Rect1);// Копируем параметры Rect1 в canvas
  cnv.Brush.Color:=ClBlue;
  Kist:=Windows.CreateSolidBrush(255);
  FrameRgn(cnv.Handle,Rect,Kist,Form1.Width,Form1.Height);
 
  SetWindowRgn(Form1.Handle,Rect,true);
End;
 
End.

только регион выставляет, а границы так и не чертит.
Вадим К

Вадим К (статус: Академик), 14 августа 2010, 21:08 [#5]:

cnv:=TCanvas.Create;
cnv:=Form1.Canvas;
одна с этих строк точно лишняя.
В остальном коде какой то мусор.
Галочка "подтверждения прочтения" - вселенское зло.
SOA

SOA (статус: Посетитель), 14 августа 2010, 22:26 [#6]:

Почему мусор?
Rect1 например определяет область в которой будет прорисовываться canvas, она на 10 пикселов слева и справа меньше чем область занимаемая формой.
Не понимаю...
Amidamaru

Amidamaru (статус: 4-ый класс), 16 августа 2010, 20:03 [#7]:

хм. нужно наверное читать учиться описания функций.
FrameRgn(cnv.Handle,Rect,cnv.Brush.Handle,Form1.Width,Form1.Height);
вот последние 2 параметра это что?
нет, не правильно, это толщина горизонтальных и вертикальных линий, а не размеры формы.
ну и во вторых. ты же рисуешь на форме. зачем создавать ещё одну канву?? используй канву формы и всё.
Приглашаю Вас на наш IRC-канал: #delphiintru в сети DalNet.
SOA

SOA (статус: Посетитель), 16 августа 2010, 21:24 [#8]:

Да протупил я :)
Так работает(оказывается я всетаки рисовал рамку за пределами окна).
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
 
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
  Rect: Hrgn;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.Button1Click(Sender: TObject);
begin
Form1.SetBounds(0,0,Form1.Width,form1.Height);
Rect:=CreateRoundRectRgn(Form1.BoundsRect.Left,Form1.BoundsRect.Top,Form1.BoundsRect.Right,Form1.BoundsRect.Bottom,20,20);
Form1.Canvas.Brush.Color:=ClBlue;
FrameRgn(Form1.Canvas.Handle,Rect,Form1.Canvas.Brush.Handle,50,50);
SetWindowRgn(Form1.Handle,Rect,True);
end;
 
end.

Только теперь другая проблема, если окошко закрыть а потом активировать, то часть рамки стирается. Пробывал через события OnActivate, OnShow,OnPaint поредством FrameRgn(Form1.Canvas.Handle,Rect,Form1.Canvas.Brush.Handle,50,50);
востанавливать, не получилось почему то.
Amidamaru

Amidamaru (статус: 4-ый класс), 17 августа 2010, 00:52 [#9]:

Ну значит одной FrameRgn не хватает. Может ещё Form1.Canvas.Brush.Color:=ClBlue; нужно?
Есть ещё один способ решить эту проблему:
поставить на форму TImage, растянуть на всю форму (Align=alClient) и использовать его канву, а не формы. У TImage она автоматически перерисовывается.
Приглашаю Вас на наш IRC-канал: #delphiintru в сети DalNet.
SOA

SOA (статус: Посетитель), 17 августа 2010, 09:42 [#10]:

Все разобрался если сделать так, то все перерисовывается.

unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;
 
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormPaint(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
  Rect: Hrgn;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.FormPaint(Sender: TObject);
begin
Rect:=CreateRoundRectRgn(Form1.BoundsRect.Left-Form1.Left,Form1.BoundsRect.Top-Form1.Top,Form1.BoundsRect.Right-Form1.BoundsRect.Left,Form1.BoundsRect.Bottom-Form1.BoundsRect.Top,20,20);
Form1.Canvas.Brush.Color:=ClBlue;
FrameRgn(Form1.Canvas.Handle,Rect,Form1.Canvas.Brush.Handle,50,50);
SetWindowRgn(Form1.Handle,Rect,True);
end;
 
End.

Правда немного коряво внизу.

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:37
Выполнено за 0.04 сек.