Getting Cross with CrossVCL

August 17th, 2020

Thought I would give CrossVCL VirtualTreeView support a look see, but when I installed it I couldn’t even run any sample applications.  Kept getting “ld-linux.exe: error: cannot find -lGL”.  Being a Linux newbie I searched the KSDEV CrossVCL issue forum and FAQ thought I was onto something, but after expanding the compiler messages I discovered it was GTK3 related.

A little googling and I found this post which explains that if you want to compile apps for GTK3 you need to change the version of the GTK3 libs that come with Ubuntu 18.04 LTS.

To use gtk2 or gtk3 apps you don’t need to install anything. But, if you want to develop (or even just compile) apps this is what you’re looking for:

sudo apt-get install libgtk-3-dev

After issuing the command above and updating the SDK I was able to compile and run CrossVCL apps.  No need to get cross, just the correct libs.

Another GExperts GEM

August 11th, 2020

I’ve used GExperts for some time, and I keep finding gold nuggets or gems as the saying goes, that make it easier to accomplish day to day tasks.

GIT may be  a great version control system, but it probably contributes to a lot of task switching, which can impact productivity.  For instance, I often need to switch branches to address smaller issues, or make a fix for something QA has found during testing of a fix (hey..sh..it happens…).  Each time I do so, all the files I had open in the IDE for that particular issue, are lost in terms of knowing which ones they were.  AFAIK (as far as I know) there is no way to have the IDE save this information such that when you switch branches it will be preserved.  The IDE will save the current open file list in a project DSK file so it can restore them, but if you have the DSK file in version control, switching branches will replace it.  DSKs are normally not versioned because sharing them between developers is not desirable.  If it’s not in version control, saving it on a different branch will overwrite the list of files.  What is the solution?

