Wednesday, 17 July 2013

TFireMonkeyContainer - a VCL control for mixing VCL and FMX

I've created a small MPL-licensed component called TFireMonkeyContainer.  It's a VCL control that can host a FireMonkey form - 2D or 3D, it doesn't matter.

This will let you use FireMonkey's swishy graphics, animations, etc in an existing VCL application, either in a form among other controls, or if the host container is client-aligned then as though the whole window is a FireMonkey form (it just happens that the window chrome is a VCL form.)  As far as I know, while lots of people ask about mixing FireMonkey in a VCL app, there are no easy-to-use components which let you do so.  I hope, with some further development and bugfixes, this will do so.

Here's a screenshot from the example app:



How to use

  1. Drop a TFireMonkeyContainer control on a VCL form.
  2. Add a FMX form to your project if you haven't got one already (the IDE makes this difficult; you might need to create it in a separate FMX project and then add the unit to the VCL project.)
  3. At designtime, you can set the FireMonkeyForm property to an existing, auto-created FMX form. Note that for the IDE to see it, the form has to be open in a tab.
  4. At runtime, you can set the FireMonkeyForm property to a new instance of a FMX form.  Note that it doesn't take ownership of the form, so you will need to free the form yourself.  This is something that might change in future.

Known bugs

Yes, there definitely are known bugs.  This version is the result of only a couple of hours' work :)
  • The host form's title bar changes to paint as inactive when you click inside the hosted FMX form.  I plan to fix this by handling WM_NCACTIVATE and related messages; if you can think of a better way, by all means please let me know.
  • At designtime, you can't set the FireMonkeyForm property unless the FMX form is open in a tab in the IDE.
  • At designtime, the embedded FMX form draws a few pixels to the right and below where it should be.  You will see a border on the top and left sides of the controls.  I don't know why this is, and at runtime it is in the right place.
  • Designtime is fairly strange all around.  You can edit the hosted FMX control, such as by dragging a button around, but trying to do something like open a style editor causes lots of problems.  I'd recommend you regard it as view-only.

Possible future changes

