Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Использование 2 форм и сегфолт, Delphi\lazarus 
V
    Опции темы
CynicRus
Дата 10.7.2012, 20:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 248
Регистрация: 31.5.2012

Репутация: нет
Всего: 5



Ещё раз приветствую уважаемых форумчан. Пишу дизайнер форм для одного скриптового языка, соответственно случилась необходимость прикрутить к этому делу небольшой редактор контролов. Я пошел следующим путем:
1) Завел структуру TSimbaComponent, описывающую компонент существующий в скриптовом языке:
Код

type
  TSimbaComponent = record
    tp: integer;
    caption: string;
    left,top,width,heigth: integer;
    fontcolor: TColor;
    fontname: string;
    fontsize: integer;
  end;
  type
  PSimbaComponent = ^TSimbaComponent;                               

2) Написал класс-обертку для TList Для удобной работы с моей структурой:
Код

type

{ TSimbaComponentList }

TSimbaComponentList = class
  private
    FList: TList; // Simba components storage
  public
  constructor Create;
  destructor Destroy; override;
  function AddItem(Item: TSimbaComponent): Integer;
  procedure RemoveItem(ItemIndex: Integer);
  function GetComponent(Idx: integer): TSimbaComponent;
  function GetComponentPtr(Idx: integer): PSimbaComponent;
  function Count: integer;
end;

implementation

{ TSimbaComponentList }

constructor TSimbaComponentList.Create;
begin
  FList := TList.Create;//create storage
  inherited Create;
end;

destructor TSimbaComponentList.Destroy;
begin
  FList.Free; //free storage
  inherited Destroy;
end;

function TSimbaComponentList.AddItem(Item: TSimbaComponent): Integer;
var
 p: PSimbaComponent;
begin
  GetMem(p, SizeOf(Item)); // independently allocate memory
  Move(Item, p^, SizeOf(Item));
  Result := FList.Add(p); // simply redirect a call
end;

procedure TSimbaComponentList.RemoveItem(ItemIndex: Integer);
begin
  FreeMem(FList[ItemIndex]); // freememory
  FList.Delete(ItemIndex);
end;

function TSimbaComponentList.GetComponent(Idx: integer): TSimbaComponent;
begin
  FillChar(Result, SizeOf(TSimbaComponent), #0);
  Result := TSimbaComponent(FList.Items[Idx]^); // redirect a call and convert it to TBitmap
end;

function TSimbaComponentList.GetComponentPtr(Idx: integer): PSimbaComponent;
begin
  Result := FList.Items[Idx];//redirect a call
end;

function TSimbaComponentList.Count: integer;
begin
  Result := FList.Count;
end;                             

3) Написал процедуру, забирающую у контрола необходимые свойства и присваивающую их структуре:
Код

function TCompForm.ComponentToSimba(cmp: TControl): TSimbaComponent;
var
   smb: TSimbaComponent;
begin
   smb.caption:=cmp.Caption;
   smb.top:=cmp.Top;
   smb.width:=cmp.Width;
   smb.left:=cmp.Left;
   smb.heigth:=cmp.Height;
   smb.tp:=GetControlType(cmp);
   smb.fontcolor:=cmp.Font.Color;
   smb.fontname:=cmp.Font.Name;
   smb.fontsize:=cmp.Font.Size;
   result:=smb;
end; 

4) На главной форме разместил стринггрид, и заполняю его:
Код

procedure TCompForm.AddToStringGrid(cmp: TControl);
 var
   smb: TSimbaComponent;
begin
   smb:=ComponentToSimba(cmp);
  CompList.AddItem(smb);
  with StringGrid1 do begin
    Cells[1,1]:=cmp.ClassName;
    Cells[1,2]:=smb.caption;
    Cells[1,3]:=IntToStr(smb.top);
    Cells[1,4]:=IntToStr(smb.left);
    Cells[1,5]:=IntToStr(smb.width);
    Cells[1,6]:=IntToStr(smb.heigth);
    Cells[1,7]:=smb.fontname;
    cells[1,8]:=IntToStr(smb.fontsize);
    Cells[1,9]:=ColorToStr(smb.fontcolor);
  end;
 end;                   

5) Форма 2 создается в рантайме, и располагается на панели формы 1. После выбора контрола на первой форме, он располагается на форме 2,  его свойства пишуться в структуру, затем структура отображается в гриде. Но только если выбран контрол, при простом клике на форму - я ловлю категорический сегфолт и уже весь мозг сломал, как же мне это вылечить. В отладчике смотрел - как я понимаю, косяк со свойством контрола Tag. Но как мне быть - придумать пока не могу-(
Код создания контрола
Код

procedure TDsgnForm.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  _comp := CreateComponent(Sender, X, Y);
  if (_comp.Tag <> 0) then
  CompForm.AddToStringGrid(_comp) else
    CompForm.AddToStringGridEx(CompForm.CompList.GetComponent(0),_comp);
end;  

Если убрать последние 3 строчки, то работает восхитительно. Если при клике на форму - выбран контрол для создание - то и с 3 последними строчками, все пашет замечательно. Так вот собственно вопрос - как избежать сегфолтов при клике на пустую форму, а при клике на существующий на форме 2 контрол -  запихнуть в грид уже существующую информацию о нем из обертки?

PS: сегфолт ловлю на строке
Код

if (_comp.Tag <> 0) then
 если её убрать, то - на строке 2788 модуля control.inc, и выглядит она
Код
 if TMethod(@Self.GetTextBuf).Code = Pointer(@TControl.GetTextBuf)

PM MAIL   Вверх
DarkProg
Дата 10.7.2012, 23:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Законченный романтик
***


Профиль
Группа: Завсегдатай
Сообщений: 1784
Регистрация: 11.3.2009
Где: Земля

Репутация: 2
Всего: 19



Код

constructor TSimbaComponentList.Create;
begin
  FList := TList.Create;//create storage
  inherited Create;
end;


Сначала родительский конструктор, потом всё что хотите своё, т.е. сначала inherited, а потом всё остальное.

Для вот этого
Код

    fontcolor: TColor;
    fontname: string;
    fontsize: integer;

Можно использовать класс TFont, отлично работает.

Кстати зачем вы вообще используете TList, если у вас вполне определённый тип объектов? Создайте массивчик динамический и храните всё там, функциональчик получится несколько меньше, но работать будет.
TList сам вполне умеет добавлять и удалять элементы, GetMem вам тоже делать не надо, там внутри только указатели будут. Ваша же задача написать обёрточку что положить и что извлечь(просто сделать приведение типов).
Собственно вот отличный пример работы с TList http://delphibasics.ru/TList.php


--------------------
"И твоя голова всегда в ответе за то куда сядет твой зад..."

"Я студент - скажите с какого я ВУЗа..."

 smile  smile  smile 
PM MAIL   Вверх
CynicRus
Дата 11.7.2012, 08:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 248
Регистрация: 31.5.2012

Репутация: нет
Всего: 5



Спасибо за конструктивную критику-) 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0871 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.