powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Создание компонента сложной формы (аккуратной контурной стрелки).
110 сообщений из 110, показаны все 5 страниц
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39854799
Вопрос несколько шире, чем можно написать в заголовке и требует некоторого пояснения.
В моей программке есть рисовалка, которая показывает результаты расчетов пример на картинке. Но всё что отображается по сути обычный рисунок на канве. Интерактивность обеспечивается перехватом координат по клику, сравнивание с изображенным на рисунке и вызовом соответствующих процедур.



Но в определенный момент мне захотелось большей "интерактивности" (информация при наведении на элемент, информация при клике по тексту или рисунку, т.п.).
Так же когда объемы и форматы выводимой информации стали весьма значительными
(рисунки для примера)




добавление любых новых данных стало ну очень сложным (так как всё один рисунок + интерактивность + куча условий + каждый раз данные подгружаются разные, надо всё учитывать, ну и т.п.) решил попробовать сделать свой компонент наследника от панели (из-за удобной возможности "ручного" перетаскивания и широкого выбора событий) с лейблами для вывода текста и прочим подобным.

Сделать это на первый взгляд оказалось не сложно (на картинки каждый шестигранник - компонент)...
пример - картинка
,
но только на первый взгляд, одним из очень важных элементов визуального отображения результатов являются стрелки
картинка - пример тут всё является одним рисунком

и вот тут возникла сложность, а как рисовать стрелки поверх панелек не перекрывая доступ к ним (яж хочу "интерактивность"). Ну и в общем основной вопрос в этом. Как реализовать такие стрелки?
Наиболее очевидным для меня было сделать контурную стрелку и вырезать панельку по ней, так я и сделал, но результат сильно разочаровал:
пример со стрелками вырезанными из панелек

Во первых ужасное "сглаживание" наклонных линий (есть ли способ уменьшить эти лесенки?).
Во вторых я никак не могу понять почему основания стрелок сужаются/расширяются? Что-то с округлением и непопаданием пикселей, вроде тригонометрия правильная? Почему криво обрезаются...
Из решений пока думаю сделать панельку прозрачной(теми или иными способами) и рисовать стрелки старым способом.

Я резонно предполагаю, что способ реализации выбранный мной ну очень спорный, потому открыт для любых адекватных предложений.
Отдельные вопросы:
1. Создания сотен панелей потенциально не опасно для работы программы? Что-нибудь может поломаться? В принципе что по памяти, что по отклику проблем никаких не замечено.
2. Имеет ли смысл включать канвас на панели вместо создания на ней Image, это даст какие-то ресурсные преимущества, ну или, возможно, это правильнее?
3. Как можно ускорить создание панелек, несколько сотен панелек создается несколько секунд, что не много, но не мгновенно.
4. Можно ли рисовать прям поверх всех панелей при этом не ограничивая взаимодействия.
5. Почему
Код: pascal
1.
2.
CreatePolygonRgn (pt,NPoint,1); 
SetWindowRgn(Handle,CirRgn,true);

при использовании динамического массива просто уничтожает работу системы. Винда зависает почти в ноль даже на многоядерном процессоре, данные на входе проверял - правильны.
То есть такой код работает нормально:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
    Var
  pt      :array[0..5]  of TPoint;
  ...
 begin
  CirRgn:= CreatePolygonRgn (pt,6,1);
  SetWindowRgn(Handle,CirRgn,true);
 end

А вот такой убивает винду (по крайней мере на Delphi7), почему?
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
    Var
  pt      :array  of TPoint;
  ...
 begin
  Setlength (pt,6)
  CirRgn:= CreatePolygonRgn (pt,6,1);
  SetWindowRgn(Handle,CirRgn,true);
 end



Если интересен код, вот, сильно не бейте, писалось просто что в голову придет и я пока просто учусь:
код
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

TArrow = array [0..6] of TPoint;

type
  TestPanel = class (TPanel)
  private
     Image:TImage;
     Numb:integer;
     procedure MovePanelMouseDown(Sender: TObject; Button: TMouseButton;  Shift: TShiftState; X, Y: Integer);
  public
     property Index:Integer read Numb write Numb;
  end;

TFA = class
 private
    TextLabel:array [1..5] of TLabel;
    Arrow:TestPanel;
    Hex:TestPanel;
    X,Y:Real;
    RDes:Integer;
    Numb:integer;
    Parent :  TWinControl;
    function BodyArrow(X1,Y1,X2,Y2: Integer; LW: Extended):TArrow;
 public
    DeltX,DelTY:Real;
    property PosX:real write X;
    property PosY:real write Y;
    procedure DrawArrow (DeltX,DeltY:Real; Wdt:integer);
 Published
    constructor  Create(AOwner: TWinControl; PosX, PosY : real; RadDes, Index  : Integer);
 end;

TRPoint = record
x,y:real;
end;

var
  Form1: TForm1;
  RPoint: array [1..163] of TRPoint;
  FA:array [1..163] of TFA;
  
implementation

{$R *.dfm}

constructor TFA.Create(AOwner: TWinControl; PosX, PosY : real; RadDes, Index : Integer); //ñîçäàþ ìíîãîóãîëüíèê ñ òåêòîì
var
  i       :integer;
  CirRgn  :HRGN;
  pt      :array[0..5]  of TPoint;
const
  NPoint=6;
begin
  X:=PosX;  Y:=PosY;
  RDes:=RadDes;
  Parent:=AOwner;
  Numb:=Index;

  Hex:=TestPanel.Create(AOwner);
  Hex.Index:=Numb;
  Hex.Parent:=AOwner;
  Hex.SendToBack;

 with  Hex do
   begin
      BevelInner:=bvNone;  BevelOuter:=bvNone;  BorderStyle:=bsNone; //ïàðàìåíòðû ïàíåëè
      Height:=RDes*2;    Width:=RDes*2;
      Top:=Round(Y);     Left:=Round(X);

      Image:=TImage.Create(Hex);
      Image.Parent:=Hex;
      Image.Align:=alClient;
      Image.OnMouseDown:=Hex.MovePanelMouseDown;

      for i:=1 to 5 do     //òåêñò
       begin
        TextLabel[i]:=Tlabel.Create(Hex);
        TextLabel[i].Parent:=Hex;
        TextLabel[i].Caption:=inttostr(i);
        TextLabel[i].Left:=RDes-Round(TextLabel[i].width/2);
        TextLabel[i].Top:=Round(i*(2*RDes-12)/(5)-6);
        TextLabel[i].Transparent:=True;
       end;

      for i:=0 to NPoint-1 do  //ôîðìà ìíîãîóãîëüíèêà
        begin
          pt[i].Y:=Round((Sin(2*i*pi/NPoint+pi/NPoint)+1)*RDes);
          pt[i].X:=Round((Cos(2*i*pi/NPoint+pi/NPoint)+1)*RDes);
        end;
      CirRgn:= CreatePolygonRgn (pt,NPoint,1);
      SetWindowRgn(Handle,CirRgn,true);
      Image.Canvas.Pen.Width:=4;

      Image.Canvas.Brush.Color:=RGB(random(255), random(255), random(255));
      Image.Canvas.Brush.Style:=bsSolid;
      Image.Canvas.Pen.Color:=clBlack;
      Image.Canvas.Polygon(pt);
   end;
end;


function TFA.BodyArrow(X1,Y1,X2,Y2: Integer; LW: Extended):TArrow; //ðèñóþ ñòðåëêó
  var
    Angle: Extended;
    A1,A2: Extended;
    Body:  TArrow;
    SinA,CosA,AbsA:Extended;
  const
    WidthLen=2.2;
    LineLen=4.74;
    ArrAngl=0.28322;
    HeadLenght=4.5;
begin
  Angle:=ArcTan2(Y1-Y2,X2-X1);
  AbsA:=Sqrt(Sqr(Y2-Y1)+Sqr(X2-X1));
  SinA:=(Y2-Y1)/AbsA;
  CosA:=(X2-X1)/AbsA;

  Angle:=Pi+Angle;
  A1:=Angle-ArrAngl; A2:=Angle+ArrAngl;
  Body[0]:=Point(Round(X1+WidthLen*SinA),Round(Y1-WidthLen*CosA));
  Body[1]:=Point(Round(X1-WidthLen*SinA),Round(Y1+WidthLen*CosA));
  Body[2]:=Point(Round(X2-WidthLen*SinA -LW*HeadLenght*CosA),Round(Y2+WidthLen*CosA-LW*HeadLenght*SinA));
  Body[3]:=Point(X2+Round(LineLen*LW*Cos(A2)),Y2-Round(LineLen*LW*Sin(A2)));
  Body[4]:=Point(X2,Y2);
  Body[5]:=Point(X2+Round(LineLen*LW*Cos(A1)),Y2-Round(LineLen*LW*Sin(A1)));
  Body[6]:=Point(Round(X2+WidthLen*SinA -LW*HeadLenght*CosA),Round(Y2-WidthLen*CosA-LW*HeadLenght*SinA));

  BodyArrow:=Body;
end;

procedure TFA.DrawArrow (DeltX,DeltY:Real; Wdt:integer);
var
  CirRgn:HRGN;
  RecPoint:TArrow;
  Line: array [1..2] of TPoint;
  i:Integer;
  SinA,CosA,AbsA,dX,dY:Real;
  TempInteger:Integer;
begin
 AbsA:=Sqrt(Sqr(DeltX)+Sqr(DeltY));
 SinA:=(DeltY)/AbsA;
 CosA:=(DeltX)/AbsA;
 dX:=(SinA*Wdt)/2;
 dY:=(CosA*Wdt)/2;

 Arrow:=TestPanel.Create(Parent);
 Arrow.Parent:=Parent;
 Arrow.Index:=0;

with  Arrow do
  begin
   BevelInner:=bvNone; BevelOuter:=bvNone;  BorderStyle:=bsNone;   //óáèðàåì ãðàíèöû

   if DeltX>=0 then  Left:=Round(X+RDes-abs(dX))  else  Left:=Round(X+RDes+DeltX-abs(dX)); //ðàçåìðû ïàíåëè
   if DeltY>=0 then  Top:= Round(Y+RDes-abs(dY))  else  Top:= Round(Y+RDes+DeltY-abs(dY));
   Width:=Round(Abs(DeltX)+2*abs(dX));       Height:=Round(Abs(DeltY)+2*abs(dY));

   Image:=TImage.Create(Arrow);      //ñîçäàåì ïàíåëü
   Image.Parent:=Arrow;
   Image.Align:=alClient;
   Image.Canvas.Brush.Color:=clRed;
   Image.Canvas.Pen.Width:=2;

   if (DeltX>=0) then begin  Line[1].X:=Round(DeltX+abs(dX)); Line[2].X:=Round(0+abs(dX) )      end
                else  begin  Line[1].X:=Round(0+abs(dX));     Line[2].X:=Round(-DeltX+abs(dX) ) end;

   if (DeltY>=0) then begin  Line[1].Y:=Round(DeltY+abs(dY)); Line[2].Y:=Round(0+abs(dY))   end
                 else begin  Line[1].Y:=Round(0+abs(dY));     Line[2].Y:=Round(-DeltY+abs(dY)) end;

   RecPoint:=    BodyArrow(Line[1].X,Line[1].Y,Line[2].X,Line[2].Y,3);

   CirRgn:= CreatePolygonRgn (RecPoint,7,1);
   Image.Canvas.Polygon(RecPoint);
   SetWindowRgn(Handle,CirRgn,true);

   Image.OnMouseDown:=Arrow.MovePanelMouseDown;
  end;