This code is the result of one or two hours' work - it's early.  Please take that into account.  I thought it might be worth getting feedback on the component and see if it's useful before doing much more work.
That said, here are some possible future changes:
  • Make designtime view-only - don't let you edit the FMX form when it's displayed at designtime in the VCL editor, and just draw it there instead so you can see what it will look like.  This would probably make it a lot more stable.
  • Take ownership of the FMX form - set and forget.  (Currently, you have to delete the FMX form instance if you don't want a memory leak.)
  • Add two events for runtime form creation and deletion, so that when the component is created, you can handle an event and create a new FMX form, and when it is destroyed you can optionally do something with the FMX form before it is freed, or stop it being freed entirely.
I'm interested in other ideas too!

Credits

I saw some example code linked from this Delphi Sorcery post which inspired this component.  The code was DSharp.Windows.FMXAdapter.pas by Stefan Glienke.  My code is considerably expanded so I view it as a separate work - it solves some bugs (eg, removing flicker when the host VCL form is resized, hiding the phantom FMX application window, etc) and of course is a component.  Thanks go to those two pages for showing the basic technique!

Getting the code

You can grab the code via Subversion from Google Code here:
http://firemonkey-container.googlecode.com/svn/trunk/
or via the command line:
svn checkout http://firemonkey-container.googlecode.com/svn/trunk/ firemonkey-container-read-only

You will find two packages (one designtime, one runtime - both 32 and 64-bit) and one small example project.  It's only been tested with XE4 so far!

Have fun, and please contribute back any bugfixes you find.

Thursday, 2 August 2012

Native controls for FireMonkey - the KickStarter project needs your help

FireMonkey does not mimic native controls perfectly, especially on OSX.  This is simply because all its controls are implemented fully in FireMonkey, and so all behaviour has to be coded - and it is very unlikely to ever get an implementation that is indistinguishable from the platform-native controls.  Platform-native is important.

But, what if there was a library of native FireMonkey controls, using Cocoa on OSX and the WinAPI - like the VCL - on Windows?

Jason Southwell has started a project on KickStarter to implement native controls for FireMonkey, under the name 'NakeyMonkey'.  He has a goal of $20,000, but with seven days to go only $7,642 has been pledged.

This project is just what FireMonkey and cross-platform Delphi and C++ Builder needs.  I'm posting since I think it needs more exposure, and more backers - I am worried it may not reach its goal.  I read about it a few days ago and thought, 'ah, it'll get funded, I don't need to do anything' - but maybe I do.  So:



Remember, you'll only actually pay if the project reaches the funding goal - if it misses, no-one loses money.

Jason has also added prizes / credits if you pledge more than a certain amount, too, such as getting beta builds, getting a license of the product and a year's support, or two year's support, phone calls with the developers, etc, as extra incentives for funding specific amounts.

On another note: one person has pledged $1500.  Whoever that is, you're a generous guy / gal!

Tuesday, 13 March 2012

FireMonkey Fonts and Native Look & Feel

Since XE2 Update 4 was released, there have been a few online complaints (1, 2) about FireMonkey's fonts on Windows.  I had most of a blog post written explaining why it actually was fine, when I read that there will be a hot fix targeting this and other issues.  I guess it is an issue after all, then!

But when it comes to FireMonkey's text, there are more important things than antialiasing or fitting to the pixel grid.

From the perspective of text UI controls & fonts, this article will examine:
  • FireMonkey as a cross-platform UI framework
  • How FireMonkey actually looks on different OSes
  • What you can do to improve the native look and feel of FireMonkey
  • Some ideas for FireMonkey enhancements (because you shouldn't have to do anything.)

Wednesday, 7 March 2012

Transparent graphics with pure GDI (Part 2) - and introducing the TTransparentCanvas class

This is part 2 of a short series that examines alpha-aware graphics using native GDI only - not GDI+, not DirectX, and not with any other custom non-GDI graphics implementation.

This post will cover:
  • Non-rectangular drawing
  • Handling GDI's clobbering of the alpha channel
  • Better use of per-pixel alpha (based on what's drawn, which is more useful than a horizontal gradient)
  • Introduction of the TTransparentCanvas class: a TCanvas-like class allowing you to draw rectangles, ellipses, text etc as you normally would, including using TPen, TBrush and TFont.  It composes the layers of drawing as you go, building a per-pixel alpha-aware image.  It also allows you to draw on glass - something VCL applications traditionally have trouble with.
Previous posts in the series:
If you're not very familiar with GDI and alpha transparency on Windows, including the intricacies of using AlphaBlend and its BLENDFUNCTION parameter, please (re-)read those before continuing.  Content in this post refers to classes and techniques introduced in the first two articles.

Monday, 5 March 2012

Free ~4GB of disk space used by XE2 installation files

Update: this may not be a good idea - see below.

Original post: I run on a rather disk-space-restricted system, with Windows running on a 50GB "disk" in VMWare Fusion.  50GB isn't much, but it's a lot when I only have a 128GB disk on the host machine, too (a speedy SSD.)  Most of that 50GB is validly used, but I had only 1GB free when I expected to have 5 or 6 - not enough to install XE2 Update 4.

The Disk Cleanup tool showed only a few megabytes of possible files to delete.  So I went hunting for large folders that didn't contain data I knew I wanted, and found the following in c:\Program Data:


(On Windows 7, c:\Program Data is the non-roaming 'all users' application data path, the path returned when passing CSIDL_COMMON_APPDATA to SHGetFolderPath.)

The eight folders with GUID names contained 3.83GB of files that appear to be part of the C++Builder XE2 installer and help installer.  They appeared to contain boost installation files, help update files, and what appear to be general updates: a lot of folders named after components or folders in the C++ Builder installation directory.  Luckily, the folders were compressed, but they still took up almost 4GB - that's about 8% of my hard disk space.  Deleting these has done no visible harm.  Together with a few other deleted files, I now have about 7GB free disk space, hopefully enough to install the XE2 update.

Follow this at your own risk, but if you are running C++Builder or Delphi on a virtual machine and disk space is low, try looking here.

Update: At this stage I was thinking 'Great!  I've got rid of 4GB of space that the installer for the version I'm about to get rid of used.  Now I can use that space to install update 4!'  But I soon found out:

Following the XE2U4 instructions, I tried to uninstalled XE2 from the Add/Remove Programs applet.  All the 'Uninstall' menu item did was remove the XE2 entry from the Programs list.  It was at this point that I realised the installation files I had deleted were probably also uninstallers.  I don't know why all 4GB are required, but it seems a fair conclusion that's what these folders / files were for.

When I ran the XE2U4 installer, it thought it was already installed, and so I chose the option to uninstall rather than repair.  Uninstalling showed several errors about 'unable to load required plugin', but seemed to mostly work.  I then re-ran the installer, and XE2U4 seemed to install itself properly.

So: if you desperately need space, deleting the old installation files seems to work ok, but might not be a wise idea.  It might be better to uninstall XE2, and then delete the old installation files, in order to free disk space.

Given this is at least the second (?) update to XE2 that has required uninstalling and reinstalling, and that the entire installation data set of 4GB or so seems to need to stay around in order to uninstall, it would be great to see this trimmed and a dedicated uninstall option provided by Embarcadero.  Of course, the best option is to always be able to update, not uninstall and reinstall.  At that point, the old installer becomes useless and can be removed.

Thursday, 10 November 2011

XE2 Hotfix for Lion

I just saw a hot fix has been released to fix some issues in Update 2 (found through this Embarcadero blog post by J T.)  It looks like it only affects C++: it fixes a linker error and an error compiling STL containers.

If you use C++ Builder or RAD Studio, this looks worth applying.

As a side note, I only noticed this because I keep a close eye on community blog posts (through DelphiFeeds, a very useful site for collecting multiple sources together.)  Does anyone know if there's a specific feed where things like these hot fixes are announced?  I'm wondering how I would have been supposed to hear about it if I didn't happen to have seen it mentioned in a blog.

Tuesday, 8 November 2011

Transparent graphics with pure GDI (Part 1 1/2)

Last post, I said that the next part of my transparent graphics series would be Part 2, and would introduce a class I've written to simplify drawing to glass, drawing partially transparent shapes and text, etc.

I haven't posted this yet, simply because life has got in the way - since my last post, I spent a couple of weeks back home in Australia visiting friends and colleagues, and traveling a bit on the way back here.  (I went camel-riding.  They're surprisingly weird animals.)  I'm afraid I simply haven't had time to write the article and to polish the final bits of the library code.

Part 2 really is coming, and I'm sorry it's taking so long.  In the meantime, here is a quick post, Part 1 1/2, addressing a couple of questions asked in the comments for Part 1.