{****************************************************************** JEDI-VCL Demo Copyright (C) 2002 Project JEDI Original author: Contributor(s): You may retrieve the latest version of this file at the JEDI-JVCL home page, located at http://jvcl.sourceforge.net The contents of this file are used with permission, subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/MPL-1_1Final.html Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. ******************************************************************} unit JvPasImportForm; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls, ExtCtrls, JvFormPlacement, JvComponentBase, JvAppStorage, JvAppIniStorage; type TJvPasImport = class(TForm) eSource: TEdit; bSource: TButton; Label1: TLabel; eDestination: TEdit; Label2: TLabel; bDestination: TButton; bImport: TButton; OpenDialog: TOpenDialog; SaveDialog: TSaveDialog; ProgressBar1: TProgressBar; Label3: TLabel; lbClasses: TListBox; bReadClasses: TButton; bParams: TButton; bAddToReg: TButton; Label4: TLabel; cbClasses: TCheckBox; cbFunctions: TCheckBox; cbConstants: TCheckBox; cbDirectCall: TCheckBox; AppStorage: TJvAppIniFileStorage; JvFormStorage1: TJvFormStorage; procedure bSourceClick(Sender: TObject); procedure bDestinationClick(Sender: TObject); procedure bImportClick(Sender: TObject); procedure FormShow(Sender: TObject); procedure eSourceChange(Sender: TObject); procedure FormCreate(Sender: TObject); procedure bParamsClick(Sender: TObject); procedure bAddToRegClick(Sender: TObject); public end; var PasImport: TJvPasImport; implementation uses JvJCLUtils, JvHLParser, JvInterpreter, JvDebugForm, JvRegClassesForm; {$R *.dfm} procedure TJvPasImport.bSourceClick(Sender: TObject); var S: string; begin OpenDialog.FileName := eSource.Text; if OpenDialog.Execute then begin eSource.Text := OpenDialog.FileName; S := ExtractFileName(eSource.Text); if ANSIStrLIComp(PChar(S), 'I_', 2) = 0 then Delete(S, 1, 2); eDestination.Text := ExtractFilePath(eDestination.Text) + 'JvInterpreter_' + S; end; end; procedure TJvPasImport.bDestinationClick(Sender: TObject); begin SaveDialog.FileName := eDestination.Text; if SaveDialog.Execute then eDestination.Text := SaveDialog.FileName; end; procedure TJvPasImport.bImportClick(Sender: TObject); var i: Integer; P: Integer; Token: string; Parser: TJvIParser; S: string; Output: TStringList; Params: TStringList; ClassName: string; Adapter: TStringList; AdapterNames: TStringList; RClasses: TStrings; Year, Month, Day: Word; Name: string; { for all } Typ: string; { for functions and properties } IndexTyp: string; { for properties } IndexDefault: Boolean; { default indexed property } PropRead, PropWrite: Boolean; { for properties } Decl: string; Roll: Integer; DirectCall: Boolean; const SetArgs = '(const Value: Variant; Args: TJvInterpreterArgs)'; GetArgs = '(var Value: Variant; Args: TJvInterpreterArgs)'; function CT(S: string): Boolean; begin Result := Cmp(Token, S); end; procedure Add(S: string); begin Output.Add(S); if DebugLog.cbDebug.Checked then DebugLog.memDebug.Lines.Add(S); end; function NextToken: string; begin Token := Parser.Token; if (Token = '') or CT('implementation') then Abort; P := Parser.Pos; if P mod 100 = 0 then try ProgressBar1.Position := Parser.Pos; except end; Result := Token; if Roll = 0 then begin if (Token[1] in [';', ':', ',', '(', ')']) or (Length(Decl) > 0) and (Decl[Length(Decl)] = '(') then Decl := Decl + Token else Decl := Decl + ' ' + Token; end else Dec(Roll); end; procedure RollBack(Count: Integer); begin Parser.RollBack(Count); Roll := Count; end; procedure DeleteAdapterLastLine; begin if (Adapter.Count > 0) and (Adapter[Adapter.Count - 1] = '') then Adapter.Delete(Adapter.Count - 1); end; function UnitNameStr: string; begin Result := ChangeFileExt(ExtractFileName(eSource.Text), ''); if ANSIStrLIComp(PChar(Result), 'I_', 2) = 0 then Delete(Result, 1, 2); end; procedure NextPublicSection; begin while True do begin if CT('end') then Abort; if CT('public') then Break; NextToken; end; { while } end; procedure ReadParams; var VarParam: Boolean; ParamType: string; i, iBeg: Integer; begin while True do begin VarParam := False; NextToken; if Token = ')' then Break; if CT('var') then begin VarParam := True; NextToken; end; if CT('const') then NextToken; iBeg := Params.Count; while True do begin if Token = ';' then Break; if Token = ')' then Exit; if Token = ':' then begin ParamType := NextToken; while True do begin if Token[1] in [')', ';'] then begin RollBack(1); Break; end; NextToken; end; Break; end; if Token <> ',' then begin // Params.Add(Token + '|' + IntToStr(Integer(VarParam))); if VarParam then Params.Add('var ' + Token) else Params.Add(Token); end; NextToken; end; for i := iBeg to Params.Count - 1 do begin Params[i] := Params[i] + ': ' + ParamType; end; end; end; function ParamStr: string; var i: Integer; begin Result := ''; if Params.Count = 0 then Exit; Result := '('; for i := 0 to Params.Count - 1 do begin // Result := Result + SubStr(Params[i], 0, '|'); if Result <> '(' then Result := Result + '; '; Result := Result + Params[i] end; Result := Result + ')'; end; function TypStr(const Typ: string; const RetEmty: Boolean): string; begin if Cmp(Typ, 'TObject') or (RClasses.IndexOf(Typ) > -1) then Result := 'varObject' else if Cmp(Typ, 'Integer') or Cmp(Typ, 'TColor') then Result := 'varInteger' else if Cmp(Typ, 'Pointer') then Result := 'varPointer' else if Cmp(Typ, 'Word') then Result := 'varSmallint' else if Cmp(Typ, 'Boolean') then Result := 'varBoolean' else if Cmp(Typ, 'String') then Result := 'varString' else if Cmp(Typ, 'Double') then Result := 'varDouble' else if RetEmty then Result := 'varEmpty' else Result := Typ; end; function ParamTypStr: string; var i: Integer; begin if Params.Count = 0 then begin Result := '[varEmpty]'; Exit; end; Result := '['; for i := 0 to Params.Count - 1 do begin // Result := Result + SubStr(Params[i], 0, '|'); if Result <> '[' then Result := Result + ', '; Result := Result + TypStr(Trim(SubStrBySeparator(Params[i], 1, ':')), True); if SubStrBySeparator(Params[i], 0, ' ') = 'var' then Result := Result + ' or varByRef'; end; Result := Result + ']'; end; procedure ReadFun; begin Name := NextToken; NextToken; Params.Clear; if Token = '(' then begin ReadParams; NextToken; end; if Token = ':' then begin Typ := NextToken; NextToken; { Decl := Decl + ';'} end; end; function ReadProp: Boolean; begin Result := False; Name := NextToken; if (Length(Name) > 2) and (Name[1] = 'O') and (Name[2] = 'n') and (Name[3] in ['A'..'Z']) then { Skip Event Handlers } Exit; NextToken; Params.Clear; PropRead := False; PropWrite := False; IndexTyp := ''; IndexDefault := False; if Token = ';' then begin { we must reading property info from ancestor } { not implemented } Exit; end; if Token <> ':' then begin if Token <> '[' then { something going wrong } Exit; { indexed property } NextToken; if NextToken <> ':' then { more than one index - not implemented } Exit; IndexTyp := NextToken; if NextToken <> ']' then { something going wrong } Exit; NextToken; end; Typ := NextToken; while True do begin NextToken; if Token = ';' then begin NextToken; if CT('default') then IndexDefault := True else RollBack(1); Break; end; if CT('read') then PropRead := True; if CT('write') then PropWrite := True; end; Result := True; end; function V2Param(S: string; ParamType: string): string; begin Result := S; if Cmp(ParamType, 'TObject') then Result := 'V2O(' + Result + ')' else if lbClasses.Items.IndexOf(ParamType) > -1 then Result := 'V2O(' + Result + ') as ' + ParamType else if RClasses.IndexOf(ParamType) > -1 then Result := 'V2O(' + Result + ') as ' + ParamType else if Cmp(ParamType, 'PChar') then Result := 'PChar(string(' + Result + '))' else if Cmp(ParamType, 'Char') then Result := 'string(' + Result + ')[1]' else if Cmp(ParamType, 'Pointer') then Result := 'V2P(' + Result + ')' end; function Result2V(S: string): string; var ParamType: string; begin Result := S; ParamType := Trim(Typ); if Cmp(ParamType, 'TObject') then Result := 'O2V(' + S + ')' else if lbClasses.Items.IndexOf(ParamType) > -1 then Result := 'O2V(' + S + ')' else if RClasses.IndexOf(ParamType) > -1 then Result := 'O2V(' + Result + ')' else if Cmp(ParamType, 'PChar') then Result := 'string(' + S + ')' else if Cmp(ParamType, 'Pointer') then Result := 'P2V(' + S + ')' end; function ResVar: string; var ParamType: string; VType: Integer; begin ParamType := Trim(Typ); VType := TypeName2VarTyp(ParamType); case VType of varInteger: Result := 'varInteger'; varSmallInt: Result := 'varSmallInt'; varBoolean: Result := 'varBoolean'; varDouble: Result := 'varDouble'; varString: Result := 'varString'; varDate: Result := 'varDate'; else if (VType = varObject) or (lbClasses.Items.IndexOf(ParamType) > -1) or (RClasses.IndexOf(ParamType) > -1) then Result := 'varObject' else Result := 'varEmpty'; end; end; function ConvertParams: string; var i: Integer; function VarCast(S: string): string; var Typ: string; begin Result := S; if SubStrBySeparator(Params[i], 0, ' ') <> 'var' then Exit; Typ := Trim(SubStrBySeparator(Params[i], 1, ':')); if Cmp(Typ, 'integer') then Result := 'TVarData(' + Result + ').VInteger' else if Cmp(Typ, 'smallint') then Result := 'TVarData(' + Result + ').VSmallint' else if Cmp(Typ, 'byte') then Result := 'TVarData(' + Result + ').VByte' else if Cmp(Typ, 'word') then Result := 'Word(TVarData(' + Result + ').VSmallint)' else if Cmp(Typ, 'string') then Result := 'string(TVarData(' + Result + ').VString)' else if Cmp(Typ, 'pointer') then Result := 'TVarData(' + Result + ').VPointer' else if Cmp(Typ, 'double') then Result := 'TVarData(' + Result + ').VDouble' else if Cmp(Typ, 'boolean') then Result := 'TVarData(' + Result + ').VBoolean' else if Cmp(Typ, 'currency') then Result := 'TVarData(' + Result + ').VCurrency' end; begin Result := ''; if Params.Count = 0 then Exit; Result := '('; for i := 0 to Params.Count - 1 do begin if Result <> '(' then Result := Result + ', '; Result := Result + VarCast(V2Param('Args.Values[' + IntToStr(i) + ']', Trim(SubStrBySeparator(Params[i], 1, ':')))); end; Result := Result + ')'; end; procedure AddCons; begin ReadFun; Add(''); Add('{ constructor ' + Name + ParamStr + ' }'); Add(''); Add('procedure ' + ClassName + '_' + Name + GetArgs + ';'); Add('begin'); Add(' Value := O2V(' + ClassName + '.' + Name + ConvertParams + ');'); Add('end;'); Adapter.Add(' AddGet(' + ClassName + ', ''' + Name + ''', ' + ClassName + '_' + Name + ', ' + IntToStr(Params.Count) + ', ' + ParamTypStr + ', ' + ResVar + ');'); end; procedure AddFun; var PS, TS: string; begin ReadFun; PS := ParamTypStr; TS := TypStr(Typ, True); if DirectCall and (Pos('varEmpty', PS) = 0) then { direct call } begin Adapter.Add(' { ' + Decl + ' }'); Adapter.Add(' AddDGet(' + ClassName + ', ''' + Name + ''', ' + '@' + ClassName + '.' + Name + ', ' + IntToStr(Params.Count) + ', ' + ParamTypStr + ', ' + TS + ', ' + ResVar + ', [ccFastCall]);'); end else begin Add(''); Add('{ ' + Decl + ' }'); Add(''); Add('procedure ' + ClassName + '_' + Name + GetArgs + ';'); Add('begin'); Add(' Value := ' + Result2V(ClassName + '(Args.Obj).' + Name + ConvertParams) + ';'); Add('end;'); Adapter.Add(' AddGet(' + ClassName + ', ''' + Name + ''', ' + ClassName + '_' + Name + ', ' + IntToStr(Params.Count) + ', ' + ParamTypStr + ', ' + ResVar + ');'); end; end; procedure AddProc; var PS: string; begin ReadFun; PS := ParamTypStr; if DirectCall and (Pos('varEmpty', PS) = 0) then { direct call } begin Adapter.Add(' { ' + Decl + ' }'); Adapter.Add(' AddDGet(' + ClassName + ', ''' + Name + ''', ' + '@' + ClassName + '.' + Name + ', ' + IntToStr(Params.Count) + ', ' + ParamTypStr + ', varEmpty, [ccFastCall]);'); end else begin Add(''); Add('{ ' + Decl + ' }'); Add(''); Add('procedure ' + ClassName + '_' + Name + GetArgs + ';'); Add('begin'); Add(' ' + ClassName + '(Args.Obj).' + Name + ConvertParams + ';'); Add('end;'); Adapter.Add(' AddGet(' + ClassName + ', ''' + Name + ''', ' + ClassName + '_' + Name + ', ' + IntToStr(Params.Count) + ', ' + ParamTypStr + ', ' + ResVar + ');'); end; end; procedure AddFun2; var S: string; begin ReadFun; Add(''); Add('{ ' + Decl + ' }'); Add(''); Add('procedure ' + 'JvInterpreter_' + Name + GetArgs + ';'); Add('begin'); Add(' Value := ' + Result2V(Name + ConvertParams) + ';'); Add('end;'); S := UnitNameStr; AdapterNames.Add(S); Adapter.Add(' AddFunction(c' + UnitNameStr + ', ''' + Name + ''', ' + 'JvInterpreter_' + Name + ', ' + IntToStr(Params.Count) + ', ' + ParamTypStr + ', ' + ResVar + ');'); end; procedure AddProc2; var S: string; begin ReadFun; Add(''); Add('{ ' + Decl + ' }'); Add(''); Add('procedure ' + 'JvInterpreter_' + Name + GetArgs + ';'); Add('begin'); Add(' ' + Name + ConvertParams + ';'); Add('end;'); S := UnitNameStr; AdapterNames.Add(S); Adapter.Add(' AddFunction(c' + S + ', ''' + Name + ''', ' + 'JvInterpreter_' + Name + ', ' + IntToStr(Params.Count) + ', ' + ParamTypStr + ', ' + ResVar + ');'); end; procedure AddProp; begin if ReadProp then begin if PropRead then if IndexTyp = '' then begin Add(''); Add('{ property Read ' + Name + ': ' + Typ + ' }'); Add(''); Add('procedure ' + ClassName + '_' + 'Read_' + Name + GetArgs + ';'); Add('begin'); Add(' Value := ' + Result2V(ClassName + '(Args.Obj).' + Name + ConvertParams) + ';'); Add('end;'); Adapter.Add(' AddGet(' + ClassName + ', ''' + Name + ''', ' + ClassName + '_' + 'Read_' + Name + ', 0, [varEmpty], ' + ResVar + ');'); end else begin Add(''); Add('{ property Read ' + Name + '[' + IndexTyp + ']: ' + Typ + ' }'); Add(''); Add('procedure ' + ClassName + '_' + 'Read_' + Name + GetArgs + ';'); Add('begin'); Add(' Value := ' + Result2V(ClassName + '(Args.Obj).' + Name + '[Args.Values[0]]' {+ ConvertParams}) + ';'); Add('end;'); Adapter.Add(' AddIGet(' + ClassName + ', ''' + Name + ''', ' + ClassName + '_' + 'Read_' + Name + ', 1, [varEmpty], ' + ResVar + ');'); if IndexDefault then Adapter.Add(' AddIDGet(' + ClassName + ', ' + ClassName + '_' + 'Read_' + Name + ', 1, [varEmpty], ' + ResVar + ');'); end; if PropWrite then if IndexTyp = '' then begin Add(''); Add('{ property Write ' + Name + '(Value: ' + Typ + ') }'); Add(''); Add('procedure ' + ClassName + '_' + 'Write_' + Name + SetArgs + ';'); Add('begin'); Add(' ' + ClassName + '(Args.Obj).' + Name + ConvertParams + ' := ' + V2Param('Value', Typ) + ';'); Add('end;'); Adapter.Add(' AddSet(' + ClassName + ', ''' + Name + ''', ' + ClassName + '_' + 'Write_' + Name + ', 0, [' + ResVar + ']);'); end else begin Add(''); Add('{ property Write ' + Name + '[' + IndexTyp + ']: ' + Typ + ' }'); Add(''); Add('procedure ' + ClassName + '_' + 'Write_' + Name + SetArgs + ';'); Add('begin'); Add(' ' + ClassName + '(Args.Obj).' + Name + '[Args.Values[0]]' { + ConvertParams} + ' := ' + V2Param('Value', Typ) + ';'); Add('end;'); Adapter.Add(' AddISet(' + ClassName + ', ''' + Name + ''', ' + ClassName + '_' + 'Write_' + Name + ', 0, [varNull]);'); if IndexDefault then Adapter.Add(' AddIDSet(' + ClassName + ', ' + ClassName + '_' + 'Write_' + Name + ', 0, [varNull]);'); end; end; end; procedure ReadSection; begin while True do begin if CT('function') then AddFun; if CT('procedure') then AddProc; if CT('constructor') then AddCons; if CT('property') then AddProp; if CT('end') or CT('private') or CT('protected') then Exit; Decl := ''; NextToken; end; end; procedure SkipClass; begin if Token = ';' then Exit; if Cmp(NextToken, 'of') then Exit; if Cmp(Token, 'end') then Exit; while not Cmp(NextToken, 'end') do if Token = '' then Exit; end; function ReadClass: Boolean; var S: string; begin Result := False; ClassName := Parser.History[3]; if Token = '(' then begin while True do begin NextToken; if Token = ')' then Break; end; NextToken; end; if Sender = bReadClasses then begin lbClasses.Items.Add(ClassName); Exit; end; if (lbClasses.Items.Count > 0) and not lbClasses.Selected[lbClasses.Items.IndexOf(ClassName)] then begin SkipClass; Exit; end; Add(''); Add('{ ' + ClassName + ' }'); DeleteAdapterLastLine; Adapter.Add(' { ' + ClassName + ' }'); S := UnitNameStr; AdapterNames.Add(S); Adapter.Add(' AddClass(c' + S + ', ' + ClassName + ', ' + '''' + ClassName + ''');'); if Token = ';' then Exit; Decl := Token; try while True do begin ReadSection; NextPublicSection; end; except on E: EAbort do ; else raise; end; Result := True; end; procedure ReadEnum(SetName: string); var En: string; S: string; begin Name := SetName; DeleteAdapterLastLine; Adapter.Add(' { ' + Name + ' }'); while True do begin En := NextToken; if not (NextToken[1] in [',', ')']) then Break; S := UnitNameStr; AdapterNames.Add(S); Adapter.Add(' AddConst(c' + S + ', ''' + En + ''', Ord(' + En + '));'); if Token = ')' then Break; end; Adapter.Add(''); end; begin Parser := TJvIParser.Create; Output := TStringList.Create; Params := TStringList.Create; Adapter := TStringList.Create; AdapterNames := TStringList.Create; AdapterNames.Sorted := True; AdapterNames.Duplicates := dupIgnore; if Sender = bReadClasses then lbClasses.Items.Clear; RClasses := RegClasses.memClasses.Lines; DirectCall := cbDirectCall.Checked; Output.Clear; DebugLog.memDebug.Lines.Clear; try S := LoadTextFile(eSource.Text); Parser.pcProgram := PChar(S); Parser.pcPos := Parser.pcProgram; if ProgressBar1.Max = 0 then try ProgressBar1.Max := Length(S); except end; ProgressBar1.Visible := True; if Sender = bImport then begin DecodeDate(Now, Year, Month, Day); Add('{-----------------------------------------------------------------------------'); Add('The contents of this file are subject to the Mozilla Public License'); Add('Version 1.1 (the "License"); you may not use this file except in compliance'); Add('with the License. You may obtain a copy of the License at'); Add('http://www.mozilla.org/MPL/MPL-1.1.html'); Add(''); Add('Software distributed under the License is distributed on an "AS IS" basis,'); Add('WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for'); Add('the specific language governing rights and limitations under the License.'); Add(''); Add('The Original Code is: ' + ExtractFileName(eDestination.Text) + Format(', generated on %.4d-%.2d-%.2d.', [Year, Month, Day])); Add(''); Add('The Initial Developer of the Original Code is: Andrei Prygounkov '); Add('Copyright (C) ' + Format('%.4d', [Year]) + ' Andrei Prygounkov.'); Add('All Rights Reserved.'); Add(''); Add('Contributor(s):'); Add(''); Add('Last Modified:'); Add(''); Add('You may retrieve the latest version of this file at the Project JEDI''s JVCL home page,'); Add('located at http://jvcl.sourceforge.net'); Add(''); Add('Description:'); Add(' adapter unit - converts JvInterpreter calls to Delphi calls'); Add(''); Add('Known Issues:'); Add(' if compiled with errors:'); Add(' - to convert variant to object use function V2O'); Add(' - to convert object to variant use function O2V'); Add(' - to convert variant to pointer use function V2P'); Add(' - to convert pointer to variant use function P2V'); Add(' - to convert set to variant use function S2V and'); Add(' typecasting such as:'); Add(' Value := S2V(Byte(TFont(Args.Obj).Style))'); Add(' - to convert variant to set use typecasting'); Add(' and function V2S such as:'); Add(' TFont(Args.Obj).Style := TFontStyles(Byte(V2S(Value))) '); Add(' depending on size of set (f.e. SizeOf(TFontStyles)),'); Add(' try to use Byte, Word or Integer types in typecasting'); Add(' - sets with more than 32 elements cannot be used in JvInterpreter'); Add('-----------------------------------------------------------------------------}'); Add(''); Add('unit ' + ChangeFileExt(ExtractFileName(eDestination.Text), ';')); Add(''); Add('interface'); Add(''); Add('uses'); Add(' JvInterpreter;'); Add(''); Add('procedure RegisterJvInterpreterAdapter(JvInterpreterAdapter: TJvInterpreterAdapter);'); Add(''); Add('implementation'); Add(''); Add('uses'); Add(' ' + ChangeFileExt(ExtractFileName(eSource.Text), '') + ';'); end; Roll := 0; NextToken; try while True do begin if CT('class') then begin if cbClasses.Checked or (Sender = bReadClasses) then begin NextToken; if (Token <> ';') and (Parser.History[2] = '=') and not CT('of') then ReadClass; end else SkipClass; end else if CT('interface') and (Parser.History[1] = '=') then SkipClass else if cbFunctions.Checked and (Sender = bImport) then begin Decl := Token; if CT('function') and (Parser.History[1] <> '=') and (Parser.History[1] <> ':') then begin AddFun2; // Abort; end else if CT('procedure') and (Parser.History[1] <> '=') and (Parser.History[1] <> ':') then begin AddProc2; // Abort; end; end else if cbConstants.Checked and (Sender = bImport) then begin if (Token = '(') and (Parser.History[1] = '=') then ReadEnum(Parser.History[2]) else if (Token = '(') and Cmp(Parser.History[1], 'of') and Cmp(Parser.History[2], 'set') and (Parser.History[3] = '=') then ReadEnum(Parser.History[4]); end; NextToken; end; except on E: EAbort do ; else raise; end; ProgressBar1.Max := ProgressBar1.Position; ProgressBar1.Position := 0; ProgressBar1.Visible := False; if Sender = bImport then begin DeleteAdapterLastLine; Adapter.Add(' end;'); Adapter.Add('end;'); Add(''); Output.Add('procedure RegisterJvInterpreterAdapter(JvInterpreterAdapter: TJvInterpreterAdapter);'); if AdapterNames.Count > 0 then begin Output.Add('const'); for I := 0 to AdapterNames.Count-1 do Output.Add(' c' + AdapterNames[I] + ' = ''' + AdapterNames[I] + ''';') end; Output.Add('begin'); Output.Add(' with JvInterpreterAdapter do'); Output.Add(' begin'); Output.AddStrings(Adapter); if DebugLog.cbDebug.Checked then DebugLog.memDebug.Lines.AddStrings(Adapter); Add(''); Add('end.'); if (not FileExists(eDestination.Text) or (MessageDlg('File ''' + eDestination.Text + ''' already exists. Overwrite ?', mtWarning, [mbYes, mbNo, mbCancel], 0) = mrYes)) then Output.SaveToFile(eDestination.Text); end; if Sender = bReadClasses then begin for i := lbClasses.Items.Count - 1 downto 0 do lbClasses.Selected[i] := True; end; finally Parser.Free; Params.Free; Adapter.Free; Output.Free; AdapterNames.Free; end; end; procedure TJvPasImport.FormShow(Sender: TObject); begin DebugLog.Show; end; procedure TJvPasImport.eSourceChange(Sender: TObject); begin ProgressBar1.Max := 0; lbClasses.Items.Clear; end; procedure TJvPasImport.FormCreate(Sender: TObject); begin eSourceChange(nil); AppStorage.FileName:=ChangeFileExt(paramstr(0),'.ini'); end; procedure TJvPasImport.bParamsClick(Sender: TObject); begin RegClasses.Show; end; procedure TJvPasImport.bAddToRegClick(Sender: TObject); var i: Integer; begin for i := 0 to lbClasses.Items.Count - 1 do if lbClasses.Selected[i] and (RegClasses.memClasses.Lines.IndexOf(lbClasses.Items[i]) = -1) then RegClasses.memClasses.Lines.Add(lbClasses.Items[i]); end; end.