end;

procedure TestPanel.MovePanelMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  ReleaseCapture;
  (Sender as TImage).Parent.Perform(WM_SYSCOMMAND, $F012, 0);
end;

procedure LoadData;
 var
  sl,dmsl:TStringList;
  i:integer;
begin
  sl:=TStringList.Create;
  sl.LoadFromFile('fa_locations.c1');
  dmsl:=TStringList.Create;
  dmsl.Delimiter:=' ';
  for i:=0 to 162 do
  begin
   dmsl.DelimitedText:=sl[i];
   RPoint[i+1].x:=StrToFloat (dmsl[1]);
   RPoint[i+1].y:=StrToFloat (dmsl[2]);
  end;
  dmsl.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  i:Integer;
begin
Panel1.Visible:=false;
 if FileExists('fa_locations.c1') then LoadData
    else for i:=1 to 163 do begin RPoint[i].x:=Random(3000)/1000-1.5; RPoint[i].y:=Random(3000)/1000-1.5; end;


 for i:=1 to 163 do if FA[i]=nil then  FA[i]:=TFA.Create(Panel1,RPoint[i].x*220+400,RPoint[i].y*220+350,30,i);
Panel1.Visible:=True;
Button2.Enabled:=True;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  i:Integer;
begin
Panel1.Visible:=false;
 for i:=1 to 163 do   FA[i].DrawArrow(Random(50)+50,Random(50)+50,10);
Panel1.Visible:=True;
end;

End.



Ну а теперь отдельно.
Если мои вопросы слишком глупы для данного форума, то, вроде, есть более лояльные к новичкам форумы, просто это мне показался наиболее живым из существующих, если считаете что не стоит тут задавать, то более не буду.
Если же мои вопрос слишком сложны и надо писать их в разделе "работа", то поясню, всё что я делаю, по сути делаю для "научного интереса", то есть мне за это никто не платит, я за это ничего не получу (кроме, возможно, благодарности). Можно сказать что я просто учусь и заодно что-то делаю облегчая жизнь себе и коллегам. Банально мне это интересно и нравится.
П.С. Мне на форуме советовали книгу по типам данных Delphi, теперь никак не могу найти где именно мне её посоветовали. Скачал несколько по алгоритмам, хорошие книги, но пока не совсем то, что мне надо. Чтож за книгу там мне посоветовали...
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39854801
Сомневаюсь, что кому-то нужно, но прицепил программку. Зато можно стрелочки порисовать :).
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39854830
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей ИгоревичП.С. Мне на форуме советовали книгу по типам данных Delphi, теперь никак не могу найти где именно мне её посоветовали. Скачал несколько по алгоритмам, хорошие книги, но пока не совсем то, что мне надо. Чтож за книгу там мне посоветовали...
Я вам писал о вот этой книжке:
https://royallib.com/book/baknell_dgulian/fundamentalnie_algoritmi_i_strukturi_dannih_v_Delphi.html
Но может быть вы что-то другое имеете в виду.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39854835
s62Андрей ИгоревичП.С. Мне на форуме советовали книгу по типам данных Delphi, теперь никак не могу найти где именно мне её посоветовали. Скачал несколько по алгоритмам, хорошие книги, но пока не совсем то, что мне надо. Чтож за книгу там мне посоветовали...
Я вам писал о вот этой книжке:
https://royallib.com/book/baknell_dgulian/fundamentalnie_algoritmi_i_strukturi_dannih_v_Delphi.html
Но может быть вы что-то другое имеете в виду.
А, эту книгу я уже скачал. Хорошая, но некоторая сложность в том, что алгоритмы из книги я нигде пока не использую (ну из начала кнаги по крайней мере), а что не использовал, то почти сразу забываю (треклятая дырявая память), сейчас добью "Библию Делфи" (ничего нового особо не узнал, но некоторое систематизировал) и попробую эту ещё раз уже пытаясь куда-нибудь применив.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39854849
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей ИгоревичСделать это на первый взгляд оказалось не сложно (на картинки каждый шестигранник - компонент)...
Ну ты, брат, силен. Основную работу работать-то успеваешь? :)

зы. если честно, ЯНХНП. Но, если суть вопроса в корректной и оптимальной отрисовке, дождись, пока ответит Соколинский Борис , он в этом вопросе продвинут, КМК.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39854860
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробуй вместо панелек отрисовку в Tshape с перекрытым Draw и Brush.Style=bsClear. Да, регионы очень тормознутые, тем более когда их сотни.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39854864
ДокАндрей ИгоревичСделать это на первый взгляд оказалось не сложно (на картинки каждый шестигранник - компонент)...
Ну ты, брат, силен. Основную работу работать-то успеваешь? :)

зы. если честно, ЯНХНП. Но, если суть вопроса в корректной и оптимальной отрисовке, дождись, пока ответит Соколинский Борис , он в этом вопросе продвинут, КМК.
Лето, пара отпусков, всё начальство отдыхает, вот и ковыряюсь пока время есть. По факту я уже раза 3-4 почти всё переделывал, на это (и на поиск ошибок от выхода за пределы массива) уходить куда больше времени, чем на создание чего-то нового :).

Суть вопроса достаточно проста:
как нарисовать красивую стрелочку поверх всего(панелек, имеджей, ...) на форме при том чтоб стрелка не перекрывала доступ к компонентам под ней .

Остальное уже так, заранее ответил на возможные вопросы :) (по опыту). Нашел несколько готовых решений, но там везде идет перекрытие (стрелка на прозрачном фоне). Наверняка в сети "тыщу" раз это обсуждалось, но я не всегда умею грамотно спросить у гугла (обычно знаешь что спрашивать уже зная ответ).
Ну и просто может кто по опыту скажет, что я вообще не правильно всё делаю и надо делать не так (ну там не панельки использовать, не так компоненты рисловать, и т.п.).
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39854875
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: pascal
1.
и на поиск ошибок от выхода за пределы массива



Программа сама найдет

Range checking
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39854878
X-Cite
Код: pascal
1.
и на поиск ошибок от выхода за пределы массива


Программа сама найдет
Range checking
Спасибо, попробую, нужная вещь. Вроде и знал о данной возможности, а вроде и ленился найти как включить. Ведь каждый раз думаешь "ну в чем же ошибка, ну в этот раз точно не динамический массив", а по факту постоянно из-за него :), как я не люблю динамические массивы, будь они неладны...

Василий 2Попробуй вместо панелек отрисовку в Tshape с перекрытым Draw и Brush.Style=bsClear. Да, регионы очень тормознутые, тем более когда их сотни.
Попробую, пока что-то не разобрался как её на передний план вывести и будет ли прямоугольник компонента перекрывать доступ, но поковыряюсь.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39854890
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Почему в пользу "интеракивности" был выбран TWinControl + SetWindowRgn, а не просто TGraphicsControl ?
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39854909
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей Игоревич,

ЖСТКО
Такие вещи только вручную рисуют, через промежуточный буфер - двойная буферизация называется, в сети полно примеров
Ссли уж так охота всё отдельынми компонентами, то наследуйтесь от TGraphicsControl, он у вас хоть окна создавать не будет (дискрипторы окон лимитированный ресурс)

а CreatePolygonRgn у вас выпадает из-за того, что вы ему адрес не буфера передаёте, а условно "мусор", используйте с ним [0]
Код: pascal
1.
CreatePolygonRgn (pt[0],6,1);
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39854915
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)(дискрипторы окон лимитированный ресурс)
Насколько я помню, со времён Windows 95 ситуация несколько изменилась.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39854952
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarerkealon(Ruslan)(дискрипторы окон лимитированный ресурс)
Насколько я помню, со времён Windows 95 ситуация несколько изменилась.если к делу подходят специалисты :-)
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39854978
DimaBrПочему в пользу "интеракивности" был выбран TWinControl + SetWindowRgn, а не просто TGraphicsControl ?
Что на текущий момент знал, то и использовал. Сейчас, по мере наличия свободного времени, буду про предложенное вами читать и пробовать.
kealon(Ruslan)Андрей Игоревич,
ЖСТКО
Такие вещи только вручную рисуют, через промежуточный буфер - двойная буферизация называется, в сети полно примеров
Ссли уж так охота всё отдельынми компонентами, то наследуйтесь от TGraphicsControl, он у вас хоть окна создавать не будет (дискрипторы окон лимитированный ресурс)
а CreatePolygonRgn у вас выпадает из-за того, что вы ему адрес не буфера передаёте, а условно "мусор", используйте с ним [0]
Код: pascal
1.
CreatePolygonRgn (pt[0],6,1);


Спасибо, попробую поискать примеры в сети "двойной буферизации".
На счет "лимитированного ресурса", вроде пару тысяч для теста создавал, ничего не падало (хотя программка и начала тормозить), но буду иметь в виду и попробую предложенные способы.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855097
asviridenkov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей Игоревич,

На стандартном канвасе красивой графики не получить. Нужно делать на GDI+, или еще лучше на Direct2D.
Никаких контролов, все рисовать самому, все объекты свои, каждый умеет отрисовываться и обрабатывать события.
При желании, за пол года вполне сможете сделать нормальную версию.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855115
Фотография Kast2K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей Игоревич,

Попробуйсте с TpaintBox, но качественной графики от него не ждите.

Демка с просторов интернета.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855174
stanilar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вопрос делится на два: сделать в дельфи и сделать хорошо и быстро.

Насчет первого вопроса... Ну, раз Вы начали сами программировать то, что хотите - то продолжайте, это полезно. Создать своего наследника панели это очень круто, на него можно кинуть фрейм - удобство дельфовой визуальной разработки засверкает новыми красками. Стрелочки можно нарисовать на холсте того компонента, на котором лежат Ваши наследники панели.

Правда знание особенностей дельфовой объектной обертки над WIN API вроде как мало востребовано. Думаю что даже меньше востребовано чем просто хорошее знание WIN API. IMHO хорошее знание WIN API лучше сочетается с билдером.

