Porting REALbasic applications to Windows

I recently ported Belle Nuit Textfilter from Macintosh to Windows 2000 using the latest version of REALbasic 4.

REALbasic does a great job in porting the code, so I needed only some adaptations to have a working application in Windows 2000.

I want to explain some of the adaptations so you can use them for your application.

Platform

Decide what platform you are going to support. I only have access to Windows 2000 systems, so I will only support them. They should work on 95,98,NT and XP as well, but i will not be able to test them. Avoid the situation having clients complaining about bugs on configurations you cannot test.

File format

If you are going to provide a cross-platform application, your documents should be cross-platform, too. You can go three ways

The last option works great for small data like TextFilter projects. It uses HTML-entities for special characters, binhex-style encoding for binary data and is human-readable as textfile, which is great for debugging.

Filetypes

Be sure to use the order of file extensions you want for the filetypes. The first extension is the one that will be used for saving files. If you use ".ascii;.text;.txt" files will be saved as "myfile.ascii", however if you use ".txt;.ascii;.text", it will still open all these types, but save them as "myfile.txt".

Given you have defined the filetype ".tfp" for your documents, you can tell Windows 2000 that it should open ".tfp" files with your application when you double-click on it, using Folder Options.

Click Change, then Other to select yourapplication.exe as the connected application.

Drop me a mail to matti@belle-nuit.com if you know a better solution (like a shell command which could be executed on installation).

Conditional compiling

Avoid splitting the project in two versions, you will not be able to maintain the code. Use conditional compiling instead.

#if targetmacos then
do this
#else
do the windows stuff
#end if

But on repeating code, it is even better to use Constants or Small platform dependent methods as below.

Constants

Use constants whenever possible for the most platform-dependent strings. This avoids too much conditional compiling.

Name Macintosh Windows
Newline chr(13) chr(13)+chr(10)

It is sometimes a little bit difficult to copy special characters in the constants-definitions. You can, however, also define global properties in a module and assign values to them in an Init method.
Sometimes, it is even more complex, so you will write a global method (see the Preferences File example). The global method is still better than using conditional compiling with the same code on two places.

Preferences file

As there is no preferences folder, I use a textfilter.ini file in the applications folder.This makes some changes in the readpreferences and the writepreferences method of the application class.As the rest of the code is not platform-specific, i create a global getpreferencesfolderitem method

Function GetPreferenceFolderItem() as FolderItem
dim f as folderItem
#if targetmacos
 f = PreferencesFolder.child("TextFilter Preferences")
#else
 f = Getfolderitem("textfilter.ini")
#endif
return f
End Function

SDI or MDI application

You have to decide if you want to make a single document interface (SDI) or a multiple document interface (MDI). If you do MDI, there is a mother window with the menus which does hold the document windows. You do not have much things to add. In SDI, there can only be one document window at one time, with its menu. However, you can have multiple instances of the application.

When you decide for SDI, then you have to change some code.

f=getfolderItem("textfilter.exe")
if f<>nil then
 f.launch
else
 beep
end

Be sure that the user does not rename the application.

User Interface

Checkboxes have a gray background (in fact the gray of the window). This poses a problem for me, because I have a rectangle behind them. I choose then a background color according to the gray background of the window, but the problem is that this window color depends on the appearance settings of the application. I found a workaround which does work half way. I look for a pixel the windows.graphics at a place where I know there are no interface elements. The problem is, that i can ask this property only once the window is drawn, so that this code can neither be used in the rectangles nor in the windows open event. I had to put a timer in the window (single execution, 1 ms) with the code

#if targetwin32 then
parameterrect.fillColor = self.graphics.pixel(self.width-3,3)
#endif

I still set the initial color to middle gray to reduce flicker. If somebody has a better solution how to get this colors, please drop me a mail to matti@belle-nuit.com

I had problems with Popup-menus which did not pop-up in windows. It was difficult to find the actual reason, has to do with some dynamic resizing and control arrays, anyway, I use the popup-menus now only in the mac version and use bevelbuttons in the windows version. This makes them also more ressemble the pushbuttons.

Rectcontrols which have common left,top,width and height properties will be visible and invisible at the same time (parent-child relationship). I had the problem with an Editfield and a Listbox to be shown alternatively, this is not possible. The workaround is to displace the second control by one pixel.

Application icon

Apparently, you cannot override the application icon with an imported ressource file as you can with Macintosh. If you copy a normal icon from ResEdit to the application build settings, you are screwed, because you did not drag the mask with it (and you cannot even remove it any more!), so that the application will just have a blank rectangle as icon. The RB IDE help recommends an Icon Paste utility I did not found on the CD.The solution is to build the application for Macintosh, then to copy the icon from the GetInfo window to the application settings.

Text Encoding

You can use text encoding to convert text, but you must be aware that the native text encoding is not the same. Define a constant for TextEncoding, 0 for MacRoman and &h0500 for Windows. Now if someone has a clue how to get the native encoding other than the MacRoman from the system (in both platforms), please drop me a mail to matti@belle-nuit.com

Known Limitations

I had problems with the following features of Realbasic

DLLs

The application is self-contained, but on the first run, it does actually install some DLLs in the system folder (C:WINNT, C:WINNTsystem32). The files i suspect being from REALbasic are:

The same file are installed twice in both folders.It looks like these files are created on every new build and modified on every run.

It may happen now the rare case where you are installing on another disk, while the disk C: is full and it cannot create the DLLs. In this case you will get some very strange error message about invalid DLLs.