Codejock Hi DPI Icons
by Wil van Antwerpen
Codejock supports the use of icons that contain images for multiple sizes. DAWs dynamic loading of these icons unfortunately just uses the first icon and then depends on dynamic resizing to show the icon at the desired size. Scaling down a 48 pixel icon to 16 pixels looks VERY different from a properly designed 16x16 icon. We show you how-to write code that uses the icons dynamically.
|No Files Available
||Wil van Antwerpen
Codejock supports the use of icons that contain images for multiple sizes.
DAWs dynamic loading of these icons unfortunately just uses the first icon and then depends on dynamic resizing to show the icon at the desired size.
Scaling down a 48 pixel icon to 16 pixels looks VERY different from a properly designed 16x16 icon. As a result right now you have to provide a lot of separate icons/bitmaps per desired pixelsize and change them programmatically.
Besides that being a lot of work, the management of all those different bitmap files becomes a chore and makes it more difficult to manage.
We show you how-to write code that uses the icons dynamically.
To better display what the issue is, here's a slightly increased version of some icons.
For this demo, we're using the "Clipboard Cut.ico" image from the function icons that come with the excellent Iconworkshop Editor from Axialis Software
This icon contains 4 images, each tailored for its own size.
Obviously the ugly red lines have been added by me.
When you use this image in a DataFlex toolbar of default 16 pixel size, then it will look like this:
As you can see it is NOT using the designed 16x16 icon as the scissors would be in upright position, but the code picked another icon and then resized the image to our desired 16x16 size.
Quite frankly I think the resized icon looks horrific and that's saying it kindly.
Note that this works both ways if your icon has larger bitmaps in there, but they are not in the first spot then the DataFlex logic will also scale up from a smaller icon it found (Ugh!)
Fixing this is fairly easy, it can even be pick the resolution on the currently selected user DPI (which is another topic that I'll skip now for brevity)
First in your command bar subclass add the following property:
Class cMyCJCommandBarSystem is a cCJCommandBarSystem
Forward Send Construct_Object
Property Integer piDesiredIconSize 0 // default = 0
End_Procedure // Construct_Object
Now copy the complete function AddImageType from the cCJCommandBarSystem.pkg to your subclass.
The really interesting part is on where it uses LoadImage to actually load the image from our resource area.
If you look at LoadImage
API function on MSDN then you can see that two parameters for the desired x and y size of the image to use can be passed along.
By extending the code above into the following:
// if an Icon - load from file first then load from resource
If bIsIcon Begin
Get_File_Path sImage to sFileImage // find path in DFPATH, if appropriate
If (sFileImage<>"") Begin
Send ComLoadIcon of hoImageIcons sFileImage iId eImageType
Move True to bOk
Get piDesiredIconSize To iDesiredIconSize
Move (LoadImage(GetModuleHandle(0), sImage, IMAGE_ICON, iDesiredIconSize, iDesiredIconSize, 0)) to hBitmap
If hBitmap Begin
// this works with alpha blends - even when passed false
Send ComAddIconHandle hBitmap iId eImageType False
Move (DestroyIcon(hBitmap)) to iVoid
Move True to bOk
and then extending onCreateCommandBars with:
Forward Send OnCreateCommandBars
Set piDesiredIconSize To 16
End_Procedure // OnCreateCommandBars
Our icon now looks like:
As you can see it now uses the designed icon.
Please note that the cCJGrid also has a similar function AddImageType that you might want to consider overriding as well, in case you are using custom icons in your codejock grids.