Debugging Forms Ported from Delphi to Lazarus

One problem I was encountering in converting a few of the Delphi forms into Lazarus forms is that after I got to the point where everything was compiling, and even the point where I could run the application and bring up the main window, I still couldn’t successfully edit the forms properly.

I’d open the converted LFM (Lazarus form) and it would only display in code-view and not the “Unit View” where you can visually edit the UI. Go to View->Toggle Form/Unit View, which should cause it to switch to Unit view, and nothing would happen. Not so helpful. Or one time the option was greyed out entirely. With no real clear hints about why.

Clearly, something was wrong, and not a lot of feedback about what. I was unsuccessful in finding any guides online about how to troubleshoot such, so it took a bit of tinkering and guessing. So here’s what steps were actually useful in solving the problem.

1. Make sure all expected dependencies are listed in the Project Options (under Compiler Options->Paths)

First, since the form was fully working in Delphi before converting, there’s a very good chance the problem is an unknown property name or an object of an unknown type. This is probably not a totally unfamiliar to a Delphi developer who’s ever had a missing dependency on a form before. But since you’ve probably already done that or you wouldn’t be still trying to fix it…

2. Tools -> Check LFM in Editor

This brings up a window that checks for various errors in the LFM. If anything is found here, you should definitely fix them. In this example, I’d already replaced TDateTimePicker with TDateEdit in the corresponding .pas unit file, since Lazarus doesn’t have quite the exact same component available. But the form needed to be updated too.

Mind you, that wasn’t enough to make the form actually load. But now at least the form check has fixed all the problems it can. The wording on the informational dialog that tells you this could probably stand to be more clear, but  if you thought to read the title, that would be a big hint that this isn’t an error message.

In some cases I found it better to edit the fixes I wanted into the file in notepad rather than letting it automatically delete the objects/properties.

3. Make sure the LFM is open and saved, then select File -> Reload

Hmm, that’s interesting, all of a sudden I’m seeing a new error it didn’t tell me about when I first loaded the form.

It’s not the most easy to decipher error message, but essentially it’s the same sort of message you see in Delphi when you try to load a form that uses a component that’s not in the project path correctly. Stream position (presumably either in bytes or characters) is not nearly as helpful as a line number would be. But it did give me enough information to know what I’m looking for. Unfortunately, TabOrder is all over the file, because almost everything has a tab order. So I decided to take the easy way out and just wipe out all the TabOrder properties (Later I’ll recreate the necessary tab order properties using the GUI builder) and be done with it rather than trying to decipher the Stream position.

4. Turn on Lazarus logging

For one stubborn form, the one that was conveniently almost 3,000 lines long (not easy to find the problem by eye!), I found all these other steps were giving me no further errors or hints as to what was wrong. I researched whether there was any way to turn on a debug log or something for Lazarus. Maybe there’s an error happening or bug it’s not telling me about.

So (after some googling) I copied the shortcut for Lazarus from my start menu onto the desktop, added “ --debug-log=c:\temp\lazarusdebuglog.txt” to the run target, and restarted Lazarus from my new shortcut. I tried the menu option to switch the view that failed, quit lazarus to end caching on the log, and looked at the log. The log actually gave me a very good hint what was wrong.

TMainIDE.DoLoadLFM loading nested class TIdAntiFreeze needed by C:\projectpath\uMain.lfm
TMainIDE.DoLoadLFM DoLoadComponentDependencyHidden NestedClassName=TIdAntiFreeze failed for C:\projectpath\uMain.lfm

There were a couple other lines too, but clearly this was a problem. Dependency problem. I searched the lfm in text view for TIdAntiFreeze and quickly located the offending object on the form, which was easy to delete (to be fixed later). After editing that object out and saving, it was able to load in the GUI builder, and fix some of the other more important UI issues.

So hopefully these troubleshooting steps will be helpful to me or someone else down the line having to resolve similar types of problems.