Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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
9-1164915039
sat
2006-11-30 22:30
2008.01.13
пятнашки


3-1188898377
novill
2007-09-04 13:32
2008.01.13
IB 7.1 Что означает COMMIT RETAIN ?


3-1188949392
kalan
2007-09-05 03:43
2008.01.13
Использование Oracle и InterBase в одном приложении


15-1196885533
Cyrax
2007-12-05 23:12
2008.01.13
Авторизованные дилеры и гарантийный ремонт...


3-1189083269
Yurikon
2007-09-06 16:54
2008.01.13
TADOQuery и использование памяти





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский