聊點基本功,就是“如何在DLL中活用Interface”
<Code 1>
{-----------------------------------------------------------------------------
Unit: dmBaseModule
Author: Aleyn.wu
Date: 2002-05-12
Descript: Base Module Interface
-----------------------------------------------------------------------------}
unit dmBaseModule;
interface
uses
Classes, SysUtils, Variants, hmOleDataSet, hmOleVariant;
type
IBaseOle = interface;
IBaseService = interface
['{D40CB2CF-23FF-4C41-BB7E-C9FCD28AE7E7}']
//GetSqlLanguage 取得SQL语句
function GetSqlLanguage(Index: integer; var Params, Body: WideString): Boolean; stdcall;
//InTranstion 服务层是否已经为事务中
function InTranstion: WordBool; stdcall;
//GetInfo 取得服务层信息
function GetInfo: WideString; stdcall;
procedure ShowMessage(Msg: WideString); stdcall;
procedure OpenQuery(Sql: WideString); stdcall;
procedure CloseQuery; stdcall;
//Execute 让服务层执行SQL语句
procedure Execute(Sql: WideString); stdcall;
//GetFieldNames 取得某个表(Table)的所有栏位名称(FieldName)
procedure GetFieldNames(TableName: WideString; var FieldNames: WideString); stdcall;
//BeginTrans 服务层开始事务
procedure BeginTrans; stdcall;
//CommitTrans 服务层提交事务
procedure CommitTrans; stdcall;
//RollbackTrans 服务层事务回滚(取消事务)
procedure RollbackTrans; stdcall;
//ApplyUpdates 直接用Delta更新数据
procedure ApplyUpdates(const Delta: OleVariant; TableName, KeyField: WideString); stdcall;
//ApplyUpdatesWithOle 通知服务层 Delta已经在服务层的OleParam里,
// 名称为DeltaName 更新方式和ApplyUpdates一样
procedure ApplyUpdatesWithOle(const DeltaName, TableName, KeyField: WideString); stdcall;
//ApplyUpdatesRecordInfo
procedure ApplyUpdatesRecordInfo(const DeltaName, TableName, KeyField: WideString); stdcall;
//ApplyUpdatesWithOle 通知服务层 Delta已经在服务层的某一个DataSet里,
// 序号为DataSet 更新方式和ApplyUpdates一样
procedure ApplyUpdatesWithDataSet(const DataSet: integer; TableName, KeyField: WideString); stdcall;
//ReceiveDataWithDefault 通知服务层,数据已经准备好,在缺省的Query里,请直接返回给客户。
procedure ReceiveDataWithDefault; stdcall;
//ReceiveDataWithCustom 通知服务层,数据已经准备好,在OleParam里,请返回给客户。
procedure ReceiveDataWithCustom; stdcall;
//ReceiveDataWithResult 通知服务层,数据在DLL函数中定义,请返回给客户。
procedure ReceiveDataWithResult; stdcall;
//ReceiveDataWithNoData 通知服务层,DLL函数没有可返回的数据。
procedure ReceiveDataWithNoData; stdcall;
//RaiseError 通知服务层产生一个异常信息给客户
procedure RaiseError(Msg: WideString); stdcall;
//DropTable 通知服务层删除一个表格(实际上也是执行SQL删除表格语句)
procedure DropTable(TableName: WideString); stdcall;
//AssignQueryToDataSet 通知服务层 缺省的Query需要从其它DataSet取得数据
// DataSetIndex:DataSet的序号
// DataSetField:DataSet Field Name
// QueryField :Query FieldName
procedure AssignQueryToDataSet(DataSetIndex: integer; DataSetField, QueryField: WideString); stdcall;
//AssignQueryToDataSet 通知服务层 其它DataSet需要从缺省的Query取得数据
procedure AssignDataSetToQuery(DataSetIndex: integer; DataSetField, QueryField: WideString); stdcall;
//从服务层取得一个16位的惟一键字串
function UniKey: WideString; stdcall;
//取得服务层缺省Query的接口
function GetQuery: IHMOleADOQuery; stdcall;
//取得服务层其它ClientDataSet的接口
function GetDataSet(Index: integer): IHMOleClientDataSet; stdcall;
//取得服务层返回参数的接口(OLE格式)
function GetOle: IBaseOle; stdcall;
//取得服务层客户参数接口(OleVariant格式)
function GetParams: IHMOleVariant; stdcall;
//取务服务层刚刚执行的SQL语句所参生的记录总数
function GetRecordsAffected: integer; stdcall;
property RecordsAffected: integer read GetRecordsAffected;
property Query: IHMOleADOQuery read GetQuery;
property DataSet[index: integer]: IHMOleClientDataSet read GetDataSet;
property Ole: IBaseOle read GetOle;
property Params: IHMOleVariant read GetParams;
end;
IBaseDataModule = interface
['{0CEF4911-3E0C-4AC9-AAD7-69CA907E3979}']
//取得本规则模块的信息
function GetModuleInfo: WideString; stdcall;
//取得或设置服务层接口
function GetBaseService: IBaseService; stdcall;
procedure SetBaseService(const Value: IBaseService); stdcall;
//取得或设置本规则模块的序号
function GetModule(): integer; stdcall;
procedure SetModule(const value: integer); stdcall;
//服务层调用本规则的总入口
function Operation(var Data, Msg: OleVariant): WordBool; stdcall;
// LoadOleParam暂时不用
procedure LoadOleParam(const Param: OleVariant); stdcall;
property BaseService: IBaseService read GetBaseService write SetBaseService;
property Module: integer read GetModule write SetModule;
property ModuleInfo: WideString read GetModuleInfo;
end;
IDataModuleInfo = interface
['{B1B99EE8-E0B5-475C-9E21-92E6B416065E}']
function GetModuleName: WideString; stdcall;
function GetVersion: Widestring; stdcall;
function GetDesignner: Widestring; stdcall;
function GetMemo: Widestring; stdcall;
function GetLastUpdate: WideString; stdcall;
function GetModuleIndex: Integer; stdcall;
property ModuleIndex: Integer read GetModuleIndex;
end;
IBaseOle = interface
procedure AddDspAsName(Name: WideString); stdcall;
procedure Clear; stdcall;
function GetValue(Name: WideString): OleVariant; stdcall;
procedure SetValue(Name: WideString; Value: OleVariant); stdcall;
property Value[Name: WideString]: OleVariant read GetValue write SetValue;
end;
implementation
end.
<code 2>
unit dmBaseService;
interface
uses
Classes, Windows, SysUtils, Variants, dmBaseModule, hmUniKey, hmMemTools, DB,
hmSqlTools, hmOleDataSet, hmOleVariant, hmDateTools;
type
TReceiveDataType = (rdDefault, rdCustom, rdResult, rdNoData);
TServiceState = (srStart, srStop, srPause);
type
TSafeInterfacedObject = class(TObject, IUnknown)
protected
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: integer; stdcall;
function _Release: integer; stdcall;
end;
type
TBaseOle = class;
TBaseService = class(TSafeInterfacedObject, IBaseService)
private
FParent: TComponent;
FOle: TBaseOle;
FReceiveDataType: TReceiveDataType;
function GetReceiveDataType: TReceiveDataType;
protected
procedure InnerApplyUpdates(TableName, KeyField: WideString); stdcall;
procedure InnerApplyUpdates2(TableName, KeyField: WideString); stdcall;
public
constructor Create(AOwner: TComponent);
destructor Destroy; override;
procedure Reset;
function GetSqlLanguage(Index: integer; var Params, Body: WideString): Boolean; stdcall;
function InTranstion: WordBool; stdcall;
function GetInfo: WideString; stdcall;
procedure ShowMessage(Msg: WideString); stdcall;
procedure OpenQuery(Sql: WideString); stdcall;
procedure CloseQuery; stdcall;
procedure Execute(Sql: WideString); stdcall;
procedure GetFieldNames(TableName: WideString; var FieldNames: WideString); stdcall;
procedure BeginTrans; stdcall;
procedure CommitTrans; stdcall;
procedure RollbackTrans; stdcall;
procedure ApplyUpdates(const Delta: OleVariant; TableName, KeyField: WideString); stdcall;
procedure ApplyUpdatesWithOle(const DeltaName, TableName, KeyField: WideString); stdcall;
procedure ApplyUpdatesRecordInfo(const DeltaName, TableName, KeyField: WideString); stdcall;
procedure ApplyUpdatesWithDataSet(const DataSet: integer; TableName, KeyField: WideString); stdcall;
procedure ReceiveDataWithDefault; stdcall;
procedure ReceiveDataWithCustom; stdcall;
procedure ReceiveDataWithResult; stdcall;
procedure ReceiveDataWithNoData; stdcall;
procedure RaiseError(Msg: WideString); stdcall;
procedure DropTable(TableName: WideString); stdcall;
procedure AssignQueryToDataSet(DataSetIndex: integer; DataSetField, QueryField: WideString); stdcall;
procedure AssignDataSetToQuery(DataSetIndex: integer; DataSetField, QueryField: WideString); stdcall;
function UniKey: Widestring; stdcall;
function GetQuery: IHMOleADOQuery; stdcall;
function GetDataSet(Index: integer): IHMOleClientDataSet; stdcall;
function GetOle: IBaseOle; stdcall;
function GetParams: IHMOleVariant; stdcall;
function GetRecordsAffected: integer; stdcall;
property ReceiveDataType: TReceiveDataType read GetReceiveDataType;
end;
TBaseOle = class(TSafeInterfacedObject, IBaseOle)
private
FParent: TComponent;
protected
procedure AddDspAsName(Name: WideString); stdcall;
procedure Clear; stdcall;
function GetValue(Name: WideString): OleVariant; stdcall;
procedure SetValue(Name: WideString; Value: OleVariant); stdcall;
public
constructor Create(AOwner: TComponent);
end;
type
TCreateDataModule = function(const BaseService: IBaseService): IBaseDataModule; stdcall;
TCreateDataModuleInfo = function(): IDataModuleInfo; stdcall;
PModuleLibrary = ^TModuleLibrary;
TModuleLibrary = record
ModuleIndex: Integer;
LibHandle: THandle;
CreateDataModule: TCreateDataModule;
CreateDataModuleInfo: TCreateDataModuleInfo;
ModuleState: TServiceState;
FileName: pChar;
end;
implementation
uses DataServer_form, swModuleIndex;
{ TSafeInterfacedObject }
function TSafeInterfacedObject._AddRef: integer;
begin
Result := -1;
end;
function TSafeInterfacedObject._Release: integer;
begin
Result := -1;
end;
function TSafeInterfacedObject.QueryInterface(const IID: TGUID; out Obj): HResult;
const
E_NOINTERFACE = $80004002;
begin
if GetInterface(IID, Obj) then
Result := 0
else
Result := -1; {E_NOINTERFACE}
end;
{ TBaseService }
constructor TBaseService.Create(AOwner: TComponent);
begin
inherited Create;
FParent := AOwner;
FReceiveDataType := rdNoData;
FOle := TBaseOle.Create(AOwner);
end;
destructor TBaseService.Destroy;
begin
FOle.Free;
inherited;
end;
procedure TBaseService.BeginTrans;
begin
(FParent as TDataServer2).Connection.BeginTrans;
end;
procedure TBaseService.CloseQuery;
begin
(FParent as TDataServer2).Query.Close;
end;
procedure TBaseService.CommitTrans;
begin
(FParent as TDataServer2).Connection.CommitTrans;
end;
procedure TBaseService.Execute(Sql: WideString);
begin
//(FParent as TDataServer2).Cmd.CommandText := Sql;
(FParent as TDataServer2).Cmd.Execute(Sql);
end;
procedure TBaseService.GetFieldNames(TableName: WideString;
var FieldNames: WideString);
var
FieldList: TStringList;
begin
FieldList := TStringList.Create;
(FParent as TDataServer2).Connection.GetFieldNames(TableName, FieldList);
FieldNames := FieldList.Text;
FieldList.Free;
end;
function TBaseService.GetInfo: WideString;
begin
Result := 'ClassName:' + (FParent as TDataServer2).ClassName + ';ComponentName:' + (FParent as TDataServer2).Name;
end;
function TBaseService.GetSqlLanguage(Index: integer; var Params,
Body: WideString): Boolean;
begin
with (FParent as TDataServer2) do
begin
SqlLang.Close;
SqlLang.SQL.Text := 'Select * from Func..sqlClient where sq_StoreKey=' + inttostr(Index);
SqlLang.Open;
if (SqlLang.Active) and (SqlLang.RecordCount > 0) then
begin
Params := SqlLang['sq_Param'];
Body := SqlLang['sq_Body'];
Result := True;
end
else
Result := False;
end;
end;
function TBaseService.InTranstion: WordBool;
begin
Result := (FParent as TDataServer2).Connection.InTransaction;
end;
procedure TBaseService.OpenQuery(Sql: WideString);
begin
with (FParent as TDataServer2) do
begin
Query.Close;
Query.SQL.Text := Sql;
end; // with
end;
procedure TBaseService.RaiseError(Msg: WideString);
begin
raise Exception.Create(Msg);
end;
procedure TBaseService.ReceiveDataWithCustom;
begin
FReceiveDataType := rdCustom;
end;
procedure TBaseService.ReceiveDataWithDefault;
begin
FReceiveDataType := rdDefault;
end;
procedure TBaseService.ReceiveDataWithResult;
begin
FReceiveDataType := rdResult;
end;
procedure TBaseService.RollbackTrans;
begin
(FParent as TDataServer2).Connection.RollbackTrans;
end;
procedure TBaseService.ShowMessage(Msg: WideString);
begin
//(FParent as TDataServer2).Memo1.Lines.Add(Msg);
end;
function TBaseService.GetReceiveDataType: TReceiveDataType;
begin
Result := FReceiveDataType;
end;
procedure TBaseService.Reset;
begin
FReceiveDataType := rdNoData;
end;
function TBaseService.GetQuery: IHMOleADOQuery;
begin
Result := (FParent as TDataServer2).Query.IDataSet;
end;
procedure TBaseService.ReceiveDataWithNoData;
begin
FReceiveDataType := rdNoData;
end;
function TBaseService.UniKey: Widestring;
begin
Result := hmUniKey.UniKey((FParent as TDataServer2).UKI);
end;
function TBaseService.GetRecordsAffected: integer;
begin
Result := (FParent as TDataServer2).Cmd.RecordsAffected;
end;
procedure TBaseService.DropTable(TableName: WideString);
begin
(FParent as TDataServer2).Cmd.Execute('Drop Table ' + TableName);
end;
procedure TBaseService.AssignQueryToDataSet(DataSetIndex: integer; DataSetField, QueryField: WideString); stdcall;
begin
with (FParent as TDataServer2) do
case DataSetIndex of //
0: Pub1[DataSetField] := Query[QueryField];
1: Pub2[DataSetField] := Query[QueryField];
2: Pub3[DataSetField] := Query[QueryField];
else
raise Exception.Create('(GetDataSet)Pub DataSet Out Bound');
end; // case
end;
procedure TBaseService.AssignDataSetToQuery(DataSetIndex: integer; DataSetField, QueryField: WideString); stdcall;
begin
with (FParent as TDataServer2) do
case DataSetIndex of //
0: Query[QueryField] := Pub1[DataSetField];
1: Query[QueryField] := Pub2[DataSetField];
2: Query[QueryField] := Pub3[DataSetField];
else
raise Exception.Create('(GetDataSet)Pub DataSet Out Bound');
end; // case
end;
function TBaseService.GetOle: IBaseOle;
begin
Result := FOle;
end;
procedure TBaseService.ApplyUpdatesWithOle(const DeltaName, TableName, KeyField: WideString);
var
Flag: boolean;
begin
with (FParent as TDataServer2) do
begin
if VarIsNull(OleParams[DeltaName]) then exit;
cdsDelta.Close;
cdsDelta.Data := OleParams[DeltaName];
Flag := cdsDelta.FindField('SYS_STATUS') <> nil;
end; // with
if Flag then
InnerApplyUpdates2(TableName, KeyField)
else
InnerApplyUpdates(TableName, KeyField);
end;
procedure TBaseService.ApplyUpdates(const Delta: OleVariant; TableName, KeyField: WideString);
var
Flag: Boolean;
begin
if VarIsNull(Delta) then exit;
with (FParent as TDataServer2) do
begin
cdsDelta.Close;
cdsDelta.Data := Delta;
Flag := cdsDelta.FindField('SYS_STATUS') <> nil;
end; // with
if Flag then
InnerApplyUpdates2(TableName, KeyField)
else
InnerApplyUpdates(TableName, KeyField);
end;
function TBaseService.GetDataSet(Index: integer): IHMOleClientDataSet;
begin
with (FParent as TDataServer2) do
case Index of //
0: Result := Pub1.IDataSet;
1: Result := Pub2.IDataSet;
2: Result := Pub3.IDataSet;
else
raise Exception.Create('(GetDataSet)Pub DataSet Out Bound');
end; // case
end;
function TBaseService.GetParams: IHMOleVariant;
begin
Result := (FParent as TDataServer2).OleParams;
end;
procedure TBaseService.InnerApplyUpdates(TableName, KeyField: WideString);
var
i: integer;
s1, s2: string;
CmdStr: string;
FieldList: TStringList;
begin
with (FParent as TDataServer2) do
begin
FieldList := TStringList.Create;
Connection.GetFieldNames(TableName, FieldList);
if not cdsDelta.Active then cdsDelta.Open;
for i := 1 to FieldList.Count do
if cdsDelta.FindField(FieldList[i - 1]) <> nil then
cdsDelta.FindField(FieldList[i - 1]).Tag := 1;
FieldList.Free;
if cdsDelta.RecordCount > 0 then
begin
cdsDelta.First;
s1 := '';
s2 := '';
while not cdsDelta.Eof do
begin
CmdStr := '';
case cdsDelta.UpdateStatus of
usUnmodified:
begin
s2 := VarToSql(cdsDelta[KeyField]);
end;
usModified:
begin
s1 := '';
for i := 1 to cdsDelta.FieldCount do
if (not cdsDelta.Fields[i - 1].IsNull) and (cdsDelta.Fields[i - 1].Tag = 1) then
begin
if s1 = '' then
s1 := Trim(cdsDelta.Fields[i - 1].FieldName) + ' = ' + VarToSql(cdsDelta.Fields[i - 1].Value)
else
s1 := s1 + ',' + Trim(cdsDelta.Fields[i - 1].FieldName) + ' = ' + VarToSql(cdsDelta.Fields[i - 1].Value);
end;
if s1 <> '' then
begin
CmdStr := 'Update ' + TableName + ' Set ' + s1 + ' Where ' + KeyField + ' = ' + s2;
end;
end;
usInserted:
begin
s1 := '';
s2 := '';
for i := 1 to cdsDelta.FieldCount do
if (not cdsDelta.Fields[i - 1].IsNull) and (cdsDelta.Fields[i - 1].Tag = 1) then
begin
if s1 = '' then
begin
s1 := Trim(cdsDelta.Fields[i - 1].FieldName);
s2 := VarToSql(cdsDelta.Fields[i - 1].Value);
end
else
begin
s1 := s1 + ',' + Trim(cdsDelta.Fields[i - 1].FieldName);
s2 := s2 + ',' + VarToSql(cdsDelta.Fields[i - 1].Value);
end;
end;
if s1 <> '' then
begin
CmdStr := 'Insert into ' + TableName + '(' + s1 + ') Values (' + s2 + ')';
end;
end;
usDeleted:
begin
s2 := VarToSql(cdsDelta[KeyField]);
CmdStr := 'Delete ' + TableName + ' Where ' + KeyField + ' = ' + s2;
end;
end;
if CmdStr <> '' then Cmd.Execute(CmdStr);
cdsDelta.Next;
end;
cdsDelta.First;
cdsDelta.EmptyDataSet;
cdsDelta.Close;
end;
end;
end;
procedure TBaseService.ApplyUpdatesWithDataSet(const DataSet: integer; TableName, KeyField: WideString);
var
Flag: boolean;
begin
with (FParent as TDataServer2) do
begin
cdsDelta.Close;
case DataSet of //
0: cdsDelta.Data := Pub1.Data;
1: cdsDelta.Data := Pub2.Data;
2: cdsDelta.Data := Pub3.Data;
else
raise Exception.Create('(ApplyUpdatesWithDataSet) Out of DataSet Index')
end; // case
Flag := cdsDelta.FindField('SYS_STATUS') <> nil;
end; // with
if Flag then
InnerApplyUpdates2(TableName, KeyField)
else
InnerApplyUpdates(TableName, KeyField);
end;
procedure TBaseService.ApplyUpdatesRecordInfo(const DeltaName, TableName, KeyField: WideString);
var
s1, s2: string;
CmdStr: string;
Flag: Boolean;
UpdateStatus: TUpdateStatus;
begin
with (FParent as TDataServer2) do
begin
if VarIsNull(OleParams[DeltaName]) then exit;
cdsDelta.Close;
cdsDelta.Data := OleParams[DeltaName];
cdsDelta.Open;
if cdsDelta.RecordCount > 0 then
begin
cdsDelta.First;
s1 := '';
s2 := '';
Flag := cdsDelta.FindField('SYS_STATUS') <> nil;
while not cdsDelta.Eof do
begin
CmdStr := '';
if Flag then
UpdateStatus := cdsDelta.UpdateStatus
else
UpdateStatus := TUpdateStatus(cdsDelta.IV['SYS_STATUS']);
case UpdateStatus of
usUnmodified:
begin
s2 := VarToSql(cdsDelta[KeyField]);
end;
usModified:
begin
if Flag then s2 := VarToSql(cdsDelta[KeyField]);
s1 := 'ri_ModifyPsn = ' + VarToSql(OleParams['UserID']);
s1 := s1 + ', ri_ModifyDate = ' + ToSqlStr(DateToStr(Today));
CmdStr := 'Update dlgRecordInfo Set ' + s1 + ' Where ri_UniKey = ' + s2;
end;
usInserted:
begin
s1 := 'ri_UniKey';
s1 := s1 + ', ri_TableName';
s1 := s1 + ', ri_CreatePsn ';
s1 := s1 + ', ri_CreateDate ';
s1 := s1 + ', ri_ModifyPsn ';
s1 := s1 + ', ri_ModifyDate ';
s2 := VarToSql(cdsDelta[KeyField]);
s2 := s2 + ',' + VarToSql(Uppercase(TableName));
s2 := s2 + ',' + VarToSql(OleParams['UserID']);
s2 := s2 + ',' + ToSqlStr(DateToStr(Today));
s2 := s2 + ',' + VarToSql(OleParams['UserID']);
s2 := s2 + ',' + ToSqlStr(DateToStr(Today));
CmdStr := 'Insert into dlgRecordInfo (' + s1 + ') Values (' + s2 + ')';
end;
usDeleted:
begin
s1 := 'ri_DeletePsn = ' + VarToSql(OleParams['UserID']);
s1 := s1 + ', ri_DeleteDate = ' + ToSqlStr(DateToStr(Today));
s1 := s1 + ', ri_Deleted = 1';
s2 := VarToSql(cdsDelta[KeyField]);
CmdStr := 'Update dlgRecordInfo Set ' + s1 + ' Where ri_UniKey = ' + s2;
end;
end;
if CmdStr <> '' then Cmd.Execute(CmdStr);
cdsDelta.Next;
end;
cdsDelta.First;
cdsDelta.EmptyDataSet;
cdsDelta.Close;
end;
end;
end;
procedure TBaseService.InnerApplyUpdates2(TableName, KeyField: WideString);
var
i: integer;
s1, s2: string;
CmdStr: string;
FieldList: TStringList;
UpdateStatus: integer;
begin
with (FParent as TDataServer2) do
begin
FieldList := TStringList.Create;
Connection.GetFieldNames(TableName, FieldList);
if not cdsDelta.Active then cdsDelta.Open;
for i := 1 to FieldList.Count do
if cdsDelta.FindField(FieldList[i - 1]) <> nil then
cdsDelta.FindField(FieldList[i - 1]).Tag := 1;
FieldList.Free;
if cdsDelta.RecordCount > 0 then
begin
cdsDelta.First;
s1 := '';
s2 := '';
while not cdsDelta.Eof do
begin
CmdStr := '';
UpdateStatus := cdsDelta.IV['SYS_STATUS'];
case TUpdateStatus(UpdateStatus) of
usUnmodified, usModified:
begin
s1 := '';
s2 := VarToSql(cdsDelta[KeyField]);
for i := 1 to cdsDelta.FieldCount do
if cdsDelta.Fields[i - 1].CanModify and (cdsDelta.Fields[i - 1].Tag = 1) and (UpperCase(cdsDelta.Fields[i - 1].FieldName) <> Uppercase(KeyField)) then
begin
if s1 = '' then
s1 := Trim(cdsDelta.Fields[i - 1].FieldName) + ' = ' + VarToSql(cdsDelta.Fields[i - 1].Value)
else
s1 := s1 + ',' + Trim(cdsDelta.Fields[i - 1].FieldName) + ' = ' + VarToSql(cdsDelta.Fields[i - 1].Value);
end;
if s1 <> '' then
begin
CmdStr := 'Update ' + TableName + ' Set ' + s1 + ' Where ' + KeyField + ' = ' + s2;
end;
end;
usInserted:
begin
s1 := '';
s2 := '';
for i := 1 to cdsDelta.FieldCount do
if (not cdsDelta.Fields[i - 1].IsNull) and (cdsDelta.Fields[i - 1].Tag = 1) then
begin
if s1 = '' then
begin
s1 := Trim(cdsDelta.Fields[i - 1].FieldName);
s2 := VarToSql(cdsDelta.Fields[i - 1].Value);
end
else
begin
s1 := s1 + ',' + Trim(cdsDelta.Fields[i - 1].FieldName);
s2 := s2 + ',' + VarToSql(cdsDelta.Fields[i - 1].Value);
end;
end;
if s1 <> '' then
begin
CmdStr := 'Insert into ' + TableName + '(' + s1 + ') Values (' + s2 + ')';
end;
end;
usDeleted:
begin
s2 := VarToSql(cdsDelta[KeyField]);
CmdStr := 'Delete ' + TableName + ' Where ' + KeyField + ' = ' + s2;
end;
end;
if CmdStr <> '' then Cmd.Execute(CmdStr);
cdsDelta.Next;
end;
cdsDelta.First;
cdsDelta.EmptyDataSet;
cdsDelta.Close;
end;
end;
end;
{ TBaseOle }
constructor TBaseOle.Create(AOwner: TComponent);
begin
inherited Create;
FParent := AOwner;
end;
procedure TBaseOle.AddDspAsName(Name: WideString);
begin
(FParent as TDataServer2).Ole[Name] := (FParent as TDataServer2).dspTest.Data;
end;
procedure TBaseOle.Clear;
begin
(FParent as TDataServer2).Ole.Clear;
end;
function TBaseOle.GetValue(Name: WideString): OleVariant;
begin
Result := (FParent as TDataServer2).Ole[Name];
end;
procedure TBaseOle.SetValue(Name: WideString; Value: OleVariant);
begin
(FParent as TDataServer2).Ole[Name] := Value;
end;
end.
2004-05-21 14:55:23 煙灰缸(2282902)
我想了想,今天還是和大家聊點基本功,就是“如何在DLL中活用Interface”
2004-05-21 14:56:40 黑夜(13633497)
問一個更基本的問題:
三層分工之前要先定義好接口函數嗎?比如說函數名,參數什麼的
2004-05-21 14:57:24 煙灰缸(2282902)
TO黑夜,今天講完這個,明天就講你那個如何?
2004-05-21 14:58:00 黑夜(13633497)
明天週末不上網啊
2004-05-21 14:58:54 黑夜(13633497)
其實回答可以很簡單,是或不是啊,