Насчет второго... Тут нужно подобрать хорошую технологию. Из известных мне - SVG. Он не только стрелочки сможет рисовать. Но для интерактивности потребуется работать с компонентом TWebBrowser или поискать полную реализацию под дельфан. А такого, скорее всего нет, потому что SVG по возможностям почти как HTML(тока css не нужен, таки картинка).
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855177
asviridenkov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stanilarSVG по возможностям почти как HTML(тока css не нужен, таки картинка).

Еще как нужен.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855196
stanilar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asviridenkovЕще как нужен.

При использовании в рамках HTML - можно поставить корню ширину, высоту и позицию. А в остальном у него все свое, это ведь картинка. Зачем картинке css?
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855206
asviridenkov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stanilarasviridenkovЕще как нужен.

При использовании в рамках HTML - можно поставить корню ширину, высоту и позицию. А в остальном у него все свое, это ведь картинка. Зачем картинке css?

Это не картинка, это набор векторных элементов с CSS стилями.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855215
stanilar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asviridenkovЭто не картинка, это набор векторных элементов с CSS стилями.

Вот постоянно сталкиваюсь с SVG. Даже либу для построения графиков написал. Но не понимаю тебя.

SVG, это аналог HTML. В нем есть место и для CSS, если кому хочется. Кому не хочется - тот обходится без CSS. Код с примером можешь привести, зачем нужен CSS в SVG?
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855224
asviridenkov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stanilarasviridenkovЭто не картинка, это набор векторных элементов с CSS стилями.

Вот постоянно сталкиваюсь с SVG. Даже либу для построения графиков написал. Но не понимаю тебя.

SVG, это аналог HTML. В нем есть место и для CSS, если кому хочется. Кому не хочется - тот обходится без CSS. Код с примером можешь привести, зачем нужен CSS в SVG?

Для всего. Атрибут style у элементов SVG, это тоже CSS. А, например, интерактивность вроде

.vbar g:hover {fill-opacity: 0.7}

только через глобальный stylesheet делается.

Да, какие-то свойства в SVG можно задавать через атрибуты, но не все, не всегда, и вообще не лучший вариант.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855235
stanilar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asviridenkov.vbar g:hover {fill-opacity: 0.7}

Код: javascript
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
<rect id="rect1" class="bar" x="20" y="60" width="80" height="120">
    <set attributeName="fill" to="#ec008c"
         begin="rect1.mouseover"
         end="rect1.mouseout"/>
    <set attributeName="opacity" to="0.4"
         begin="rect2.mouseover"
         end="rect2.mouseout"/>
    <set attributeName="opacity" to="0.4"
         begin="rect3.mouseover"
         end="rect3.mouseout"/>
</rect>



asviridenkovДа, какие-то свойства в SVG можно задавать через атрибуты, но не все, не всегда, и вообще не лучший вариант.
IMHO самый лучший вариант. Такую SVG картинку всегда можно экспортировать/импортировать. А при программировании интерактивной картинки со стороны js - вообще только так. Как ты каллбек mouseleave/mouseenter из SVG в js пробросишь, если у тебя hover из css задается?
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855261
asviridenkov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stanilar,

В моем примере устанавливалось для всех элементов определенного класса, а здесь для конкретных.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855272
asviridenkovАндрей Игоревич,
При желании, за пол года вполне сможете сделать нормальную версию.
Это очень жестоко (пол года)... Но по возможности попробую поизучать GDI+.
Kast2KАндрей Игоревич,
Попробуйсте с TpaintBox, но качественной графики от него не ждите.
Демка с просторов интернета.
Пока поверхностно потыкал пример (но, кстати, на 7й не работал, только на 10), но там перекрытие прямоугольником компонентов за линией, с TPaintBox тоже, но надо повникать, как я понял он позже 7ки появился (нашел его только в 10ке).

stanilarПравда знание особенностей дельфовой объектной обертки над WIN API вроде как мало востребовано. Думаю что даже меньше востребовано чем просто хорошее знание WIN API. IMHO хорошее знание WIN API лучше сочетается с билдером.

На текущий момент меня востребованность не очень волнует, приложение пишется "для себя". Более обидно будет, если Делфи окончательно прикроют (грустно изучать то, что уже не будет развиваться).
А вопрос, а как Чарт в 10й делфе рисует свои картинки? Ну просто для сравнения графики в нем в 7ке и 10ке:
для понимания разницы картинки надо смотреть без масштабирования браузером

Ну и другие вещи (всякие скругленные бары и прочее) они рисует просто прекрасно.

asviridenkovstanilarпропущено...
Вот постоянно сталкиваюсь с SVG. Даже либу для построения графиков написал. Но не понимаю тебя.
SVG, это аналог HTML. В нем есть место и для CSS, если кому хочется. Кому не хочется - тот обходится без CSS. Код с примером можешь привести, зачем нужен CSS в SVG?
Для всего. Атрибут style у элементов SVG, это тоже CSS. А, например, интерактивность вроде
.vbar g:hover {fill-opacity: 0.7}
только через глобальный stylesheet делается.
Да, какие-то свойства в SVG можно задавать через атрибуты, но не все, не всегда, и вообще не лучший вариант.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855273
stanilar Стрелочки можно нарисовать на холсте того компонента, на котором лежат Ваши наследники панели.

А как сделать, чтоб стрелочки были поверх этих самых наследников (в том числе и всяких лейблов, имеджей и прочего, что я могу напихать в свой компонент позже).
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855278
stanilar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asviridenkov,

В твоем случае один и тот же атрибут, для одного и того же элемента будет устанавливается не только из нескольких разных участков кода, но и из нескольких разных типов файлов (js, css, html).
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855283
stanilar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей Игоревич"для себя"
Думаю что "для себя", если ты не планируешь стать гуру программирования вин-апи, есть задачи и поинтересней и более востребованней.

Андрей ИгоревичНу и другие вещи (всякие скругленные бары и прочее) они рисует просто прекрасно у него свой алгоритм рисования. Разницу в картинках не вижу, но предполагаю что на ТееChart для 10-ки, по умолчанию, включено сглаживание для графиков.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855292
stanilarАндрей Игоревич"для себя"
Думаю что "для себя", если ты не планируешь стать гуру программирования вин-апи, есть задачи и поинтересней и более востребованней.Яж прикладную задачу решить хочу, и хочу "чтоб было красиво (и удобно)" :), потому тыкаюсь в то, что удается найти или что вычитал. Но да, многие пути оказываются слишком сложными.
stanilarАндрей ИгоревичНу и другие вещи (всякие скругленные бары и прочее) они рисует просто прекрасно у него свой алгоритм рисования. Разницу в картинках не вижу, но предполагаю что на ТееChart для 10-ки, по умолчанию, включено сглаживание для графиков.
А я как-то могу "включить" эту функцию сглаживания для своих рисований на канвасе?
П.С. На картинках очень большая разница, может у вас браузер сглаживает или масштабирует?
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855297
asviridenkov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей ИгоревичА я как-то могу "включить" эту функцию сглаживания для своих рисований на канвасе?


Я уже писал, GDI+ или Direct2D
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855311
asviridenkovАндрей ИгоревичА я как-то могу "включить" эту функцию сглаживания для своих рисований на канвасе?

Я уже писал, GDI+ или Direct2DasviridenkovПри желании, за пол года вполне сможете сделать нормальную версию.
Ладно, обойдусь пока без сглаживания... :)
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855338
stanilar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asviridenkovЯ уже писал, GDI+ или Direct2D

Вроде у вин-контролов есть процедура, в котором они сами себя нарисовать могут. Можно самому алгоритм сглаживания написать. И не обязательно за пол года. Задача то сглаживать стрелочки? Такую, может быть, можно и из учебника скопипастить.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855366
Я вот совсем чуть поковырялся с наследниками TGraphicControl (ну для примера тот же Image или SpeedButton) и такой вопрос возник, как же его на передний план выносить выше панелей, это же по сути рисунки. В интернете предлагают способы которые опять перекрывает другие компоненты. Пока вот не могу придумать. Есть ли возможность создать какой-нибудь невидимый слой, которые не перекрывает компоненты?
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855367
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Все ваши шестиугольники и стрелочки - TGraphicsControl, а ПОЛЕ на котором они в конечно итоге нарисованы - TWinControl.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855371
DimaBrВсе ваши шестиугольники и стрелочки - TGraphicsControl, а ПОЛЕ на котором они в конечно итоге нарисованы - TWinControl.
Я понимаю (это очевидно), но как я понял из написанного, мне предлагают отказаться от TWinControl использовав для рисования стрелок сразу TGraphicsControl на Форме/Большой Панели. Так как 3+ сотни TWinControl - это плохо.
Отказываться от панелей под шестигранники не хочется, они удобные. А вот как стрелочки поверх нарисовать без TWinControl под них пока не понял.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855374
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторОтказываться от панелей под шестигранники не хочется, они удобные.
Что именно удобного ?
автор А вот как стрелочки поверх нарисовать без TWinControl под них пока не понял.
Графические Стрелочки могут быть нарисованы на Оконном контроле. Чтобы они были поверх шестиугольников, сами шестиугольники должны быть графическими.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855389
DimaBrавторОтказываться от панелей под шестигранники не хочется, они удобные.
Что именно удобного ?
Ну основное что на них будет несколько label и image (на котором буду рисовать другие картинки (не стрелочки, но вместе со стрелочками)), может потом ещё что-то буду добавлять из компонентов (там много всего разного в зависимости от загруженных данных). Которые я просто кинул на панель и дальше мне только саму панельку двигать и больше ни о чем не думать (в картинках примерах я показал что у меня всё двигается, перемещается и перетаскивается, маштабируется, сейчас сделано через взаимные связи координат).
На что ещё можно кинуть другие компоненты и при этом, что бы можно было обрезать компонент по контуру (шестиугольник)? Ещё на панель удобно перетаскивать мышкой чрез предельно простые две строчки кода.

DimaBrавтор А вот как стрелочки поверх нарисовать без TWinControl под них пока не понял.
Графические Стрелочки могут быть нарисованы на Оконном контроле. Чтобы они были поверх шестиугольников, сами шестиугольники должны быть графическими. И это мало чем будет отличаться от того, что рисую я сейчас, просто перехват координат на рисунке и события будет сам делфи делать.

