View
244
Download
5
Category
Tags:
Preview:
DESCRIPTION
Study Notes
Citation preview
Introduction to visual programming
RAD – Rapid Application Development IDE – Integrated Development Environment GUI – Graphical User Interface
Form Designer: Design user interface for program (‘design mode’, execute program ‘run mode’) Object Inspector: set initial properties of all components in user interface Two tabs – Properties and Events ObjectName.PropertyName := value; Object Properties:
Caption – caption on top of component (button, label, form, radio button) text string to identify object to user Name – Program code refer to component name. Change during design time only. TabOrder – Order which component receive focus when user press <Tab> or during runtime set component focus reday for input from user: edtText.SetFocus;
Enabled – component is active or not (True or False) Color – colour of object (clPurple, clYellow,clBlue)
Height – Vertical size of component (pixels) Width – Horizontal size of component (pixels) Top – Vertical position of top-left corner relevant to form (pixels) Left – Left side of component on form (pixels)
Kind – Bitmap Button type (bkClose, bkOk, bkYes, bkNo, bkRetry) Text – Text for entering text during design or run time. Valid for Edit Components Clear – to clear component property during runtime: edtText.Clear; Readonly – able to enter text (True or False)
Hint – Text to hint when cursor over item Showhint – Show or hide hint (True or False)
Naming conventions: TButton: btnName Bitmap Button: bmbName TLabel: lblText TEdit: edtText
TForm: frmName TRadioButton: radName TSpindEdit: sedName
Event Handler: procedure TForm1.button1Click(Sender: TObject); begin //marks beginning of program statements make up event handler Form1.Color := clYellow; Form1.Caption := ‘Yellow’; Form1.Enabled := True; end; // end of procedure
end. // end of program, using full stop Events: OnClick – user click component Accelerator (hot) keys: Allow user operate program buttons from keyboard. Insert ampersand (&) in front of appropriate letter in Caption property. Assignment statement: Assign values to component properties (text, caption, color, ...) lblText.Caption := ‘New Text’; frmForm1.Color := clPurple; btnButton.Enaled := True; Transfer value of one object property to another: bntCalc.Caption := edtEdit.Text; Assignment Operator ‘:=’ Components from Standard Menu: Button // Press button on form to do action Edit //input text Label // display an output string value Frame // CheckBox RadioButton Components from Additional Menu: BitBtn Popup Menu during design time: press <Ctrl-Space> Constructing Comments:
//Text entered after double-slash { Text between left and right brace} (* Tesxt between left-parenthesis-plus-asterisk and asterisk-plus-right-parenthesis *)
Delphi distinguishes between simple statement and compound statements. A simple statement is one executable line of code (not one line of code in Code Editor). A compound statement is a block of simple statements surrounded by begin/end keywords.
//simple statement
Form1.Caption := 'Ha! New caption ';
//compound statement
begin
Top := Top - 10;
Width := Width + 5;
end
a semicolon (;) is always required to separate two simple statement.
Associating Variables with variable names: var NewText: string;
Variables in Pascal hold informations (values). Variables have to be declared before they can be used. We do this after the var keyword. The var keyword can be used in several places in the code, such as at the beginning of the code of a function or procedure, to declare variables local to the routine, or inside a unit to declare global variables.
When declaring a variable, we must state its type. The type of a variable defines the set of values the variable can have.
var
SomeValue : Integer;
NewAdress : string;
IsThisWorthy : boolean;
GimmeMoney : Currency;
Something : variant;
A, B, C : char;
Lookout : Pointer;
can declare more than one variable of the same type by placing a comma between them. (SomeValue is variable of Integer type.)
Assigning values to variables After declare variable, use to manipulate data in memory. Uses the := sign for assigning values to variables.
GimmeMoney := 323,23; //Curreny type variable
IsThisWorthy := True; //boolean type
NewAdress := 'My new home adress'; //string type
Delphi enforces strict rules on kind assignments make between variable types. Can't assign string value to currency type variable.
Constants (values that do not change during program execution) are declared using the const keyword. To declare a constant you don't need to specify a data type, but only assign an initial value.
const
Min = 30;
Max = 500;
Middle = (Max + Min) div 2;
ErrStr = 'Some errors occured';
MaxAmount = 123.45;
SomeValue := Middle + 200;
Variable Types: String // Series of characters String[15] // Specify maximum length for string Integer // Numbers Boolean // True or False Char // Sing Character Rules for variable names:
1) Name any length, but Delphi only use first 255 characters 2) First character must be letter or an underscore 3) Characters following first can be letters, numbers or underscores 4) No spaces allowed, and is case insensitive
ListBox components Add components to list box: Var Boy: string; Boy := edtName.Text;
lstBoys.Items.Add(Boy); // Add input from text box to list editName.clear; editName.SetFocus;
String Concatenation Concatenate one string onto end of another string using + sign TheOtherString := SthisString + ThatString; SpinEdit component: Found component Samples tab under tool pallet Value from SpinEdit component: Answer := SedName.Value; What is a Delphi unit? A Delphi unit is a separate file used to store procedures and functions. If you know what a form is, a unit is exactly the same, except it has no visual interface. So you can't put windows controls on it like buttons and edit boxes. A form has windows controls and their associated code behind them, a unit only has the code. Converting Integer to String: edtAnswer.Text := IntToStr(Answer); Numbers in strings: var Ninety: string; Ninety := ‘90’; Cannot do any arithmetic calculations Integer Arithmetric: + Addition
- Substraction * Multiplication DIV Division producing integer component (no remainder) MOD Integer remainder after division of integers
Sum := 10 + 3; Difference := 10 – 3; Product := 10 * 3; IntDivide := 19 DIV 5; // result is 3, discarding remainder Remainder := 19 MOD 5; // result is remainder 4 Floating point (real) numbers: Fractional parts, floating point or real data types Single 2.5 X 10E-45 ... 3.4 X 10E38 Double 5.0 X 10E-324 ... 1.7 X 10E308 Extended 3.6 X 10E-4951 ... 1.1 X 10E4932 Currency -922337203685477.5808 ... 922337203685477.5807 Convert Real number to string: edtEuro.text := FloatToStrF(Euro, ffFixed, 15,2); FloatToStrF(Value, Format, Precision, Digits); Also use FloatToStr(FloatValue);
Constants: Declaration of reserved word const followed by identifier, followed by equal sign and constant value
const ExchangeRate = 0.1236; Declare more than one const: const Greeting = ‘Hello’; //string DaysInWeek = 7; // integer InchToCm = 2.54; //real
Conversion Functions: IntToStr Convert integer to string StrToInt Convert string to Integer StrToFloat Convert string to floating-point number FloatToStrF Convert floating-point to string and format the string (digits after decimal) FloatToStr Convert floating-point to string (without formatting)
Boolean Expressions: Mathematical Notation Delphi Notation Meaning = = equal to ≠ <> not equal to < < less than > > greater than
<= less than or equal to
>= greater than or equal to
Price > 20.00 {True if Price greater than 20.00, otherwise false} Value <> 0 {True if value not equal to 0, otherwise false} X >= y {True if x greater than or equal to y, otherwise false}
The if ... then ... else statements If value1 = value2 then
lblEqual.caption := ‘TRUE’
else
lblEquation.Caption := ‘FALSE’;
!note no semi-column after if statements before else to continue Difference between = and := llblEquation.Caption = ‘FALSE’
and
lblEqual.Captioni := ‘FALSE’
First is Boolean expression comparing values of left side of ‘=’ with value of right. Values to either True or False. Second is assignment statement assign value on right of ‘:=’ to property (or variable) on left. Comparing Strings
Same way as comparing numbers with relation operators (< and >). String ‘A’ is less than ‘B’, ‘x’ is greater than ‘a’. One first in alphabet is smaller. With long strings, individual letters are compared one-by-one from left to right. ‘adam’ is less than ‘eve’, the ‘a’ comes before ‘e’, and ‘apple’ is greater than ‘adam’, because ‘p’ comes after ‘d’. Uppercase letters come before lowercase. ‘Z’ smaller than ‘a’, ‘A’ smaller than ‘a’. ‘Eve’ less than ‘adam’.
Ignoring CASE when comparing strings Use UpperCase or LoweCase functions if UpperCase(value1) = UpperCase(value2) then
lblEqual.caption := ‘TRUE’
else
lblEqual.caption := ‘FALSE’;
Alternative CASE conversion Edit component has CharCase property which can be set to ecUpperCase, ecLowerCase or ecNormal. If CharCase for edtValue1 to ecUpperCase in Object Inspector, the user’s input will be converted to upper case as he type.
The if ... then ... else statement General Format: If Condition then
Statement1
else
statement2;
Condition is Boolean expression. If True, then Statement1 execute. If False statement2 execute. Can leave out Else part if nothing should happen if statement is False. Statements can be single program, or compound statement group placed between Begin and End. Never use Semicolon after word Then or after word Else. No semicolon between statement1 and Else. Logical operators in Boolean expressions Addition to operators (<,>,=), Boolean can include logical operators and, or and not. Combine conditions with and and or operands to form compound Boolean expression. (value1 > 10) and (value1 < 20)
(value1 = 10) or (value1 = 20)
If apply not operator to condition, it returns negation of condition’s value. Change value from True to False not(value1 > 10)
return False if value1 is greater than 10 and True if less than or equal to 10. Value1 Value2 (Value1 and Value2) (Value1 or Value) Not(Value1) True True True True False True False False True False False True False True True False False False False True Order of precedence (operators in expression have same precedence and evaluated left to right)
1 Bracketed Expressions 2 The NOT operator 3 And 4 Or 5 Relational operators(>,<,=, etc). A and B or C
= FALSE and FALSE or TRUE //and has precedence over or
= FALSE or TRUE //evaluate 1st part (give FALSE)
= TRUE //FALSE or TRUE give result TRUE
A and (B or C)
= FALSE and (FALSE or TRUE) //brackets have precedence
= FALSE and TRUE // evaluate 2nd part (give TRUE)
= FALSE // FALSE and TRUE give FALSE
Min <= x and x <= Max, Delphi evaluate x and x, result compile error (Min <= x) and (x <= Max), Boolean expressions both sides of and evaluated and then and is applied to resulting Boolean values.
Compound statements If frmColour.color = clYellow then
begin
frmcolour.color := clPurple;
frmcolour.caption := ‘Purple’;
end
else
begin
frmColour.color := clYellow;
frmColour.Caption := ‘Yellow’;
end;
When more than one statement appear in Then or Else part, statements must be enclosed by Begin and End. Note no semicolon before else statement. Structuring if...then...else If Salary > 7000.00 then tax := salary * highTax else
Tax := salary * lowTax;
If slalary > 7000 then
Tax := salary * highTax else
Tax := Salary * lowTax;
If salary > 7000 then
Tax := slalary * highTax
Else
Tax := salary * lowTax;
Semicolons in if...then...else statements Rule1: Semicolon is not used after the word Then Semicolon after Then interpreted as end of if...then...else If x >= 50 then; //wrong – semicolon after then
Result := ‘Pass’
Else //error occur since else not
//considered as part of statement
Result := ‘Fail;
If x >= 50 then; //if x >= 50 then do nothing
Result := ‘Pass’; //this will always be executed
Rule2: Semicolon not used directly after word else. Semicolon after else will not cause syntax error, cause program to give incorrect result. If x >= 50 then
Result := ‘Pass’
Else; //else do nothing
Result := ‘Fail’ // always execute
Rule3: Semicolon directly before else will always report syntax error
Common Windows dialogs in Delphi Dialog box is window (or form in Delphi) appears on top of existing windows to display information to user or to get information from user. Windows dialog boxes OpenDialog, SaveDialog and PrintDialog appear as components in Dialogs tab of Component/Tool pallet Visual versus non-visual components Components like OpenDialog, SaveDialog, FontDialog are never visible to user during runtime. Delphi use non-visual components for ‘behind the scenes’ operations. Program make Windows dialog ot represents visible when user action requires that dialog. Execute method First statement of btnLoadClick event handler If opdOpenDemo.Execute then
Common dialog box open when its Execute method is called. Inside the If statement, call opdOpenDemo’s Execute method. Execute returns True if user choose Open button on dialog, and False if user choose Cancel. Since chose Open, Execute returned True. Dialog’s FileName property gets value user typed into File name input box. Since Execute return True, the Then part of If statement execute memDemo.Lines.LoadFromFile(opdOpenDemo.FileName);
LoadFromFile method loads contents of file name in brackets into Lines property of memDemo. Required file name obtained from FileName property of opdOpenDemo.
If condition also function call, as long as function return Boolean value. Exception Handling Can overwrite default exception handling by wrapping statement in Try block so program handle exception. //Loading text from a file
procedure TfrmDialogDemo.btnLoadClick(Sender: TObject);
begin
if opdOpenDemo.Execute then
try
memDemo.Lines.LoadFromFile(opdOpenDemo.FileName);
except
ShowMessage('Error loading file ' +
opdOpenDemo.FileName);
end;
end;
The try...except statement Delphi executes statements that follow the Try keyword. If exception raised by one of these statements, Delphi jumps to the statement following the Except keyword. Statements can correspond appropriately to the exception occurred. If no exception raised by Try block, Delphi skip Except block and continues with statement after end. Saving text to file
procedure TfrmDialogDemo.btnSaveClick(Sender: TObject);
begin
if svdSaveDemo.Execute then
memDemo.Lines.SaveToFile(svdSaveDemo.FileName);
end;
Need to investigate how to check if file already exist when saving, informing user file will be overwritten. Changing Memo’s font Changing font in Memo component, use Set Font button to display Windows Font selection dialog
procedure TfrmDialogDemo.btnFontClick(Sender: TObject);
begin
if fodFontDemo.Execute then
memDemo.Font := fodFontDemo.Font;
end;
TMemo Properties: Lines – contain lines of text displayed in the Memo
ScrollBars – vertical/horizontal scrollbars (ssVertical, ssHorizontal, ssBoth and ssNone) WordWrap – If true word displayed on next line if not fit into a line
Methods: lines. LoadFromFile – loads lines of text from text file Lines.SaveToFile – Save to file Use: Give user space to type text of more than one line Nested IF statement if IsMammal then lblClass.Caption := ‘Mammal’;
if IsReptile then
lblClass.Caption := ‘Reptile’;
if not (IsMammal) and not(IsReptile) then
lblClass.Caption := ‘Unknown’;
If first if is true, the rest should not be executed. Replace IF structure with Nested IF statement if IsMammal then
lblClass.Caption := ‘Mammal’
else
if IsReptile then
lblClass.Caption := ‘Reptile’
else
if not (IsMammal) and not(IsReptile) then
lblClass.Caption := ‘Unknown’;
Layout of Nested IF Statements If Condition1 then If Condition2 then Statment1 else Statement2 else Statement3; Else belong to nearest IF preceding it which does not already have an Else part. Alternative: If Condition1 then if Condition2 then Statement1 else Statement2 else Statement3;
Consider: If Condition1 then
If Condition2 then
Statement1
else
Statement2;
One Else part. Apply rule first IF preceding Else, line 2. IF in line 1 has only Then part. If want Else part belong to outer If, must place nested if...then between begin and end: If Condition1 then
begin
if Condition2 then
Statement1;
end
else
Statement2;
Then part of first IF consist only of compound statement between begin and end. Could not put semicolon after Statement1 to indicate second IF. Delphi syntax rule state never use semicolon in front of Else since will cause compile error. Rule1: No semicolon after Then Rule2: No semicolon directly after Else Rule3: No semicolon after Else
Nested If structure with multiple If statements: Series of nested If statements where every Else part consist of neste if..,then...else statements. if Condition1 then
Statement1
else if Condition2 then
Statement2
else if Condition3 then
Statement3
else
Statement4;
TCheckBox: Properties: Checked If true a tick appears in box; if false box is empty Prefix: chk... Use: True/False (or Yes/No) choice
The CASE Statement: procedure TfrmBursary.btnEvaluateClick(Sender: TObject);
var
Amount: String;
begin
case sedAverage.Value of
90..100 : amount := 'R10 000.00';
75..89 : if chkAccounting.Checked or chkEconomics.checked then
amount := 'R8 000.00'
else
amount := 'R5 000.00';
60..74 : if chkAccounting.Checked then
amount := 'R3 000.00'
else
amount := 'R 0.00';
else
Amount := 'R 0.00';
end;
lblAmount.Caption := 'Bursary of ' + Amount + ' is awwarded.';
end;
Structure of CASE Statement: Case selector of
Option1 : statement1;
Option2 : statement2;
.
.
OptionN : statmentN;
Else
Statement;
end;
Else part is optional. SELECTOR is variable, expression or component property of Char, Boolean or Integer data type. SELECTOR may not be real or string. Option1, Option2, ... may be of form:
1) Constant of same type as Selector 2) List of values of same type as Selector. Values separated by commas (1, 2, 3) If value of
selector equal to any one of these, this alternative is chosen 3) Range of values of same type as Selector (1..10) If value of Selector within range, this
alternative is chosen 4) Combination of 1, 2 and 3 above
Const Myvalue = 100;
Var
SelectValue: integer;
Begin
SelectValue := seDemo.value;
Case SelectValue of
Myvalue : lblDemo.Caption := ‘Option type 1’;
40, 50, 60 : lblDemo.Caption := ‘Option type 2’;
70..99 : lblDemo.Caption := ‘Option type 3’;
1..39, 41..49, 51 : lblDemo.Caption := ‘Option type 4’;
Else
lblDemo.Caption := ‘Not in one of the options’;
end;
end;
For Char: ‘A’..’H’ : A to H
‘I”..’L’, ‘N’..’P’ : I to L, then N to P
‘M’ : Single character M only
Can also be compound statements enclosed within begin ... end. When is CASE statement preferable to IF statement:
CASE statement generally preferable to multiple alternative IF because easier to programmer to read and understand. CASE statement used only if all alternative options depend on value of same ordinal variable. If choice depends on different variables, real or string variable, nested IF statements must be used. CASE statement can be replaced with multiple IF structure, but not all multiple IF can be replaced with CASE
Generating words from characters Valid characters: ‘a’ ‘A’ ‘n’ ‘9’ ‘0’ ‘*’ ‘,’ ‘ ‘
Last character is single space. Invalid Characters: ‘ab’ //string contains two characters
‘b ‘ //string of 2 characters: ‘b’ and a space
‘’ //empty string contains no characters
Character can be treated as string, reversal not true. Var
Ch: char;
Str: string;
Begin
Ch := ‘a’;
Str := Ch; //character ‘a’ converted to string
Ch := Str; //error: incompatible types
To specify character inside string, need to specify index in square brackets Ch := Str[1]; //first character of the string converted to character Input Dialog boxes Input box is standard Delphi dialog box. Includes space for user to type input value in string format and always has OK and CANCEL button Surname := InputBox(‘User input’, ‘Enter a surname’, ‘’);
Will open dialog box with caption ‘User input’, the prompt ‘Enter a surname’ and the empty string as default input value. When click OK, InputBox statement return string to program where assigned to variable Surname. If click CANCEL, the default string is returned.
String Processing 1) Delete specific section in string 2) Insert substring into string at given location 3) Get length of string 4) Find position of substring in string 5) Extract part of string
Finding substring in a string: Position := Pos(StrToFind,TextToSearch);
Return position where located. Assign value to variable Position. Position := Pos(‘is’,’This is it!’);
Stores the integer value 3 in variable Position, because first occurrence of ‘is’ is in ‘This’.
function Pos(Str, Source : string): integer; Returns an integer specifying the position of the first occurrence of one string within another. Pos looks for the first complete occurence of Str in Source. If it finds one, it returns the character position in Source of the first character in Str as an integer value, otherwise it returns 0. Pos is case sensitive.
function PosEx(Str, Source : string, StartFrom : cardinal = 1): integer;
Returns an integer specifying the position of the first occurrence of one string within another, where the search starts at a specified position. PosEx looks for the first complete occurence of Str in Source, beginning the search at StartFrom. If it finds one, it returns the character position in Source of the first character in Str as an integer value, otherwise it returns 0. PosEx also returns 0 if StartFrom is greater then Length(Source) or if StartPos is < 0
Delete a substring from a string delete(TextToSearch,Position,length(StrToFind));
Start at position Position, it deletes the number of characters given by third value. Number of characters is length of StrToFind which get from Length(StrToFind) procedure Delete(var S: string; Index, Count : Integer)
Removes Count characters from a string S, starting at Index. Delphi leaves the string unchanged if Index is not positive or greater than the number of characters after the Index. If Count is greater than the rest of the characters after the Index, the rest of the string is deleted.
function Length(const S: string): integer
function Length(const S: array): integer
Returns an integer containing the number of characters in a string or the number of elements in an array. For an array, Length(S) always returns Ord(High(S))-Ord(Low(S))+1
Inserting a Substring into a string Insert(ReplaceStr,TextToSearch,Position);
Insert ReplaceStr into TextToSearch at position Position. Sentence := ‘what inserted?’; Insert(‘is ‘, Sentence, 6); procedure Insert(Source : string; var S : string; Index : Integer): string;
Inserts a substring Source into a string S at a given position Index. If Index is zero or negative Source is inserted at the beginning of S. If Index is greater than the Length of the string, Source is added to the end of S.
Copy part of a string Substr := Copy(TheString, BeginPosition, Len);
Copies substring in TheString from character in BeginPosition and containing Len characters to variable SubStr. TheString must be character string while BeginPosition and Len must be integers. If BeginPosition is greater than length of TheString, empty string is returned. If Len specifies more characters than remain from position BeginPosition, whatever is there is returned. Word := copy(‘This is copied’, 1, 4);
Assigns string ‘This’ to word.
function Copy(S; Index, Count: Integer): string; function Copy(S; Index, Count: Integer): array; Returns a substring of a string or a segment of a dynamic array. S is an expression of a string or dynamic-array type. Index and Count are integer-type expressions. Copy returns a string containing a specified number of characters from a string or sub array containing Count elements starting at S[Index].
If Index is greater than the length of S, Copy returns a zero-length string ("") or an empty array. If Count specifies more characters or array elements than are available, only the characters or elements from S[Index] to the end of S are returned.
To determine the number of characters in string, use the Length function. A convenient way to copy all the elements of S from the starting Index is to use MaxInt as Count.
Trim String
function Trim(const S: string): string;
Returns a string containing a copy of a specified string without both leading and trailing spaces and non-printing control characters.
Dialog box examples: // Simple ShowMessage dialog
ShowMessage(‘Simple show message example’);
// Input dialog
//Note: User Input is of type string
UserInput := InputBox(‘The Caption’ , ‘Please enter
something:’, ‘Something’);
// Warning dialog with OK button
MessageDlg(‘ This is a warning’, mtwarning,[mbOK],0);
//Information dialog with OK
MessageDlg(‘ This is some informationi’,
mtInformation,[mbOK],0);
// Error dialog with OK and Abort
If MessageDlg(‘This is an error’,mtError,[mbOK,mbAbort],0) =
mrOK then
// execute if user clicks OK
Else
//execute if user clicks Abort
// Confirmation dialog with Yes/No
If MessageDlg(‘Are you sure you want to exit?’,
mtConfirmation, [mbYes, mbNo], 0) = mrYes then
//execute if user clicks Yes
Else
// execute if user clicks No
General format of MessageDlg function: MessageDlg(StringToDisplay, TypeOfMessage, whichButtons, HelpTopic);
- StringToDisplay is message displayed inside dialog - TypeOfMessage is Delphi constant (mtWarning or mtError) determains icon and box
caption - whichButtons is Delphi constants represent selection of standard buttons. Exmaple OK
button ([mbOK]), OK and Abort ([mbOK, mbAbort]) and [mbYes, mbNo] - HelpTopic is integer value, normally 0
Handlin exceptions using message dialogs Procedure TfrmComission, btnCalculateClick(Sender: TObject);
Var
Sales, Comission: doubl;
Begin
Try
Sales := StrToFloat(edtSales.Text);
Except
If MessageDlg(‘unable to process sales value ‘ +
edtSales.Text, mtError, [mbOK, maAbort],0) = mrOK then
begin // user click OK
edtSales.SetFocus;
exit; //jump out of event handler
end
else // user click Abort
Close; //end the program
End; // end of try ... except
Description The MessageDlg function is used to display messages to the user. These
messages may be informational, or warnings or whatever. There is complete freedom over
the choice of buttons that the user may press to acknowledge the dialog.
For example, the user may be shown an error message, and be allowed to abort, retry or
cancel the erroneous process.
The DialogType may have one of the following enumerated values:
mtWarning Displays a exclamation symbol
mtError Displays a red 'X'
mtInformation Displays an 'i' in a bubble
mtConfirmation Displays an question mark
mtCustom Displays just the message
The Buttons value may be one or more of the following enumerated values :
mbYes Displays a 'Yes' button
mbNo Displays a 'No' button
mbOK Displays an 'OK' button
mbCancel Displays a 'Cancel' button
mbAbort Displays an 'Abort' button
mbRetry Displays a 'Retry' button
mbIgnore Displays an 'Ignore' button
mbAll Displays an 'All' button
mbNoToAll Displays a 'No to all' button
mbYesToAll Displys a 'Yes to all' button
mbHelp Displays a 'Help' button
You specify these values comma separated in square brackets, as in the second code example.
Delphi provides a number of predefined button combinations:
mbYesNoCancel = [mbYes,mbNO,mbCancel]
mbYesAllNoAllCancel =[mbYes,mbYesToAll, mbNo,mbNoToAll,mbCancel]
mbOKCancel =[mbOK,mbCancel]
mbAbortRetryCancel =[mbAbort,mbRetry,mbCancel]
mbAbortIgnore =[mbAbort,mbIgnore]
Now Delphi seem to have made a design error when setting the return value from the dialog
box. Instead of specifying the enumeration value of the button pressed, it uses a completely
different set of enumeration names:
mrYes = 6
mrNo = 7
mrOK = 1
mrCancel = 2
mrAbort = 3
mrRetry = 4
mrIgnore = 5
mrAll = 8
mrNoToAll = 9
mrYesToAll = 10
The values given are the numerical values of these enumerations, given in the numerical
order that the mb equivalents are defined. This is very odd.
Additionally, these values are defined in the Controls unit, not the Dialogs unit.
Note that the Help button has no equivalent return value. This is because it does not
terminate the dialog.
The HelpContext value is used in conjunction with the Help button. It's use is beyond the
scope of Delphi Basics.
Repetition
The For Loop for count := sedLower.Value to sedUpper.Value do
Starts a loop that executes a finite number of times Counter Driven Loop
1 for Variable := Integer Expression to|downto Integer Expression do
statement;
2 for Variable := Char Expression to|downto Char Expression do Statement;
3 for Variable := Enum Expression to|downto Enum Expression do Statement;
// Loop 5 times
For i := 1 to (10 div 2) do
ShowMessage('i = '+IntToStr(i));
For c := 'E' downto 'A' do
ShowMessage('c = '+c);
Structure: For CounterVariable := LowValue to HighValue do
Statement;
For x := 10 to (y*10-30) do ...
For x := 100 to 50 do ... //never executed since smaller
//bigger than upper value
For c := ‘a’ to ‘z’ do ... //execute 26 times
For c := ‘a’ to ‘a’ do ... //executed once
For z := HighValue downto LowValue do ... //count down
Can also be used with compound statements starting with BEGIN and ending with END;
The Random function Generating random number from 1 to 6: Throw := Random(6) + 1;
Random(6) generate numbers between 0 and 5. Generate a random floating point or integer number
1 function Random : Extended; 2 function Random ( LimitPlusOne : Integer ) : Integer;
The Random function generates random numbers. They can be floating point numbers in the range : 0 <= Number < 1.0 or integer numbers in the range : 0 <= Number < LimitPlusOne Delphi uses a pseudo random number generator that always returns the same sequence of values (232) each time the program runs. To avoid this predictability, use the Randomize procedure. It repositions into this random number sequence using the time of day as a pseudo random seed.
Randomize Reposition the Random number generator next value procedure Randomize ;
The Randomize procedure is used in conjunction with the Random function. It repositions the random number generator in its sequence of 232 pseudo random numbers. Randomize uses the time of day as the seed for this repositioning, so should provide a reliable method of creating an unpredictable sequence of numbers, even if they are a part of a predetermined sequence. // Get an integer random number in the range 1..100
ShowMessage('Fixed first 5 random numbers');
for i := 1 to 5 do
begin
int := 1 + Random(100); // The 100 value gives a range 0..99
ShowMessage('int = '+IntToStr(int));
end;
// Now randomize to reposition
Randomize;
ShowMessage('');
// Get an integer random number in the range 1..100
ShowMessage('Random next 5 numbers');
for i := 1 to 5 do
begin
int := 1 + Random(100); // The 100 value gives a range 0..99
ShowMessage('int = '+IntToStr(int));
end;
Fixed first 5 random numbers
int = 1
int = 4
int = 87
int = 21
int = 28
Random next 5 numbers
int = 35
int = 74
int = 45
int = 50
int = 31
Nested For Loops For OuterChar := ‘a’ to ‘e’ do
Begin
MyString := ‘’;
For InnerChar := ‘a’ to OuterChar do
MyString := MyString + InnerChar;
lstStrings.Items.add(MyString);
end; Result: ‘a’
‘ab’
‘abc’
‘abcd’
‘abcde’
The While ... do statement General purpose loop, can handle counter-controlled loops as well as ‘conditional’ loops. Conditional loop number repetitions determined by condition (ie Boolean expression). While loop, the loop body repeats as long as certain condition is True and end when that condition become False. Implements iteration structure that repeats statements while some condition is True While Condition do
Statement;
Repeat statements whilst a continuation condition is met While Expression do Statement;
The While keyword starts a control loop that is executed as long as the Expression is satisfied (returns True). The loop is not executed at all if the expression is false at the start. You need Begin or End markers if multiple statements are required in the loop. It is used when it is important that the statements are at only executed when necessary. // Display squares of integers until we reach 100 in value
While sqrNum <= 100 do
begin
// Show the square of num
ShowMessage(IntToStr(num)+' squared = '+IntToStr(sqrNum));
// Increment the number
Inc(num);
// Square the number
sqrNum := num * num;
end; Can replace any For Loop with While Loop. Sum := 0;
for count := sedLower.value to sedUpper.value do
sum := sum + count;
While loop:
Sum := 0;
Count := sedLower.value;
While count <= sedUpper.value do
begin
Sum := sum + count;
Count := count + 1;
End;
For loop automatically sets Count initially to the value in sedLower, While loop have to include assignment to do this. Rules for using While..do statements:
Rule1: Variable(s) appear in loop condition must be initialized before While Loop encountered. Called loop control variable(s).
Rule2: Inside loop body the value of loop control variable(s) must be modified to ensure loop condition become False at some stage, otherwise program will continue forever.
Repeat ... Until Implement iteration structure of which body always execute at least once Repeat
Statements sequence (loop body)
Until Condition;
Repeat statements until a termination condition is met Repeat
Statement1;
{Statement2;
...}
Until Expression
The Repeat keyword starts a control loop that is always executed at least once, and which terminates when the Expression is satisfied (returns True). There is no need for Begin or End markers - the Repeat and Until keywords serve that purpose. It is used when it is important that the statements are at least executed once.
Arrays and Indexes
Strings and indexes To get copy of first letter of string FirstLetter := Surname[1];
Index to first character of a string is 1. First element of other lists (items in ListBox) has index 0 Reversing string entered: Procedure TfrmReverseWord.btnReverseClick(Sender: TObject);
Var
Word, NewWord: String;
Index: Integer;
Begin
Word := edtWord.Text; // copy input string to variable
NewWord := ‘’; // Initialize NewWord to empty string
For Index := length(Word) down to 1 do // working from end
NewWord := NewWord + Word[Index]; // append char
ediWord.text := NewWord;
end;
Following will also solve problem correctly For index := 1 to length(Word) do
NewWord := Word[Index] + NewWord;
Arrays Is a data structure allows storing set of data items of same type under single name. Compare array with Items property of ListBox (or Memo), which also store list of data items in one structure. Difference is elements of array can be of any Delphi data type, not just strings as ListBox. Var NamesArray: array[1..20] of String;
Refer to individual elements with NameArray[1], ect, or with integer NamesArray[Index] 1 to 20. Lower bound of index range neet not be 1 Var TotalRainfall: array[1990..1999] of double;
Holds 10 rainfall figures relevant to year as index, more meaningful than using 1 to 10. Assignment statement TotalRainfall[1990] := StrToFloat(edtInput.Text);
Or
NamesArray[1] := ‘James’;
Looping through an array For Loops useful accessing and manipulating arrays.
Sum := 0;
For Counter := 1990 to 1999 do
Sum := Sum + TotalRainfall[Counter];
Dynamic Arrays Do not know how many elements there will be. When declare dynamic array, leave out the index range Var
ManyWord: array of string;
Number of elements is unknown. Before using array, size must be set by calling SetLength procedure SetLength(ManyWords, 10);
Dynamic array indexed from 0 to number of elements – 1. In example, ManyWords[0] is first element and ManyWords[9] is last element.
Initialising Arrays and Array Constants Initialising array and give its values when declared. Notation used for array constants. Array constants are arrays which do not change. Const
BoxinWeightLimits: array[1..10] of integer = (48, 51, 54, 57,
60, 64, 69, 75, 81, 91);
Two-dimensional Arrays Multi-dimensional arrays store tables with several rows and columns (like spreadsheet) Var Rainfall : array[1995..1999, 1..12] of double;
Declare two-dimensional array with 5 rows (indexed 1995 to 1999] and 12 columns (indexed 1 to 12). Each row store the 12 monthly rainfall figures for the relevan year.
The ComboBox component Looks like edit box with little down arrow to display list of options from which user can choose. TComboBox Properties Items Contains string that appear in drop-down list ItemIndex Index of currently selected item in list. Value -1 if no item selected Items.Count Number of items in the ComboBox Style Display style of ComboBox. Set property to csDropDownList result
user cannot enter text manually. Style csDropDown allow user to enter text.
Methods Item.Add Add string to end of list of items Prefix cbo...
Use Edit box with scrollable drop-down list attached. User can either select from list or type directly into edit box.
Const
Cities: array[1..3] of string = (‘Durban’, ‘Cape Town’,
‘Johannesburg’);
For I := 1 to 3 do
cboFromCity.Items.Add(Cities[I]); //Add cities to ComboBoxes
dboFromCity.ItemIndex := 0; // default index of ComboBox to 1st City
ListBoxes TListBox Properties ItemIndex Gives index of currently selected item in list. Value -1 no item
selected Item.Count Number of items listed in ListBox Prefix lst... Suppose have ListBox called lstName, then lstNames.Items[0] is first item and lstNames.Items[NoOfItems – 1] is the last item. NoOfItems is number of items in ListBox and given by property lstNames.Items.Count Load from file: lstNames.Items.LoadFromFile(dlgLoad.FileName);
To clear liest use: lstNames.Clear;
lstNames.SetFocus;
Deleting item from the list lstNames.Items.Delete(Index);
Index is the current item to be deleted. Index appear in round brackets. Delete method of Items property and Index is parameter (not an index) that is passed to that method. When value in square brackets follow reference list (eg lstNames.Items[Index], where lstNames.Items refer to list), value is an index to specific value in the list.
RadioGroups Special GroupBox that contains only RadioButtons. To add RadioButtons to RadioGroup edit Items property in Object Inspector. Each string in Items represent Caption of a RadioButton. Number of strings in Items property determines number of RadioButtons in the group. ItemIndex property (integer) indicates which RadioButton in group currently selected. If value 0, 1st button selected. If none, value is -1. TRadioGroup Properties Items Contains Captions of RadioButtons appear in group ItemIndex Index of currently RadioButton in RadioGroup. Value is -1 if none
Selected Items.Count Number of RadioButtons in RadioGroup Columns Integer value determine number of columns in which RadioButtons
Arranged inside RadioGroup. Default value 1 makes buttons appear in single column
Events OnClick Activated if user clicks any RadioButtons in RadioGroup Prefix rgp... Use GroupBox contains only RadioButtons. Number of RadioButtons and Captions
determined by strings caontained in Items propert. Using Case statements with Radio Group Case rgpAverage.ItemIndex of
-1 : MessageDlg(‘Indicate average score.’, mtWarninig,
[mbOK],0);
0 : Amount := ‘R10 000.00’;
1 : If chkAccounting.Checked or chkEconomics.Checked then
Amount := ‘R8 000.00’;
Else
Amount := ‘R5 000.00’;
2 : If chkAccounting.Checked then
Amount := ‘R3 000.00’;
End;
Events and Parameters
Event-driven Programming Stages to the event-processing sequence
1) Some action (’event’) occurs 2) Windows detects this event and sends event message to Delphi 3) IF programmer created event handler, Delphi initiates the event handler. If no linked event
handler, Delphi discard event message from Windows Because of GUI Delphi programs are event-driven. Event handler is group of program statements, (‘mini-programs’) attached to an event, runs whenever event occurs. OnMouseMove event handlers The mouse-click is common user event, alternative OnMouseMove
There are three fundamental mouse event handlers: OnMouseDown, OnMouseMove, and OnMouseUp. The MouseUp and MouseDown event handlers take the same five parameters as follows (the MouseMove lacks a Button parameter):
Sender - The object that detected the mouse action. Button - Indicates which mouse button was involved: mbLeft, mbMiddle, or mbRight. Shift - Indicates the state of the Alt, Ctrl, and Shift keys and the state of the mouse buttons
when the event occurred. X, Y - The pixel coordinates of the mouse pointer in the client area of the Sender.
OnMouseMove occurs when the user moves the mouse pointer while the mouse pointer is over a control. Since the OnMouseMove event handler will be called relatively frequently, any code inside this event handler will be executed often.
As we know, we can combine the keyboard with the mouse. For example, we can have the Shift-Move combination draw a circle. Let's see MouseMove in action (new project/new form):
procedure TForm1.FormMouseMove(Sender: TObject;
Shift: TShiftState; X,Y: Integer) ;
begin
if ssShift in Shift then
Canvas.Ellipse(x-20,y-20,x+20,y+20)
else if ssCtrl in Shift then
Canvas.Rectangle(x-20,y-20,x+20,y+20) ;
end;
With this code, moving the mouse over the form causes circles to follow the mouse if Shift key was pressed during move, and rectangles if Ctrl key was pressed
procedure TfrmShow.bmbCloseMouseMove(Sender: TObject; Shift:
TShiftState; X, Y: Integer);
begin
bmbClose.Font.style := [fsBold,fsunderline];
end; //Change font when mouse move over botton
procedure TfrmShow.FormMouseMove(Sender: TObject; Shift:
TShiftState; X, Y: Integer);
begin
bmbClose.Font.Style := [];
end; //reset font back when mouse move over form
User events and System events OnClick and OnMouseMove initiated by user. ‘System Events’ respond to something happening in the computer without direct action by user. Computer has internal clock which trigger Delphi’s Timer component and event handler. Other system events as OnCreate and OnShow, in form management.
Procedure TfrmSystemTime.tmrSysTimeTimer(Sender: TObject);
begin
lblSysTime.Caption := TimeToStr(time);
end;
TimeToStr function convert Time data type variable to string Timer Interval default value is 1000, changing to 5000 will update timer value every 5th second. OnMouseDown and OnMouseUp procedure TfrmSystemTime.FormMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
tmrSysTime.Enabled := False;
end;
procedure TfrmSystemTime.FormMouseUp(Sender: TObject; Button:
TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
lblSysTime.Caption := TimeToStr(time);
tmrSysTime.Enabled := True;
end;
The ‘form’ system events procedure pnlShowMouseMove(Sender: TObject;
Shift: TShiftState; X, Y: Integer);
procedure FormMouseMove(Sender: TObject;
Shift: TShiftState; X, Y: Integer);
procedure bmbCloseMouseMove(Sender: TObject;
Shift: TShiftState; X, Y: Integer);
Each list contain three groupings: Sender: TObjects;
Shift: TShiftState;
X, Y: Integer;
Name on left of colon (Sender, Shift, X, Y) represent parameter. Delphi makes parameters available in the event handler. Name of right of colon, (TObjects, TShiftStates, Integer), represent data type of corresponding parameters. procedure TfrmMousePos.FormMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
if button = mbLeft then
frmMousePos.Canvas.Rectangle(x-10, y-10, x+10, y+10);
end;
end.
TMousButton can have values mbLeft, mbRight, mbMiddle. TShiftState can have values none, one or more of ssShift, ssAlt, ssCtrl, ssLeft, ssRight, ssMiddle, ssDouble. Show whether any keyboard buttons where held down when OnMouseDown event occurred and whether event was initiated by mouse left, right or middle button or double-click.
Methods and Memo component procedure TfrmMemoDemo.btnClearClick(Sender: TObject);
begin
memDemo.Clear;
memDemo.SetFocus;
end;
procedure TfrmMemoDemo.btnCopyClick(Sender: TObject);
begin
memDemo.CopyToClipboard;
memDemo.SetFocus;
end;
procedure TfrmMemoDemo.btnPasteClick(Sender: TObject);
begin
memDemo.PasteFromClipboard;
memDemo.SetFocus;
end;
procedure TfrmMemoDemo.btnCutClick(Sender: TObject);
begin
memDemo.CutToClipboard;
memDemo.SetFocus;
end;
Several components (eg Memo and Edit) have Clipboard methods (CutToClipboard, CopyToClipboard, PasteFromClipboard).
Methods with constants as parameters Methods just used give single, direct command: Clear, SetFocus, CutToClipboard. When using Canvas, need additional information to method. Following Methods calls (no assignments):
procedure TfrmCanvasMethods.btnTextClick(Sender: TObject);
begin
Canvas.TextOut(40, 15, 'Two rectangles and two ellipses');
end;
procedure TfrmCanvasMethods.btnShapesClick(Sender: TObject);
begin
Canvas.Rectangle(40,40,400,200);
Canvas.Rectangle(80,80,360,160);
Canvas.Ellipse(150,50,290,190);
Canvas.Ellipse(100,100,340,140);
end;
Rectangle(x1, y1, x2, y2); Parameters must be integers, upper left corner (x1,y2) and lower right corner (x2, y2). Top left corner of canvas is (0,0) Ellipse(x1, y1, y2, y2);
Same coordinates as for Rectangle. Ellipse then drawn as largest ellipse to fit in rectangle. Specified bounding box of ellipse. If bounding box is square, ellipse become a circle.
Canvas methods used: Procedure TextOut (X, Y: Integer; const Text: String); Procedure Rectangle(X1, Y1, X2, Y2: Integer); Procedure Ellipse(X1, Y1, X2, Y2: Integer); Additional Notes on Canvas Drawing (not from book): ********************* DrawBtnClick ******************}
procedure TForm1.DrawBtnClick(Sender: TObject);
{Draw some ellipses on the canvas - random size and color}
var
i:integer;
cx,cy:integer;
begin
with image1, canvas do
begin
for i:= 1 to 10 do
begin
cx:=random(width);
cy:=random(height);
brush.color:=random(256*256*256);
ellipse(cx,cy,cx+random(100), cy+random(100));
end;
end;
end;
{******************* ClearBtnClick ****************}
procedure TForm1.ClearBtnClick(Sender: TObject);
{Erase the canvas by drawing a big rectangle}
begin
with image1, canvas do
begin
brush.color:=clwhite;
canvas.rectangle(clientrect);
end;
end;
{***************** SaveBtnClick *******************}
procedure TForm1.SaveBtnClick(Sender: TObject);
{Make a bitmap, copy canavsa to it and save it in a listbox}
var
b:TBitmap;
begin
b:=TBitmap.Create;
b.height:=image1.height;
b.width:=image1.width;
b.canvas.copyrect(rect(0,0,b.width,b.height),image1.canvas,image1.cl
ientrect);
listbox1.items.addobject('Image
#'+inttostr(listbox1.items.count+1),b);
end;
{******************* ListBox1Click *****************}
procedure TForm1.ListBox1Click(Sender: TObject);
{Retrieve bitmap from listbox and copy it to the canvas}
var
b:TBitmap;
begin
if listbox1.itemindex>=0 then
with listbox1 do
begin
b:=TBitmap(items.objects[itemindex]);
image1.Canvas.CopyRect(image1.clientrect,b.canvas,rect(0,0,b.width,b
.height));
end;
end;
{******************** Image1MouseDown **************}
procedure TForm1.Image1MouseDown(Sender: TObject; Button:
TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
with image1.canvas do
begin
pen.width:=3;
pen.color:=clblack;
drawing:=true;
moveto(x,y);
end;
end;
{*************** Image1MouseMove **************}
procedure TForm1.Image1MouseMove(Sender: TObject; Shift:
TShiftState; X,
Y: Integer);
begin
If drawing
then with image1 do
begin
cursor:=crNone; {to keep cursor redraw from erasing part of our
line}
canvas.lineto(x,y);
cursor:=crdefault;
end;
end;
{***************** Image1MouseUp ****************}
procedure TForm1.Image1MouseUp(Sender: TObject; Button:
TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
drawing:=false;
end;
{******************* Formcreate *************}
procedure TForm1.FormCreate(Sender: TObject);
begin
clearbtnclick(sender); {draw initial rectangle to clear image
canvas}
end;
procedure TForm1.Button1Click(Sender: TObject);
var
b:TBitMap;
begin
If savedialog1.execute
then image1.picture.savetofile(savedialog1.filename);
end;
Procedures and parameters Declaring and defining a method Entire code for entire unit example: 1 unit Unit1;
2 interface
3 uses
4 Windows, Messages, SysUtils, Variants, Classes, Grapgics,
5 Controls, Forms, Dialogs;
6 type
7 TForm1 = class(TForm)
8 Button1: TButton;
9 Procedure Button1Click(Sender: TObject);
10 Private
11 { Private declarations}
12 Public
13 { Public declarations}
14 end;
15 var
16 Form1: TForm1;
17 implementation
18 {$R *.nfm}
19 procedure TFOrm.Button1Click(Sender: TObject);
20 begin
21 Color := clPurple;
22 end;
23 end.
18 {$R *.nfm} – generate a.NET from module
Delphi consists of 3 parts: Name (line1) Interface (lines 2-16) Implementation (lines 17-23) Up to now worked with implementation section. In declaring method also interested in type declaration (lines 6-14). TButton in form, Delphi declared component of type TButton to Button1(line 8) part of TForm1 class (line 7). Also created event handler, procedure called Button1Click, Delphi declared this procedure also as part of TForm1 class (line 9). This procedure, the event handler, is method of TForm class. Definition follows in implementation section (lines 19-22). Note header in method definition (line 19) combines class name, TForm1, and method name, Button1Click and has same parameter list as declaration (line 9). When crate own methods follow Delphi’s example. Declare method’s signature, in private section of form’s type definition, (lines 10-11), and define method in implementation section as defined event handler methods earlier. unit C12e01u;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls, ExtCtrls;
type
TfrmSixpenceJoe = class(TForm)
rgpPoducts: TRadioGroup;
lblCostText: TLabel;
procedure rgpPoductsClick(Sender: TObject);
private
{ Private declarations }
procedure DisplayPrice (Product, Price: String);
public
{ Public declarations }
end;
var
frmSixpenceJoe: TfrmSixpenceJoe;
implementation
{$R *.dfm}
procedure TfrmSixpenceJoe.DisplayPrice(Product, Price: String);
begin
lblCostText.Caption := Product + ' cost R' + price + ' per
kilogram';
end; {proc TfrmSixpenceJoe.DisplayPrice}
procedure TfrmSixpenceJoe.rgpPoductsClick(Sender: TObject);
begin
case rgpPoducts.ItemIndex of //using TRadio Group
0 : displayPrice('Flour', '12.99');
1 : displayPrice('Rice', '4.39');
2 : displayPrice('Sugar', '4.10');
3 : displayPrice('Mealie', '2.16');
end;
end; {procedure TfrmSixpenceJoe.rgpPoductsClick}
end.
Procedures
1) Reduce amount of programming, result shorter ‘simpler’ program 2) Make changing program simpler 3) Less likely to cause errors 4) Lead to library of re-usable procedures that may be useful in future programs
Calling (invoking) a procedure Own procedure similar to writing event handler and calling procedure similar to calling a standard method. When user clicks RadioButton, Delphi calls associated event handler. Event handler code calls procedure DisplayPrice, passing required values for Product and Price string variables as parameters. Procedure call has form: DisplayPrice (‘Flour’, ’12.99);
Can create procedure that does not use parameters. Parameters of call must match header in order, number and type of parameter. General comments on procedures Parameters provide communication between subroutine and surrounding program. Within subroutine parameter has value that can be manipulate like other variable. Unlike local variables declared within subroutine, parameters also have meaning outside subroutine. Points when using procedures:
1) Parameter list of procedure call and procedure definition must mach in respect of type, order and number of parameters.
2) Within procedure, parameter matching is by name, not by order. 3) Procedure that are methods must be declared in class’s type declaration 4) Values send in procedure call van either be constants or variables 5) If procedure is method part of a class, procedure is bound to that class. When define
procedure must explicitly include class name in header.
Components as parameters Extend concept of parameters to include components as parameters unit C12e07u;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls;
type
TfrmStudyGroups = class(TForm)
btnNextName: TButton;
gpbGroup: TGroupBox;
lblGroup: TLabel;
lstGroup1: TListBox;
lstGroup2: TListBox;
lstGroup3: TListBox;
lblGroup1: TLabel;
lblGroup2: TLabel;
lblGroup3: TLabel;
procedure btnNextNameClick(Sender: TObject);
private
{ Private declarations }
procedure ShowGroup (GrpNo, Surname: string;
GroupList: TListBox);
public
{ Public declarations }
end;
var
frmStudyGroups: TfrmStudyGroups;
implementation
{$R *.dfm}
procedure TfrmStudyGroups.ShowGroup (GrpNo, Surname: string;
GroupList: TListBox);
{pass component}
begin
lblGroup.Caption := 'Group ' + GrpNo;
gpbGroup.Caption := Surname;
GroupList.Items.Add(Surname); //component TListBox
end; // procedure TfrmStudyGroups.ShowGroup
procedure TfrmStudyGroups.btnNextNameClick(Sender: TObject);
var
Surname: string;
begin
Surname := inputbox('User Input', 'Enter Surname', '');
if surname <> '' then //input box not empty
begin
case upcase(surname[1]) of
'A'..'G' : ShowGroup('1', Surname,lstGroup1);
'H'..'O' : ShowGroup('2', Surname,lstGroup2);
'P'..'Z' : ShowGroup('3', Surname,lstGroup3);
else //first letter not alphabet
lblGroup.Caption := '?'
end; //case
end //if surname
else //User press Cancel or left input box blank
showmessage('No surname provided');
end;
end.
Why and when should we use procedures? When same or similar task more than once. Using methods consolidate program statements connected to particular operation in one place. Good practise to choose name that describes clearly what method does. Comment clearly, include brief comment after method’s header to describe what the method does and role of each parameter. Returning values from a procedure Can write procedure that sends data in other direction, out of procedure to the calling statement. Place the reserved word var in the parameter list in front of the parameter whose value we want to calculate end then send out from the procedure to the calling statement. The Inc(x) procedure Inc() use variable parameters. Inc(x) is same as x := x + 1;
Example of parameter as method to use to provide return value. unit C12e08u;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls, Spin;
type
TfrmFee = class(TForm)
sedTakings: TSpinEdit;
btnFee: TButton;
lblFee: TLabel;
procedure btnFeeClick(Sender: TObject);
private
{ Private declarations }
procedure CalcFee (Takings: integer; var FeeStr: string);
public
{ Public declarations }
end; // end TfrmFee = class(TForm)
var
frmFee: TfrmFee;
implementation
{$R *.dfm}
procedure TfrmFee.CalcFee (Takings: integer; var FeeStr: string);
var
Fee: double;
begin
Fee := Takings * 0.075 + 20; //Calculate fee
FeeStr := 'The fee is ' + FloatToStrF(Fee, ffCurrency, 15, 2)
end; // procedure CalcFee
procedure TfrmFee.btnFeeClick(Sender: TObject);
var
FeeStr: string;
begin
CalcFee(sedTakings.Value, FeeStr); // Proc call: derive string
lblFee.Caption := FeeStr; //display it
end; // procedure TfrmFee.btnFeeClick
end.
CalcFee takes two parameters: Takings, value parameter of type integer, and FeeStr, variable parameter of type string. Reserve word var is immediately before FeeStr in parameter list. Have both variable parameters, declared in the method header and local variables, declared between method header and the begin statement. Parameters provide communication between calling statement and procedure and has value outside the method. Local variables are available only inside a method. TSpeedButton Properties AllowAllUp If allowAllUp is True, all SpeedButtons in group can be unselected. If
False, group acts like group of RadioButtons. Down To select SpeedButton, set Down property to True. GroupIndex SpeedButtons can function independently or in group. If GroupIndex
is zero, it functions independently. If several SpeedButtons have same nonzero value for GroupIndex, they function as a group
Prefix spd... Use Speed buttons often have images on their faces and used with panels to create
toolbars. Can function either independently or in groups. unit C12e09u;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, Buttons, StdCtrls;
type
TfrmMarkUp = class(TForm)
gpbWholesale: TGroupBox;
gpbMarkUp: TGroupBox;
gpbSelling: TGroupBox;
edtWholesale: TEdit;
lblSelling: TLabel;
spdFifteen: TSpeedButton;
spdTwenty: TSpeedButton;
spdTwentyFive: TSpeedButton;
bmbReset: TBitBtn;
procedure spdFifteenClick(Sender: TObject);
procedure bmbResetClick(Sender: TObject);
procedure spdTwentyClick(Sender: TObject);
procedure spdTwentyFiveClick(Sender: TObject);
private
{ Private declarations }
procedure SellingPrice (Cost: String; Markup: double;
var SellStr: string); // new method
public
{ Public declarations }
end;
var
frmMarkUp: TfrmMarkUp;
implementation
{$R *.dfm}
procedure TfrmMarkUp.SellingPrice (Cost: String; Markup: double;
var SellStr: string); // new method
var
Wholesale, Selling: double;
begin
Wholesale := StrToFloat(Cost);
Selling := Wholesale + Wholesale * Markup; // add markup
SellStr := FloatToStrF(Selling, ffCurrency, 15, 2);
end; // procedure TfrmMarkUp.SellingPrice
procedure TfrmMarkUp.spdFifteenClick(Sender: TObject);
var
SellStr: string;
begin
SellingPrice(edtWholesale.Text, 0.15, SellStr);
lblSelling.Caption := SellStr;
end; // procedure TfrmMarkUp.spdFifteenClick
procedure TfrmMarkUp.spdTwentyClick(Sender: TObject);
var
SellStr: string;
begin
SellingPrice(edtWholesale.Text, 0.2, SellStr);
lblSelling.Caption := SellStr;
end;
procedure TfrmMarkUp.spdTwentyFiveClick(Sender: TObject);
var
SellStr: string;
begin
SellingPrice(edtWholesale.Text, 0.25, SellStr);
lblSelling.Caption := SellStr;
end;
procedure TfrmMarkUp.bmbResetClick(Sender: TObject);
begin
edtWholesale.clear; // clear wholesale price
lblSelling.Caption := ''; //clear selling price
edtWholesale.SetFocus;
spdFifteen.down := false; // setet 15% button
spdTwenty.down := false; // setet 15% button
spdTwentyFive.down := false; // setet 15% button
end;
end.
Constant parameter – restricted version of value parameter since cannot change values. Using where appropriate can limit chance of changing values by mistake. Out parameter – restricted version of variable parameter, can only return value from method and cannot bring value into method the way variable parameter can. Procedure SellingPrice (const Cost: string; const Markup: double;
out SellStr: string);
User Interface Factors Reversibility – reversibility state user should be able to backtrack when choices are made. User should ideally fell free to experiment with interface without being concerned that they will do something wrong that cannot be undone. Conflicting principles – Different user interface design principles may conflict with each other (eg reversibility and economy).
Functions and Exceptions
- Event Handlers = special type of procedure, activated by user-events such as mouse click, but also called by system-events as OnTimer or OnFormShow
- Standard Methods = may be either procedures or functions. Provide capabilities of different types of object (eg Ellipse of Canvas object)
- Standard Subroutines = StrToInt and ShowMessage, may be either procedures or functions
- Programmer-written methods = programmer writes, eg SellingPrice procedure There are similarities between functions and procedure. Also differences: functions designed particularly for doing arithmetic and mathematical operations and supply single value without using variable or out parameters. Functions may be either methods (part of class) or standalone functions. Delphi’s standard functions doing string handling NewValue := StrToInt(‘2468’);
CapitalsStr := UpperCase(‘This is a crazy string’);
Message Dialogs also involve functions If MessageDlg(‘Do you want to exit?’, mtConfirmation,
[bYes, mbNo], 0) = mrYes then
// executed if user clock Yes
Else
// executed if user clicks No
Functions different from procedures, function’s name carries a value. Examples StrToInt ot UpperCase have values assigned to variables, MessageDlg has value that can be tested in IF statement. Procedure names do not carry any values, supply through the VAR and OUT parameters in their parameter list. unit C13e01u;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls, Buttons;
type
TfrmTax = class(TForm)
gpbSell: TGroupBox;
gpbTax: TGroupBox;
edtSell: TEdit;
lblTax: TLabel;
bmbOK: TBitBtn;
bmbClear: TBitBtn;
procedure bmbOKClick(Sender: TObject);
procedure bmbClearClick(Sender: TObject);
private
{ Private declarations }
function TaxIncl (Selling, Rate: double): double; //added
public
{ Public declarations }
end;
var
frmTax: TfrmTax;
implementation
{$R *.dfm}
function TfrmTax.TaxIncl (Selling, Rate: double): double; //added
begin
Result := (Selling * Rate) + Selling;
end; // function TfrmTax.TaxIncl
procedure TfrmTax.bmbOKClick(Sender: TObject);
const
Rate = 0.14;
var
Selling, Tax: double;
begin
try
Selling := StrToFloat(edtSell.Text); //convert input to double
Tax := TaxIncl(Selling, Rate); // calculate tax via function
lblTax.Caption := FloatToStrF(Tax, ffCurrency, 15,2); //display
except
ShowMessage('Invalid Input');
bmbClear.Click; // Reset interface by 'Clicking' bmbClear
end;
end;
procedure TfrmTax.bmbClearClick(Sender: TObject);
begin
lblTax.Caption := '';
edtSell.Clear;
edtSell.SetFocus;
end; //procedure tFrmTax.bmbClearClick;
end.
General form of function declaration: Function FunctionName (ParameterList): ReturnType;
Use only value or constant parameters to bring values into function. Function calcuolate value of type ReturnType attached to function’s name, and function’s name similar to variable’s name. Heade definition is similar to function declaration except class name attached to front of function name Declaration:
function TaxIncl (Selling, Rate: double): double;
Function header includes name of class: function TfrmTax.TaxIncl (Selling, Rate: double): double;
Delphi create temporary Result variable when a function is called. Use Result to set value calling statement receives when function end. Alternative use function name (TaxIncl) instead of Result: TaxIncl := (Selling * Rate) + Selling;
Enhancing the IF Statements Improve IF statements in some way: Statement: If status = true then
Alternative: If status then
Statement: If validate (A, B, C) = true then
Alternative: If validate (A, B, C) then
Statement: If (Sum > 0) and (Leftover = 0) then
Result := true
Else
Result := false;
Alternative: Result := (Sum > 0) and (Leftover = 0);
Statment: If Validate (A, B, C) = true then
ShowAccessStatus (true)
Else
ShowAccessStatus (false);
Alternative: ShowAccessStatus (Validate (A, B, C));
Differences between functions and procedures Procedure declaration using constant and out parameters: Procedure DoCalc (const InValue: Integer;
out OutValue: Double);
Function declaration: Function OutValue (const InValue: Integer): Double;
Subsequent program steps for procedure: DoCalc(InVal, OutVal);
Function call: OutVal := OutValue(InVal);
If wanted to add 10 to value calculated by subroutine, procedure would be: DoCalc(InVal, OutVal);
Final := OutVal + 10;
Function part of expression: Final := OutValue(InVal) + 10;
Nested Function Calls Advantage of functions is that function is similar to a variable. Procedure TfrmFuncProc.btnDoubleClick(Sender: TObject);
Begin
lblOut.Caption := IntToStr(StrToInt(edtIn.text) * 2);
end; //procedure TfrmFuncProc.btnDoubleClick
First function call StrToInt(edtIn.Text) convert input value to integer. This takes integer value and can be doubled (* 2). Expression after doubling also has value, use as parameter in IntToStr function call. This return string value which can be assigned directly to Label’s Caption.
Exception Handling When exception occurs in subroutine that does not have exception handler, that subroutine terminates and exception return occurs to the calling subroutine. If subroutine has exception handling path, exception is steered through it. If not, subroutine is also abandoned and exception return happens to its calling subroutine and so on. If not include any specific exception handling for particular exception anywhere in program, Delphi calls default exception handler which then display message. Program from example: Procedure TfrmAccess.ReadCode (out A, B, C: integer);
Var
strValue: string;
begin
strValue := edtCode.Text;
C := StrToInt(strValue[3]);
B := StrToInt(strValue[2]);
A := StrToInt(strValue[1]);
End; //procedure TfrmAccess.ReadCode
Procedure TfrmAccess.bmbOKClick(Sender: TObject);
Var
A, B, C: integer;
Begin
ReadCode(A, B, C);
ShowAccessStatus(Validate(A, B, C));
ResetUI;
End; // procedure TfrmAccess.bmbOKClick;
When user enter alphabetic string into edtCode, StrToInt function raises exception. ReadCode is abandoned and execution returns to subroutine call. Because exception not handled it is still alive. bmbOKClick does not have calling routines and Delphi default exception action and display exception message. Accepting three characters only Use RAISE keyword to generate own exception: Procedure TfrmAccess.ReadCode (out A, B, C: integer);
Var
strValue: string;
begin
strValue := edtCode.Text;
if length (strValue) <> 3 then
raise Exception.create (‘Length Invalid’);
C := StrToInt(strValue[3]);
B := StrToInt(strValue[2]);
A := StrToInt(strValue[1]);
End; //procedure TfrmAccess.ReadCode
Must change bmbOKCLick to handle the exception in orderly way and update display accordingly Procedure TfrmAccess.bmbOKClick(Sender: TObject);
Var
A, B, C: integer;
Begin
try
ReadCode(A, B, C);
Except
A := 0;
B := 0;
C := 0;
Showmessage (‘Recovery from an exception’); //test mess
End;
ShowAccessStatus(Validate(A, B, C));
ResetUI;
End; // procedure TfrmAccess.bmbOKClick;
If user enter alphabetic character or code not three digits long, an exception occurs in ReadCode, causing exception return to bmbOKClick. bmbOKClick now has exception handling and execution is not abandoned but continues in the exception handling path. Parameters set to zero and suitable message displayed. Exception can be raised in one place and handled somewhere else. Exception raised either in StrRoInt ot ReadCode procedure but handled in bmbOKClick event handler. The try...finally construction Can be used when finalisation code must be executed irrespective of whether or not exception occurs. Want to ResetUI to run irrespective of whether or not exception occurred. Can wrap a try...finally around a try...except statement: Procedure TfrmAccess.bmbOKCLick(Sender: TObject);
Var
A, B, C: integer;
Begin
Try
Try
readCode(A, B, C);
ShowAccessStatus(Validate(A, B, C));
Except
ShowAccessStatus(false); //force error display
End; //end try...except
Finally
resetUI;
end; // end try...finally
end; // procedure TfrmAccess.bmbOKClick;
IIf axception occurs in call line execution continues which calls ShowAccessStatus with parameter set to false. The end; terminates the try..except section and finally introduces code that runs irrespective of whether exception has occurred or not. Delphi guarantees ResetUI will always run. We give no notification that exception handling has been performed.
Recommended