After I added too many user defined values to my application, I had to develop something like below. And now, it is getting complex. I do not want to keep developing this tool. At least, I would like to compare my tool's properties to other solutions.
So, I wonder if there is a generic solution for this kind of job. I googled but I do not know right keywords for this approach (I use Delphi 6. I can read C++ and C#).
My goal is,
- Avoid coding user defined parameter definition
- Avoid coding user defined parameter user interface and coding business rule
- In code, accessing parameter as if strictly defined (not like this:
GetParameter('parameter_name_str')
) - In code, accessing parameter without type casting from a generic type
--
Okay, I wrote a tool program. By using it, one can produce xml files like this:
<?xml version="1.0"?>
<parameters>
<parameter id="PrinterEnable">
<description>Select yes to use printer.</description>
<group>Printer Settings</group>
<title>Enable Your Printer</title>
<type>boolean</type>
</parameter>
<parameter id="PrinterConnection">
<description>You can refer to your printer's manuel to select correct cable.</description>
<group>Printer Settings</group>
<title>How to connect your printer</title>
<type>list</type>
<items>
<item value="1">Usb</item>
<item value="2">Serial</item>
<item value="3">Parallel</item>
</items>
</parameter>
<parameter id="PrinterWidth">
<description>Enter width of paper to use in millimeters</description>
<group>Printer Settings</group>
<title>Paper Width</title>
<type>integer</type>
<default>25</default>
<min>20</min>
<max>200</max>
</parameter>
</parameters>
Then, same tool, automatically creates two files: A Delphi rc file includes a referance to above xml file and (after ask me a few question like class name, unit name) another Delphi pas unit file like this below :
unit AppParameters;
interface
uses
libParameters3;
type
TAppParameters =class(TParameters3)
private
FFileName :string;
public
constructor Create;
procedure Load;
procedure Save;
function PrinterEnable: Boolean;
function PrinterConnection: Integer;
function PrinterWidth: Integer;
end;
implementation
uses
Classes, Forms, SysUtils, Windows;
{ AppParameters }
constructor TAppParameters.Create;
var
AStream :TResourceStream;
begin
AStream :=TResourceStream.Create(HInstance, 'APP_PARAMETERS', RT_RCDATA);
try
inherited LoadDefFromStream(AStream);
finally
AStream.Free;
end;
FFileName :=ChangeFileExt(Application.ExeName, '.ini');
end;
procedure TAppParameters.Load;
var
AFileStream :TFileStream;
begin
AFileStream :=TFileStream.Create(FFileName, fmOpenRead or fmShareDenyWrite);
try
LoadValFromStream(AFileStream);
finally
AFileStream.Free;
end;
end;
procedure TAppParameters.Save;
var
AFileStream :TFileStream;
begin
AFileStream :=TFileStream.Create(FFileName, fmCreate or fmShareDenyWrite);
try
SaveValToStream(AFileStream);
finally
AFileStream.Free;
end;
end;
function TAppParameters.PrinterEnable: Boolean;
begin
Result :=GetParameter('PrinterEnable').AsBoolean;
end;
function TAppParameters.PrinterConnection: Integer;
begin
Result :=GetParameter('PrinterConnection').AsInteger;
end;
function TAppParameters.PrinterWidth: Integer;
begin
Result :=GetParameter('PrinterWidth').AsInteger;
end;
end.
After all, in Delphi on my real code, I can use it like this below:
procedure TForm1.FormCreate(Sender: TObject);
var
AWidth :integer;
begin
FAppParameters :=TAppParameters.Create; //defined in TForm1 private
FAppParameters.Load;
if FAppParameters.PrinterEnable then begin
case FAppParameters.PrinterConnection of
1 : begin end; {Do Usb}
2 : begin end; {Do Serial}
3 : begin end; {Do Parallel}
end;
AWidth :=FAppParameters.PrinterWidth;
//Do something with AWidth
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Form2 :=TForm2.Create(Self);
try
Form2.Caption :='Options';
FAppParameters.PopulateEditor(Form2, Form2);
Form2.ShowModal;
finally
Form2.Free;
end;
end;