Я хочу, что бы была возможность навести/кликнуть на любое число/рисунок и увидеть дополнительную информацию, по сути у меня получилось почти всё, кроме треклятых стрелочек :).
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855390
Я тут подумал, что может не очень точно выразился в часть "не блокирует взаимодействие", то место где сами стрелки находятся, там можно и блокировать взаимодействие(это не очень важно), просто все доступные способы рисования стрелки блокируют не только контур стрелки, но и весь прямоугольник в который она вписана.
В принципе я могу обрезать панель чуть шире стрелки и сделать её прозрачной, по крайней мере то ужасное обрезание лесенками не будет видно. Но это всё равно приведет у нескольким сотням ВиндКонтролов.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855391
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторНу основное что на них будет несколько label и image (на котором буду рисовать другие картинки
Зачем кидать какие то дополнительные контролы ? Не проще ли просто вывести текст и картинку поверх шестиугольника ?

авторЯ хочу, что бы была возможность навести/кликнуть на любое число/рисунок и увидеть дополнительную информацию
Разве нельзя обработать клик по шестиугольнику ?
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855392
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Смотрите, какая есть заготовка !!!
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855394
DimaBrавторНу основное что на них будет несколько label и image (на котором буду рисовать другие картинки
Зачем кидать какие то дополнительные контролы ? Не проще ли просто вывести текст и картинку поверх шестиугольника ?

авторЯ хочу, что бы была возможность навести/кликнуть на любое число/рисунок и увидеть дополнительную информацию
Разве нельзя обработать клик по шестиугольнику ?
Ну я вначале это описал, всё можно, даже не просто можно, я как бы уже всё это сделал почти так (просто перехват координат и события реализовал сам, а не через компоненты).

Сложно объяснить не углубляясь в суть отображаемых данных (а это долго), но панель с контролами просто банально удобнее как с алгоритмичесткой точки зрения (есть один компонент, который полностью самодостаточен, рисование, перемещение, вывод данных, обработку событий, вывод хинтов и т.п. всё можно реализовать внутри него, а я просто присваиваю параметры и всё), так и с точки зрения кода. Ну банально, вот хочу я переместить один шестиугольник (смотри картинки "примеры" в первом комментарии), в случае с панелькой я просто перемешаю её и как бы всё, больше ничего не надо, а в случае с компонентами надо их как-то связать (компоненты одного шестиугольника), перемещать совместно.
Я попробую сделать как вы говорите, может там и не так всё сложно. Просто уж больно мне компонент- наследник панели понравился, ни тебе канвасы не нужны, ни какие-то дополнительные условия.
DimaBrСмотрите, какая есть заготовка !!!
А что тут происходит?
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855395
asviridenkov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей ИгоревичСложно объяснить не углубляясь в суть отображаемых данных (а это долго), но панель с контролами просто банально удобнее как с алгоритмичесткой точки зрения


Пока не захотите все это зуммировать
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855396
asviridenkovАндрей ИгоревичСложно объяснить не углубляясь в суть отображаемых данных (а это долго), но панель с контролами просто банально удобнее как с алгоритмичесткой точки зрения


Пока не захотите все это зуммировать
А в чем подводные камни? Я планировал отключать видимость панели на которой они расположены (и всех своих компонентов), далее менять размеры панелей, "перевырезать" форму и опять включать. Хотя лейблы надо будет смещать, но относительные координаты просто на коэффициент помножить, не сложно, вроде. Если панели созданы и невидимы SetWindowRgn, вроде, быстро работает.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855398
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
на коленке
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
TMyShape = class(TPaintBox)
  protected
    procedure Paint; override;
  public
    Text1: string;
    Text2: string;
    Text3: string;
end;

procedure TMyShape.Paint;
var P : array [1..7] of TPoint;
    a,i,R: integer;
begin
  Canvas.Brush.Color := clRed;
  Canvas.Brush.Style := bsSolid;
  a := 0;
  R := Width div 2;
  for i:= 1 to 7 do begin
    P[i].x := R+Round(R*sin(a*pi/180));
    P[i].y := R+Round(R*cos(a*pi/180));
    a := a+60;
  end;
  Canvas.Polygon(P);
  Canvas.TextOut((Width-Canvas.TextWidth(Text1)) div 2,10,Text1);
  Canvas.TextOut((Width-Canvas.TextWidth(Text2)) div 2,22,Text2);
  Canvas.TextOut((Width-Canvas.TextWidth(Text3)) div 2,35,Text3);
end;

procedure TForm1.FormCreate(Sender: TObject);
var i: integer;
    S: TMyShape;
begin
  for i := 0 to 999 do begin
    S := TMyShape.Create(self);
    S.Parent := self;
    S.SetBounds(Random(Width-60),Random(Height-60),60,60);
    S.Text1 := '№ '+IntToStr(i);
    S.Text2 := FormatFloat('#0.00',Random*1000);
    S.Text3 := FormatFloat('#0.000',Random*1000);
  end;
end;


...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855400
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855549
DimaBr

Повторил, заменив текс на лейблы. В принципе рабочая схема. Но по факту - стрелки это рисунок который всё время надо перерисовывать. Ну и форма Пейнбокса таки квадрат в который что-то вписано, с соответсвующим перекрытием
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855576
Фотография Квейд
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей ИгоревичDimaBr

Но по факту - стрелки это рисунок который всё время надо перерисовывать.потому что кадр нужно генерировать целиком, сразу со всеми элементами, и только после этого выводить на экран, например
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855600
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей ИгоревичПовторил, заменив текс на лейблы. В принципе рабочая схема. Но по факту - стрелки это рисунок который всё время надо перерисовывать. Ну и форма Пейнбокса таки квадрат в который что-то вписано, с соответсвующим перекрытием
Выставь просто DoubleBuffered = True у контейнера (в данном случае это TForm1) на котором находятся все компоненты. VCL сделает двойную буферизацию.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855633
КвейдАндрей Игоревичпропущено...

Но по факту - стрелки это рисунок который всё время надо перерисовывать.потому что кадр нужно генерировать целиком, сразу со всеми элементами, и только после этого выводить на экран, например

Понятно, просто тоже надо продумывать будет. А что у вас на гифке происходит?
kealon(Ruslan)Андрей ИгоревичПовторил, заменив текс на лейблы. В принципе рабочая схема. Но по факту - стрелки это рисунок который всё время надо перерисовывать. Ну и форма Пейнбокса таки квадрат в который что-то вписано, с соответсвующим перекрытием.

Выставь просто DoubleBuffered = True у контейнера (в данном случае это TForm1) на котором находятся все компоненты. VCL сделает двойную буферизацию.
Спасибо, попробую, не успел ещё с ней разобраться.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855640
Фотография Квейд
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей ИгоревичПонятно, просто тоже надо продумывать будет. А что у вас на гифке происходит?

Это пример того, о чем я говорил. Кадр со всеми элементами (линиями и якорями, за которые линии "цепляются") прорисовывается в буфере, затем целиком выводится на экран. Получается плавная анимация. В вашей задаче нужно реализовать подобный механизм.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855747
Вопрос в продолжении.
Как срабатывает событие Paint? Как оно влияет на обновление канваса?
Попробовал рисовать стрелку в событии Paint PintBox-а но на канвасе родителя, но получилось не очень. Канвас обновляется не весь сразу, а после отрисовки каждого ПаинБокса (при том сами пайнбоксы все сразу обновляются, а вот стрелки - нет). Как-то попросить/заставить его этого не делать можно? Двойная буферизация включена.
В жизни всё не так плохо, как на гифке, просто мерцает. Вторая часть гифки когда пошагово выполнял. Дабы не вносить лишние ошибки рисую линию простым MoveTo;

...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855778
Фотография Квейд
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей ИгоревичВопрос в продолжении.
Как срабатывает событие Paint? Как оно влияет на обновление канваса?
Попробовал рисовать стрелку в событии Paint PintBox-а но на канвасе родителя, но получилось не очень. Канвас обновляется не весь сразу, а после отрисовки каждого ПаинБокса (при том сами пайнбоксы все сразу обновляются, а вот стрелки - нет). Как-то попросить/заставить его этого не делать можно? Двойная буферизация включена.
В жизни всё не так плохо, как на гифке, просто мерцает. Вторая часть гифки когда пошагово выполнял. Дабы не вносить лишние ошибки рисую линию простым MoveTo;
выложи исходник
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855782
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asviridenkovkealon(Ruslan)ну например объекты в "псевдокоде" надо как-то связать с действиями и поддерживать согласованность довольно трудно
сравни со стандартным редактором формы, почти на любой объект есть реальное поле в коде.
И это не просто фигуры рисования, это уже отдельные сущности


Когда число элементов заранее неизвестно, то а коде поля на объект очевидно не будет, т.к. они создаются рантайм.
А что касается обработки событий объектов одного типа, то тоже решается очень просто
<g onclick="form.GroupClick(this)"..
Собственно все. Опять же, на фоне сравнения десятка строчек для визуализации здесь, и тысяч строк при варианте в лоб, это несерьезно.если добавить к этому коду его "бизнеслогику", в обоих вариантах выйдет прибизительно столько же

другое дело, что ему пока сложно "отделять мух от котлет" и у него всё в куче, но все на чём-то учатся, у него же программирование не основная деятельность - процесс будет идти дольше
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855812
КвейдАндрей ИгоревичВопрос в продолжении.
выложи исходникБлин, на работе осталось, на эту папку забыл синхронизацию настроить.
Ну суть там в этом коде из примера выше от DimaBr .
В принципе у меня уже есть мысли как это обойти, но надо пробовать. Если рисовать стрелки почти в любом другом месте кода - то, вроде, рисуются нормально (например при перетаскивании). В общем надо ещё поковырятья, просто голова сегодня не работает :(.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
procedure TMyShape.Paint;
var P : array [1..7] of TPoint;
    a,i,R: integer;
begin
  Canvas.Brush.Color := clRed;
  Canvas.Brush.Style := bsSolid;
  a := 0;
  R := Width div 2;
  for i:= 1 to 7 do begin
    P[i].x := R+Round(R*sin(a*pi/180));
    P[i].y := R+Round(R*cos(a*pi/180));
    a := a+60;
  end;
  Canvas.Polygon(P);
  Canvas.TextOut((Width-Canvas.TextWidth(Text1)) div 2,10,Text1);
  Canvas.TextOut((Width-Canvas.TextWidth(Text2)) div 2,22,Text2);
  Canvas.TextOut((Width-Canvas.TextWidth(Text3)) div 2,35,Text3);

//вот тут рисуется линия TDrawPanel - панель со включенным канвасом (на ней рисую);
 (Self.Parent as TDrawPanel).Canvas.Pen.Width:=3; 
 (Self.Parent as TDrawPanel).Canvas.Moveto (Round(Left+width/2)-80,Round(Top+height/2)+80);
 (Self.Parent as TDrawPanel).Canvas.Lineto (Round(Left+width/2),Round(Top+height/2)) ;

end;

...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855881
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей Игоревич
Код: sql
1.
2.
3.
4.
//вот тут рисуется линия TDrawPanel - панель со включенным канвасом (на ней рисую);
 (Self.Parent as TDrawPanel).Canvas.Pen.Width:=3; 
 (Self.Parent as TDrawPanel).Canvas.Moveto (Round(Left+width/2)-80,Round(Top+height/2)+80);
 (Self.Parent as TDrawPanel).Canvas.Lineto (Round(Left+width/2),Round(Top+height/2)) ;


Зачем вы рисуете на Parent ?
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39855903
DimaBrАндрей Игоревич
Код: sql
1.
2.
3.
4.
//вот тут рисуется линия TDrawPanel - панель со включенным канвасом (на ней рисую);
 (Self.Parent as TDrawPanel).Canvas.Pen.Width:=3; 
 (Self.Parent as TDrawPanel).Canvas.Moveto (Round(Left+width/2)-80,Round(Top+height/2)+80);
 (Self.Parent as TDrawPanel).Canvas.Lineto (Round(Left+width/2),Round(Top+height/2)) ;


Зачем вы рисуете на Parent ?
Тут можно понять вопрос в двух вариантах.
1. Почему на Parent, а не на Пеинтбоксе? - Потому что стрелки могут выходить сильно за пределы шестигранника и рисовать их на канвасе пеинтбокса неразумно, он тогда будет перекрывать доступ ко всему.
2. Почему написал Parent, а не конкретный компонент? - есть дальнейшие планы по реализации, и там хочется все "шестигранные компоненты" включить в компонент наследник панели с канвасом в виде MyDrawPanel.Item[xxx].(процедуры и параметры) . В принципе описать можно по разному, сути не меняет. На указанную проблему мерцания не влияет, можно и конкретный канвас указать, так же будет. Мне больше интересно как вообще событие Paint обновляет канвас, видимо из него рисовать на других канвасах вне ПейнБокса плохая идея, надо будет разобраться.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39856441
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
UP.

Товарищи, просьба срач не устраивать.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39856656
mkr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а если всё это рисовать в directX (2d) или opengl?!
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39856781
mkrа если всё это рисовать в directX (2d) или opengl?!Освоение возможностей данных библиотек я оставил на чуть попозже. Стоит ли сейчас туда лезть?

По поводу стрелок. Чего-то не соображу как их рисовать.
Дело в чем, событие Pain у TPainBox срабатывает в самом конце, после любого кода. То есть если я нарисуют стрелки на канвасе родителя в коде даже после создания TPainBox, пример для сути (не код, просто суть)
Код: pascal
1.
2.
PainBox:=TPainBox.Create(Parent);
With Parent.Canvas do LineTo (X,Y);


То событие Paint всё равно нарисует PaintBox поверх линии.

Если же рисовать стрелку вызывая на канвасе родителя из события Paint, то могут происходить самые разные вакханалии, например обновление канваса родителя вызывает событие Paint у PaintBox-ов который вызывает канвас родителя который... (ну вы поняли, зациклится и будет мерцать вечтно). При двойной буферизации такого не происходит, но происходят другие неприятности (видимо, просто цикл обновлений канваса прерывается на случайном месте и стрелка то видна, то нет).
Если попробовать рисовать стрелки в событии OnMove тоже интересные эффекты рядом с ПаинБоксом (видимо канвас родителя перерисовывается не весь, а только рядом с перемещаемым ПаинБоксом).
В общем мои идеи рисования стрелок что-то не сработали. Вот блин сложная задача для меня :).
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39856813
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей Игоревич,

кажется тут уже писали, есть другой вариант, идея которого в том, что не использовать какие-либо компоненты для изображения шестиугольников и стрелок, а рисовать всё прямо на одном PaintBox (или на Canvas какого-то другого компонента).
Написать функцию, которая рисует шестиугольник заданного размера и цвета в заданном месте, функцию, которая рисует стрелку в заданном направлении в заданном месте. Хранить данные о всех шестиугольниках и стрелках в массивах или каком-то другом контейнере.
Перемещение реализовать через обработку событий мыши. Мышка нажата - в массиве шестиугольников отыскивается тот, на котором она нажата. Когда отпускается - этот шестиугольник перерисовывается в новом месте.
Всё рисуется на скрытом Bitmap, а потом готовая, полностью нарисованная картинка копируется на PaintBox.

Direct2D добавляется в таком варианте просто, в справке описано.

Не знаю, может тут есть какие-то не видные мне недостатки и проблемы (например недостатки GDI), но по-моему это - самый легковесный способ рисования по сравнению с созданием десятков или сотен компонентов для шестиугольников.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39856816
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
s62,
>>>Когда отпускается - этот шестиугольник перерисовывается в новом месте.
Точнее, в таком варианте нужно видимо всю картинку перерисовать.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39856822
asviridenkov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
s62,

Я это все написал еще на первой странице, но самурай не ищет прямых путей, хочет сам набить все шишки.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39856854
s62кажется тут уже писали, есть другой вариант, идея которого в том, что не использовать какие-либо компоненты для изображения шестиугольников и стрелок, а рисовать всё прямо на одном PaintBox (или на Canvas какого-то другого компонента).
Написать функцию, которая рисует шестиугольник заданного размера и цвета в заданном месте, функцию, которая рисует стрелку в заданном направлении в заданном месте. Хранить данные о всех шестиугольниках и стрелках в массивах или каком-то другом контейнере.
Перемещение реализовать через обработку событий мыши. Мышка нажата - в массиве шестиугольников отыскивается тот, на котором она нажата. Когда отпускается - этот шестиугольник перерисовывается в новом месте.
Всё рисуется на скрытом Bitmap, а потом готовая, полностью нарисованная картинка копируется на PaintBox.

Один в один всё уже реализовано в работающем коде именно так :), смотри первый пост, даже на битмапе уже рисую "ассоциирую". Мне то чего хотелось:
Я хотел сделать компонент который был полностью самодостаточен и существует отдельно от остального кода (многоугольник + стрелка + лейблы + рисунок типа стрелки). Создал в коде - там сразу всё по умолчанию уже хорошо. Далее меняя параметры получаю нужную мне картинку.
Ну и хотел реализовать события на клики по лейблам и высвечивающиеся подсказки. Ещё дополнительно компонент родитель в виде массивов компонентов типа описанного выше с доступом Родитель.Item[...].(Свойство или Метод)

Просто у меня в коде просто огромное количество разных данных в разных форматах, я их постоянно добавляю и редактирую, и рисовальщик в виде массива с которого рисуется вся картинка с прорвой параметров (цвет, 5 текстов (размер, стиль, позиция, цвет), толщина обводки, цвет обводки, координаты многоугольника, размер многоугольника, тип рисунка (стрелка, годограф), ещё куча всего) для всех элементов, который расположен в коде программы очень неудобен. Я решил его вынести в отдельный модуль и описать качественно для максимального удобства работы в дальнейшем (а это будет постоянно).
Единый рисунок можно (и уже сделано), но не очень удобно. Особенно в часть перехвата координат мыши.
Ну например, я вот сделал и описал код на событие "OnMove" для вывода подсказки при наведени на текст, а тут что-то надо в конструкторе менять, переделывать под новые реалии - и всё уползает, опять всё переделывать, а там куча взаимосвязей (координаты, размер, масштаб, координаты текста), это сложно и неудобно (постоянно всё ломается), куда менее удобно чем небольшие сегментированные компоненты за работоспособностью которых следить куда проще.

Наверно тут мудрёно написано и оно вам не особо надо, просто хз как объяснить :). Ну для примера, вы же не рисуете на форме все компоненты рисунками (сами, а не готовые из делфи), а потом не начинаете писать тучу кода для того, что бы реализовать все возможные взаимодействия (через перехват координат или ещё как). Вы пользуетесь готовыми решениями (даже если по сути это тоже рисунок), для которых всё уже написано и сделано, и в которых каждый компонент "вещь в себе".
Вот и для меня этот рисунок из многоугольников по сути целая интерактивная панель, работать с которой (в части кода) гораздо удобнее если каждый элемент - это компонент. Но это не отменяет возможности работы с ней, как с рисунком.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39856865
asviridenkov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей Игоревич,

