Get picture of current application icon

Hi -
I want to display our application’s icon in a few places around it, but I can’t be bothered to update all those other places whenever we update our icon. Is there a way of extracting the picture of our icon (on both Mac and Windows, but happy to use MBS plugins) so all I need to do is update the app icon in the App inspector, and the rest of the places it shows will update themselves?

#if TargetMacOS then dim p as picture = app.BundleFolderMBS.IconImageMBS(256) p.Mask = app.BundleFolderMBS.IconMaskMBS(256) #endif #if TargetWin32 then dim p as picture = app.ExecutableFile.IconImageMBS(256) p.Mask = app.ExecutableFile.IconMaskMBS(256) #endif

will do it. But resizing that image gives nasty jagged curves so I’ll need to resize the image myself and save a copy of it.

Not the fastest way, but this does get the 1024 x 1024 picture from the dockitem on a Mac.

dim p as new picture(app.DockItem.Graphics.width, app.DockItem.Graphics.height) for x as integer = 0 to app.DockItem.Graphics.width for y as integer = 0 to app.DockItem.Graphics.height p.RGBSurface.Pixel(x, y) = app.DockItem.Graphics.Pixel(x,y) next next

You could do that in a timer to not hold the UI upon launch of the app.

The alternative is to place the picture in your project when you update the app.

There’s a lot of discussion about ways to resize images at - I’ve chosen to simply make the image at the right size, though.

Why do you need MBS here? You can get the icon on OS X with one declare (see macoslib).
Just call “iconForFile” as shown in this Swift line:

let icon = NSWorkspace().iconForFile("/Users/sample/Desktop/sample.tif")

Sure, I could do it with a declare, too. We’ve got the complete MBS set, that’s all, so don’t mind using it!

Besides, MBS works for more than just the Mac.

Just for the records:
Define the NSRect struct (x, y, w, h as Single), put the code below in a Canvas Paint event and add your “targetFilePath”:

[code] #pragma Unused areas

dim targetImageSize as Integer = min(g.width, g.height)
const targetFilePath = “/SAMPLE/PATH/SAMPLE_FILE”

declare function NSClassFromString lib “Cocoa” (aClassName as CFStringRef) as Ptr
declare function iconForFile lib “Cocoa” selector “iconForFile:” (obj_id as Ptr, fullPath as CFStringRef) as Ptr
declare function sharedWorkspace lib “Cocoa” selector “sharedWorkspace” (class_id as Ptr) as Ptr
declare sub CGContextDrawImage lib “Cocoa” (context as Ptr, rect as NSRect, image as Ptr)
declare function CGImageForProposedRect lib “Cocoa” selector “CGImageForProposedRect:context:hints:” (obj_id as Ptr, byref proposedDestRect as NSRect, referenceContext as Ptr, hints as Ptr) as Ptr

dim imageRef as MemoryBlock = iconForFile(sharedWorkspace(NSClassFromString(“NSWorkspace”)), targetFilePath)

dim p as new picture(targetImageSize,targetImageSize)
dim rect As NSRect
rect.w = targetImageSize
rect.h = targetImageSize

// Convert the NSImage to CGImage
dim cntx as Ptr =ptr(p.Graphics.Handle(Graphics.HandleTypeCGContextRef))
dim cgPtr as Ptr = CGImageForProposedRect( imageRef, rect, nil, nil)

// Draw the CGImage to our Xojo picture
CGContextDrawImage cntx, rect, cgPtr

g.DrawPicture p, 0, 0

With parts based on and and of course macoslib.

Note: No error checking done here.

1 Like

40209 - All sizes 48 and under missing in icns
Status: Needs Review Rank: Not Ranked Product: Xojo Category: N/A

Michel Bujardet Today at 11:27 AM
OS: OS X 10.10.4

Xojo: Xojo 2015r2.2

Steps: There is a big issue going on with icons in Mac builds.

In the project I attached, I placed a picture in each slot of the app icon, with the size of it. For 32 and 16, I made the 8 bit icon in red.

After building, I extracted the icon created by Xojo (attached as App.icns).

When open in Preview (see Preview.png), the 32 and 16 icons are there, but they are just grey. Also, there is only one of each ; no distinction between 32 and 8 bit. I dragged the picture to the finder, it is an empty picture, an invisible background.

I used App WRaper Mini to get a fuller list, in particular to see if Retina support was there. See AppWMini.png. The result is even more worrysome :

All icons 48 and down are incorrect.

  • 48 is missing
  • 32 and 16 are all simply empty (present but invisible)
  • 32 and 16 8 bits are absent.

The only picture with Retina support is the 512 2x (1024).

The icns file itself does not display correctly. It shows up with no icon at all when shown in a list (icns icon missing.png). Makes sense, the 16 x 16 is entirely transparent.

Expected Result:
all sizes 48 and down contain pictures

Actual Result:
48 and down are transparent.


If you have the retinaKit you can use the following.

Dim appIcon as retinaKit.RKPicture = retinaKit.imageNamed( retinaKit.imagename.applicationIcon )

Then draw it where you want or even set it as the icon for buttons, menus and so on.