* 사용환경 : 델파이3/ Windows 98
* 에러 메시지 : stack overflow
일반적으로 TCollection를 이용하여 만든 프로퍼티는 오브젝트 인스펙터에 일단계형식으로등록이 되어 사용되는데 제가 만든 건 일단계프로퍼티를 선택하고 그다음에 TCollection를 이용한 프로터피 에디터를 만드는 것입니다.
그런데 이단계로 넘아갈때 자꾸 똑같은 프로퍼티들만 생성이 돼고 stack overflow가 컴포넌트 컴파일시에 나면서 델파이가 다운이 돼요...
소스를 같이 올리니깐 문제점을 좀 찾아주시구 왜 그렇게 되는지좀 알려 주세요...
그리구 한가지더 있는데 이단계 프로퍼티에서 인덱스 명령을 쓰는데..이것을 넣고 컴파일을 하면 일단계 프로퍼티조차 실행이 안돼요....이것두 좀 갈켜주세요..
현재 소스에는 그부분들을 다 먹았는데도 STACK OVERFLOW가 나내요...
이궁...콤포넌트 만들기 정말 힘들당....
제발 갈켜 주세요....
참 한가지더요...지금 만들구 있는 콤포넌트가 델파이 3.0이구요...
윈도우98에서 실행하구 있어요....그리구 델파이 3.0 엔터프라이즈 버전에서 제공되전 Tentara와 관련된 소스파일이 있으시면 저한테 제공을 해주실수 있나요...?
unit TmaxProv;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, DB, dbclient, provider, DsgnIntf;
{ Error Codes }
const
UpdateFailed = 1;
UpdateSkipped = 2;
type
{ Forward Declarations }
TTMaxConnection = class;
TTMaxProvider = class;
{ TPacketDataSet }
TPacketDataSet = class(TClientDataSet)
private
FGetNewValuesModified : Boolean;
FSetNewValuesModified : Boolean;
FGetStreamMetaData : Boolean;
FSetStreamMetaData : Boolean;
FGetUseCurValues : Boolean;
FSetUseCurValues : Boolean;
protected
procedure DataEvent(Event: TDataEvent; Info: Longint); override;
function GetStateFieldValue(State: TDataSetState; Field: TField): Variant; override;
procedure InternalClose; override;
procedure InternalOpen; override;
procedure InternalInitRecord(Buffer: PChar); override;
procedure SetStateFieldValue(State: TDataSetState; Field: TField;
Value: Variant); override;
public
procedure ResultFromDelta(DataSet: TClientDataSet);
function HasCurValues: Boolean;
procedure InitAltRecBuffers;
procedure InitCurValues(const CurValues: Variant);
function HasMergeConflicts: Boolean;
function UpdateKind: TUpdateKind;
property NewValuesModified: Boolean read FGetNewValuesModified write FSetNewValuesModified;
property StreamMetaData: Boolean read FGetStreamMetaData write FSetStreamMetaData;
property UseCurValues: Boolean read FGetUseCurValues write FSetUseCurValues;
end;
{ TParamDef }
TDataType = (dtDefault, dtString, dtInteger, dtSmallint, dtReal, dtFloat,
dtDouble, dtBinary);
TParamType = (ptUnknown, ptInput, ptOldValue, ptNewValue, ptOutput, ptColumn);
TParamDef = class(TCollectionItem)
private
FGetValue : Variant;
FSetValue : Variant;
FParamDataType : TDataType;
FParamFieldName : string;
FParamFieldSize : Integer;
FParamFieldType : TFieldType;
FParamParamName : string;
FParamParamType : TParamType;
FParamRequired : Boolean;
protected
procedure Assign(Source: TPersistent); override;
function FieldNameStored: Boolean;
function GetDisplayName: string; override;
procedure SetDataType(Value: TDataType);
procedure SetFieldType(Value: TFieldType);
procedure SetParamName(const Value: string);
public
constructor Create(AOwner: TCollection); override;
property Value: Variant read FGetValue write FSetValue;
published
property DataType: TDataType read FParamDataType write SetDataType default dtDefault;
property FieldName: string read FParamFieldName write FParamFieldName;
property FieldSize: Integer read FParamFieldSize write FParamFieldSize default 0;
property FieldType: TFieldType read FParamFieldType write SetFieldType default ftUnknown;
property ParamName: string read FParamParamName write SetParamName;
property ParamType: TParamType read FParamParamType write FParamParamType default ptUnknown;
property Required: Boolean read FParamRequired write FParamRequired default False;
end;
{ TRPCParams }
TRPCParams = class(TCollection)
private
FParamsOwner: TRPCFunction;
function GetRPCParamsItems(Index : Integer) : TParamDef;
procedure SetRPCParamsItems(Index : Integer; FRPCParams : TParamDef);
protected
function GetOwner: TPersistent; override;
public
constructor Create(Owner: TPersistent);
function Add: TParamDef;
function ParamByFieldName(const FieldName: string;
ParamType: TParamType): TParamDef;
function ParamByName(const ParamName: string): TParamDef;
property Items[Index: Integer]: TParamDef read GetRPCParamsItems write SetRPCParamsItems; default;
end;
{ TRPCFunction }
TDataRef = record
Ptr: Pointer;
Size: Integer;
DataType: TDataType;
end;
PDataRefList = ^TDataRefList;
TDataRefList = array[0..0] of TDataRef;
PVariantList = ^TVariantList;
TVariantList = array[0..0] of OleVariant;
TRPCAttributes = set of (raIdempotent, raInterruptible);
TRPCFunction = class(TPersistent)
private
// FRPCParams : TRPCParams;
FGetContext : Pointer;
FSetContext : Pointer;
FGetOwner : TComponent;
FGetRetCode : Integer;
FSetRetCode : Integer;
FGetAttributes : TRPCAttributes;
FSetAttributes : TRPCAttributes;
FGetIndex : Integer;
FSetIndex : Integer;
FGetRPCFunctionName : string;
FSetRPCFunctionName : string;
FGetRPCParams : TRPCParams;
FSetRPCParams : TRPCParams;
protected
procedure AddDataRef(Index: Integer; const DataRef: TDataRef);
procedure Assign(Source: TPersistent); override;
function GetFieldCount: Integer;
function GetFieldData(Index: Integer): Variant;
function GetFieldParam(Index: Integer): TParamDef;
function GetOwner: TPersistent; override;
function GetParamCount: Integer;
procedure InitFieldParams;
function ParamsStored: Boolean;
public
constructor Create(AOwner: TComponent);
destructor Destroy; override;
function EndOfData: Boolean;
function Invoke(Server: TTmaxConnection; DoRelease: Boolean): Integer;
procedure Release(Server: TTmaxConnection);
property Context: Pointer read FGetContext write FSetContext;
property FieldCount: Integer read GetFieldCount;
property FieldData[Index: Integer]: Variant read GetFieldData;
property FieldParams[Index: Integer]: TParamDef read GetFieldParam;
property Owner: TComponent read FGetOwner;
property ParamCount: Integer read GetParamCount;
property RetCode: Integer read FGetRetCode write FSetRetCode;
published
property Attributes: TRPCAttributes read FGetAttributes write FSetAttributes default [];
property Index: Integer read FGetIndex write FSetIndex default 0;
property Name: string read FGetRPCFunctionName write FSetRPCFunctionName;
property Params: TRPCParams read FGetRPCParams write FSetRPCParams;
end;
{ TTmaxConnection }
TTransportMode = (tmTCP, tmDCE, tmOLE);
TOpenFileList = class(TStringProperty)
public
procedure Edit; override;
function GetAttributes : TPropertyAttributes; override;
end;
TRPCCount = class(TIntegerProperty)
public
procedure Activate; override;
function GetAttributes : TPropertyAttributes; override;
end;
TTmaxConnection = class(TComponent)
private
FGetConfigFile : string;
FGetLogin : string;
FSetLogin : String;
FSetPassword : string;
FGetRPCCount : Integer;
FSetRPCCount : Integer;
FGetServerName : string;
FSetServerName : string;
FGetServerUUID : string;
FSetServerUUID : string;
FGetServerVersion : string;
FSetServerVersion : string;
FGetSQLFile : string;
FSetSQLFile : string;
FGetTransportMode : TTransportMode;
protected
function DCEInvoke(RPC: TRPCFunction): Integer;
function GetPassword: string;
function OLEInvoke(RPC: TRPCFunction): Integer;
procedure ReleaseAll;
procedure SetConfigFile(const Value: string);
procedure SetRPCList(Value: TList);
procedure SetTransportMode(Value: TTransportMode);
function TCPInvoke(RPC: TRPCFunction): Integer;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function RPCInvoke(RPC: TRPCFunction): Integer;
procedure RPCRelease(RPC: TRPCFunction);
property RPCList: TList write SetRPCList;
published
property ConfigFile: string read FGetConfigFile write SetConfigFile;
property Login: string read FGetLogin write FSetLogin;
property Password: string read GetPassword write FSetPassword;
property RPCCount: Integer read FGetRPCCount write FSetRPCCount default 0;
property ServerName : string read FGetServerName write FSetServerName;
property ServerUUID: string read FGetServerUUID write FSetServerUUID;
property ServerVersion: string read FGetServerVersion write FSetServerVersion;
property SQLFile: string read FGetSQLFile write FSetSQLFile;
property TransportMode: TTransportMode read FGetTransportMode write SetTransportMode;
end;
{ TTmaxProvider }
TResolverResponse = (rrSkip, rrAbort, rrMerge, rrApply, rrIgnore);
TProviderDataEvent = procedure(DataSet: TClientDataSet) of object;
TUpdateRecordEvent = procedure(DataSet: TClientDataSet;
UpdateKind: TUpdateKind; var Applied: Boolean) of object;
TResolverErrorEvent = procedure(DataSet: TClientDataSet; E: EDatabaseError;
UpdateKind: TUpdateKind; var Response: TResolverResponse) of object;
TTmaxProvider = class(TCustomProvider)
private
// FRPCFunction : Array[0..4] of TRPCFunction;
// FGetRPCFunction : TRPCFunction;
FGetServer : TTmaxConnection;
FSetServer : TTmaxConnection;
FOnGetData : TProviderDataEvent;
FOnUpdateData : TProviderDataEvent;
FOnUpdateError : TResolverErrorEvent;
FOnUpdateRecord : TUpdateRecordEvent;
protected
procedure BindParameters(Params: TRPCParams; DeltaData: TPacketDataSet;
NewOnly: Boolean);
procedure CreatePacketData;
procedure DoUpdate(DeltaData: TPacketDataSet);
function GetRPCFunction(Index: Integer): TRPCFunction;
function HandleUpdateError(DeltaData: TPacketDataSet; E: EDatabaseError;
var MaxErrors, ErrorCount: Integer): Boolean; virtual;
procedure InitializeConflictBuffer(DeltaData: TPacketDataSet); virtual;
procedure LogUpdateError(DeltaData: TPacketDataSet; E: EDatabaseError;
Response: TResolverResponse); virtual;
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
function PackageRecords(Count: Integer): Integer;
procedure SetRPCFunction(Index: Integer; Value: TRPCFunction);
procedure SetServer(Value: TTmaxConnection);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function ApplyUpdates(Delta: OleVariant; MaxErrors: Integer;
out ErrorCount: Integer): OleVariant; override;
function GetRecords(Count: Integer; out RecsOut: Integer): OleVariant; override;
procedure Reset(MetaData: WordBool); override;
procedure SetParams(Values: OleVariant); override;
property Provider;
published
property ConflictRPC : TRPCFunction index 4 read GetRPCFunction write SetRPCFunction;
property DeleteRPC : TRPCFunction index 2 read GetRPCFunction write SetRPCFunction;
property InsertRPC : TRPCFunction index 1 read GetRPCFunction write SetRPCFunction;
property SelectRPC : TRPCFunction index 3 read GetRPCFunction write SetRPCFunction;
property Server: TTmaxConnection read FGetServer write FSetServer;
property UpdateRPC : TRPCFunction index 0 read GetRPCFunction write SetRPCFunction;
property OnDataRequest;
property OnGetData: TProviderDataEvent read FOnGetData write FOnGetData;
property OnUpdateData: TProviderDataEvent read FOnUpdateData write FOnUpdateData;
property OnUpdateError: TResolverErrorEvent read FOnUpdateError write FOnUpdateError;
property OnUpdateRecord: TUpdateRecordEvent read FOnUpdateRecord write FOnUpdateRecord;
end;
procedure Register;
implementation
{$ASSERTIONS OFF}
procedure Register;
begin
RegisterComponents('Tmax', [TTmaxConnection]);
RegisterPropertyEditor(TypeInfo(string), TTmaxConnection, 'ConfigFile', TOpenFileList);
RegisterPropertyEditor(TypeInfo(Integer), TTmaxConnection, 'RPCCount', TRPCCount);
RegisterPropertyEditor(TypeInfo(string), TTmaxConnection, 'SQLFile', TOpenFileList);
RegisterComponents('Tmax', [TTmaxProvider]);
end;
{TPacketDataSet Start}
procedure TPacketDataSet.DataEvent(Event: TDataEvent; Info: Longint);
begin
//
end;
function TPacketDataSet.GetStateFieldValue(State: TDataSetState; Field: TField): Variant;
begin
//
end;
procedure TPacketDataSet.InternalClose;
begin
//
end;
procedure TPacketDataSet.InternalOpen;
begin
//
end;
procedure TPacketDataSet.InternalInitRecord(Buffer: PChar);
begin
//
end;
procedure TPacketDataSet.SetStateFieldValue(State: TDataSetState; Field: TField; Value: Variant);
begin
//
end;
procedure TPacketDataSet.ResultFromDelta(DataSet: TClientDataSet);
begin
//
end;
function TPacketDataSet.HasCurValues: Boolean;
begin
//
end;
procedure TPacketDataSet.InitAltRecBuffers;
begin
//
end;
procedure TPacketDataSet.InitCurValues(const CurValues: Variant);
begin
//
end;
function TPacketDataSet.HasMergeConflicts: Boolean;
begin
//
end;
function TPacketDataSet.UpdateKind: TUpdateKind;
begin
//
end;
{TPacketDataSet End}
{TParamDef Start}
constructor TParamDef.Create(AOwner : TCollection);
begin
// inherited Create(AOwner);
end;
procedure TParamDef.Assign(Source: TPersistent);
begin
{ if Source is TParamDef then
begin
DataType := TParamDef(Source).DataType;
FieldName := TParamDef(Source).FieldName;
FieldSize := TParamDef(Source).FieldSize;
FieldType := TParamDef(Source).FieldType;
ParamName := TParamDef(Source).ParamName;
ParamType := TParamDef(Source).ParamType;
Required := TParamDef(Source).Required;
end
else
inherited Assign(Source);
}end;
function TParamDef.FieldNameStored: Boolean;
begin
Result := (FParamFieldName <> '');
end;
function TParamDef.GetDisplayName: string;
begin
{ Result := FieldName;
if Result = '' then
Result := inherited GetDisplayName;
}end;
procedure TParamDef.SetDataType(Value: TDataType);
begin
if Value = FParamDataType then Exit;
FParamDataType := Value;
Changed(False);
end;
procedure TParamDef.SetFieldType(Value: TFieldType);
begin
if Value = FParamFieldType then Exit;
FParamFieldType := Value;
Changed(False);
end;
procedure TParamDef.SetParamName(const Value: string);
begin
if (Value = '') then Exit;
FParamParamName := Value;
Changed(False);
end;
{TParamDef End}
{TRPCParams Start}
constructor TRPCParams.Create(Owner: TPersistent);
begin
// inherited Create(TParamDef);
// FParamsOwner := Owner;
end;
function TRPCParams.Add: TParamDef;
begin
Result := TParamDef(inherited Add);
end;
function TRPCParams.ParamByFieldName(const FieldName: string; ParamType: TParamType): TParamDef;
begin
//
end;
function TRPCParams.ParamByName(const ParamName: string): TParamDef;
begin
//
end;
function TRPCParams.GetRPCParamsItems(Index : Integer) : TParamDef;
begin
// Result := TParamDef(inherited GetItem(Index));
end;
procedure TRPCParams.SetRPCParamsItems(Index : Integer; FRPCParams : TParamDef);
begin
// inherited SetItem(Index, FRPCParams);
end;
function TRPCParams.GetOwner: TPersistent;
begin
// Result := FParamsOwner;
end;
{TRPCParams End}
{ TTmaxConnection Start}
constructor TTmaxConnection.Create(AOwner : TComponent);
begin
inherited Create(AOwner);
end;
procedure TTmaxConnection.SetRPCList(Value : TList);
begin
//
end;
destructor TTmaxConnection.Destroy;
begin
inherited Destroy;
end;
function TTmaxConnection.DCEInvoke(RPC: TRPCFunction): Integer;
begin
//
end;
function TTmaxConnection.GetPassword: string;
begin
//
end;
function TTmaxConnection.OLEInvoke(RPC: TRPCFunction): Integer;
begin
//
end;
procedure TTmaxConnection.ReleaseAll;
begin
//
end;
procedure TTmaxConnection.SetConfigFile(const Value: string);
begin
//
end;
procedure TTmaxConnection.SetTransportMode(Value: TTransportMode);
begin
//
end;
function TTmaxConnection.TCPInvoke(RPC: TRPCFunction): Integer;
begin
//
end;
function TTmaxConnection.RPCInvoke(RPC: TRPCFunction): Integer;
begin
//
end;
procedure TTmaxConnection.RPCRelease(RPC: TRPCFunction);
begin
//
end;
function TOpenFileList.GetAttributes : TPropertyAttributes;
begin
Result := inherited GetAttributes + [paDialog];
end;
procedure TOpenFileList.Edit;
var
OpenDialog1 : TOpenDialog;
begin
with TOpenDialog.Create(nil) do
try
if GetName = 'ConfigFile' then
begin
Filter := 'DAP/ENV files (*.dap;*.env)|*.dap;*.env';
end
else
begin
Filter := 'SQL files (*.sql)|*.sql';
end;
if Execute then
begin
SetStrValue(FileName);
end;
finally
Free;
end;
end;
function TRPCCount.GetAttributes : TPropertyAttributes;
begin
Result := inherited GetAttributes;
end;
procedure TRPCCount.Activate;
begin
SetOrdValue(2);
end;
{ TTmaxConnection End}
{TRPCFunction Start}
constructor TRPCFunction.Create(AOwner: TComponent);
begin
// inherited Create;
// FRPCParams := TRPCParams.Create(Self);
end;
procedure TRPCFunction.AddDataRef(Index: Integer; const DataRef: TDataRef);
begin
//
end;
procedure TRPCFunction.Assign(Source: TPersistent);
begin
//
end;
function TRPCFunction.GetFieldCount: Integer;
begin
//
end;
function TRPCFunction.GetFieldData(Index: Integer): Variant;
begin
//
end;
function TRPCFunction.GetFieldParam(Index: Integer): TParamDef;
begin
//
end;
function TRPCFunction.GetOwner: TPersistent;
begin
//
end;
function TRPCFunction.GetParamCount: Integer;
begin
//
end;
procedure TRPCFunction.InitFieldParams;
begin
//
end;
function TRPCFunction.ParamsStored: Boolean;
begin
//
end;
function TRPCFunction.EndOfData: Boolean;
begin
//
end;
function TRPCFunction.Invoke(Server: TTmaxConnection; DoRelease: Boolean): Integer;
begin
//
end;
procedure TRPCFunction.Release(Server: TTmaxConnection);
begin
//
end;
destructor TRPCFunction.Destroy;
begin
// inherited Destroy;
// FRPCParams.Free;
end;
{TRPCFunction End}
{TTmaxProvider Start}
constructor TTmaxProvider.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
// FGetRPCFunction := TRPCFunction.Create(Self);
end;
function TTmaxProvider.ApplyUpdates(Delta: OleVariant; MaxErrors: Integer;
out ErrorCount: Integer): OleVariant;
begin
//
end;
function TTmaxProvider.GetRecords(Count: Integer; out RecsOut: Integer): OleVariant;
begin
//
end;
procedure TTmaxProvider.Reset(MetaData: WordBool);
begin
//
end;
procedure TTmaxProvider.SetParams(Values: OleVariant);
begin
//
end;
destructor TTmaxProvider.Destroy;
begin
// FGetRPCFunction.Free;
inherited Destroy;
end;
procedure TTmaxProvider.BindParameters(Params: TRPCParams; DeltaData: TPacketDataSet;
NewOnly: Boolean);
begin
//
end;
procedure TTmaxProvider.CreatePacketData;
begin
//
end;
procedure TTmaxProvider.DoUpdate(DeltaData: TPacketDataSet);
begin
//
end;
function TTmaxProvider.HandleUpdateError(DeltaData: TPacketDataSet; E: EDatabaseError;
var MaxErrors, ErrorCount: Integer): Boolean;
begin
//
end;
procedure TTmaxProvider.InitializeConflictBuffer(DeltaData: TPacketDataSet);
begin
//
end;
procedure TTmaxProvider.LogUpdateError(DeltaData: TPacketDataSet; E: EDatabaseError;
Response: TResolverResponse);
begin
//
end;
procedure TTmaxProvider.Notification(AComponent: TComponent; Operation: TOperation);
begin
//
end;
function TTmaxProvider.PackageRecords(Count: Integer): Integer;
begin
//
end;
procedure TTmaxProvider.SetServer(Value: TTmaxConnection);
begin
//
end;
function TTmaxProvider.GetRPCFunction(Index : integer) : TRPCFunction;
begin
// Result := FRPCFunction[Index];
end;
procedure TTmaxProvider.SetRPCFunction(Index : Integer; Value : TRPCFunction);
begin
// if FRPCFunction[Index] <> Value then
// FRPCFunction[Index] := Value;
// FGetRPCFunction.Assign(Value);
end;
{TTmaxProvider End}
end.