Никто не говорит отказываться от объектной модели, просто не делайте эти объекты компонентами дельфи.
Опишите свой класс с методами отрисовки, отработки событий и.т.д, а далее делайте класс контейнер который будет обрабатывать массив объектов этих классов, вызывая отрисовку и передавая события.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39856875
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
TDrawObject = class
  private
    fCanvas: TCanvas; // канвас, на котором будем рисовать (или на панели или на движущемся PaintBox)
    fBounds: TRect;
  public
    procedure Draw(R: TRect); virtual;abstract;
    property Bounds: TRect read fBounds write fBounds;
end;

TArrow = class(TDrawObject)
  private
    fPenSize: integer;
  public
    procedure Draw(R: TRect);override;
    property PenSize: integer read fPenSize write fPenSize;
end;

THexagon = class(TDrawObject)
  private
    fArrow: TArrow; // стрелка к фигуре
    fText1: string;
    fText2: string;
  public
    procedure Draw(R: TRect);override;
    property Text1: string read fText1 write fText1;
    property Text2: string read fText2 write fText2;
end;

TDrawPanel = class(TPanel)
  private
    fHexList: TList;  // список всех фигур
    fMoveHex, fMoveArrow: TPaintBox; // эти Боксы для передвижения
    fHex: THexagon; // указатель на ту фигуру которую двигаем
    xHex,yHex,xArrow,yArrow: integer;
    procedure DoPaintHex(Sender: TObject);
    procedure DoPaintArrow(Sender: TObject);
  public
    procedure Paint;override;
    constructor Create(AOwner: TComponent);override;
    destructor Destroy; override;
    function FindHexagon(X,Y: integer): THexagon;
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
    procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
    procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
end;

// отрисовка панели
procedure TDrawPanel.Paint;
var i: integer;
begin
  inherited;
// рисуем все фигуры
  for i := 0 to fHexList.Count-1 do THexagon(fHexList[i]).Draw(THexagon(fHexList[i]).Bounds);
// а затем рисуем все стрелки
  for i := 0 to fHexList.Count-1 do THexagon(fHexList[i]).fArrow.Draw(THexagon(fHexList[i]).fArrow.Bounds);
end;



...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39856880
DimaBr
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
TDrawObject = class
  private
    fCanvas: TCanvas; // канвас, на котором будем рисовать (или на панели или на движущемся PaintBox)
    fBounds: TRect;
  public
    procedure Draw(R: TRect); virtual;abstract;
    property Bounds: TRect read fBounds write fBounds;
end;

TArrow = class(TDrawObject)
  private
    fPenSize: integer;
  public
    procedure Draw(R: TRect);override;
    property PenSize: integer read fPenSize write fPenSize;
end;

THexagon = class(TDrawObject)
  private
    fArrow: TArrow; // стрелка к фигуре
    fText1: string;
    fText2: string;
  public
    procedure Draw(R: TRect);override;
    property Text1: string read fText1 write fText1;
    property Text2: string read fText2 write fText2;
end;

TDrawPanel = class(TPanel)
  private
    fHexList: TList;  // список всех фигур
    fMoveHex, fMoveArrow: TPaintBox; // эти Боксы для передвижения
    fHex: THexagon; // указатель на ту фигуру которую двигаем
    xHex,yHex,xArrow,yArrow: integer;
    procedure DoPaintHex(Sender: TObject);
    procedure DoPaintArrow(Sender: TObject);
  public
    procedure Paint;override;
    constructor Create(AOwner: TComponent);override;
    destructor Destroy; override;
    function FindHexagon(X,Y: integer): THexagon;
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
    procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
    procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