One potential solution is to use GExperts Favorites feature.  You can create folders for each set of files (by project or issue # for instance),  Then just add the files you want and next time you switch you can easily re-open the files of interest from your favorites.  It even has the ability to add your Favorites to the File menu.

One of the great things about Delphi’s IDE is the OpenTools API which allows for such extensive add-ins, and Thomas Mueller has put a lot of effort in maintaining and evolving the project.  Thanks!

hcOPF supports Delphi 10.4 Sydney

July 25th, 2020

Things have been a little crazy in case you hadn’t noticed.  Between COVID-19, the economic fallout and all the turmoil in our nearest neighbour, I plum forgot to blog about updating hcOPF to support Delphi Sydney 10.4.

It might also be because adding support for a newer compiler version doesn’t take a great deal of effort. I normally just copy the ones from the previous version, and modify them as needed for the new one.  It would of course be a whole lot easier if {$LIBSUFFIX AUTO} was implemented and I could use that as well (or something like it) to set the output folder. Then I wouldn’t even need to make a copy and update the projects!

DevExpress now Supporting FMX

July 24th, 2020

I was so excited when I read Frank’s post today about DevExpress offering a FMX grid control.  So I went to download it, only to discover that in order to get the CTP release, an * “Active VCL Subscription or Express GridPack is required”.

Sadly I don’t personally have an active subscription so looks like I will have to wait until the release to give it a spin.  For those of you lucky enough to meet the requirements, who haven’t already purchased a TMS or Infpower grid for FMX, let me know what you think.  For the VCL, the Quantum Grid has practically been the defacto standard in most applications I’ve worked on, so I’m very interested to see what DexExpress is offering for FMX.

DevExpress took a wait and see position with FMX, so it’s very encouraging for the Delphi ecosystem to see them throw their hat into the ring.

Resolving Ubuntu HDMI Sound Issues

May 28th, 2020

The Simple solution works for Ubuntu 18.04 LTS found here.

The summary is as below but I used:

sudo gedit /etc/pulse/default.pa

When signal is lost to HDMI (during sleep) Pulse Audio is automatically configured to active source (your laptop’s speakers). Upon resume the sound device is still your laptop. To override this setting, tell Pulse Audio to never switch sound devices automatically:

  • edit the file /etc/pulse/default.pa
  • find the line load-module module-switch-on-port-available
  • insert a # at the beginning of the line to disable automatic port switching
  • save the file and reboot.

10.4 Good Buddy

May 27th, 2020

For a long time there has been a lot of complaints about Error Insight in Delphi giving more false positives (red swiggly lines) than actual problems. It also slowed down the IDE so much that I for one, simply turned it off to avoid the noise and IDE lag. Code Insight also had it’s fair share of issues in terms of parsing blocking the IDE main thread making it unresponsive. The suggestions were not always relevant either.

Then there were IDE updates distributed as a ZIP file that you had to manually unzip and place the files in the correct installation subfolders. There wasn’t even a way to automatically find out if patches were available. The larger updates even required a re-install.

If you thought EMBT did not hear you, they just responded with a big 10-4; RAD Studio/Delphi 10.4. This is arguably the most significant release since Delphi 7. The new Delphi LSP unifies all the IDE code parsing, providing the compiler’s interpretation of the code. This makes Code and Error Insight much faster without blocking the IDE main thread so you can continue to actually use the IDE to….code. It also makes Code and Error Insight, well… more insightful.

Besides the plethora of fixes, there are other major features like managed records and the unification of all platform memory models, and another personal favourite that caught me by surprise; GetIt can now apply patches.

If you’re not on subscription or haven’t updated your Delphi version for some time, 10.4 is a release worthy of getting to know.

Exit Stage Left

May 8th, 2020

The Exit procedure has been around as long as Goto in Object Pascal.  Goto is considered an antiquated command, but what about about Exit?  When should it be used if at all?

I have often seen guard code at the beginning of a method that performs an Exit if the parameters passed are not appropriate or indicate the method does not need to act on the parameters passed.  This might happen in a method like this:

procedure TSomeForm.CheckHaveID(const AID: string);
begin
  if AID <> EmptyStr then
    Exit;

  ...other code to populate AID if necessary...
end;

In this case the first few lines are a common place to see such guard code. In fact, guard code is usually only in place to throw exceptions to let the developer know prerequisites have not been met. Exit calls may be more applicable depending on the purpose of the method but I would caution that taking this to extreme is the equivalent of making a function that returns a boolean for success and then never checking the result in the calling code. It’s a bad practice that will one day bite you. Pick a strategy, document it, and adhere to it. Consistency is king even if the code is less than ideal. Consistent code is easier to re-factor later.

Anyway, I digress, contrast the first method to the following:

procedure TSomeForm.CheckHaveID(const AID: string);
begin
  if not FIShouldCallCheckHaveID then
    Exit;

  if AID <> EmptyStr then
    Exit;

  ...other code to populate AID if necessary...
end;

Here a private field variable is accessed within the called method to determine if the called method should in fact have been called. Seems a little “ass backwards” to me. You don’t go to Vegas and then ask yourself “should I be in Vegas?”. You think before you act. If the method should not have been called, then the caller should make that determination and simply not call it. There is overhead with every method call.

What has also happened now, is that the CheckHaveID method is coupled to the form, making refactoring harder. This is the problem with business logic being tied to a form. Business logic needs to be applied throughout the application but it can’t do that if some variation is embedded in all related forms. Let’s say I want to pull the CheckHaveID method out into another unit as a classless or static class method so it can be shared in another form. Now I have to deal with changing the calling logic to account for the FIShouldCallCheckHaveID condition. If this had been done in the first place the risk of breaking code would have been non-existent.

The argument can be made that if you have 5 early Exits these tests should not be duplicated in every place the method is called, that it just doesn’t make sense. I would respond to such a statement that code duplication is a primary code smell that should result in re-factoring, In this case, all 5 instances of the calling code would be extracted into another method where the decision would be made. Just because putting the logic test in guard code eliminates duplication doesn’t mean you’re putting it in the right place.

In my opinion conditional flow logic should be implemented in the caller. In keeping with the Single Responsibility Principle, a method should do one and only one thing and it’s name should reflect exactly what it does. This keeps code readable and understandable. That was the whole purpose behind step-wise refinement I was taught in Computer Science. Embedding business logic (execution flow) in a method that is named DoX means it should not also do Y. Such code requires minimal documentation because it’s name says it all (well almost).

Structured programming purists would say never use Exits, but more modern engineers like Martin Fowler are advocate smaller methods with multiple Exits. The keyword here is smaller methods. In legacy code I’ve seen methods spanning several hundred lines. Try to find an Exit call in that code!

Not using Exit calls can certainly increase the level of nested if..then..else statements which can also be hard to follow and lead to bugs if begin/end blocks are not used. Again size does matter (method size).

I think as with most things in life, there is a balance, and at a certain point it becomes a personal choice but I think in at least this case, I have made an argument for avoiding the code shown.

Delphi Basics site sums it up quite nicely:

Warning : use with caution - jumping is a concept at odds with structured coding - it makes code maintenance difficult.

Making Sure Your App Doesn’t Leak like a Sieve

April 19th, 2020

If you have been following the Delphi Roadmap, you know that a Unified Memory model across all supported platforms is coming.  That memory model is Delphi’s standard ownership model coupled with optional interface refcounting.  IOW, it’s completely up to the developer to ensure proper memory management just as it has always been.  Once this is the case, memory management, especially on memory “constrained” mobile devices will be very important.

FastMM4 provides memory leak reporting on shutdown, and since everyone has 80% or better unit test coverage using this feature, they probably don’t need have another tool in their toolbox ;-).  Just in case you don’t I would consider adding DeLeaker to your toolbox.  It does far more than just check for memory leaks, and it does so at run-time!

