Virtual Pascal for OS/2 v1.10 Frequently Asked Questions (C) 1996 fPrint UK Ltd The answers to many of these questions can be found in the printed manual too. Q: When I write a program, any "read" and "write" statements are syntax highlighted along with reserved words. Why? A: In the new object model, available in the {$Delphi+} state, Read and Write are standard directives used in property definitions. A future version of VP/2 will allow you to specify separate colours for standard directives and reserved words. Q: I am not able to generate any PM programs! The program compiles and links OK, but the executable is not a PM program. Am I doing something wrong? A: You have to specify the application type to be PM application (Options|Linker|Application radio buttons). Alternatively, you can specify the {$PMTYPE Parm} directive to set the application type. Q: I have just created a Presentation Manager application, and I want to debug it using Virtual Pascal. Once I get past the point where the message queue is created, the system hangs! What do I do wrong? A: OS/2 Presentation Manager programs can only be debugged safely if you run Virtual Pascal in a Full Screen session or if you run VP/PM. VP/Txt in a window on the desktop should be used to debug text-mode applications only. Q: The clock PM apps compiles and runs fine, but the PM game triplex compiles, but does nothing. It's there as a process but there is no window. A: The compiler is not able to find the resource files required by the application. You have either to change to the directory where your resource file is located or include this directory into Options|Directories|Resource directories input box. Also check the messages in the Messages window. Compilation should include the following stages: Compiling... Linking... Compiling resources... (if there is no binary resource file or the resource script file is newer than the binary resource) Binding resources... (if binary resource file is found) Success. Q: How can I make VP to compile and add resources to my program? In BP7 under Windows I use the {$R filename.res} directive. A: You can use the $R statement in VP as well. Make sure that the .RES file in question is available in either the current directory or in a directory listed in the Options|Directories|Resource Dirs entry field. Q1: I want to port a UI unit I wrote using Turbo Pascal to VP. In it I need to write directly to the screen. How can I do this in VP? Q2: VP does not compile "absolute $B800:$0000" for video memory. I tried defining the addresses through variables, but then I receive a RUNTIME error #216. A: Absolute memory addresses have no meaning in protected mode, so they are not supported. You can use the following code to obtain a pointer to the logical screen buffer, write something to it and then show its contents. ===Cut=== { Fills entire screen with character 'A' } uses Os2Base, Use32; type PScreenBuffer = ^TScreenBuffer; TScreenBuffer = array [0..7999] of record Ch: Char; Attr: Byte; end; var I: Integer; BufSize: SmallWord; ScreenBuffer: Pointer; begin VioGetBuf(ScreenBuffer, BufSize, 0); { Get logical screen buffer address } SelToFlat(ScreenBuffer); { Convert it from selector:offset form to flat } for I := 0 to BufSize div 2 - 1 do with PScreenBuffer(ScreenBuffer)^[I] do begin Ch := 'A'; { 'A' } Attr := $4F; { White on red } end; VioShowBuf(0, { Buffer offset } BufSize, { Length in bytes to show } 0); { Vio handle - should be 0 for text mode apps } end. ===Cut=== Q: The following code brings up the error-message: Error 26: Type mismatch uses Dos; var Year,Month,Day,DayOfWeek: Word; begin GetDate(Year,Month,Day,DayOfWeek); end. A: You have to include the Use32 unit in uses of each unit. Please refer to the manual for details. Q: The Delay function from the Crt unit seems does not work correctly if values less then 150 are specified. A: The OS/2 system timer interval is 31ms, which is why it is not possible to make a delay less than this value using the OS/2 API. VP/2 uses a special routine for small time intervals to make small delays. Unfortunately, even this routine cannot be exact in a multi-tasking environment like OS/2. Q: Ctrl-F2 in BP is like Shift-F4 in VP/2; why not make it the same ? A: The are not quite the same. Since the VP/2 IDE includes some features from the standalone debugger, there are 2 functions: Ctrl-F2 and Shift-F4. Ctrl-F2 - Restart program - is the same as the Turbo Debugger Reset program. You should use it to restart a debugging session, and debug your program once more. You can also use it to load a just compiled program (BP does not have this feature at all). Shift-F4 is like Reset Program in BP, but you are not able to run/debug your program without recompilation, since it terminates the debugging session and frees the debug information. Q: In the integrated debugger, even after termination of the program, the session with program output is still available and debugging process is still present in the task list. How can I get rid of it? A: After termination of the program, you still can examine the value of static variables (typed constant and global variables) and see the program's screen output. You can use the Run|Reset program command (Shift-F4) to terminate the debugging session and free the debug information. It also deletes the screen session of the debugging program. However, having done so, further debugging is not possible unless you recompile the program. Q: Even though the source is compiled, if I load program I can not step through the source (The assembler window takes focus). What happens? A: You have to enable {$D+} (Options|Compiler|Debug information is checked). Q: Unlike BP, the value of the iteration index becomes 1 more than the number of iterations in FOR loop. For example: for I := 1 to 4 do; at this point VP says I = 5 whereas TP says I = 4. Is there something wrong? A: No, VP generates different code for FOR loops. The value of the FOR control variable is not defined by the language and depends on different implementations of the compiler. You should not rely on the value of the FOR control variable outside the loop body. Q: Since VP is a 32-bit compiler and has no 64K restriction on size of the variables, I tried to compile a little program like this: ===Cut=== var HugeVar: array[0..32*1024*1024] of Byte; begin FillChar(HugeVar, SizeOf(HugeVar), 'A'); end. ===Cut=== but receive the following message from LINK386: LINK386 : fatal error L1204 A: Use the built-in linker of VP/2 instead of LINK386. The built-in linker does not have the restrictions imposed by LINK386. Q: When I compile code containing "DosError", the compiler reports an error saying something resembling, "Error: '(' expected" after the "DosError" variable, as if it expected arguments, like in a procedure call. To work around this, I replaced "DosError" with "Dos.DosError" to direct VP to the DOS unit. It compiled successfully this way. Any idea why? Should I be using "DosError" in a special way? A: OS/2 has function named DosError, defined in the Os2Base unit. Thus, if the Dos unit is included before Os2Base in your Uses clause, the DosError function from Os2Base unit is found before the Dos unit variable. You have either to put the Dos unit after Os2Base in the uses clause or use a fully qualified identifier - the latter being the recommended way of resolving the problem. Q: I use the following code fragment to search for files, but it never returns the volume label. Am I doing something wrong? ===Cut=== FindFirst('*.*', $3F, SR); ===Cut== A: The volume label is not returned by the OS/2 version of FindFirst. If you want to query the volume label, you need to use the DosQueryFSInfo API call: ===Cut=== Uses Use32, Os2Def, Os2Base; Var DriveNumber : Word; Buf : Record SerialNum : Word; VolLabel : String; end; Begin DriveNumber := 3; { Drive C } DosQueryFSInfo( DriveNumber, fsil_VolSer, Buf, Sizeof( Buf )); End; ===Cut=== Q: The ChDir standard procedure does not work correctly. If I change my directory in a program and leave the program I find the working directory unaltered. What is wrong? A: OS/2 maintains a current directory for each process. If you change the current directory in your program, it does not affect the current directory of the parent process (usually CMD.EXE which is used to run your program). That is why when your program terminates, the current directory remains the same as it was before running it. Q: I have noticed that PathStr have changed from String[79] in BP to String. DirStr, NameStr and ExtStr have changed too. Is there a reason for that? A: Yes, VP supports HPFS long file names of the OS/2. The length of each path component can be up to 255 characters long. That is why PathStr and other types in Dos unit have been extended to String type. The File and Text variables have been expanded accordingly to hold long file names (cf the FileRec and TextRec types in Dos unit). Q: I can not declare a variable of the important type REGISTERS. Please give me a hint. A: Neither MsDos or Intr from Borland Pascal are supported. OS/2 application have no access to the BIOS/DOS API like BIOS/DOS interrupts, DPMI, etc. OS/2 performs all file I/O, video and memory management tasks itself. The only way to support these functions is to emulate all DOS API using the OS/2 API which is almost impossible to do. Instead of using DOS and BIOS calls you should use base OS/2 API calls, defined in the Os2Base unit or make use of the interface functions provided in the VPUtils unit. Q: What should I do with my 16-bit inline assembler codes? A: Since 16-bit inline codes should be rewritten as 32-bit code, you have two alternatives: - replace the offending inline statement with an ASM ... END statement; - use inline functions/procedures that can be written in Pascal (cf inline procedural directive, see the manual for details). Q: I have just got some strange test results with the MaxAvail and MemAvail functions. Normally MaxAvail <= MemAvail, but in some cases MemAvail > MaxAvail...? A: MemAvail and MaxAvail gives you only rough estimates of the remaining memory, since system conditions change constantly in a multitasking environment. Your results just means that another process (or the system itself) has allocated (or freed) some memory between the calls to MemAvail and MaxAvail. Q: With MemAvail being unreliable, is there a way of accurately finding out if my program suffers from a memory loss because I forget to free some dynamically allocated memory? A: Yes; the MemUsed function in VPUtils returns the number of bytes currently allocated on the heap. Q: In many of my old programs, I return $FFFF in a Word variable to signal "failure" or "not found". In Virtual Pascal, a Word is 32 bit so my test fails. What should I do to make the code work with both BP7 and VP/2? A: Typecast -1 to Word and compare with this value. In VP, Word(-1) is $FFFFFFFF, and in BP, Word(-1) is $FFFF. For your comparison to work in both Borland and Virtual Pascal, it should be ===Cut=== If Test <> Word(-1) then Writeln('Found'); ===Cut=== Q: VP.EXE starts from both DOS and OS/2 tasks, and never gives an error saying "This program requires OS/2". This is nice, and I want my programs to do the same! How? A: Any program linked with the built-in linker of VP/2 will behave in this way. Q: I have defined a PM dialog, that requires a function of type FnWp as a parameter. I have defined a function of this type, and specify the name of the function in the WinDlgBox call. When I compile, I get a "Type Conflict" error. Why? A: Provided the function header is correct, and matches the definition in Os2PmApi, you probably use the wrong calling convention. This procedure needs to be called by OS/2, and needs to use the C-style calling convention. Adding the cdecl; procedural directive after the function definition will probably make it work. Q: I wish to save the current directory when I save my desktop settings, just like in Borland Pascal. How do I do this? A: Check the "Return to last dir" checkbox in the Options|Environment|Preferences dialog. Q: I have written multithreaded programs using the Beta or EEP version of VP/2, and the BeginThread calls do not compile anymore. What has changed? A: The BeginThread function has changed to take the same parameters as in Borland Delphi v2. This means, that the thread function should be declared as Function ThreadFunc( P : Pointer ) : Longint; In addition to this change, a number of extra parameters are required. If you just want to start a thread and use a set of default values that normally make sense, you can use VPUtils.VPBeginThread. Q: I have enabled Smart Linking to prevent unused functions from taking up space in my executable. If I look at the output file, not all of them are removed! Why? How can I make this work? A: This requires a bit of explanation: The first step of Smart Linking in VP/2 takes place at compile time. When Smart Linking is disabled, the compiler generates one object module (which is stored in an .OBJ file) per unit and these modules are then linked to form the executable. When Smart Linking is enabled, one object module per procedure, function and typed constant is generated and the result is stored in a .LIB file. At link time, only those object modules required by the application are linked into the executable. To link the executable, the linker needs the main file to be an OBJ file, however. Thus, any functions defined in the main program file are not smart linked away. If this is a problem, the solution is to have an "empty" main program, that only uses one unit and calls the main function of that unit as its only action. Q: I have a program that uses the new SysUtils unit. When an exception occurs, a big red screen pops up! What is wrong? A: When an exception causes the program to terminate, the termination routines can either display the message in Grey on Black as it happens for run-time errors, or it can display the message in a full-screen window to prevent the user screen from being corrupted by the error message. The default is the last approach; you can change this behaviour by setting PopupErrors := False; Q: I have enabled Exception Location Information in all units, but my program crashes without displaying line number information. Why? A1:Only units compiled in the {$D+,LocInfo+} state will have location information available. If you program crashes in a unit not compiled in this state, for example the System unit, no ELI will be displayed. A2:Remember to check the Options|Linker|Generate Location Info checkbox in the Options|Linker dialog. Q: I have found the OS/2 .SYM files on the OS/2 CD-ROM; how do I make use of these in VP/2's debugger? A: Specify the directory containing the files as a parameter to VP. For example, if some of the files are in C:\VP11\SYM and some in D:\SYM, start VPPM.EXE with VPPM.EXE /sC:\VP11\SYM;D:\SYM or change the Parameters section in the settings/proprties for the VP program objects on the desktop. Q: The compiler complains that my $LINKER statement is invalid, though I have checked that all the keywords are valid. Why? A: All statements in a $LINKER statement (or .DEF file) are case sensitive and must be entered in upper case. Q: How do I determine what type of disk is associated with a particular drive letter? A: Call the GetDriveType function of the VPUtils unit with the drive letter as the parameter. This function returns one of the following enumerated values: dtFloppy - Floppy disk dtHDFAT - FAT Hard Disk Drive dtHDHPFS - HPFS Hard Disk Drive dtInvalid - Invalid drive dtNovellNet - Novell Net drive dtCDRom - CD ROM drive dtLAN - LAN drive Q: I would like to get a list of all valid drive letters on a system. How? A: The GetValidDrives procedure in the VPUtils unit returns a set containing all valid drive letters.