end;

// отрисовка панели
procedure TDrawPanel.Paint;
var i: integer;
begin
  inherited;
// рисуем все фигуры
  for i := 0 to fHexList.Count-1 do THexagon(fHexList[i]).Draw(THexagon(fHexList[i]).Bounds);
// а затем рисуем все стрелки
  for i := 0 to fHexList.Count-1 do THexagon(fHexList[i]).fArrow.Draw(THexagon(fHexList[i]).fArrow.Bounds);
end;




В принципе рабоче, хотя уже почти то же самое, что и было изначально :). Ладно, видимо только так можно.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39861655
Наконец появилось свободное время поковыряться. В принципе всё что хотел изначально - сделал. Не так просто в коде как с панельками, но пойдет. Не уверен, конечно, в своих решения, но, вроде, работает :). От лейблов пришлось отказаться, всё-таки 500 штук сильно долго рисуются (0.2-0.3 секунды).
Единственно Хинты не совсем идеально работают. Вывод Хинта привязал к MouseMove (если попал в многоугольник то..., если в шестиграннике попал на текст, то..). Но, видимо, так как всё один компонент - само не перерисовывалось (хотя в статусбаре при присвоении менялось сразу), пришлось выводить через Application.ActivateHint(), но он мгновенно рисуется при наведении. В принципе и так неплохо, может даже и лучше.

В принципе по алгоритмам вопросов много (часто кажется, что как-то неправильно сделал), но, наверное, наглеть не стоит с вопросами. Всем просто огромнейшее спасибо.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39862159
mkr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей Игоревич,
визуально - круто.
бросайте исходники демки на github, может кто и глянет.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39877935
Такой вопрос возник. Есть панель, на основании делаю наследника с нужными мне особенностями, пусть будет ChangingPanel (панель с возможностью изменения размеров + рамка + иконка указателя) и на основании неё уже делаю наследника с нужным содержимым панели - пусть будет LegendPanel.
Сложность в чём, я хотел бы рисовать рамку в ChangingPanel (дабы в наследниках уже не думать об этом), а в наследнике рисовать уже то, что мне нужно.
Делал так:
В ChangingPanel и LegendPanel:
Код: pascal
1.
 procedure Paint; override;


В ChangingPanel
Код: pascal
1.
2.
3.
4.
procedure LegendPanel.Paint;
Begin
 //рисую рамку
end;


в LegendPanel уже
Код: pascal
1.
2.
3.
4.
5.
procedure LegendPanel.Paint;
Begin
  inherited;
  //рисую всякое
end;



но Inherited вызывает Paint изначальной Панели, а не ChangingPanel. Почему?

(по факту рисую посложнее, на панели - paitbox с отступами от границ для рамки и везде использую буферный канвас который в конце процедуры копирую).

Для наглядности, рисую легенду.

Ну и в принципе, есть ли более простые способы реализовать показанное на гифке, сейчас я рамку вообще в ручную рису (прямоугольник + 4 прямоугольника по углам, перемещение через ReleaseCapture; perform(WM_SysCommand, $F0.., 0) ну и тому подобное ), может уже всё давно готовое есть и я кривой велосипед изобретаю?

...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39877936
А, и ещё хотел спросить, можно ли сделать, что бы процедура/функция или свойство было доступно только для потомка (не глубже), а уже для основной программы всё было недоступно, кажется где-то я что-то такое видел.
И можно ли вообще сделать так же, но для родителя? Чтоб потомок имел доступ к свойству родителя (пусть через parent.property), и никто более. Просто ну очень сложно мне продумать логику так, чтоб всё в private было и писать для каждой фигни property тоже тяжко. А всё public как-то неправильно.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39877937
ёёёёё
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39878281
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей Игоревич, ты это собираешься продавать программистам? Если нет - не парься над тем что неважно. Главное чтоб тебе было всё ясно-понятно и легко было поддерживать. Культура программирования хорошо оттачивается в командах, но это отдельная песня. Лучше найми дизайнера, а то в цветовой каше глаза сломаешь, хрен прочтешь половину текста
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39878393
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей ИгоревичА, и ещё хотел спросить, можно ли сделать, что бы процедура/функция или свойство было доступно только для потомка (не глубже), а уже для основной программы всё было недоступно, кажется где-то я что-то такое видел.
strict protected ?
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39878418
ёёёёё
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpАндрей ИгоревичА, и ещё хотел спросить, можно ли сделать, что бы процедура/функция или свойство было доступно только для потомка (не глубже), а уже для основной программы всё было недоступно, кажется где-то я что-то такое видел.
strict protected ?
Из другой оперы, немного.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39878467
ёёёёёАвтар, http://docwiki.embarcadero.com/RADStudio/Rio/en/Methods_(Delphi)#Final_Methods
Слегка не понял. Да и на 7ке, вроде, не работает, как я понимаю. Но поизучаю поподробнее.

white_niggerАндрей Игоревич, ты это собираешься продавать программистам? Если нет - не парься над тем что неважно. Главное чтоб тебе было всё ясно-понятно и легко было поддерживать. Культура программирования хорошо оттачивается в командах, но это отдельная песня. Лучше найми дизайнера, а то в цветовой каше глаза сломаешь, хрен прочтешь половину текста

Ну так, в рамках развития потихоньку приучаю себя к культуре :), когда программа разрастается до очень больших размеров это очень помогает. Ну и очень помогает, когда свой код читаешь через некоторое время.

white_nigger Лучше найми дизайнера ха-ха :(

Это отладочная программа в которой вывожу почти всё, что только можно, дабы сразу отловить ошибки. В основной программе такого объема данных не будет (по факту на гифке просто огромное количество информации выводиться, такое в принципе читать сложно, в основной программе выводятся отдельные группы данных)

alekcvpАндрей ИгоревичА, и ещё хотел спросить, можно ли сделать, что бы процедура/функция или свойство было доступно только для потомка (не глубже), а уже для основной программы всё было недоступно, кажется где-то я что-то такое видел.
strict protected ?
У меня и так каждый компонент в отдельном модуле, думаю это избыточно.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39878469
ёёёёё
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей ИгоревичёёёёёАвтар, http://docwiki.embarcadero.com/RADStudio/Rio/en/Methods_(Delphi)#Final_Methods
Слегка не понял. Да и на 7ке, вроде, не работает, как я понимаю. Но поизучаю поподробнее.
...
"Запечатывание" виртуального метода, запрещающее перекрытие в наследнике.
Да, в 7-ке не работает.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39878471
ёёёёё
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей ИгоревичА, и ещё хотел спросить, можно ли сделать, что бы процедура/функция или свойство было доступно только для потомка (не глубже), а уже для основной программы всё было недоступно, кажется где-то я что-то такое видел...
Может быть, тебе protected члены нужны? http://www.delphibasics.ru/Protected.php
protected члены класса доступны в наследниках, но из других объектов - недоступны. Ну, кроме тех, которые в том же модуле (юните) находятся.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39878479
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ёёёёёalekcvp strict protected ?
Из другой оперы, немного.
ёёёёёМожет быть, тебе protected члены нужны? http://www.delphibasics.ru/Protected.php
WAT? O_o
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39878487
ёёёёёАндрей ИгоревичА, и ещё хотел спросить, можно ли сделать, что бы процедура/функция или свойство было доступно только для потомка (не глубже), а уже для основной программы всё было недоступно, кажется где-то я что-то такое видел...
Может быть, тебе protected члены нужны? http://www.delphibasics.ru/Protected.php
protected члены класса доступны в наследниках, но из других объектов - недоступны. Ну, кроме тех, которые в том же модуле (юните) находятся.
Я вот всегда туплю в определении "наследник".

Код: pascal
1.
2.
3.
TClassB = class (TClassA)
   ClassD: TClassD;
End;


Вопрос - наследник/потомок это ClassB от ClassA или ClassD потомок от ClassB? Или тут более хитрая терминология. Просто в интернете и то и то видел как называют потомком.
В первом случае protected доступны, во втором нет.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39878489
ёёёёё
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей Игоревичёёёёёпропущено...

Может быть, тебе protected члены нужны? http://www.delphibasics.ru/Protected.php
protected члены класса доступны в наследниках, но из других объектов - недоступны. Ну, кроме тех, которые в том же модуле (юните) находятся.
Я вот всегда туплю в определении "наследник".

Код: pascal
1.
2.
3.
TClassB = class (TClassA)
   ClassD: TClassD;
End;


Вопрос - наследник/потомок это ClassB от ClassA или ClassD потомок от ClassB? Или тут более хитрая терминология. Просто в интернете и то и то видел как называют потомком.
В первом случае protected доступны, во втором нет.

Класс TClassA - родитель класса TClassВ.
Класс TClassB - наследник класса TClassА.
Класс TClassB связан с классом TClassА отношением "наследование".

Объекта класса TClassD агрегирован в класс TClassB.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39878495
ёёёёёкласса TClassD агрегирован в класс TClassB.
Жуть, первый раз вижу такой термин применительно к Delphi.
В общем я писал про доступность из агрегированных классов к процедурам ээ...ээ.. агрегатора?
И наоборот.

Хотя основной мой вопрос был, почему Inherites проскакивало через несколько наследников(тут всё корректно) сразу к Panel, может ли быть это связано с owner, который я не переприсваивал у потомков (обходясь parent).
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39878499
ёёёёё
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей Игоревич...почему Inherites проскакивало через несколько наследников...
Не было такого, "мамой клянусь".
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39878730
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В общем случае мне больше нравятся термины: "унаследован от", "предок", "наследник"
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39878732
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей ИгоревичНу так, в рамках развития потихоньку приучаю себя к культуре :), когда программа разрастается до очень больших размеров это очень помогает. Ну и очень помогает, когда свой код читаешь через некоторое время.Это все жалкое подобие развитию при работе в команде - регулярное code review с обсуждением спорных мест и решений, плюс сразу можно оценить качество кода и стоимость поддержки. Если твой код будет прозрачен для других программистов - значит движение идет в правильном направлении.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39878818
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей ИгоревичХотя основной мой вопрос был, почему Inherites проскакивало через несколько наследников(тут всё корректно) сразу к Panel
Единственное, что мне приходит в голову - это то, что где-то в этой цепочке у переопределения методов было пропущено слово override (при этом должно быть предупреждение от компилятора), в результате inherites обращался к последнему переопределённому методу, а не к этим.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39918342
В свете перехода мной с Delphi 7 на 10 начинают возникать куча мелких непонятных проблем в уже, казалось бы сделанных вещах.