DeLeaker comes as both an external EXE and a very similar UI integrated into RAD Studio under it’s own menu.  The documentation is well written and tutorials are available to get you up to speed quickly.

One of the things I like most about DeLeaker is the ability for it to monitor resource consumption live.  As you use the application you can see the memory utilization and spot potential leaks as memory consumption grows, confirm them using DeLeaker’s detection and go to the relevant code with a double click.

It also supports taking snapshots as the application runs, and comparing them.  Did I mention it monitors not only memory, but also GDI, handles and other resources?

You might think I have AQTime included with Delphi, and I would ask where?  It hasn’t been provided with Delphi for a number of releases.  I have used AQTime and it’s a great product, but I recently discovered that the standard edition doesn’t even support 64 bit EXEs.  Smartbear seems more focused on it’s new web product portfolio so perhaps choosing a smaller vendor committed to supporting RAD Studio customers would be prudent.  At $599 $799 USD for AQTime Pro compared with $399 USD for Deleaker it’s a good value equation if you don’t need the additional features of AQTime Pro.

I have numerous tools in my toolbox, and I am always looking for new or better ones.  I am now adding DeLeaker to the list.

Happy Birthday Delphi!

February 13th, 2020

February 14th is Delphi’s 25th Birthday.  Yes Delphi was introduced on Valentine’s Day, so no wonder I love it!  Anders Hejlsberg must be a proud papa!  Any tool that lasts 25 years in the software business is a great success.

I was a Turbo Pascal fan in school and graduated to using Delphi as my primary dev tool when version 2 shipped.  It was just better than anything else at the time!  VB didn’t have the speed of compiled code and I hated the language, but not quite as much as I hated C/C++.  Pascal was just so much more readable and elegant.

Not a day goes by that I regret not being a member of the M$ herd and dealing with all the churn in their APIs.  Delphi kept moving forward with an eye on backwards compatibility.  It says a lot when you can compile 25 year old source essentially unchanged.  This is one of the reasons I have seen, and helped build many industry leading applications using Delphi.

A lot of things have changed in the development space in the last 25 years, and Delphi has grown up during that time.  It now supports multiple operating systems, has a cross platform UI library, and is reaching for the clouds.  There is little you cannot do today with Object Pascal!

If you think Delphi is an old outdated technology, then think again.  Check out all the #Delphi25th celebrations. Give it a try…you never know it just might be your cup of tea!

IDE Generation of Interface Methods

December 29th, 2019

Just a note to myself so I don’t forget, it’s possible to generate the methods for an interface in a new class that implements it, by pressing Ctrl+Space within the new class declaration.  A list of methods will appear, and you can multi-select them, press Enter and the method declarations will be placed in the class definition as public methods.  Using Class Completion (Ctrl+Shift+C) will the generate the implementation method bodies.

Not sure if or where this is documented as it only took 20 years before I came to know it via others on DelphiPraxis.