Advice to get help from delphi
and from the internet. What do I do?
1. When I meet a new component.
2. When I need to perform
something, but I don't have any idea what component or method or third party
tools I should use.
Naming conventions. I have too many Unit1...
Programming Problems:
-
How can I show another form in my application? (4 steps tutorial)
Advice to get help from delphi and from the internet. What do I do?
1. When I meet a new component:
- I put it to my
form,
- I make a new event handler (button click or form click)
- I type
the name to the code editor inside the event handler with a dot in the end. This
will call the Code Completion wizard. I can see the methods, event and
parameters what I can choose from.
- I push an enter, if I find an
interesting method.
- If I highlight this expression and push F1, I usually
find more information, sometimes with examples.
2. When I need to perform something, but I don't have any
idea what component or method or third party tools should I use:
- I open my
books indexes and search through keywords.
- Go to the internet: http://developers.href.com/ Best tool
what I could find! Search all the newsgroups in one place. Fastest way to
find the answers to my problems.
If I have a problem, almost sure somebody
else had too, and s/he have already asked it and got the answer. My only job to
read the possible solutions.
Sometimes I copy the best answers to a question
to the notepad so I can use it as a reference later.
- Occasionally I still
did not find the answer. So I go to a newsgroup and ask my question. If I posted
my question to the right newsgroup, I usually get answer in 2-3 days.
- It is very important to give a unique name either for your programs and
your units. Forget about the Unit1 and Project1.
- Good practice to start
your unit names with "u". You can easily distinguish them from the program
names.
- I usually give the same name for my main unit (plus "u") as my
program.
- I recommend to make a separate directory for your every programs.
- How can I show another form in my application?
When I designed my main form and I need to show a second form,
1. I
choose "File/New Form"
2. I click back to the main form
3. "File/Use
Unit" will show the available forms, in this case Unit2. I choose it and click
OK.
This will add a line under the implementation:
uses Unit2;
4. Now I can call my new form with Form2.Show or Form2.ShowModal.
I
usually use the "show" with a form and the "showmodal" with a dialog box. The
difference is that I have to close the modal form before I switch to another
form.
1. Say you have 7 jokes for every day of the week. Make a new type, call it TJokes. Type this to the interface section:
Type
TJokes = Array [0..6] of String;
2. Make a new variable under the Form1: TForm;
var
DailyJoke: TJokes;
3. In the form create method (Object Inspector/Form1/OnCreate double click) type:
Randomize;
DailyJoke[0] := 'This is suppose to be
funny.';
DailyJoke[1] := 'Ha-Ha';
...
Type seven jokes. You should call the "Randomize" only once in your whole program!
4. Now the core of the program: shuffle. Put it to an event handler as form activate.
var
I, J: Integer;
Substitute: String;
begin
for I:= (High(DailyJoke))
downto (Low(DailyJoke)) do
begin
J:=Low(DailyJoke) +
Random(High(DailyJoke)-Low(DailyJoke))+1;
Substitute:=DailyJoke[J];
DailyJoke[J]:=DailyJoke[I];
DailyJoke[I]:=Substitute;
end;
end;
I think you need some explanation. I change only 2 joke place with each other
in this code, but call it 7 times. (for loop).
The Random method never give
back the highest range. For example Random(7) return 0 to 6.
I need to add
one to the randomized difference of the high and low values to reach the last
joke too. In our example, the low(DailyJoke) is 0 so this is optional to add it
to the random number. In other cases, maybe you will have to use it.
5. Show on the form what we got. Put a button and a label to it. We want
every button click show another joke in the new order.
6. We need a global
variable what is outside of the scope of the button click event handler. Type in
the implementation section:
var
K: integer;
7. Always initialize it. One way is: before the final end at the bottom of the unit type:
initialization
K := 0;
end.
8. Now to the button click event handler type:
If (K <= High(DailyJoke)) then
begin
label1.Caption := DailyJoke[K];
inc(K);
end;
- How can I copy protect my program and make it shareware (stop working in 14-30 days.)?
This is a real difficult task. I spent a lot of time to figure out the
solution.
- My program should write the date to the registry when it first
start.
- Every time checking how many days left.
- Checking, that the
computer time was not set back.
- Encode the information in the registry, so
the user can't change it manually.
- More difficult to generate a user
specific unique registration key. When somebody buy your program it will turn
the shareware a fully working program.
You will save money that you do not
have to send the working program in a disk or e-mail. And the user save time to
not uninstall the shareware and install the program; only type the registration
number.
Solution: A third party tool: RTRegControl.
I put 3
component to my form. Set some properties and I have a fully functional
shareware in 10 minutes.
Even I can set that how many days or how many calls
I will allow, or a specific date when the program will expire.
This
component base solution not too hard to break. But nobody will spend a lot of
time to break a cheap program. If you have an expensive program, where you want
more security, use the dcu version.
I have got a RegKey program too with my
registered version. So I can make as many registration key as I want. I do not
have to pay for it.
The RTRegControl coasted me $59. One of the
cheapest solution. And definitely one of the best.
They have a home page: http://www.rtsoftware.com/
I
appreciate their customer service too. Tomasz always answered my questions
within 24 hours.
I will show you an example where we will make a registration program. We will ask the user's details and write it to the registry. And later on we will read it from there.
1. Put 2 labels, 2 edit box and 2 buttons to the form. (NameLbl, CompanyLbl,
NameEdit, CompanyEdit, RegisterBtn, ShowInfoBtn)
2. Put the "registry" to
your uses clause. (to the interface).
3. Double click to the RegisterBtn
OnClick Events. Type this to the event handler shell:
var
MyRegistry: TRegistry;
begin
if (NameEdit.Text <> '') and (CompanyEdit.Text <> '')
then
begin
MyRegistry:= TRegistry.Create;
if
MyRegistry.OpenKey('SOFTWARE\S-CoolSoft\Registration\', True) then
begin
with MyRegistry
do
begin
WriteString('Name', NameEdit.Text);
WriteString('Company', CompanyEdit.Text);
CloseKey;
Free;
end;
end;
end;
end;
Explanation: HKEY_CURRENT_USER is the default root key. Our key will be added
to this. If we set the OpenKey second parameter to "True" this will create the
new directories to the registry if it has not been there before. The SOFTWARE
directory was there. You should add your company name and your program name to
it. As I did in my example.
See in the RegEdit program what happened
exactly. (Start/Run/Regedit.exe)
4. Read the values from the registry. Double click to the ShowInfoBtn OnClick Events. Type this to the event handler shell:
var
MyReg: TRegistry;
n, c: string;
begin
MyReg := TRegistry.Create;
if
MyReg.OpenKey('SOFTWARE\S-CoolSoft\Registration\', False) then
begin
if
MyReg.ValueExists('Name') then
n :=
MyReg.ReadString('Name');
if
MyReg.ValueExists('Company') then
c :=
MyReg.ReadString('Company');
MyReg.CloseKey;
MyReg.Free;
MessageDlg('This program is registered to'
+ #13 + n + ', ' + c,
mtInformation, [mbOK], 0);
end
else
MessageDlg('This is an unregistered version.'
+ #13 + 'Please, register first.',
mtWarning, [mbOK], 0);
end;
I used the same registry key but "false" parameter. If it does not exist yet, we cannot read any data from there. In this case a warning dialog will appear. If everything is all right we will see an information dialog with the details.
5. It would be even better if we disable the ShowInfoBtn until the entry is
made to the registry. Do it in designer time with the Object Inspector.
To
enable make a new code line to the RegistrationBtn click event handler.
...
CloseKey;
Free;
end;
ShowInfoBtn.Enabled := True;
{new line}
If you do this extra step, you won't see the warning dialog box ever.
The problem is, that when I use the Install Shield Express the result will be
not only one file but many (8-12..) This is not a real problem if I want to
distribute my program in disks or Cd. But for the internet I should make one
file.
The ZIP archive would be a good solution, but some people don't have
unzip program.
So a self-extracting zip would be even better.
I have found a freeware delphi zip components. Written by Eric W. Engler. You can download it from several place: ftp://ftp.teleport.com/vendors/greglief/delzip14.exe or http://www.cdrom.com/pub/delphi/ or http://www.objectlessons.com/~ol/
You can write your zip program with this. Now I would like to recommend you the Demo1 program (C:\Zip\Demo1\ZipDemo1.dpr) Compile and run it. This is a really great, fully functional program.
How to make your own self-extracting install program?
1. Push the "New
Zipfile" button. Give a name for it and click Open.
2. Click the "Add to
Zip" button.
3. Find the files what you have made with the Install Shield
Express. If they are a separate directory, push "Select all files" then "Add
file ==>".
4. If every file, what you need, in the list box then click
the "DO IT NOW" button. This will make your zip file.
5. You will see a
messages window and a dialog what tell you how many files were added. Click Ok
in the dialog and Dismiss the messages window.
6. You need a self-extracting
file, so convert your zip file with the "Convert to EXE" button.
7. Change
the caption as you wish.
8. Give a Default Extract Directory, for example:
"C:\temp\myprogram". This won't mess up the user's hard drive. S/he can find it
and delete it easily.
9. To the "Command line to exec after extraction" edit
box write this: "><Setup.exe" Don't use the quotation marks. The setup.exe
is the original name. If you changed it to something else, use that.
10.
Push the "Do it now" button. You get your self-extracting exe.
You can try
it out. Double click on it will automatically start the installation after
extraction.
I feel disappointed when I find out that the help making not a Delphi issue.
I can buy some expensive program to make this important task.
I tried lots
of way:
- Combine the Word with the Help workshop. In this case, you will
spend more time to make your help than to make your program.
- HelpScribble:
http://www.tornado.be/~johnfg/helpscr.html
It is one of the best solution. It is a good program. I can connect with the
delphi help contents very easily. It is cost around $79-90 (depend of the
source). I did not buy it yet but maybe I will later on.
- HTML help
workshop. This is the new Microsoft stuff. It is free. But it is turned me down
when it did not worked with the Delphi. I should buy some compatibility tool to
make it work together :-(
- After experimenting in the help writing area I decide to write my simple
and free help. It is not as good as the commercial product, but it is working
OK.
Steps:
1. I put two panels to my form. The first aligned to
the left the second is "alClient".
2. I put a Splitter between them. It will
automatically align to the left.
3. I put a TreeView component to my first
panel and a RichEdit component to my second panel.
The TreeView will show
the contents. The RichEdit will show the descriptions.
4. I made an .rtf
(rich text format) with an editor as the WordPad. Saved it Overv.RTF. You can
make as many .rtf file as you need to your help.
5. I double clicked to the
TreeView component. This will invoke the TreeView Editor.
6. I clicked the
New Item button and typed Overview to the text edit box. You can create your own
complex contents here.
7. I create an event handler to the TreeView double
click. (Object Inspector: Event/OnDblClick)
8a. To the empty shell type
this:
If AnItem.Text ='Overview' then
RichEdit1.Lines.LoadFromFile('Overv.RTF');
It was simple, isn't it?
8b. If you plan to place your help file to a separate directory under the program exe file directory, then use the path (I call this directory to "Help"): If you want to know more about the path, watch this link.
path := ExtractFilePath(ParamStr(0)) + 'Help\';
If AnItem.Text
='Overview' then
RichEdit1.Lines.LoadFromFile(path
+ 'Overv.RTF');
I recommend this way. Your program directories become more clear.
No you
have a working help file.
You can improve it:
9. With graphics in the TreeView.
- I put an
ImageList component to my form.
10. Double click invoke the editor.
11.
I click the "Add" button.
12. I chose "C:\Program
Files\Borland\Delphi3\Images\Buttons" first "BookShut"; second "BookOpen"; third
"Docsingl". You can use any graphics what you like.
The editor put two image
every time, but I always deleted the disabled images. So I have only 3 image
instead of 6.
To show these images.
13. I went back to the TreeView editor, chose the
subitems and changed the "Image Index" and Selected Index" properties to 2.
(page image) I leave the main items properties 0. (closed book)
14. I should
modify the contents tree node image if it is opened to open book and a closed
book when it is closed. I do it with code:
- Object Inspector:
TreeView/OnExpanded double click:
Node.ImageIndex := 1;
- Object Inspector: TreeView/OnCollapsed double click:
Node.ImageIndex := 0;
15. It is better if I close the whole stuff when I close the form.
In the
form close event handler I type this:
TreeView1.Items.Item[0].Collapse(true);
Additional improvement:
- I made a pop-up window
- I made links in
the .rtf files.
These are not very important to make helps so I will not
enter into the details. You can see a complete working example, if you download
any of my shareware programs.
- E-mail to database
(download)
- Best Test (download)
- Best Test Editor
(download)
I hope you can use this example to make your own help.
If you do so,
please put a link to this site in your readme and help, and tell me, that you
find it useful.
You do not have to but I would appreciate it. :-)
1. The easiest way to put an image component to your form or a panel.
2.
Make the alignment to client.
3. Load a bitmap to it. (Make sure it fit
properly without stretch.) Use the "Tools/Image Editor" if you have to.
4.
Make sure that the labels transparent properties are true.
5. If you do not
see the the labels in run time. Click to the Image component "Edit/Send to
Back".
This solution have many disadvantages. If you cover a large surface, your bitmap should be large too. You can change the stretch property to true but it won't be too beautiful. The bigger bmp will radically increase your program size.
This is why I like to tile smaller bitmaps. See next example.
How to add an about window to your application and make it splash when it starts:
1. Click File/New... from the New Items dialog Forms tab I choose the About
Box.
2. Design the form.
3. Put a Timer component to it. (from the
System tab)
4. Set the Timer Interval property for example to 3000 (3
seconds).
5. Set the Enabled property to false. If somebody wants to see the
about window more then 3 second s/he can do it. We change it programmatically
when it is splash.
6. Double click on the Timer/OnTimer event. Type to the
open shell:
Close;
Free;
This will close your splash screen after 3 seconds.
7. Change the About
box look when it is splash with code. Make a new method, call it splash.
-
To the interface public part type:
procedure Splash;
- To the implementation:
procedure TAboutBox.Splash;
begin
BorderStyle
:= bsNone;
FormStyle := fsStayOnTop;
OKButton.Visible := False;
Show;
Update;
end;
You can change any other property if you want to.
8. Now we should switch back to the main form. Add the About box unit name
(unit2 or uabout) to the interface uses clause.
9. To the form create method
(Object Inspector/Form1/OnCreate) type:
var
SplashScreen: TAboutBox;
begin
SplashScreen := TAboutBox.Create(Application);
With SplashScreen do
begin
Splash;
Timer1.Enabled := True;
end;
end;
10. Withdraw the About window from the auto-create forms. Project/Options,
click on the AboutBox and > button. This will put the AboutBox to the
Available forms list.
11. You should design a main menu. Under the Help,
write About. Double click on it and type:
var
About: TAboutBox;
begin
About := TAboutBox.Create(Application);
About.ShowModal;
end;
This is very similar to the form create method. But we don't call the splash or the timer methods, only show the original form.
var
path: string;
....
path
:= ExtractFilePath(ParamStr(0))
ParamStr(0) returns the path and file name of the executing program.
The
ExtractFilePath will give you the drive and the directory name of the given
filename.
I have made a shareware program to make your life easier. You can download it.
If you are interested the main steps of the programming continue to read.
1. You need an internet form, what is send the submissions as an attachment
to you directly by mailto:myname@my.com. When you open it with a mail program
(Netscape...) you will see something like this:
First+name=Jo&Last+name=Brown&Phone=555-5555
Copy it to an edit
box of your program.
2a. If you do not have any open database table, you
have to create a table run time with the given fields. I converted + to _ .
2b. If you have an open database table, compare the fields. Add the new
fields to it if any. In this step, I used a library unit from the "How to program Delphi 3"
book. Pretty useful book.
3. Post the values to the appropriate fields.
This program contains lots of string manipulations. Thanks for Marco Cantu's examples in the Delphi Developer's Handbook. This is a very advanced book. If you are a beginner, first read the Mastering Delphi before you buy this.
Download "E-mail to
Database" shareware.
1. Start the Database Desktop program.
2. Click Tools/Alias Manager...
3. Click the New button.
4. Type your alias name - for example TEST - to
the Database Alias box.
5. The Driver Type leave it STANDARD.
6. To find
the correct path, push the Browse... button. You will see the Directory Browser.
When you find the path - for example: "C:\Program Files\S-CoolSoft\Data" - click
on the Ok button.
7. Click OK in the Alias Manager. This will save your
changes.
1. Start the Database Desktop program.
2. File/New/Table...
3. The
Create Table dialog will show the table types. Leave it Paradox 7.
4. You
can design your own fields or you can borrow (Borrow... button) from an existing
table.
5. When you are ready, click Save as... and give a unique name to it.
1. Put 4 labels, 4 edit boxes, a Table, a DataSource, a DbGrid and a button to the form. (Name the labels and edit boxes: TableNameLbl, TableNameEdit, Field1Lbl, Field1Edit, Field2Lbl...., the button name: CreateBtn)
2. Connect the database components to each other. In the Object Inspector
choose DbGrid1.DataSource to DataSource1; DataSource1 DataSet property to
Table1; Table1 Database property to one of your own alias (If you have not
created any yet, you can use the DEMOS).
Leave the Table1 TableName property
empty.
3. The required values the Table name and the first field. We will test only them. Type this to the CreateBtn Onclick event handler:
If (TableNameEdit.Text <> '') and (Field1Edit.Text <> '')
then
begin
Table1.TableName :=
TableNameEdit.Text;
Table1.TableType :=
ttParadox;
with Table1.FieldDefs do
begin
Add(Field1Edit.Text, ftString,
40, False);
if
(Field2Edit.Text <> '') then
Add(Field2Edit.Text, ftString, 40, False);
if
(Field3Edit.Text <> '') then
Add(Field3Edit.Text, ftString, 40, False);
end;
Table1.CreateTable;
Table1.Open;
end;
4. This code need a lot of improvement. If accidentally the user click the Create button again. It will cause database error, because the table already open. Just disable the button after the Table opened.
...
Table1.Open;
CreateBtn.Enabled := False;
5. We declared all fields to string, only 40 characters and not required. We can ask the user instead what s/he really needs.
6. We should watch for special characters what is not allowed in the table creations.
Have you heard about the bookmarks. This is it.
Make a new bookmark: Push
Ctrl and Shift and a number. This will add a green square with a number to the
line where your cursor was.
To find your bookmark: Push Ctrl and the number
what you need.
I like this feature very much. Use it!
How long have you studied Delphi? |