Sign in Join
Wiki copytemporary

Pascal for Visual Basic users: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: Pascal for Visual Basic users

OldNewLine
1+## Overview
2+
3+This wiki page has been created to help you if you are switching from Visual Basic to Free Pascal (the Pascal dialect and compiler used by Lazarus). It is not meant to convince you that Lazarus is better than VB (or vice versa). Although VB and Pascal have superficial similarities these two languages differ greatly. Since VB programmers beginning to use Pascal face immediate difficulties in trying to do things which in VB have nice syntax that Pascal does not provide, we focus here on those differences.
4+
5+## Comparison and assignment of values
6+
7+Values in Pascal are compared using the = operator.
8+
9+Values in Pascal are assigned using the := operator (there is a : added).
10+
11+For example:
12+
13+``` pascal
14+if a = 1 then b := 2;
15+```
16+
17+## Beginning and ending statements
18+
19+Blocks of Pascal code have no distinguishing end statements for functions, procedures, loops, etc. Pascal needs only **begin** and **end**. You can easily add a comment manually following **end** statements to clarify which named routine corresponds to this particular **end;**.
20+
21+For example:
22+
23+``` pascal
24+for i := 0 to 100 do
25+begin
26+ ...
27+end; // for i do
28+```
29+
30+## Variables
31+
32+### Declaring variables
33+
34+In Pascal **all** variables have to be declared before use, and you have to make the declarations in a special **var** section which must precede the code that makes use of the variable. You cannot declare a new variable in the middle of code.
35+
36+For example:
37+
38+``` pascal
39+procedure VarDecl;
40+var
41+ MyVar1: string;
42+ Myvar2, MyVar3: integer; //Multiple variables can be declared on the same line.
43+begin
44+ WriteLn('Print something');
45+ var MyVar4: string = 'else'; // This declaration is not allowed here - it must be moved three lines above to the var section
46+ WriteLn('Print something ', MyVar2);
47+end; //VarDecl
48+```
49+
50+Local variables do not get initialized upon declaration. They get random value (whatever value happen to be on the stack where they landed). Global variables are initialized to zero.
51+
52+To initialize a local variable upon declaration the following syntax can be used in procedures and functions only.
53+
54+``` pascal
55+var
56+ MyVar1: string = '';
57+ MyVar2: integer = 0;
58+```
59+
60+### Types of variables
61+
62+Besides the variables known in VB, Free Pascal supports unsigned integers. You should pay special attention not to mix them with signed integers.
63+
64+## Loops
65+
66+Free Pascal has four kinds of loops.
67+
68+[[Basic Pascal Tutorial/Chapter 3/FOR..DO|for... do...]]
69+
70+[[Basic Pascal Tutorial/Chapter 3/WHILE..DO|while... do]]
71+
72+[[Until|repeat... until]]
73+
74+[[for-in loop|for.. in..]]
75+
76+**Note:** In FPC there is the [[Continue]] procedure to jump to the end of the loop.
77+
78+### For... do...
79+
80+This is quite similar to the For.. Next loop in VB, but more limited in syntax. The following restrictions apply in Pascal:
81+
82+1\. A for loop counter must be an integer (it cannot be a floating point type).
83+
84+2\. There is no Step property. To emulate the VB Step syntax you have to introduce a second counter variable yourself.
85+
86+3\. To decrement the value of the loop counter from a positive value, you use the keyword DOWNTO in place of TO.
87+
88+For example:
89+
90+``` pascal
91+procedure ForLoop;
92+var
93+ i: integer;
94+begin
95+ for i := 50 downto 0 do
96+ begin
97+ ...
98+ end; // for i
99+end. // procedure ForLoop
100+```
101+
102+4\. In Lazarus it is possible to loop down when the index is a **byte**, which is **not** possible in VB6.
103+
104+``` pascal
105+procedure ForLoop;
106+var
107+ i: byte;
108+begin
109+ for i := 200 downto 195 do
110+ begin
111+ ShowMessage (IntToStr (i));
112+ end;
113+end;
114+```
115+
116+5\. The value of the counter (i in the example above) can**not** be changed programmatically inside the loop. Attempting to do so will throw a compiler error. Instead one could use *Continue* to skip execution of a loop:
117+
118+``` pascal
119+procedure ForLoop;
120+var
121+ i: integer;
122+begin
123+ for i := 0 to 5 do
124+ begin
125+ if i=2 then Continue; //Following part of the loop will not be executed
126+ ShowMessage (IntToStr (i));
127+ end; // for i
128+end. // procedure ForLoop
129+```
130+
131+6\. In order to interrupt execution of a loop one could use *Break*.
132+
133+``` pascal
134+procedure ForLoop;
135+var
136+ i: integer;
137+begin
138+ for i := 0 to 5 do
139+ begin
140+ if i=2 then
141+ begin
142+ ShowMessage (IntToStr (i));
143+ break;
144+ end; //if
145+ end; // for i
146+end. // procedure ForLoop
147+```
148+
149+## Functions and procedures
150+
151+Output of functions is supplied as:
152+
153+``` pascal
154+Result:=Value
155+```
156+
157+Note that *Result:=* does **not** act as *Return*. Function will **not** exit after assigning it.
158+
159+One should use
160+
161+``` pascal
162+exit(Value)
163+```
164+
165+instead.
166+
167+### Visibility
168+
169+In FPC a function or a procedure cannot see another one, which is written **after** it.
170+
171+Example:
172+
173+``` pascal
174+procedure Proc1;
175+begin
176+ Proc2; //This is not possible
177+end;
178+
179+procedure Proc2;
180+begin
181+ Proc1; //This is possible
182+end;
183+```
184+
185+To enable visibility, disregarding writing order, functions and procedures have to be declared.
186+
187+``` pascal
188+unit MyUnit;
189+...
190+procedure Proc1;
191+procedure Proc2;
192+...
193+implementation
194+
195+procedure Proc1;
196+begin
197+ Proc2; //This is possible now
198+end;
199+
200+procedure Proc2;
201+begin
202+ Proc1; //This is possible
203+end;
204+```
205+
206+### Using default parameters in functions and procedures
207+
208+In Pascal functions and procedures it is possible for parameters to automatically take default values. However, in the parameter list the parameters that might take default values must be declared as a contiguous list at the end of the parameter declaration part. Also, when a routine with default parameter(s) is subsequently called in your code, you can only specify non-default values beginning at the first parameter which would otherwise take a default value. You cannot specify a non-default value for a later parameter, if there are preceding parameters you have to specify values for which have not also been specified explicitly in the function or procedure call.
209+
210+For example:
211+
212+If a procedure is declared (correctly) as follows with two default parameters:
213+
214+``` pascal
215+procedure SampleProc(parm1: integer; parm2: string= 'something'; parm3:Boolean= True);
216+begin
217+end. //proc
218+```
219+
220+it is not possible to call SampleProc as in VB like this:
221+
222+``` pascal
223+ SampleProc(5,,False);
224+```
225+
226+This will produce a compiler error.
227+
228+When calling a procedure (or function), if you specify a parameter which has a default value, you must also specify all parameters that have a default value that are in front of it. So, in the example above if you want the third parameter to be False, then you must also specify the value of second parameter.
229+
230+These are valid calls:
231+
232+``` pascal
233+ SampleProc(5,'something',False);
234+
235+ SampleProc(5,'nothing');
236+
237+ SampleProc(5,'');
238+
239+ SampleProc(5);
240+```
241+
242+## Dynamic arrays
243+
244+In Pascal the minimum index of a dynamic array is 0, i.e. *MyArray (1)* will return the **second** elements of an array named *MyArray*.
245+
246+Arrays are resized using:
247+
248+``` pascal
249+setlength (MyArray, NewDimension);
250+```
251+
252+*SetLength* does **not** clear the array, i.e. it acts like *ReDim Preserve*, not like *ReDim*.
253+
254+## Translation of some commonly sought commands
255+
256+DoEvents = TApplication.ProcessMessages
257+
258+``` pascal
259+var
260+ app: TApplication;
261+ i: integer;
262+begin
263+ app := TApplication.Create(nil);
264+
265+ for i := 0 to 1000000 do
266+ begin
267+ app.ProcessMessages; // Handling process messages.
268+ OutputDebugString(PChar(IntToStr(i)));
269+ end
270+end;
271+```
272+
273+While the *OutputDebugString* printing the number to *Event Log*, you may do any events with Form without *Freezing* except when you close the form, you must wait the loop until finished.
274+
275+## VB commands, which are not present in FPC/Lazarus
276+
277+*Split* - Split is not a separate function in FPC. It shall be used the following way:
278+
279+``` pascal
280+String1D := '1;2,3;4;5,6'.Split([',',';']);
281+```
282+
283+*Join* works the following way:
284+
285+``` pascal
286+MyString := ''.Join(';',String1D);
287+```
288+
289+## Debugging
290+
291+Lazarus IDE has no Instant panel.
292+
293+In order to debug in Windows the dos prompt windows shall be enabled the following way: *Lazarus IDE-\> Main menu -\> Project -\> Project options... -\> Compiler Options -\> Config and Target -\>* uncheck *Win32 gui application (-WG)*
294+
295+In Linux the console invokes itself.
296+
297+Then the *write* and *writeln* commands can be used to print debug messages.
298+
299+Compiler might give some more information if the following items are checked in the IDE main menu -\> *Project* -\> *Project Option* -\> *Compiler Option* -\> *Debugging* -\> -Ci, -Cr, -Co, -St, -Cr, -Sa.
300+
301+## Substitution tables
302+
303+| VB | [[Pascal]] | Remark |
304+|----|----|----|
305+|   =   |   := |   [[Becomes]]   |
306+|   =   |   = |   [[Equal]] |
307+|   /   |   / |   [[Slash|Float Division]] |
308+|   \\   |   [[Div]] |   |
309+|   &   |   + |   String concatenation |
310+|   MOD |   [[Mod]] |   Modulo operation |
311+|   \<\>   |   \<\> |   [[Not equal]]   |
312+|   Not   |   [[Not]] |   |
313+|   And   |   [[And]] |   |
314+|   Or   |   [[Or]] |   |
315+|   Xor   |   [[Xor]] |   |
316+|   \>\>   |   [[Shr]] |   bit **sh**ift **r**ight   |
317+|   \<\<   |   [[Shl]] |   bit **sh**ift **l**eft   |
318+|   New line   |   ; |   In Pascal lines end with the ; character not by a new line.   |
319+|   _   |   |   No symbol is required for wrapping a line and new line symbols are acceptable within it.   |
320+|   '   |   // |   End of line [[Comments|Comment]] (only one line comment)   |
321+|   Exit For   |   Break |   Interrupt execution of a loop   |
322+
323+| VB type | [[Pascal]] [[Data type|type]] | Size (bits) | Range | Remark |
324+|----|----|----|----|----|
325+|   SByte   |   [[Shortint]] |   8-bit |   -128 .. 127 |   |
326+|   Byte   |   [[Byte]] |   8-bit |   0 .. 255 |   |
327+|   Short |   [[Smallint|SmallInt]] |   16-bit |   -32768 .. 32767   | |
328+|   Char   |   [[Word]] |   16-bit |   0 .. 65535   | |
329+|   Integer   |   [[Integer]] |   32-bit |   -2147483648..2147483647   |   |
330+|   UInteger   |   [[Cardinal]] |   32-bit |   0 .. 4294967295 |   |
331+|   Single   |   [[Single]] |   32-bit |   1.5E-45 .. 3.4E+38   |   Decimal delimiter in both languages, applied **in source code** is dot on the line.   |
332+|   Double   |   [[Double]] |   64-bit |   5.0E-324 .. 1.7E+308   | |
333+|   Boolean   |   [[Boolean]] |   |   [[True]] [[False]] | |
334+| | | | | |
335+
336+### String functions
337+
338+| VB | [[Pascal]] | Remark |
339+|----|----|----|
340+|   &   |   + |   String concatenation |
341+|   Format(item, formatstring) |   format(formatstring, items) |   |
342+|   left(some_string,n) |   leftstr(some_string, n) or copy (some_string,1,n) |   |
343+|   Len(some_string) |   length(some_string) |   |
344+|   LCase(some_string) |   lowercase(some_string) |   |
345+|   Mid(some_string, startpos, numChars) |   copy(some_string, startpos, numChars) |   |
346+|   StrReverse(string) |   See [[Palindrome]] |   |
347+|   UCase(some_string) |   uppercase(some_string) |   |
348+| | | |
349+
350+## Component prefixes
351+
352+There is a [list of component prefixes](http://kodu.ut.ee/~jellen/delphi/cs.html#Components_Instance) for Delphi, which can be used in Lazarus. Using them might provide better code readability.
353+
354+It is also usual to start the name of a type with the capital letter *T*.
355+
356+## Arrays of controls
357+
358+Unlike in VB6 and like in VB.NET arrays of controls cannot be created statically (trough the IDE), and they can be created only dynamically.
359+
360+Example, creating 6 buttons above each other:
361+
362+``` pascal
363+procedure TForm1.FormCreate(Sender: TObject);
364+var
365+ i: Integer;
366+ btnArray: array of TButton;
367+begin
368+ SetLength(btnArray, 6);
369+ for i := 0 to 5 do
370+ begin
371+ btnArray[i] := TButton.Create(Self);
372+ btnArray[i].Left := 0;
373+ btnArray[i].Top := i * 30;
374+ btnArray[i].Parent := Self;
375+ end;
376+end;
377+```
378+
379+## Visual Basic to Delphi (Pascal) Converters
380+
381+- <https://www.marcocantu.com/tools/vb2delphi.htm>
382+- <https://cc.embarcadero.com/item/17064>
383+
384+---
385+*From the Free Pascal wiki, page "Pascal for Visual Basic users", as it stood on 2023-01-25 after a change by Kai Burghardt, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
386+Category: FPC
387+Category: Rosetta Stone

Back to history