Вкратце. "Главная" панель - перехватываю paint - рисую нужную мне картинку (через буферный BitMap).
На "главной" панели размещены другие панели с дополнительной информацией, в них рисую так же.
Часть функционала - перетаскивание, редактирование содержания и масштабирование информационных панелей напрямую.
С большим трудом в 7ке сделал, чтоб всё работало плавно и удобно.
Перешел на 10ку (ибо приложение надо 64битное) и при срабатывании события Paint (которое Override ) панель в самом начале кода события(до выполнения чего бы то ни было) закрашивается в базовый (выбранный цвет), из-за чего происходит раздражающее мерцание. На гифке это не так заметно, пропускает кадры - в жизни прям дико мигает.

Масштабирую через perform, который, периодически и вызывает то самое событие paint, но через раз, иногда может просто закрасить в серый не вызвав событие (потому пока дополнительно вызываю repaint);
код масштабирования и перетаскивания
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
procedure TLegendPanel.MouseDown(Sender:TObject; Button: TMouseButton;  Shift: TShiftState; X, Y: Integer);
begin
  try
   if  ChangeOnOff then
   Begin

    ReleaseCapture;
     if ( X < Width - 10 )  and ( X >  10 ) and ( Y > 10 ) and ( Y < Height - 10 )  then
        Begin
         perform(WM_SysCommand, $F012, 0);
          Move:=true;
        end else
        Begin
         if ( X > Width - 10 ) and ( Y < Height - 10 ) and ( Y > 10 ) then   perform(WM_SysCommand, $F002, 0); // right

         if ( X < 10 ) and ( Y < Height - 10 ) and ( Y > 10 ) then perform(WM_SysCommand, $F001, 0);// left

         if ( X > 10 ) and ( X < Width - 10 ) and ( Y > Height - 10 ) then  perform(WM_SysCommand, $F006, 0); // bottom

         if ( X > 10 ) and ( X < Width - 10 ) and ( Y < 10 ) then  perform(WM_SysCommand, $F003, 0);// top

         if ( X < 10 ) and ( Y < 10 ) then perform(WM_SysCommand, $F004, 0);// top left

         if  ( X > Width - 10 ) and ( Y > Height - 10 )  then  perform(WM_SysCommand, $F008, 0);//Bottom right

         if ( X < 10 )  and ( Y > Height - 10 )  then perform(WM_SysCommand, $F007, 0);// Bottom left

         if  ( X > Width - 10 ) and ( Y < 10 ) then perform(WM_SysCommand, $F005, 0); //top right

        end;
   end;
     move:=false;

    relTop:=Top/parent.Height;
    relLeft:=Left/parent.Width;
    relHeight:=Height/parent.Height;
    relWidth:= Width/parent.Width;

    RePaint;

    DoMoveLegend;

      Xn:=X;
      Yn:=Y;
  except

  end;
end;

мигает


С "главной" панелью (которая тоже мерцала) часть проблем решил через override Repaint с кодом InvalidateRect( Handle, NIL, FALSE ) ; и вызов обновления картинки только через Repaint;
Так же главная панель так же окрашивалась в серый - если один из дочерних компонентов менял родителя (у меня при каждой отрисовке сбрасывались родители, а потом назначались в зависимости от того, что рисуется). Решил убрав такое присвоение, но логики всё равно не понял, почему перед Pаint именно в этом случае панель закрашивалась в серый, а без присвоения наследников - не окрашивалась, а нормально перерисовывалась.

Главный вопрос:
Почему панель закрашивается в серый до Override paint, как это отключить? (И почему на 7ке его не было, и, кстати, если использовать res 7ки, но компилировав в 10 - не мерцает).


просто мыслиА вообще я малость замучился рисовать всё через Paint - так как там тотальное перекрёстное вызывание этих событий у всех дочерних и родительских компонентов.
Меняешь что-то на "дочерней" панели, она вызывает Paint основной, та вызывает Paint всех дочерних, в том числе и той, которая вызвала обновление, а если там что-то завязано на текущее состояние...
Любая неосторожная строчка кода сразу вызывает СтакОверфлоу или зацикленное мигание.
А уж Resize - это вообще отдельная песня, так как у меня дочерние панели масштабируются пропорционально основной, сделать так, что бы все Paint-ы не вызывались по 100+ раз при каждой итерации изменения размеров - прям отдельная головная боль.
В общем на будущее буду искать иные пути рисования, либо надо как-то очень хорошо всё продумывать.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39918354
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей Игоревич,

Мерцание панели может быть связано со свойством ParentBackground. Установи его в False. Если не поможет, попробуй обрабатывать сообщение WM_ERASEBKGND, устанавливая результат обработки AMessage.Result := 1;
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39918360
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей Игоревич,

Код: pascal
1.
2.
3.
4.
А вообще я малость замучился рисовать всё через Paint - так как там тотальное перекрёстное вызывание этих событий у всех дочерних и родительских компонентов.
Меняешь что-то на "дочерней" панели, она вызывает Paint основной, та вызывает Paint всех дочерних, в том числе и той, которая вызвала обновление, а если там что-то завязано на текущее состояние...
Любая неосторожная строчка кода сразу вызывает СтакОверфлоу или зацикленное мигание.
...


Так ведь вам предлагали не использовать множество панелей, а рисовать всё на одном канвасе, например PaintBox'а. Я так понимаю, что у вас было уже что-то готовое на панелях, потому вы не стали радикально переделывать. Но ваш вариант содержит в себе просто море ненужного обременения - все эти окна (TPanel это ведь наследник от TWinControl) ну и вообще весь ненужный в вашем случае код элементов управления. Уже писали, в том числе люди с наверное гораздо большим опытом в этой области, чем у меня, я тоже писал - вам можно было сделать процедурные или объектные обертки для рисования элементов картинки и всё рисовать на PaintBox (точнее - рисовать на невидимом TBitmap, а потом копировать его на PaintBox). И никаких панелек.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39918364
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
s62,
только была бы задача обработки кликов и перетаскивания элементов картинки. Но мне кажется, что она тоже вполне решаемая.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39918383
Kazantsev Alexey
Андрей Игоревич,

Мерцание панели может быть связано со свойством ParentBackground. Установи его в False. Если не поможет, попробуй обрабатывать сообщение WM_ERASEBKGND, устанавливая результат обработки AMessage.Result := 1;


Очень интересно. ParentBackground:=false; при перетаскивании ( (perform(WM_SysCommand, $F012, 0) ) теперь ничего не мерцает, прям совсем, а вот при изменении размеров perform(WM_SysCommand, $F002+, 0); , мерцает, но как-то совем иначе, буду разбираться.

А вот перехват обработку сообщений я пока до конца не освоил, это через так делать?
Код: pascal
1.
2.
3.
4.
5.
6.
Application.OnMessage:=AppMessage;

procedure TForm.AppMessage(var Msg: TMsg; var Handled: Boolean);
begin
  if Msg.message=WM_ERASEBKGND then ...;
end;



s62

Так ведь вам предлагали не использовать множество панелей, а рисовать всё на одном канвасе, например PaintBox'а. Я так понимаю, что у вас было уже что-то готовое на панелях, потому вы не стали радикально переделывать. Но ваш вариант содержит в себе просто море ненужного обременения - все эти окна (TPanel это ведь наследник от TWinControl) ну и вообще весь ненужный в вашем случае код элементов управления. Уже писали, в том числе люди с наверное гораздо большим опытом в этой области, чем у меня, я тоже писал - вам можно было сделать процедурные или объектные обертки для рисования элементов картинки и всё рисовать на PaintBox (точнее - рисовать на невидимом TBitmap, а потом копировать его на PaintBox). И никаких панелек.


Все многоугольники рисуются именно через свои компоненты, даже не PintBox, а через TComponent, где я уже сам свои Paint и прочие вещи писал. Панели используются именно для "Легенды", так как нагромождать всё через основной канвас ну очень сильно загромождает код (у меня там куча всяких событий и действий на всё привязано, один перехват мышки в едином канвасе будет просто огромным).
Изначально и легенду тоже рисовал на канвасе, но в итоге это оказалось ну очень неудобно, что решил через панели, тем более их тут не более 10 всё-таки.

s62
s62,
только была бы задача обработки кликов и перетаскивания элементов картинки. Но мне кажется, что она тоже вполне решаемая.

Всё это решено в полной мере, вплоть да кликов по тексту, Хинтам и прочим. Просто именно легенду так выводить неудобно.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39918386
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей Игоревич
А вот перехват обработку сообщений я пока до конца не освоил, это через так делать?

Нет, это делать так:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
TMyPanel = class
 procedure WMEraseBkgnd(Var AMessage : TMessage); Message WM_ERASEBKGND;
end;
...
procedure TMyPanel.WMEraseBkgnd(Var AMessage : TMessage);
begin
 AMessage.Result := 1;
end;
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39918390
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей Игоревич
Все многоугольники рисуются именно через свои компоненты, даже не PintBox, а через TComponent, где я уже сам свои Paint и прочие вещи писал. Панели используются именно для "Легенды", так как нагромождать всё через основной канвас ну очень сильно загромождает код (у меня там куча всяких событий и действий на всё привязано, один перехват мышки в едином канвасе будет просто огромным).
Изначально и легенду тоже рисовал на канвасе, но в итоге это оказалось ну очень неудобно, что решил через панели, тем более их тут не более 10 всё-таки.
Понятно. Из общих соображений, может я и заблуждаюсь, мне кажется, что если разумно структурировать код - написать какие-то объекты, м.б. иерархию объектов для рисования многоугольников, написания легенды и т.д., то в конечном счете код мог бы быть не более громоздким, чем в текущем варианте. Т.е. так вы оперируете компонентами, потомками TComponent, а так бы оперировали своими объектами типа ТМногоугольник и т.д. (которые бы отрисовывались на общей большой канве и эта отрисовка была бы в коде объекта, так что при оперировании объектами это не было бы видно, как и в текущем случае).
Вот события мышки обрабатывать это да, нужно было бы наверное держать данные о всех графических объектах, чтобы по клику находить, над каким из них произошло событие.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39918396
Kazantsev Alexey
Андрей Игоревич
А вот перехват обработку сообщений я пока до конца не освоил, это через так делать?

Нет, это делать так:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
TMyPanel = class
 procedure WMEraseBkgnd(Var AMessage : TMessage); Message WM_ERASEBKGND;
end;
...
procedure TMyPanel.WMEraseBkgnd(Var AMessage : TMessage);
begin
 AMessage.Result := 1;
end;



Придется поразбираться :).
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39918402
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей Игоревич
Придется поразбираться :)

Я не знаю, как у тебя там происходит рисование, но, если в Paint обновляется всё содержимое панели, то никаких артефактов отрисовки быть не должно. Даже перепроверил себя, накидал демку - ничего не мерцает.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39918406
Kazantsev Alexey
Андрей Игоревич
Придется поразбираться :)

