Как правилно да освободите контролите на StringGrid

Създавам контроли така: procedure TForm3.FormCreate(Sender: TObject); var B: TButton; P: TPanel; I, J, CurRow: Integer; begin for I := 1 to 10 do begin StringGr > P:=TPanel.Create(Panel1); P.Parent:=Self; P.W > Р.Височина:=24; P.Visible:=False;

B := TButton.Create(P); B.Parent:=Self; B.Caption:="0-"+IntToStr(i); ЧБ > B.Височина:=20; B.Top:=2; B.Left:=2; B.Visible:=Вярно; B.Name:="But0"+IntToStr(i);

B := TButton.Create(P); B.Parent:=Self; B.Caption:="1-"+IntToStr(i); ЧБ > B.Височина:=20; B.Top:=2; B.Left:=24; B.Visible:=Вярно; B.Name:="But1"+IntToStr(i);

StringGr +IntToStr(i); StringGr > край; край;

procedure TForm3.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState); var B: TButton; P: TPanel; започнете ако StringGr > ако не (gdFixed в състояние) и (P е TPanel), тогава започнете P.Left:=StringGrid1.Left+Rect.Left+Rect.Right-P.Width+Panel1.Left; P.Top:=StringGrid1.Top+Rect.Top+Panel1.Top+4; P.Visible:=Вярно; край; край;

procedure TForm3.StringGrid1VerticalScroll(Sender: TObject); begin StringGrid1.Refresh; end;

при затваряне на приложенията получавам EInvalidPointer: Невалидна операция на указател.. идея в това да направи родител всички динамично създадени контроли TPanel, който кинул на формата във времето за проектиране. както разбирам, при затваряне на приложения, всичко, което е свързано с този панел, трябва правилно да се освободи, включително всички деца в този панел. но похоже, че това не е така:) подскажете пож в чём проблема и как това е правилно организирайте

> идеята в това да направи всички динамично създадени родители > контролов TPanel

> всичко, което е свързанос този панел трябва да се освободи правилноNo. Родителят е едно нещо. Собственик (собственик) др. Всичко, което панелът притежава, ще бъде освободено.

Нито ( 2007-12-12 14:52 ) [2]

след това, ако разбрах правилно, тогава ако за панелите, които създавам, посоча собственика, например формата, върху която лежи stringgrid, тогава, когато формулярът бъде освободен, всички панели, които притежава, ще бъдат освободени?

направи това: procedure TForm3.FormCreate(Sender: TObject); var B: TButton; P: TPanel; I, J, CurRow: Integer; begin for I := 1 to 10 do begin StringGr > P:=TPanel.Create(Form3); P.Parent:=Self; P.W > Р.Височина:=24; P.Visible:=False;

B := TButton.Create(P); B.Parent:=P; B.Caption:="0-"+IntToStr(i); ЧБ > B.Височина:=20; B.Top:=2; B.Left:=2; B.Visible:=Вярно; B.Name:="But0"+IntToStr(i);

B := TButton.Create(P); B.Parent:=P; B.Caption:="1-"+IntToStr(i); ЧБ > B.Височина:=20; B.Top:=2; B.Left:=24; B.Visible:=Вярно; B.Name:="But1"+IntToStr(i);

StringGr +IntToStr(i); StringGr > край; край;

EInvalidPointer не изпада, сега въпросът е дали всичко ще бъде пуснато правилно (панели, бутони, които са на тези панели) с този подход?

> с този подход?Вашият подход е обърнат с главата навън.

В края на краищата първоначалната задача не е „да освободите правилно“, а „да натискате бутони в . Нали? Всичко останало е следствие от това, което сте смятали за "лесно" решение. И последствията не закъсняха, а? Как да поставим бутон в клетка? Как да настроя бутона за превъртане? Сега ето как да освободите.

И ако спрете малко, ще разберете, че не е нужно да се тъпчете с толкова много истинскибутони, колко клетки има. Освен това някои от бутоните все още не се виждат. Всичко, от което се нуждаете, е клетките да имат нещоизглеждащокато бутони иповеждащо секато бутони.

И за това е достатъчно рисуване и реакция на мишката.

Нито ( 2007-12-12 15:17 ) [4]

оказа се, че предлагаш да пренапишеш TButton? :) защо, след като borland вече е пробвал за мен? тази задача ще отнеме много пъти повече време и усилия .. и постоянно гледам OnMouseMove и определям на кой ред е в момента, това ще бъде много ресурсоемка задача, но не знам как иначе да разбера над коя клетка е показалецът. струва ми се, че ще бъде много по-лесно, т.к. Не ми трябва само OnClick, но това ще са снимки, за които ще ми трябва OnMouseEnter OnMouseLeave OnMouseUp OnMouseDown това е програма с напълно изчертан нестандартен интерфейс, това е бъркотията

> Няма (12/12/07 15:17) [4] > Значи предлагате да пренапишете TButton? :)Предлагам да използвате персонализираното изобразяване и събитията с мишката, които вече са предоставени от мрежата.

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

> тази задача ще отнеме многократно повече време и усилияВсе още не сте го пробвали. Ето, вижте.

тип TForm1 = клас(TForm) . private FPushed: boolean; .

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState); begin if (ACol = 2) and (ARow = 2) then begin if FPushed then DrawFrameControl(StringGrid1.Canvas.Handle, право,DFC_BUTTON, DFCS_BUTTONPUSH или DFCS_PUSHED или DFCS_ADJUSTRECT) else DrawFrameControl(StringGrid1.Canvas.Handle, Rect, DFC_BUTTON, DFCS_BUTTONPUSH или DFCS_ADJUSTRECT); ако gdFocused в състояние, тогава започнете InflateRect(Rect, -1, -1); DrawFocusRect(StringGrid1.Canvas.Handle, Rect); край; край край;

procedure TForm1.StringGrid1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var col, row: Integer; r: TRect; начало StringGrid1.MouseToCell(X, Y, col, row); FPushed := (колона = 2) и (ред = 2); r := StringGrid1.CellRect(2, 2); InvalidateRect(StringGrid1.Handle, @r, false); край;

procedure TForm1.StringGrid1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin FPushed := false; StringGrid1.Invalidate; край;

Пока за най-добрата красота е желателно да поставите DefaultDrawing = false.

Но това са три минути лабания до поправки на отговора. Пълен обнадеждаващ резултат. А ако потрати само толкова време, колко потратил до тях? Така че не надо про разы.

> това е прогрммулина с напълно нарисован нестандартен > интерфейсомНу так и рисуй его. Зачем пихать батоны, куда те не лезут.

Нито ( 2007-12-12 15:58 ) [6]

пасибо отделно голямо! аз първи път слушам MouseToCell. надо почаще в хелп да нърят и гледам какво изобщо се случва:) така много по-проще. с контроли вече пол дни ковыряюсь, първо не мога да създам, сега не мога да разруша) ещё раз пасиба!

Нито ( 2007-12-12 16:00 ) [7]

а ето още подскажи пож, трябва да приведете курсора на кнопката, да промените неговия вид.. може ли още каква чудо функция има?)

Тази мегафункциянаречен курсор

> трябва да задържите курсора на мишката върху бутона и да промените външния му вид. > . може би има друга чудотворна функция?)Позицията на курсора се проследява в събитието OnMouseMove. Курсорът, който удря клетката, се определя от MouseToCell Типът на курсора се определя от свойството Cursor

А чудото се крие в правилната комбинация от оператори.

Нито ( 2007-12-13 16:35 ) [11]

Благодаря много! Оказа се много по-лесно, отколкото си мислех