Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Как обратиться к свойству другого класса?


Автор: SkAndriy 23.8.2010, 19:53
Добрый день!

Создаю компонент со свойствами-множествами (unit MyComponent) и редактором свойств (unit PropertyEditor) по такой схеме:

Код

unit MyComponent;
 
interface
 
uses
  SysUtils, Types, Classes;
 
type 
  TMyDataRecord = record
    MyData1 : Double;
    MyData2 : Double2;
  end;
 
  TMyEnumType = (eFirst, eSecond, eThird);
  TMySetTypeFirst = (poFirst1, poSecond1, poThird1);
  TMySetTypeSecond = (poFirst2, poSecond2, poThird2);
  TMySetTypeThird = (poFirst3, poSecond3, poThird3);
 
TMyObject = class (TPersistent) 
  private 
    { Private declarations } 
    FProperty1: Double; 
    FProperty2: Double;
    FProperty3: Double;
    function GetDataElement(Index : Integer): Double;
    // procedure SetDataElement(Index : Integer; Value : Double);
  protected 
    { Protected declarations } 
  public 
    { Public declarations } 
  procedure Assign (Source: TPersistent); 
  published 
    { Published declarations } 
    property Property1: Double index 0 read GetDataElement write FProperty1; 
    property Property2: Double index 1 read GetDataElement write FProperty2; 
    property Property3: Double index 2 read GetDataElement write FProperty3;
  end;
 
type 
  TMyComponent = class(TButton) 
  private 
    { Private declarations } 
    FMyObject: TMyObject; 
    FMyEnum: TMyEnumType;
    FMyOptions: Integer;
    procedure SetMyObject(Value: TMyObject); 
  protected 
    { Protected declarations } 
  public 
    { Public declarations } 
    constructor Create(AOwner: TComponent); override; 
    destructor Destroy; override;
    function calculatesomedata : TMyDataRecord; 
  published 
    { Published declarations } 
    property MyObject : TMyObject read FMyObject write SetMyObject; 
    property MyEnumProp : TMyEnumType read FMyEnum write FMyEnum;
    property MyOptions : Integer read FMyOptions write FMyOptions;
  end;
 
  procedure Register; 
 
implementation 
 
procedure TMyComponent.SetMyObject(Value: TMyObject); 
begin 
  if Assigned (Value) then FMyObject.Assign(Value); 
end;
 
constructor TMyComponent.Create (AOwner; TComponent); 
begin 
  inherited Create (AOwner); 
  FMyObject := TMyObject.Create; 
end;
 
destructor TMyComponent.Destroy; 
begin 
  FMyObject.Free; 
  inherited Destroy; 
end;
 
function TMyComponent.CalculateSomeData : TMyDataRecord;
begin
  if если выбрано одно из подмноджеств TMySetTypeFirst или TMySetTypeSecond или TMySetTypeThird в редакторе свойств then
    Result := здесь расчет и присваивание некого результата от TMyDataRecord в зависимости от значения FOptions;
end;
 
procedure TMyObject.Assign (Source: TPersistent); 
begin 
if Source is TMyObject then 
begin 
  FProperty1 := TmyObject(Source).Property1; 
  FProperty2 := TmyObject(Source).Property2; 
  FProperty3 := TmyObject(Source).Property3;
  inherited Assign (Source); 
end; 
 
function TMyObject.GetDataElement(Index : Integer): Double;
begin
  Result := 0;
  with TMyComponent(self) do
    case Index of
       0 : Result := CalculateSomeData.MyData1;
       1 : Result := CalculateSomeData.MyData2;
       2 : Result := CalculateSomeData.MyData3;
    end; 
end;
 
end.
 
============================================================
 
unit PropertyEditor;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, DesignIntf, DesignEditors, TypInfo;
 
type
  TMySetTypeProperty = class(TEnumProperty)
  private
    function GetTypeInfo: PTypeInfo; 
  public
    function GetValue: string; override;
    procedure GetValues(Proc: TGetStrProc); override;
    procedure SetValue(const Value: string); override;
  end;
 
  procedure Register;
 
implementation
 
uses UnitMyComponent;
 
function TMySetTypeProperty.GetTypeInfo: PTypeInfo;
var
  Obj: TPersistent;
begin
  Obj := GetComponent(0);
  if Assigned(Obj) and (Obj is TMyComponent) then
    with TMyComponent(Obj) do
    begin
      case MyEnumProp of
        eFirst: Result := TypeInfo(TMySetTypeFirst);
        eSecond: Result := TypeInfo(TMySetTypeSecond);
        eThird: Result := TypeInfo(TMySetTypeThird);
      end;     
    end
  else 
    Result := GetPropType;
end;
 
function TMySetTypeProperty.GetValue: string;
var
  L: Longint;
begin
  L := GetOrdValue;
  with GetTypeData(GetTypeInfo)^ do
    if (L < MinValue) or (L > MaxValue) then L := MaxValue;
  Result := GetEnumName(GetTypeInfo, L);
end;
 
procedure TMySetTypeProperty.GetValues(Proc: TGetStrProc);
var
  I: Integer;
  EnumType: PTypeInfo;
begin
  EnumType := GetTypeInfo;
  with GetTypeData(EnumType)^ do
  begin
    for I := MinValue to MaxValue do Proc(GetEnumName(EnumType, I));
  end;
end;
 
procedure TMySetTypeProperty.SetValue(const Value: string);
var
  I: Integer;
begin
  I := GetEnumValue(GetTypeInfo, Value);
  with GetTypeData(GetPropType)^ do
    if (I < MinValue) or (I > MaxValue) then
      raise Exception.Create('');
  SetOrdValue(I);
end;
 
procedure Register;
begin
  RegisterPropertyEditor(TypeInfo(Integer), TMyComponent, 'MyOptions', TMySetTypeProperty)
end;
 
end.


Вопрос: 
 
Почему компоненнт не реагирует на переключение множеств в редакторе свойств (GetTypeInfo)?
Почему результаты вычислений функции CalculateSomeData не присваиваются полям FProperty1, FProperty2, FProperty3 моего компонента MyComponent?
Подскажите правильно ли я составил код компонента. Где ощибки в коде и как их исправить?

Спасибо.

Автор: drkot 23.8.2010, 21:41
Есть такой очень хороший способ... пошаговое исполнение кода (степ бай степ... ну и там продолжение есть).

Хотя я сомневаюсь что этот код пропустит компилятор... в нем и так полно синтаксических ошибок...

Автор: SkAndriy 23.8.2010, 22:34
спасибо за замечания, а по можно более конкретные рекомендации что надо исправить.

Автор: drkot 24.8.2010, 00:01
для начала откомпилировать и пройтись дебагером...
а потом задавать вопросы по конкретным проблемам, а не в целом о методах программирования...

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

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)