PDA

View Full Version : (Chapter 1 5)Delphi 6 Tutorials


_I_Play_Chess
11-29-2003, 11:51 AM
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD colSpan=2>Creating flat (non-relational) databases with no database components <!-- End of Headline --></TD></TR>
<TR>
<TD bgColor=#cc0000 colSpan=2 height=1><IMG height=1 src="http://images.about.com/all/bullets/dot_clea.gif" width=1 border=0></TD></TR>
<TR>
<TD colSpan=2>Delphi Personal edition does not offer database support. In this chapter, you will find out how to create your own *flat* database and store any kind of data - all without a single data aware component. <!-- End of Subhead --></TD></TR>
<TR>
<TD colSpan=2><IMG height=6 src="http://images.about.com/all/bullets/dot_clea.gif" width=1></TD></TR></TBODY></TABLE>Welcome to the fifteenth chapter of the FREE online programming course:
<H5 style="PADDING-LEFT: 10px; MARGIN-BOTTOM: 0px; COLOR: #000080">No DB support in Delphi Personal edition</H5>As you probably know, Delphi Personal edition comes with no database support, in terms of data-aware components. Hopefully, "data world" isn't only about Paradox, Access, Interbase or MySQL.

The data your application needs to operate on may not always be stored in a relational database. It may be stored in an ASCII text file or a structured binary file. It may even be stored in an XML file. As you will learn from this chapter, your application can read data from a file (of *any* structure), update "fields", add new "records", and write data back to the file as if the data were stored in a *real* database. NOTE: flat-file databases are not as scaleable (and safe) as the relational model databases (MySQL, MS SQL Server, Interbase, etc). If you are only working with a small amount of data that is rarely updated then a flat-file database could be your choice.
However, if you are looking for a database for more frequent and heavy use then a relational database is probably more suitable.

Files from Delphi perspective:

Simply put a file is a binary sequence of some type. In Delphi, there a three classes of file: typed, text, and untyped. Typed files are files that contain data of a particular type, such as Double, Integer or previously defined custom Record type. Text files contain readable ASCII characters (organized into lines). Untyped files are used when we want to impose the least possible structure on a file.
<H5 style="PADDING-LEFT: 10px; MARGIN-BOTTOM: 0px; COLOR: #000080">Building your own database system</H5>The next series of articles shows you how to use Delphi to create a simple "database" application that interacts with data in text (ASCII) or binary files:



