Форум: "Начинающим";
Текущий архив: 2008.01.13;
Скачать: [xml.tar.bz2];
ВнизКак правильно осовбодить контролы на StringGrid Найти похожие ветки
← →
Nil (2007-12-12 14:05) [0]Создаю контролы так:
procedure TForm3.FormCreate(Sender: TObject);
var
B: TButton;
P: TPanel;
I, J, CurRow: Integer;
begin
for I := 1 to 10 do
begin
StringGrid1.RowCount:=i;
P:=TPanel.Create(Panel1);
P.Parent:=Self;
P.Width:=50;
P.Height:=24;
P.Visible:=False;
B := TButton.Create(P);
B.Parent:=Self;
B.Caption:="0-"+IntToStr(i);
B.Width:=20;
B.Height:=20;
B.Top:=2;
B.Left:=2;
B.Visible:=True;
B.Name:="But0"+IntToStr(i);
P.InsertControl(B);
B := TButton.Create(P);
B.Parent:=Self;
B.Caption:="1-"+IntToStr(i);
B.Width:=20;
B.Height:=20;
B.Top:=2;
B.Left:=24;
B.Visible:=True;
B.Name:="But1"+IntToStr(i);
P.InsertControl(B);
StringGrid1.Cells[0,i-1]:="Button"+IntToStr(i);
StringGrid1.Objects[0,i-1] := P;
end;
end;
procedure TForm3.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
var
B: TButton;
P: TPanel;
begin
if StringGrid1.Objects[ACol, ARow] is TControl then P:=(StringGrid1.Objects[ACol,ARow] as TPanel) else P:=nil;
if not (gdFixed in State) and (P is TPanel) then
begin
P.Left:=StringGrid1.Left+Rect.Left+Rect.Right-P.Width+Panel1.Left;
P.Top:=StringGrid1.Top+Rect.Top+Panel1.Top+4;
P.Visible:=True;
end;
end;
procedure TForm3.StringGrid1VerticalScroll(Sender: TObject);
begin
StringGrid1.Refresh;
end;
при закрытии приложения получаю EInvalidPointer: Invalid pointer operation..
идея в том чтобы сделать родителем всех динамически созданных контролов TPanel, который кинул на форму в design time. как я понимаю, при закрытии приложения, всё что связано с этой панелью должно правильно освободиться, включая всех детей этой панели. но похоже что то пошло не так:) подскажите пож в чём проблема и как это правильнее организовать
заранее благодарен
← →
Kolan © (2007-12-12 14:08) [1]> идея в том чтобы сделать родителем всех динамически созданных
> контролов TPanel
> всё что связано с этой панелью должно правильно освободиться
Нет. Родитель(Parent) — это одно. Owner(владелец) — другое. Освободится все чем владеет панель.
← →
Nil (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
StringGrid1.RowCount:=i;
P:=TPanel.Create(Form3);
P.Parent:=Self;
P.Width:=50;
P.Height:=24;
P.Visible:=False;
B := TButton.Create(P);
B.Parent:=P;
B.Caption:="0-"+IntToStr(i);
B.Width:=20;
B.Height:=20;
B.Top:=2;
B.Left:=2;
B.Visible:=True;
B.Name:="But0"+IntToStr(i);
B := TButton.Create(P);
B.Parent:=P;
B.Caption:="1-"+IntToStr(i);
B.Width:=20;
B.Height:=20;
B.Top:=2;
B.Left:=24;
B.Visible:=True;
B.Name:="But1"+IntToStr(i);
StringGrid1.Cells[0,i-1]:="Button"+IntToStr(i);
StringGrid1.Objects[0,i-1] := P;
end;
end;
EInvalidPointer не вываливается, теперь вопрос правильно ли всё освободится (панельки, кнопки которые на этих панельках) при таком подходе?
← →
DiamondShark © (2007-12-12 15:03) [3]
> при таком подходе?
У тебя подход наизнанку вывернут.
У тебя ведь исходная задача не "правильно освободить", а "напихать кнопочек в грид". Так ведь?
Всё остальное -- следствие выбранного тобой, как тебе показалось, "лёгкого" решения.
А следствия не заставили себя ждать, ага? Как подгнать кнопочку под ячейку? Как подогнать кнопочку под скрол? Теперь вот, как освободить.
А если б ты чуть-чуть остановился, ты бы додумался, что тебе нет нужды запихивать в грид столько реальных кнопочек, сколько там ячеек. Тем более, что часть кнопочек всё равно не видна.
Тебе надо лишь чтобы в ячейках было что-то выглядящее как кнопочки, и ведущее себя как кнопочки.
А для этого достаточно отрисовки и реакции на мышь.
← →
Nil (2007-12-12 15:17) [4]получается предлагаешь переписать TButton?:) зачем, когда за меня уже постарался борланд? эта задача займёт в разы больше времени и сил.. да и постоянно смотреть на OnMouseMove и определять над какой строкой она сейчас находится, это будет очень ресурсоёмкая задача, а как по другому узнать над какой именно ячейкой находится указатель я не знаю. мне кажется так будет намного проще, т.к. мне нужен не просто OnClick, а это будут картинки для которых мне будет нужен OnMouseEnter OnMouseLeave OnMouseUp OnMouseDown.
это прогрммулина с полностью нарисованным нестандартным интерфейсом, в этом и непрятность
← →
DiamondShark © (2007-12-12 15:45) [5]
> Nil (12.12.07 15:17) [4]
> получается предлагаешь переписать TButton?:)
Я предлагаю воспользоваться уже предоставленными возможностями грида по кастом отрисовке и событиями мыши.
Впрочем, если этот кнопочкастый грид -- новаторская интерфейсная находка, то я бы написал компонент, наследник грида. Глядишь, ещё бы где пригодился.
Но для разовой работы вполне достаточно событий.
> эта задача займёт в разы больше времени и сил
Да ты ж ещё не пробовал.
Вот, смотри.
type
TForm1 = class(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, Rect, DFC_BUTTON, DFCS_BUTTONPUSH or DFCS_PUSHED or DFCS_ADJUSTRECT)
else
DrawFrameControl(StringGrid1.Canvas.Handle, Rect, DFC_BUTTON, DFCS_BUTTONPUSH or DFCS_ADJUSTRECT);
if gdFocused in State then
begin
InflateRect(Rect, -1, -1);
DrawFocusRect(StringGrid1.Canvas.Handle, Rect);
end;
end
end;
procedure TForm1.StringGrid1MouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
col, row: Integer;
r: TRect;
begin
StringGrid1.MouseToCell(X, Y, col, row);
FPushed := (col = 2) and (row = 2);
r := StringGrid1.CellRect(2, 2);
InvalidateRect(StringGrid1.Handle, @r, false);
end;
procedure TForm1.StringGrid1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
FPushed := false;
StringGrid1.Invalidate;
end;
Пока для лучшей красоты желательно поставить DefaultDrawing = false.
Но это три минуты лабания до отправки ответа.
Вполне обнадёживающий результат. А если потратить столько же времени, сколько потратил до сих пор ты?
Так что не надо про разы.
> это прогрммулина с полностью нарисованным нестандартным
> интерфейсом
Ну так и рисуй его.
Зачем пихать батоны, куда они не лезут.
← →
Nil (2007-12-12 15:58) [6]пасибо отдельное большое! я первый раз слышу о MouseToCell. надо почаще в хелп нырять и смотреть что вообще бывает:) так гораздо проще. с контролами уже пол дня ковыряюсь, сначала не мог создать, теперь не могу разрушить)
ещё раз пасиба!
← →
Nil (2007-12-12 16:00) [7]а вот ещё подскажи пож, нужно принаведении курсора на кнопочку, поменять его вид.. может ещё какая чудо функция есть?)
← →
Anatoly Podgoretsky © (2007-12-12 16:09) [8]> Nil (12.12.2007 16:00:07) [7]
← →
Anatoly Podgoretsky © (2007-12-12 16:10) [9]> Nil (12.12.2007 16:00:07) [7]
Эта мегафункция называется Cursor
← →
DiamondShark © (2007-12-12 16:24) [10]
> нужно принаведении курсора на кнопочку, поменять его вид.
> . может ещё какая чудо функция есть?)
Положение курсора отслеживается в собитии OnMouseMove.
Попадание курсора в ячейку определяется MouseToCell
Вид курсора определяется свойством Cursor
А чудо состоит в нужной комбинации операторов.
← →
Nil (2007-12-13 16:35) [11]Спасибо большое! Получилось всё гораздо проще чем я думал
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2008.01.13;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.007 c