Я не знаю, как у тебя там происходит рисование, но, если в Paint обновляется всё содержимое панели, то никаких артефактов отрисовки быть не должно. Даже перепроверил себя, накидал демку - ничего не мерцает.

Тут скорее дело в perform(WM_SysCommand, $F00.., 0), оно вызывает paint не так уж и часто, а пока мышку не отпустишь - вызывать paint иначе не получиться.
Ладно, подумаю, поковыряюсь.

А как вы масштабируете панель размещенную на панели?
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39918413
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей Игоревич
Тут скорее дело в perform(WM_SysCommand, $F00.., 0), оно вызывает paint не так уж и часто

Можно принудительно вызывать отрисовку из того-же WMEraseBkgnd.

Андрей Игоревич
А как вы масштабируете панель размещенную на панели?

В OnMouseMove пересчитываю размер.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39918422
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей Игоревич

Главный вопрос:
Почему панель закрашивается в серый до Override paint, как это отключить?

Всё есть в исходниках
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
procedure TCustomPanel.Paint;
const
  Alignments: array[TAlignment] of Longint = (DT_LEFT, DT_RIGHT, DT_CENTER);
  VerticalAlignments: array[TVerticalAlignment] of Longint = (DT_TOP, DT_BOTTOM, DT_VCENTER);
var
  Rect: TRect;
  LColor: TColor;
  LStyle: TCustomStyleServices;
  LDetails: TThemedElementDetails;
  TopColor, BottomColor: TColor;
  BaseColor, BaseTopColor, BaseBottomColor: TColor;
  //FontHeight: Integer;
  Flags: Longint;

begin
  Rect := GetClientRect;

  BaseColor := Color;
  BaseTopColor := clBtnHighlight;
  BaseBottomColor := clBtnShadow;
  LStyle := StyleServices;
  if LStyle.Enabled then
  begin
    LDetails := LStyle.GetElementDetails(tpPanelBackground);
    if LStyle.GetElementColor(LDetails, ecFillColor, LColor) and (LColor <> clNone) then
      BaseColor := LColor;
    LDetails := LStyle.GetElementDetails(tpPanelBevel);
    if LStyle.GetElementColor(LDetails, ecEdgeHighLightColor, LColor) and (LColor <> clNone) then
      BaseTopColor := LColor;
    if LStyle.GetElementColor(LDetails, ecEdgeShadowColor, LColor) and (LColor <> clNone) then
      BaseBottomColor := LColor;
  end;

  if BevelOuter <> bvNone then
  begin
    AdjustColors(BevelOuter);
    Frame3D(Canvas, Rect, TopColor, BottomColor, BevelWidth);
  end;
  if not (LStyle.Enabled and (csParentBackground in ControlStyle)) then
    Frame3D(Canvas, Rect, BaseColor, BaseColor, BorderWidth)
  else
    InflateRect(Rect, -Integer(BorderWidth), -Integer(BorderWidth));
  if BevelInner <> bvNone then
  begin
    AdjustColors(BevelInner);
    Frame3D(Canvas, Rect, TopColor, BottomColor, BevelWidth);
  end;
  with Canvas do
  begin
    if not LStyle.Enabled or not ParentBackground then
    begin
      Brush.Color := BaseColor;
      FillRect(Rect);
    end;
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39918423
Kazantsev Alexey

Андрей Игоревич
А как вы масштабируете панель размещенную на панели?

В OnMouseMove пересчитываю размер.

Изначально тоже так сделал, но очень мне не понравилось, уже и не помню почему, то ли мышка слетала с панели (если не успевала обновить размер) и OnMouseMove уже не срабатывал, то ли ещё что-то было.

Но что с мерцанием больше всего вызывает непонимание, это то, что в 7 - всё идеально, даже намека нет. И если суомпилирвать файл res в 7ке, то и в 10ке всё будет нормально.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39918425
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей Игоревич
Изначально тоже так сделал, но очень мне не понравилось, уже и не помню почему, то ли мышка слетала с панели (если не успевала обновить размер) и OnMouseMove уже не срабатывал, то ли ещё что-то было.

У винконтролов есть возможность захватывать мышку, после чего все её события идут в этот контрол.

Андрей Игоревич
И если суомпилирвать файл res в 7ке, то и в 10ке всё будет нормально.

Не понял. Если взять .res файл от семёрки и подложить его в проект Delphi 10.3?
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39918426
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimaBr
Всё есть в исходниках

Так у него же Paint перекрыт.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39918429
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexey

Так у него же Paint перекрыт.

А первой строчкой 100% стоит inherited.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39918430
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimaBr
А первой строчкой 100% стоит inherited.

Не, он говорит, что затирание происходит до вызова перекрытого Paint.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39918440
DimaBr
Kazantsev Alexey

Так у него же Paint перекрыт.

А первой строчкой 100% стоит inherited.

Не стоит. Это первое что тестировал со всех сторон. В может ли perform(WM_SysCommand, $F002+, 0) вызывать событие paint панели игнорируя мой перехват?
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39918474
Kazantsev Alexey
DimaBr
А первой строчкой 100% стоит inherited.

Не, он говорит, что затирание происходит до вызова перекрытого Paint.

Где-то до, так как на первой строчке Paint - панель уже закрашена.
Kazantsev Alexey

Андрей Игоревич
И если суомпилирвать файл res в 7ке, то и в 10ке всё будет нормально.

Не понял. Если взять .res файл от семёрки и подложить его в проект Delphi 10.3?

Зачем класть, можно сначала скомпилировать программу на 7ке, а потом на 10ке, тогда 10ка подхватит созданный 7кой res (что, наверно, не есть хорошо, но работает прекрасно, пока у нас полностью совпадает содержание). Ну нравится мне интерфейс 7ки с кучей плагинов :). Потому писал на ней, а финально компилировать в 64 бита на 10ке, сейчас вот полностью переезжаю на 10ку, есть у неё некоторые приятные возможности.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39918480
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей Игоревич
Зачем класть, можно сначала скомпилировать программу на 7ке, а потом на 10ке, тогда 10ка подхватит созданный 7кой res

Похоже, кто-то очень любит нетрадиционный... гхм. Лучше бы уже определиться с версиями окончательно и не искать себе приключений на копчик.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39918581
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
type
TMyPanel = class(TPanel)
   procedure WMEraseBkgnd(var Message: TWmEraseBkgnd); message WM_ERASEBKGND;
   procedure Paint;override;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  with TMyPanel.Create(self) do begin
    Parent := self;
    SetBounds(0,0,200,200);
  end;
end;

{ TMyPanel }

procedure TMyPanel.Paint;
begin

end;

procedure TMyPanel.WMEraseBkgnd(var Message: TWmEraseBkgnd);
begin

end;
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39918597
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
.res от десятки включает манифест с 6й версией Common Controls, отсюда и артефакты ИМХО. Что-то там внутри поменялось (те же темы). Можно попробовать в 10ке в свойствах проекта отключить темы вообще (даже родные для винды) и посмотреть что изменится.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39919102
alekcvp
.res от десятки включает манифест с 6й версией Common Controls, отсюда и артефакты ИМХО. Что-то там внутри поменялось (те же темы). Можно попробовать в 10ке в свойствах проекта отключить темы вообще (даже родные для винды) и посмотреть что изменится.

Как включать всякие цветастые стили нашел, как отключать, пока не нашел ).
Kazantsev Alexey
Андрей Игоревич
А вот перехват обработку сообщений я пока до конца не освоил, это через так делать?

Нет, это делать так:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
TMyPanel = class
 procedure WMEraseBkgnd(Var AMessage : TMessage); Message WM_ERASEBKGND;
end;
...
procedure TMyPanel.WMEraseBkgnd(Var AMessage : TMessage);
begin
 AMessage.Result := 1;
end;



В общем разобрался как с этим работать, чтоб не мерцало.
1. Надо закрашивать панель в самом начале, при том за пределами границ, иначе на границах будут "артефакты"
Brush.Color:=ClWhite;
Rectangle(-2,-2,width+2,height+2);
2. С перехватом этого сообщения почему-то не работает рисование в буферном БитМапе с последующем присваивании через Canvas.CopyRect. Почему, не понял, ещё подумаю.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39919129
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей Игоревич,

Советую экспериментировать не на боевом коде, а в новых тестовых проектах. Никакой жути, типа, рисования за пределами контрола не требуется - отрисовка по ClientRect закрашивает всё, без артефактов.
...
Рейтинг: 0 / 0
Создание компонента сложной формы (аккуратной контурной стрелки).
    #39919523
Kazantsev Alexey
Андрей Игоревич,

Советую экспериментировать не на боевом коде, а в новых тестовых проектах. Никакой жути, типа, рисования за пределами контрола не требуется - отрисовка по ClientRect закрашивает всё, без артефактов.

В принципе что хотел, получил, спасибо. Через WMEraseBkgnd(Var AMessage : TMessage); Но неужели нет никаких стандартных компонентов под такие задачи, чтоб не городить огород. Ведь в том же "билдере" всё это есть.

Для тестирования накидал пару тысяч спидбатоннов, чтоб нагрузка на форму был, иначе "мерцания" и не увидеть. И, как раз через изменение размеров посредством отлова координат мыши - при больших нагрузка мерцает, а через perform(WM_SysCommand, $, 0) - нет;
Может я как не неправильно размеры меняю? В принципе если через perform работает - то и ладно, но понять почему мерцает через второй способ - интересно.
rкод из MouseMoveV2
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
  GetCursorPos(CursPos);
    X1:=CursPos.X;
    Y1:=CursPos.Y;

  dX:=X1-X0; dY:=Y1-Y0;
  if ResizeLegend.Move then
        begin
          Top:=Top+dY;     Left:=Left+dX;
        end;

  if ResizeLegend.Right then Width:=Width+dX;
  if ResizeLegend.Top then
     Begin
      Top:=Top+dY;
      Height:=Height-dY;
     End;
  if ResizeLegend.Left then
   Begin
    left:=left+dX;
    Width:=Width-dX;
   end;
  if ResizeLegend.Bottom then  Height:=Height+dY;
  X0:=X1;  Y0:=Y1;


alekcvp
.res от десятки включает манифест с 6й версией Common Controls, отсюда и артефакты ИМХО. Что-то там внутри поменялось (те же темы). Можно попробовать в 10ке в свойствах проекта отключить темы вообще (даже родные для винды) и посмотреть что изменится.

Нашел где отключается манифест, при отключении - и в старом коде ничего не мерцает. Но это не решение... Кстати, а можно как-то вышить "манифест" в код, у нас на рабочих компах все визуальный настройки в ноль выключены и 10ка как 98я выглядит, и программа там выглядит несколько иначе, нежели на компе, где я компилирую (и где ограничений нет).
...
Рейтинг: 0 / 0
110 сообщений из 110, показаны все 5 страниц
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Создание компонента сложной формы (аккуратной контурной стрелки).
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]