<H3>TEXT FILES IN DELPHI
Handling ASCII files from Object Pascal code.</H3>&nbsp;&nbsp;&nbsp;<B>The world isn't only about Paradox, Access, Interbase, MySQL, MS' SQL Server ...</B>
Simply put, <I>text files</I> contain readable&nbsp;ASCII characters. We can think of working with text file in Delphi as analogous to playing or recording information on a cassette tape.
Although it is possible to make changes within text file, jump around when processing information or add some data to the file other than at the end, it is advisable to use a text file only when we know that we are working with ordinary text and no such operations are necessary.
Text files are considered to represent a sequence of characters formatted into lines, where each line is terminated by an end-of-line marker (a carriage-return / linefeed combination). Just think of Win.ini or Autoexec.bat. &nbsp;&nbsp;&nbsp;<B>Assign</B>
In order to start working with text files from Delphi we have to <I>link</I> a file on a disk to a file variable in our program. To create this link we must first declare a <B>variable</B> of type TextFile and then use <I>AssignFile</I> procedure in order to <I>associate</I> a file on a disk with a file variable.
<TABLE width="100%" bgColor=#ffffcc border=1>
<TBODY>
<TR>
<TD><PRE>...
<B>var</B>
SomeTxtFile : TextFile;
<B>begin</B>
AssignFile(SomeTxtFile, FileName)
...
</PRE></TD><PRE></PRE></TR></TBODY></TABLE>Note: Unless the file named <I>FileName</I> is in the current directory, we need to provide enough information to identify its path. Be sure that value of a text variable has a <I>legal</I> Windows filename. &nbsp;&nbsp;&nbsp;<B>Reading information from a Text File</B>
If we want to read back the contest of a file into a string list, our task is easy. Just one line of code will do the job.
<TABLE width="100%" bgColor=#ffffcc border=1>
<TBODY>
<TR>
<TD><PRE>...
Memo1.Lines.LoadFromFile('c:\autoexec.bat')
...
</PRE></TD><PRE></PRE></TR></TBODY></TABLE>On the other hand, to <B>read</B> information from a file line by line, we must open the file for input by using the <I>Reset</I> procedure. The <I>Reset</I> <B>opens</B> the <B>existing</B> file with the name assigned to TextFile variable. An error results if no existing external file of the given name exists. Once a file is reset, we can use <I>ReadLn</I> to read information from a file:
<TABLE width="100%" bgColor=#ffffcc border=1>
<TBODY>
<TR>
<TD><PRE>...
<B>var</B>
SomeTxtFile : TextFile;
buffer : <B>string</B>;
<B>begin</B>
AssignFile(SomeTxtFile, 'c:\autoexec.bat');
Reset(SomeTxtFile);
ReadLn(SomeTxtFile, buffer);
Memo1.Lines.Add(buffer);
CloseFile(SomeTxtFile);
<B>end</B>;
...
</PRE></TD><PRE></PRE></TR></TBODY></TABLE>Procedure called <I>ReadLn</I>, reads one line of text from a file then moves to the next line. After adding one line of text from a file to a memo component <I>SomeTxtFile</I> needs to be closed. This is done by the <I>Close</I> keyword. Note: We can also use <I>Read</I> procedure to read information from a file. <I>Read</I> works just like <I>ReadLn</I>, except it does not move the pointer to the next line. As the next example shows, we can use multiple variables in each <I>Read</I> statement:
<TABLE width="100%" bgColor=#ffffcc border=1>
<TBODY>
<TR>
<TD><PRE><B>var</B>
SomeTxtFile : TextFile;
buf1,buf2 : <B>string</B>[5];
<B>begin</B>
AssignFile(SomeTxtFile, 'c:\autoexec.bat');
Reset(SomeTxtFile);
ReadLn(SomeTxtFile, buf1,buf2);
ShowMessage(buf1 + ' ' +buf2);
CloseFile(SomeTxtFile);
<B>end</B>;
</PRE></TD><PRE></PRE></TR></TBODY></TABLE>&nbsp;&nbsp;&nbsp;<B>The EOF</B>
<I>Eof</I> is the <B>EndOfFile</B> checking function. We can use this function to make sure that we are not trying to read beyond the end of the file. Let's say we want to display the contest of the file in message boxes - one line at a time, until we get to the end of a file:
<TABLE width="100%" bgColor=#ffffcc border=1>
<TBODY>
<TR>
<TD><PRE><B>var</B>
SomeTxtFile : TextFile;
buffer : <B>string</B>;
<B>begin</B>
AssignFile(SomeTxtFile, 'c:\autoexec.bat');
Reset(SomeTxtFile);
<B>while</B> <B>not</B> EOF(SomeTxtFile) <B>do</B> <B>begin</B>
ReadLn(SomeTxtFile, buffer);
ShowMessage(buffer);
<B>end</B>;
CloseFile(SomeTxtFile);
<B>end</B>;
</PRE></TD><PRE></PRE></TR></TBODY></TABLE>Note: It is better to use <I>While</I> loop (http://delphi.about.com/library/weekly/aa081099.htm) than an <I>Until </I>loop to take into account the (unlikely) possibility that the file exists but does not contain any data. &nbsp;&nbsp;&nbsp;<B>Sending information to a Text File</B>
<B>Writing</B> text to a file is as easy as reading text from a file. The <I>WriteLn</I> command is probably the most common way to <B>send</B> individual pieces of information to a file. The following code will <B>read</B> a text from a <I>Memo1</I> component (line by line) and <B>send</B> it to some <I>newly</I> created text file.
<TABLE width="100%" bgColor=#ffffcc border=1>
<TBODY>
<TR>
<TD><PRE><B>var</B>
SomeTxtFile : TextFile;
i: integer;
<B>begin</B>
AssignFile(SomeTxtFile, 'c:\MyTextFile.txt');
Rewrite(SomeTxtFile);
<B>for</B> i := 0 <B>to</B> (Memo1.Lines.Count - 1) <B>do</B>
WriteLn(SomeTxtFile, Memo1.Lines[i]);
CloseFile(SomeTxtFile);
<B>end</B>;
</PRE></TD><PRE></PRE></TR></TBODY></TABLE>Depending on the state of the file provided to the <I>Rewrite</I> procedure in the previous example, the <I>Rewrite</I> creates a <B>new</B> file (opens the file for output) with the name assigned to <I>SomeTextFile</I>. If a file with the same name already exists, it is deleted and a new empty file is created in its place. If SomeTextFile is already open, it is first closed and then re-created. The current file position is set to the beginning of the empty file. Note: Memo1.Lines.SaveToFile('c:\MyTextFile.txt') will do the same. Sometimes we'll just need to <I>add some text data</I> to the end of an existing file. If this is the case, we'll call <I>Append</I> to ensure that a file is opened with write-only access with the file pointer positioned at the end of the file. Something like:
<TABLE width="100%" bgColor=#ffffcc border=1>
<TBODY>
<TR>
<TD><PRE><B>var</B>
SomeTxtFile : TextFile;
<B>begin</B>
AssignFile(SomeTxtFile, 'c:\MyTextFile.txt');
Append(SomeTxtFile);
WriteLn(SomeTxtFile, 'New line in my text file');
CloseFile(SomeTxtFile);
<B>end</B>;
</PRE></TD><PRE></PRE></TR></TBODY></TABLE>&nbsp;&nbsp;&nbsp;<B>Be aware</B>
In general, you should always use exception handling (http://delphi.about.com/library/weekly/aa032399.htm) when working with files. I/O is full of surprises. Always use <I>CloseFile</I> in a <I>finally</I> block to avoid the possibility of corrupting a user's <I>FAT</I>. All the previous examples should be rewritten as follows:
<TABLE width="100%" bgColor=#ffffcc border=1>
<TBODY>
<TR>
<TD><PRE><B>var</B>
SomeTxtFile : TextFile;
buffer : <B>string</B>;
<B>begin</B>
AssignFile(SomeTxtFile, 'c:\MyTextFile.txt');
<B>try</B>
Reset(SomeTxtFile);
ReadLn(SomeTxtFile, buffer);
<B>finally</B>
CloseFile(SomeTxtFile);
<B>end</B>;
<B>end</B>;
</PRE></TD><PRE></PRE></TR></TBODY></TABLE>To be sure that a given file exists we have to use <I>FileExists</I> boolean function. This function will return True if the file exists, Else otherwise. The syntax is
<TABLE width="100%" bgColor=#ffffcc border=1>
<TBODY>
<TR>
<TD><PRE>function FileExists(const FileName: string): boolean
</PRE></TD><PRE></PRE></TR></TBODY></TABLE>&nbsp;&nbsp;(to be continued.

_I_Play_Chess
11-29-2003, 12:08 PM
<H3><FONT color=maroon><FONT size=+3>M</FONT>Y <FONT size=+3>O</FONT>WN <FONT size=+3>D</FONT>ATABASE </FONT><BR><FONT size=-1><ABOUT>Working with binary files from Delphi. Use Object Pascal to manage writing, reading and updating your own types of files. </ABOUT></FONT></H3>
<P>Scenario: In my Delphi program I need a way of storing some information to the disk. I do not want to work with text files - there should be no easy way to see/alter the information in a file. There may be actions like changing/updating the existing data; but mainly writing and reading will take place. All the information is stored in my user-defined Pascal Record data type. What approach should I use?
<P>BDE plus Paradox or Access, ... well no thanks...I do not want to bother with the BDE. Should I use the ASCII text files approach, hm no, there should be some minimal protection - text files are "to visible". Delphi has the answer! The answer is: <B>typed files</B> (or <I>files of some type</I>/<I>binary files</I>).
<P>&nbsp;&nbsp;&nbsp;<B><FONT color=#000080>Files</FONT></B><BR>Simply put a <B>file</B> is a binary sequence of some type. In Delphi there a three classes of file: <I>typed</I>, <I>text</I>, and <I>untyped</I>. Typed files are files that contain data of a particular type, such as Double, Integer or previously defined custom Record type. Text files contain readable ASCII characters. Untyped files are used when we want to impose the least possible structure on a file.
<P>&nbsp;&nbsp;&nbsp;<B><FONT color=#000080>Typed Files</FONT></B><BR>While text files consist of lines terminated with a CR/LF combination, <I>typed files</I> consist of data taken from a particular type of data structure.
<P>For example, the following declaration creates a record type called <I>TMember</I> and an&nbsp;array of TMember record variables, the one we could use in our case .
<P>
<TABLE width="100%" bgColor=#ffffcc border=1>
<TBODY>
<TR>
<TD><PRE><B>type</B>
TMember = <B>record</B>
Name : <B>string</B>[50];
eMail : <B>string</B>[30];
Posts : LongInt;
<B>end</B>;

<B>var</B> Members : <B>array</B>[1..50] <B>of</B> TMember;
</PRE></TD><PRE></PRE></TR></TBODY></TABLE>
<P>Before we can write the information to the disk we have to declare a variable of a <I>file</I> type. The following line of code declares an <I>F</I> file variable.
<P>
<TABLE width="100%" bgColor=#ffffcc border=1>
<TBODY>
<TR>
<TD><PRE> <B>var</B> F : <B>file of</B> TMember;
</PRE></TD><PRE></PRE></TR></TBODY></TABLE>
<P><FONT size=-1>Note: To create a typed file in Delphi, we use the following syntax: <BR>var SomeTypedFile : file of SomeType<BR>The base type (SomeType) for a file can be a scalar type (like Double), an array type or record type. It should not be long string, dynamic array, class, object or a pointer.</FONT>
<P>In order to start working with files from Delphi we have to <I>link</I> a file on a disk to a file variable in our program. To create this link we must use <I>AssignFile</I> procedure in order to <I>associate</I> a file on a disk with a file variable.
<TABLE width="100%" bgColor=#ffffcc border=1>
<TBODY>
<TR>
<TD><PRE> AssignFile(F, 'Members.dat')
</PRE></TD><PRE></PRE></TR></TBODY></TABLE>
<P>Once the association with an external file is established, the file variable F must be 'opened' to prepare it for reading and/or writing. We call <I>Reset</I> procedure to open an existing file or <I>Rewrite</I> to create a new file. When a program completes processing a file, the file must be closed using the <I>CloseFile</I> procedure. After a file is closed, its associated external file is updated. The file variable can then be associated with another external file. In general, we should always use exception
<P>handling ; many errors may arise when working with files. For example: if we call <I>CloseFile</I> for a file that is already closed Delphi reports an I/O error. On the other hand, if we try to close a file but have not yet called <I>AssignFile</I>, the results are unpredictable.
<P><B>Write</B><BR>Suppose we have filled an array of Delphi members with their names, e-mails and number of posts and we want to store this information in a file on the disk. The following peace of code will do the work:
<P>
<TABLE width="100%" bgColor=#ffffcc border=1>
<TBODY>
<TR>
<TD><PRE> <B>var</B> F : <B>file of</B> TMember;
<B>begin</B>
AssignFile(F,'members.dat');
<FONT color=#ff0000>Rewrite</FONT>(F);
<B>try</B>
<B>for</B> i:= 1 <B>to</B> 50 <B>do</B>
<FONT color=#ff0000>Write</FONT> (F, Members[i]);
<B>finally</B>
CloseFile(F);
<B>end</B>;
<B>end</B>;
</PRE></TD><PRE></PRE></TR></TBODY></TABLE>
<P><B>Read</B><BR>In order to retreive all the information from the 'members.dat' file we could use this code:
<P>
<TABLE width="100%" bgColor=#ffffcc border=1>
<TBODY>
<TR>
<TD><PRE> <B>var</B> Member: TMember
F : <B>file of</B> TMember;
<B>begin</B>
AssignFile(F,'members.dat');
<FONT color=#ff0000>Reset</FONT>(F);
<B>try</B>
<B>while</B> <B>not</B> Eof(F) <B>do begin</B>
<FONT color=#ff0000>Read</FONT> (F, Member);
<FONT color=#000080><I>** DoSomethingWithMember; }</I></FONT>
<B>end;</B>
<B>finally</B>
CloseFile(F);
<B>end</B>;
<B>end</B>;
</PRE></TD><PRE></PRE></TR></TBODY></TABLE>
<P>Note: Eof is the EndOfFile checking function. We use this function to make sure that we are not trying to read beyond the end of the file (beyond the last stored record).
<P><B>Seeking and positioning</B><BR>Files are normally accessed sequentially. When a file is read using the standard procedure Read or written using the standard procedure Write, the current file position moves to the next numerically ordered file component (next record). Typed files files can also be accessed randomly through the standard procedure <I>Seek</I>, which moves the current file position to a specified component. The <I>FilePos</I> and <I>FileSize</I> functions can be used to determine the current file position and the current file size.
<P>
<TABLE width="100%" bgColor=#ffffcc border=1>
<TBODY>
<TR>
<TD><PRE><FONT color=#000080><I>{go back to the beginning - the first record}</I></FONT>
Seek(F, 0);

<FONT color=#000080><I>{go to the 5-th record}</I></FONT>
Seek(F, 5);

<FONT color=#000080><I>{Jump to the end - "after" the last record}</I></FONT>
Seek(F, FileSize(F));
</PRE></TD><PRE></PRE></TR></TBODY></TABLE>
<P><B>Change and update</B><BR>We just saw how to write and read the entire array of Members. What when all we want to do is to seek to the 10-th member and change his e-mail? The next procedure does exactly that:
<P>
<TABLE width="100%" bgColor=#ffffcc border=1>
<TBODY>
<TR>
<TD><PRE><B>procedure</B> ChangeEMail
(<B>const</B> RecN : integer; <B>const</B> NewEMail : <B>string</B>);
<B>var</B> DummyMember : TMember;
<B>begin</B>
<FONT color=#000080><I>{assign, open, exception handling block}</I></FONT>
Seek(F, RecN);
Read(F, DummyMember);
DummyMember.Email := NewEMail;
<FONT color=#000080><I>{read moves to the next record, we have to
go back to the original record, then write}</I></FONT>
Seek(F, RecN);
Write(F, DummyMember);
<FONT color=#000080><I>{close file}</I></FONT>
<B>end</B>;
</PRE></TD><PRE></PRE></TR></TBODY></TABLE>
<P>&nbsp;&nbsp;&nbsp;<B><FONT color=#000080>All done</FONT></B><BR>That's it, now we have all we need to accomplish our task. We can write Members information to the disk, we can read it back and we can even change some of the data (e-mail, for example) in the "middle" of the file.<BR>What's important is that this file is not an ASCII file, this is how it looks in Notepad (only one record): </P>
<P>(To be continued)</P>

_I_Play_Chess
11-29-2003, 12:13 PM
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD colSpan=2>Accessing 'Configuration Settings' files (.INI) with Delphi <!-- End of Headline --></TD></TR>
<TR>
<TD bgColor=#cc0000 colSpan=2 height=1><IMG height=1 src="http://images.about.com/all/bullets/dot_clea.gif" width=1 border=0></TD></TR>
<TR>
<TD colSpan=2>How a simple text file can beat Registry in storing a few pieces of application specific configuration data. <!-- End of Subhead --></TD></TR>
<TR>
<TD colSpan=2><IMG height=6 src="http://images.about.com/all/bullets/dot_clea.gif" width=1></TD></TR></TBODY></TABLE>The .INI files have a text-based file format for representing application configuration data in a format which is easily editable by humans and readable by a simple automatic parser. Most people who use Windows have at least a passing acquaintance with .INI files and with the WIN.INI and SYSTEM.INI files in particular (check your Windows directory). Windows stored (and still does) such important information as configuration information about Windows in plain text files that are easily deleted, modified or viewed.
Even though, in 32-bit Windows Microsoft recommends using&nbsp;Registry to store application specific configuration data, in many cases you'll find that using INI files is much faster and safer. One simple use of INI files, as a status saving mechanism, would be to save the size and location of a form if you want a form to reappear at it's previous position. In general everything you store in Registry you could store in an INI file. &nbsp;&nbsp;&nbsp;<B>.INI file format</B>
Initialization or Configuration Settings file (.INI) is a text file with 64Kb limit divided into sections, each containing zero or more keys. Each key contains zero or more values. Example: [SectionName]
keyname=value
;comment
keyname=value
Section names are enclosed in square brackets, and must begin at the beginning of a line. Section and key names are case-insensitive, and cannot contain spacing characters. The key name is followed by an equal sign ("="), optionally surrounded by spacing characters, which are ignored.
If the same section appears more than once in the same file, or if the same key appears more than once in the same section, then the last occurrence prevails.
A key can contain string, integer or boolean value. Delphi uses INI file format in many cases. For example, the .DSK files (desktop settings) have a file format as described above. &nbsp;&nbsp;&nbsp;<B>TIniFile</B>
Delphi provides the TIniFile class with methods designed to store and retrieve application-specific information and settings from INI files. The TIniFile class is declared in the inifiles.pas unit. Prior to working with the TIniFile control you need to create an instance of the class:
<TABLE width="100%" bgColor=#ffffcc border=1>
<TBODY>
<TR>
<TD><PRE><B>uses</B> inifiles;
...
<B>var</B>
IniFile : TIniFile;
<B>begin</B>
IniFile := TIniFile.Create('myapp.ini');
</PRE></TD><PRE></PRE></TR></TBODY></TABLE>This code creates an IniFile object and assigns 'myapp.ini' to the only property of the class - the FileName property - used to specify the name of the INI file you are to use.
The code as written above looks (stores) for the myapp.ini file in the \Windows directory. A better way to store application data is in the application's folder - just specify the full path name of the file for the Create method:
<TABLE width="100%" bgColor=#ffffcc border=1>
<TBODY>
<TR>
<TD><PRE><I>// place the INI in the application folder,
// let it have the application name
// and 'ini' for extension:</I>
IniFile := TIniFile.Create(ChangeFileExt(
Application.ExeName,'.ini'));
</PRE></TD><PRE></PRE></TR></TBODY></TABLE><B>Reading</B>
The TIniFile class has several "read" methods. The ReadString reads a string value from a key, ReadInteger, ReadFloat and similiar are used to read a number from a key. All "read" methods have a default value that can be used if the entry does not exist. For example the ReadString is declared as: function ReadString(const Section, Ident, Default: String): String; override; <B>Writing</B>
The TIniFile has a corresponding "write" method for each "read" method. In other words they are WriteString, WriteBool, WriteInteger, etc.
<TABLE cellSpacing=1 cellPadding=1 align=left bgColor=#808080 border=0>
<TBODY>
<TR>
<TD bgColor=#c0c0c0><B>&nbsp;project1.ini</B></TD></TR>
<TR>
<TD bgColor=#c0c0c0>&nbsp;[User]
&nbsp;Last=Joe Blo
&nbsp;Date=12/04/2003
&nbsp;[Placement]
&nbsp;Top=20
&nbsp;Left=35
&nbsp;Width=500
&nbsp;Height=340
</TD></TR></TBODY></TABLE>For example, if we want a program to remember the name of the last person who used it, when it was, and what were the main form coordinates, we might establish a section called "Users" and a keyword called "Last" and "Date" to track the information; and another section called "Placement" with keys "Top", "Left", "Width", "Height". Note that the key named "Last" holds a string value, "Date" holds a TDateTime value, all keys in the "Placement" section hold an integer value.
<P clear=all>The OnCreate event of the main form is the perfect place to store the code needed to access the values in the application's initialization file:
<TABLE width="100%" bgColor=#ffffcc border=1>
<TBODY>
<TR>
<TD><PRE><B>procedure</B> TForm1.FormCreate(Sender: TObject);
<B>var</B>
IniFile : TIniFile;
LastUser : <B>string</B>;
LastDate : TDateTime;
<B>begin</B>
IniFile := TIniFile.Create(
ChangeFileExt(Application.ExeName,'.ini'));

<I>//if no last user return an empty string</I>
LastUser := IniFile.ReadString('User','Last','');
<I>//if no last date return todays date</I>
LastDate := IniFile.ReadDate('User', 'Date', Date);

<I>//show the message</I>
ShowMessage('This program was previously used by '
+ LastUser + ' on '
+ DateToStr(LastDate));

Form1.Top := IniFile.ReadInteger
('Placement','Top', Form1.Top);
Form1.Left := IniFile.ReadInteger
('Placement','Left', Form1.Left);
Form1.Width := IniFile.ReadInteger
('Placement','Width', Form1.Width);
Form1.Height := IniFile.ReadInteger
('Placement','Height', Form1.Height);

IniFile.Free;
<B>end</B>;
</PRE></TD><PRE></PRE></TR></TBODY></TABLE>The OnClose event is ideal for the Save part of the project. Before the application terminates (OnClose of the main form) we save its current position and the info on the user:
<TABLE width="100%" bgColor=#ffffcc border=1>
<TBODY>
<TR>
<TD><PRE><B>procedure</B> TForm1.FormClose
(Sender: TObject; <B>var</B> Action: TCloseAction);
<B>var</B>
IniFile : TIniFile;
<B>begin</B>
IniFile := TIniFile.Create(
ChangeFileExt(Application.ExeName,'.ini'));

IniFile.WriteString('User','Last','Zarko Gajic');
IniFile.WriteDate('User', 'Date', Date);

<B>With</B> IniFile, Form1 <B>do</B>
<B>begin</B>
WriteInteger('Placement','Top', Top);
WriteInteger('Placement','Left', Left);
WriteInteger('Placement','Width', Width);
WriteInteger('Placement','Height', Height);
<B>end</B>;

IniFile.Free;
<B>end</B>;
</PRE></TD><PRE></PRE></TR></TBODY></TABLE><B>Working with Sections</B>
There are several methods designed to operate on entire sections of the INI file. For example the EraseSection erases an entire section of an INI file. The ReadSection and ReadSections fill a TStringList object with the names of all sections (and key names) in the INI file. Note: another class in the registry unit, the TRegIniFile class was introduced for easy access to the system's Registry without having to know the structure of the Registry. TRegIniFile uses similar functional access to the Registry as TIniFile does to an INI file. &nbsp;&nbsp;&nbsp;<B>Limitations and downsides</B>
The TIniFile class uses the Windows API which imposes a limit of 64KB on INI files. If you need to store more than 64KB of data, you should use the TMemIniFile instead, it does not have a limit of 64KB. Another problem might rise if you have a section with more than 8K value. The ReadSection method uses the GetPrivateProfileString API function with the 8K buffer. One way to solve the problem is to write your own version of the ReadSection method. The fact that anyone could access and change INI files means that the integrity of the information contained in the files could not be guaranteed. Yet, the Registry too can be edited with the tools provided by Microsoft. That's it. I hope you'll think twice the next time you ask yourself "where should I store my application's data".

nscopex
12-02-2003, 10:36 PM
Why do I not think he writes these? From looking at how he usually posts and then these tutorials. Is it just me?

GOD
12-02-2003, 10:38 PM
he gets em from websites cause theyre word for word what they are

nscopex
12-02-2003, 10:40 PM
I ahvent bothered going through them I dont really wanna learn Delphi.

GOD
12-02-2003, 10:41 PM
i read the first 3 chapters then i thought to myself
i really dont care about this and went and got really drunk

nscopex
12-02-2003, 10:51 PM
Theres a plan. :-D I like it.

_I_Play_Chess
12-03-2003, 10:46 AM
There's 2 more chapters as tutorials and after that we will discuss making project for the community!

&nbsp;

Yes some of these lessons are from many souces but I assembled them in

here .

I hope you like them guys!!!!

&nbsp;

&nbsp;

-SPLIFFY-
12-05-2003, 12:37 AM
what is all this?
some sort of teaching?