<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>64k &#187; Cocoa</title>
	<atom:link href="http://www.64k-tec.de/tag/cocoa/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.64k-tec.de</link>
	<description>Software development and more ...</description>
	<lastBuildDate>Tue, 10 Jan 2012 21:58:41 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Adding a badge to the unified toolbar on Mac OS X</title>
		<link>http://www.64k-tec.de/2011/01/adding-a-badge-to-the-unified-toolbar-on-mac-os-x/</link>
		<comments>http://www.64k-tec.de/2011/01/adding-a-badge-to-the-unified-toolbar-on-mac-os-x/#comments</comments>
		<pubDate>Fri, 21 Jan 2011 21:41:56 +0000</pubDate>
		<dc:creator>cp</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[IT]]></category>
		<category><![CDATA[bagde]]></category>
		<category><![CDATA[beta]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[NSResponder]]></category>
		<category><![CDATA[NSView]]></category>
		<category><![CDATA[objc]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[toolbar]]></category>
		<category><![CDATA[unified titlebar]]></category>
		<category><![CDATA[VirtualBox]]></category>

		<guid isPermaLink="false">http://www.64k-tec.de/?p=2013</guid>
		<description><![CDATA[Mac OS X and the applications running on it are known for being sometimes unusual in the look and feel. For some reason developer on Mac OS X seems to be more creative than on other platforms. For an application developer which deals with user input it is important to make any user interaction as [...]]]></description>
			<content:encoded><![CDATA[<p>Mac OS X and the applications running on it are known for being sometimes unusual in the look and feel. For some reason developer on Mac OS X seems to be more creative than on other platforms. For an application developer which deals with user input it is important to make any user interaction as useful as possible and present this information in a way which is on the one side as much less annoying as possible but also attractive and informative on the other side. Lastly I was thinking about how to show the users they are using a beta version, which should remind them that this is not production ready software, but on the same time make it easy to respond to bugs they find in this pre-release. The solution, I came up with, was a badge in the toolbar which shows this is a release which is definitely in a testing phase, but also allows the user to double-click to give a respond to this particular version. In the following post I will show how to do this.</p>
<h2>Getting the superview</h2>
<p>In Cocoa all user displayed content is a <a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Classes/NSView_Class/Reference/NSView.html" target="_blank">NSView</a> (most of the time; forget about the Dock). This is really nice, cause you could manipulate them. Although there are no public methods for getting the NSView of the toolbar or even the titlebar, they exist as an NSView. The NSView of the toolbar could be accessed by a private method. As always in Objective C you could ask for a particular method by using the <a href="http://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Protocols/NSObject_Protocol/Reference/NSObject.html#//apple_ref/occ/intfm/NSObject/respondsToSelector:" target="_blank"><code>respondsToSelector</code></a> statement like in the following:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #400080;">NSToolbar</span> <span style="color: #002200;">*</span>tb <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>pWindow toolbar<span style="color: #002200;">&#93;</span>;
<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>tb respondsToSelector<span style="color: #002200;">:</span><span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>_toolbarView<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>
<span style="color: #002200;">&#123;</span>
 <span style="color: #400080;">NSView</span> <span style="color: #002200;">*</span>tbv <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>tb performSelector<span style="color: #002200;">:</span><span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>_toolbarView<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
 <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>tbv<span style="color: #002200;">&#41;</span>
 <span style="color: #002200;">&#123;</span>
  <span style="color: #11740a; font-style: italic;">/* do something with tbv */</span>
 <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre></div></div>

<p>This return the NSView of the toolbar at least until 10.6. But be warned this is a private method and of course this could be changed in a future version of Mac OS X. At least the shown method will correctly fail in the case Apple change his mind which will result in doing nothing. Anyway this will not include the area of the titlebar. To get the NSView which covers both the title bar and the toolbar you need another trick. The titlebar usual has a close, minimize or maximize button. These buttons are NSButton's and added by the system depending of the window type. As a NSButton is also a NSView it also has a parent. This dependency allows us to access the view which is responsible for displaying the unified titlebar and the toolbar. The following code shows how to get the responsible view and how to add an additional <a href="http://developer.apple.com/library/mac/#documentation/cocoa/reference/ApplicationKit/Classes/NSImageView_Class/Reference/Reference.html" target="_blank">NSImageView</a> to it:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #400080;">NSView</span> <span style="color: #002200;">*</span>wv <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>pWindow standardWindowButton<span style="color: #002200;">:</span>NSWindowCloseButton<span style="color: #002200;">&#93;</span> superview<span style="color: #002200;">&#93;</span>;
<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>wv<span style="color: #002200;">&#41;</span>
<span style="color: #002200;">&#123;</span>
 <span style="color: #11740a; font-style: italic;">/* We have to calculate the size of the title bar for the center case. */</span>
 NSSize s <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>pImage size<span style="color: #002200;">&#93;</span>;
 NSSize s1 <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>wv frame<span style="color: #002200;">&#93;</span>.size;
 NSSize s2 <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>pWindow contentView<span style="color: #002200;">&#93;</span> frame<span style="color: #002200;">&#93;</span>.size;
 <span style="color: #11740a; font-style: italic;">/* Correctly position the label. */</span>
 <span style="color: #400080;">NSImageView</span> <span style="color: #002200;">*</span>iv <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSImageView</span> alloc<span style="color: #002200;">&#93;</span> initWithFrame<span style="color: #002200;">:</span>
        NSMakeRect<span style="color: #002200;">&#40;</span>s1.width <span style="color: #002200;">-</span> s.width <span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>fCenter ? <span style="color: #2400d9;">10</span> <span style="color: #002200;">:</span> <span style="color: #2400d9;">0</span><span style="color: #002200;">&#41;</span>,
                   fCenter ? s2.height <span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span>s1.height <span style="color: #002200;">-</span> s2.height <span style="color: #002200;">-</span> s.height<span style="color: #002200;">&#41;</span> <span style="color: #002200;">/</span> <span style="color: #2400d9;">2</span> <span style="color: #002200;">:</span> s1.height <span style="color: #002200;">-</span> s.height <span style="color: #002200;">-</span> <span style="color: #2400d9;">1</span>,
  	           s.width, s.height<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
 <span style="color: #11740a; font-style: italic;">/* Configure the NSImageView for auto moving. */</span>
 <span style="color: #002200;">&#91;</span>iv setImage<span style="color: #002200;">:</span>pImage<span style="color: #002200;">&#93;</span>;
 <span style="color: #002200;">&#91;</span>iv setAutoresizesSubviews<span style="color: #002200;">:</span><span style="color: #a61390;">true</span><span style="color: #002200;">&#93;</span>;
 <span style="color: #002200;">&#91;</span>iv setAutoresizingMask<span style="color: #002200;">:</span>NSViewMinXMargin | NSViewMinYMargin<span style="color: #002200;">&#93;</span>;
 <span style="color: #11740a; font-style: italic;">/* Add it to the parent of the close button. */</span>
 <span style="color: #002200;">&#91;</span>wv addSubview<span style="color: #002200;">:</span>iv positioned<span style="color: #002200;">:</span>NSWindowBelow relativeTo<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></div></div>

<p>This code needs a NSWindow, a NSImage as label and the flag fCenter for deciding if the image is vertically centered within the titlebar. Also the badge is pinned on the right side by setting the <a href="http://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSView_Class/Reference/NSView.html#//apple_ref/occ/instm/NSView/setAutoresizingMask:" target="_blank"><code>AutoresizingMask</code></a>. The following shows how this could be look like:</p>
<p style="text-align: center;"><a href="/wordpress/wp-content/uploads/badge.png"><img class="size-medium wp-image-2056 aligncenter" style="vertical-align: middle;" title="badge" src="/wordpress/wp-content/uploads/badge-300x281.png" alt="" width="300" height="281" /></a></p>
<h2>Adding functionality to the badge</h2>
<p>First we should add some information about this release by using the <a href="http://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSView_Class/Reference/NSView.html#//apple_ref/occ/instm/NSView/setToolTip:" target="_blank"><code>setToolTip</code></a> method of an NSView. Simply add this call to the code:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"> <span style="color: #002200;">&#91;</span>iv setToolTip<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Some info about the beta version.&quot;</span><span style="color: #002200;">&#93;</span>;</pre></div></div>

<p>To make this beta hint more useful, we should make it clickable. Getting mouse down events in Cocoa is only possible by handling the <a href="http://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSResponder_Class/Reference/Reference.html#//apple_ref/occ/instm/NSResponder/mouseDown:" target="_blank"><code>mouseDown</code></a> event of the <a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Classes/NSResponder_Class/Reference/Reference.html" target="_blank">NSResponder</a> sub-class. Also the view must accept first responder events. How to do this is shown in the following code:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@interface</span> BetaImageView<span style="color: #002200;">:</span> <span style="color: #400080;">NSImageView</span>
<span style="color: #002200;">&#123;</span><span style="color: #002200;">&#125;</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span>acceptsFirstResponder;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>mouseDown<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSEvent</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>pEvent;
<span style="color: #a61390;">@end</span>
<span style="color: #a61390;">@implementation</span> BetaImageView
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span>acceptsFirstResponder
<span style="color: #002200;">&#123;</span>
 <span style="color: #a61390;">return</span> <span style="color: #a61390;">YES</span>;
<span style="color: #002200;">&#125;</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>mouseDown<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSEvent</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>pEvent
<span style="color: #002200;">&#123;</span>
 <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>pEvent clickCount<span style="color: #002200;">&#93;</span> &gt; <span style="color: #2400d9;">1</span><span style="color: #002200;">&#41;</span>
  <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSWorkspace</span> sharedWorkspace<span style="color: #002200;">&#93;</span> openURL<span style="color: #002200;">:</span>
        <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSURL</span> URLWithString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;http://www.virtualbox.org/&quot;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
 <span style="color: #a61390;">else</span>
  <span style="color: #002200;">&#91;</span>super mouseDown<span style="color: #002200;">:</span>pEvent<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
<span style="color: #a61390;">@end</span></pre></div></div>

<p>Replace NSImageView with BetaViewImage in the allocation call in listing 2 and you are done. Change the URL to one where the user can respond to the beta questions, like a bug tracker or forum.</p>
<h2>Conclusion</h2>
<p>This post showed how to add an nice looking badge to the unified toolbar on Mac OS X. The user is reminded he is using some pre-release software all the time, but at the same time has an easy way to report problems with this release. Of course could such a badge used for anything else.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.64k-tec.de/2011/01/adding-a-badge-to-the-unified-toolbar-on-mac-os-x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating file shortcuts on three different operation systems</title>
		<link>http://www.64k-tec.de/2010/11/creating-file-shortcuts-on-three-different-operation-systems/</link>
		<comments>http://www.64k-tec.de/2010/11/creating-file-shortcuts-on-three-different-operation-systems/#comments</comments>
		<pubDate>Sun, 28 Nov 2010 13:44:50 +0000</pubDate>
		<dc:creator>cp</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[IT]]></category>
		<category><![CDATA[Qt]]></category>
		<category><![CDATA[AESend]]></category>
		<category><![CDATA[Alias]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[desktop]]></category>
		<category><![CDATA[Desktop Entry Specification]]></category>
		<category><![CDATA[file shortcuts]]></category>
		<category><![CDATA[freeedesktop.org]]></category>
		<category><![CDATA[gcc]]></category>
		<category><![CDATA[hard link]]></category>
		<category><![CDATA[installation]]></category>
		<category><![CDATA[IPersistFile]]></category>
		<category><![CDATA[IShellLink]]></category>
		<category><![CDATA[link]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[objc]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[platform]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[VirtualBox]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[X11]]></category>
		<category><![CDATA[Xorg]]></category>

		<guid isPermaLink="false">http://www.64k-tec.de/?p=1838</guid>
		<description><![CDATA[As you may know, developing for multiple platforms is one of my strengths. Strictly speaking, it's a basic requirement if you are involved in such a product like VirtualBox, which runs on every major (and several minor) platform available today. Beside the GUI, which uses Qt and therewith is portable without any additional cost (which [...]]]></description>
			<content:encoded><![CDATA[<p>As you may know, developing for multiple platforms is one of my strengths. Strictly speaking, it's a basic requirement if you are involved in such a product like VirtualBox, which runs on every major (and several minor) platform available today. Beside the GUI, which uses <a href="http://qt.nokia.com/" target="_blank">Qt</a> and therewith is portable without any additional cost (which isn't fully true if you want <a href="http://www.64k-tec.de/2009/12/integrating-native-cocoa-controls-into-qt/" target="_blank">real native look and feel on every platform, especially on Mac OS X</a>), all the rest of VirtualBox is written in a portable way. This is done by using only C/C++ and Assembler when necessary. Everything which needs a different approach, because of the design of the OS (and the API's which are available there), is implemented in a platform dependent way. In the history of VirtualBox, several <a href="http://www.virtualbox.org/browser/trunk/src/VBox/Runtime" target="_blank">modules</a> are created and grown by the time, which makes it really easy to deal with this differences. For stuff like file handling, paths, strings, semaphores or any other basic functionality, you can just use the modules which are available. On the other side it might be necessary, for a new feature we implement, to write it from the ground. In the following post I will show how to create a <a href="http://en.wikipedia.org/wiki/File_shortcut" target="_blank">file shortcut</a> for the three major operation systems available today.</p>
<h2>Why do you want to use file shortcuts</h2>
<p>On the classical UNIX systems you have <a href="http://en.wikipedia.org/wiki/Hard_link" target="_blank">hard</a> and <a href="http://en.wikipedia.org/wiki/Soft_link" target="_blank">soft</a> links. These are implemented by the filesystem and make it possible to link to another file or folder without any trouble. Most of the time soft links are used, but it really depends on the use case. Unfortunately these kind of links are not available on Windows (yes, I know there are also hard links and junctions on NTFS, but they are not common and difficult to handle), these links doesn't allow any additional attributes. For example one like to add a different icon to the link or provide more information through a comment field. Beside on Mac OS X, shortcuts can also be work as an application launcher, where the link contain the information what application should be started and how. In contrast to filesystem links which are handled by the operation system, these shortcuts are handled by the window system (or shell) running on the host (which doesn't mean there is no filesystem support for it). On Windows this is the Explorer, on Mac OS X the Finder and on Linux a <a href="http://www.freedesktop.org/" target="_blank">freedesktop.org</a> conforming file manager.</p>
<h2>Creating a Desktop file on Linux</h2>
<p>Desktop files on Linux (or any other UNIX system which conforms to freedesktop.org) is easy. It's a simple text file which implement the <a href="http://standards.freedesktop.org/desktop-entry-spec/latest/" target="_blank">Desktop Entry Specification</a>. In version 1.0 there are 18 possible entries, where not all of them are mandatory. In the following example I use Qt to write these files, but it should be no problem to use any other toolkit or plain C.</p>

<div class="wp_syntax"><div class="code"><pre class="cpp-qt" style="font-family:monospace;"><span style="color: #0057AE;">bool</span> createShortcut<span style="color: #006E28;">&#40;</span><span style="color: #0057AE;">const</span> <span style="color: #22aadd;">QString</span> <span style="color: #006E28;">&amp;</span>strSrcFile<span style="color: #006E28;">,</span>
                    <span style="color: #0057AE;">const</span> <span style="color: #22aadd;">QString</span> <span style="color: #006E28;">&amp;</span>strDstPath<span style="color: #006E28;">,</span>
                    <span style="color: #0057AE;">const</span> <span style="color: #22aadd;">QString</span> <span style="color: #006E28;">&amp;</span>strName<span style="color: #006E28;">&#41;</span>
<span style="color: #006E28;">&#123;</span>
 <span style="color: #22aadd;">QFile</span> link<span style="color: #006E28;">&#40;</span>strDstPath <span style="color: #006E28;">+</span> <span style="color: #22aadd;">QDir</span><span style="color: #006E28;">::</span><span style="color: #2B74C7;">separator</span><span style="color: #006E28;">&#40;</span><span style="color: #006E28;">&#41;</span> <span style="color: #006E28;">+</span> strName <span style="color: #006E28;">+</span> <span style="color: #BF0303;">&quot;.desktop&quot;</span><span style="color: #006E28;">&#41;</span><span style="color: #006E28;">;</span>
 <span style="color: #000000; font-weight:bold;">if</span> <span style="color: #006E28;">&#40;</span>link.<span style="color: #2B74C7;">open</span><span style="color: #006E28;">&#40;</span><span style="color: #22aadd;">QFile</span><span style="color: #006E28;">::</span><span style="color: #2B74C7;">WriteOnly</span> <span style="color: #006E28;">|</span> <span style="color: #22aadd;">QFile</span><span style="color: #006E28;">::</span><span style="color: #2B74C7;">Truncate</span><span style="color: #006E28;">&#41;</span><span style="color: #006E28;">&#41;</span>
 <span style="color: #006E28;">&#123;</span>
  <span style="color: #22aadd;">QTextStream</span> out<span style="color: #006E28;">&#40;</span><span style="color: #006E28;">&amp;</span>link<span style="color: #006E28;">&#41;</span><span style="color: #006E28;">;</span>
  out.<span style="color: #2B74C7;">setCodec</span><span style="color: #006E28;">&#40;</span><span style="color: #BF0303;">&quot;UTF-8&quot;</span><span style="color: #006E28;">&#41;</span><span style="color: #006E28;">;</span>
  out <span style="color: #006E28;">&lt;&lt;</span> <span style="color: #BF0303;">&quot;[Desktop Entry]&quot;</span> <span style="color: #006E28;">&lt;&lt;</span> endl
      <span style="color: #006E28;">&lt;&lt;</span> <span style="color: #BF0303;">&quot;Encoding=UTF-8&quot;</span> <span style="color: #006E28;">&lt;&lt;</span> endl
      <span style="color: #006E28;">&lt;&lt;</span> <span style="color: #BF0303;">&quot;Version=1.0&quot;</span> <span style="color: #006E28;">&lt;&lt;</span> endl
      <span style="color: #006E28;">&lt;&lt;</span> <span style="color: #BF0303;">&quot;Type=Link&quot;</span> <span style="color: #006E28;">&lt;&lt;</span> endl
      <span style="color: #006E28;">&lt;&lt;</span> <span style="color: #BF0303;">&quot;Name=&quot;</span> <span style="color: #006E28;">&lt;&lt;</span> strName <span style="color: #006E28;">&lt;&lt;</span> endl
      <span style="color: #006E28;">&lt;&lt;</span> <span style="color: #BF0303;">&quot;URL=&quot;</span> <span style="color: #006E28;">&lt;&lt;</span> strSrcFile <span style="color: #006E28;">&lt;&lt;</span> endl
      <span style="color: #006E28;">&lt;&lt;</span> <span style="color: #BF0303;">&quot;Icon=icon-name&quot;</span> <span style="color: #006E28;">&lt;&lt;</span> endl<span style="color: #006E28;">;</span>
  <span style="color: #000000; font-weight:bold;">return</span> true<span style="color: #006E28;">;</span>
 <span style="color: #006E28;">&#125;</span>
 <span style="color: #000000; font-weight:bold;">return</span> false<span style="color: #006E28;">;</span>
<span style="color: #006E28;">&#125;</span></pre></div></div>

<p>Replace <code>icon-name</code> by a registered icon on the system and you are done.</p>
<h2>Creating a Shell link on Windows</h2>
<p>Windows provides an interface for <a href="http://msdn.microsoft.com/en-us/library/bb774950%28VS.85%29.aspx" target="_blank"><code>IShellLink</code></a> since Windows XP. The following example shows how to use it:</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">bool</span> createShortcut<span style="color: #008000;">&#40;</span>LPCSTR lpszSrcFile,
                    LPCSTR lpszDstPath,
                    LPCSTR lpszName<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
 IShellLink <span style="color: #000040;">*</span>pShl <span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span>
 IPersistFile <span style="color: #000040;">*</span>pPPF <span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span>
 HRESULT rc <span style="color: #000080;">=</span> CoCreateInstance<span style="color: #008000;">&#40;</span>CLSID_ShellLink,
                               <span style="color: #0000ff;">NULL</span>,
                               CLSCTX_INPROC_SERVER,
                               IID_IShellLink,
                               <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #000040;">**</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>pShl<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
 <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>FAILED<span style="color: #008000;">&#40;</span>rc<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
  <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #008080;">;</span>
 <span style="color: #0000ff;">do</span>
 <span style="color: #008000;">&#123;</span>
  rc <span style="color: #000080;">=</span> pShl<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>SetPath<span style="color: #008000;">&#40;</span>lpszSrcFile<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>FAILED<span style="color: #008000;">&#40;</span>rc<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
   <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
  rc <span style="color: #000080;">=</span> pShl<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>QueryInterface<span style="color: #008000;">&#40;</span>IID_IPersistFile, <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #000040;">**</span><span style="color: #008000;">&#41;</span><span style="color: #000040;">&amp;</span>pPPF<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>FAILED<span style="color: #008000;">&#40;</span>rc<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
   <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
  WORD wsz<span style="color: #008000;">&#91;</span>MAX_PATH<span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
  TCHAR path<span style="color: #008000;">&#91;</span>MAX_PATH<span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color: #008000;">&#123;</span> <span style="color: #0000dd;">0</span> <span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
  lstrcat<span style="color: #008000;">&#40;</span>path, lpszDstPath<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  lstrcat<span style="color: #008000;">&#40;</span>path, <span style="color: #FF0000;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  lstrcat<span style="color: #008000;">&#40;</span>path, lpszName<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  lstrcat<span style="color: #008000;">&#40;</span>path, <span style="color: #FF0000;">&quot;.lnk&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  MultiByteToWideChar<span style="color: #008000;">&#40;</span>CP_ACP, <span style="color: #0000dd;">0</span>, buf, <span style="color: #000040;">-</span><span style="color: #0000dd;">1</span>, wsz, MAX_PATH<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  rc <span style="color: #000080;">=</span> pPPF<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>Save<span style="color: #008000;">&#40;</span>wsz, TRUE<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
 <span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">while</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
 <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>pPPF<span style="color: #008000;">&#41;</span>
  pPPF<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>Release<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
 <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>pShl<span style="color: #008000;">&#41;</span>
  pShl<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>Release<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
 <span style="color: #0000ff;">return</span> SUCCEEDED<span style="color: #008000;">&#40;</span>rc<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>As you may noticed this uses <a href="http://en.wikipedia.org/wiki/Component_Object_Model" target="_blank">COM</a>. Many API's on Windows using the COM interface to communicate between processes. If you don't use COM in your application you have to initialize it first. This is achieved by adding the following call to the front of the function:</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"> <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>FAILED<span style="color: #008000;">&#40;</span>CoInitialize<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
  <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #008080;">;</span></pre></div></div>

<p>Depending on your application it might be worth to unitialize COM after usage by appending the following to the function:</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"> CoUninitialize<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></div></div>

<p>The function itself isn't any magic. It gets a COM interface to the <code>IShellLink</code> interface and then work with it, by setting the source path and adding a target path by using the <a href="http://msdn.microsoft.com/en-us/library/ms687223%28VS.85%29.aspx" target="_blank"><code>IPersistFile</code></a> interface. As I wrote before you could do much more. Providing a path to a specific application or adding your own parameters is no problem. Have a look at the documentation.</p>
<h2>Creating an Alias file on Mac OS X</h2>
<p>Shortcut files on Mac OS X are a little bit different. At first, they aren't one. There are the classical filesystem links and <a href="http://en.wikipedia.org/wiki/Alias_%28Mac_OS%29" target="_blank">Alias</a> files. Alias files are links which targeting a specific file, but they haven't all the possibilities of shortcuts like on Windows or Linux. As the name suggest they are really only an alias for another file or directory. So specifying an application to start or things like that aren't possible. Anyway they allow changing the icon and they are more persistent than on Window or Linux cause they are working with several attributes of the target file. Even if you rename or move the target, an Alias file will resolve the target correctly (if it is possible). On the other side, being such special means also being hard to create. In principle there are two possibilities. The first one is, creating a file which is no file at all, but has several <a href="http://en.wikipedia.org/wiki/Resource_fork" target="_blank">resources forks</a> attached. Therefor you need to know exactly how Alias files are built of and make sure with every release of Mac OS X you are following the development. There is a free project which does exactly that: <a href="https://github.com/nathanday/ndalias" target="_blank">NDAlias</a>. If you are like me and a little bit more lazy, you ask someone who should know how to create Alias files. This is Finder. Although writing the files itself isn't easy, asking the Finder to do the job is not really easier, cause the information about doing exactly that are really rare. The following code shows how to achieve it:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">bool createShortcut<span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>pstrSrcFile,
                    <span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>pstrDstPath,
                    <span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>pstrName<span style="color: #002200;">&#41;</span>
<span style="color: #002200;">&#123;</span>
 <span style="color: #11740a; font-style: italic;">/* First of all we need to figure out which process Id the Finder
  * currently has. */</span>
 <span style="color: #400080;">NSWorkspace</span> <span style="color: #002200;">*</span>pWS <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSWorkspace</span> sharedWorkspace<span style="color: #002200;">&#93;</span>;
 <span style="color: #400080;">NSArray</span> <span style="color: #002200;">*</span>pApps <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>pWS launchedApplications<span style="color: #002200;">&#93;</span>;
 bool fFFound <span style="color: #002200;">=</span> <span style="color: #a61390;">false</span>;
 ProcessSerialNumber psn;
 <span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSDictionary</span> <span style="color: #002200;">*</span>pDict <span style="color: #a61390;">in</span> pApps<span style="color: #002200;">&#41;</span>
 <span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>pDict valueForKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;NSApplicationBundleIdentifier&quot;</span><span style="color: #002200;">&#93;</span>
         isEqualToString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;com.apple.finder&quot;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>
  <span style="color: #002200;">&#123;</span>
   psn.highLongOfPSN <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>pDict
                          valueForKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;NSApplicationProcessSerialNumberHigh&quot;</span><span style="color: #002200;">&#93;</span> intValue<span style="color: #002200;">&#93;</span>;
   psn.lowLongOfPSN  <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>pDict
                          valueForKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;NSApplicationProcessSerialNumberLow&quot;</span><span style="color: #002200;">&#93;</span> intValue<span style="color: #002200;">&#93;</span>;
   fFFound <span style="color: #002200;">=</span> <span style="color: #a61390;">true</span>;
   <span style="color: #a61390;">break</span>;
  <span style="color: #002200;">&#125;</span>
 <span style="color: #002200;">&#125;</span>
 <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span>fFFound<span style="color: #002200;">&#41;</span>
  <span style="color: #a61390;">return</span> <span style="color: #a61390;">false</span>;
 <span style="color: #11740a; font-style: italic;">/* Now the event fun begins. */</span>
 OSErr err <span style="color: #002200;">=</span> noErr;
 AliasHandle hSrcAlias <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>;
 AliasHandle hDstAlias <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>;
 <span style="color: #a61390;">do</span>
 <span style="color: #002200;">&#123;</span>
  <span style="color: #11740a; font-style: italic;">/* Create a descriptor which contains the target psn. */</span>
  <span style="color: #400080;">NSAppleEventDescriptor</span> <span style="color: #002200;">*</span>finderPSNDesc <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSAppleEventDescriptor</span>
                                            descriptorWithDescriptorType<span style="color: #002200;">:</span>typeProcessSerialNumber
                                            bytes<span style="color: #002200;">:&amp;</span>psn
                                            length<span style="color: #002200;">:</span><span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>psn<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span>finderPSNDesc<span style="color: #002200;">&#41;</span>
   <span style="color: #a61390;">break</span>;
  <span style="color: #11740a; font-style: italic;">/* Create the Apple event descriptor which points to the Finder
   * target already. */</span>
  <span style="color: #400080;">NSAppleEventDescriptor</span> <span style="color: #002200;">*</span>finderEventDesc <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSAppleEventDescriptor</span>
                                              appleEventWithEventClass<span style="color: #002200;">:</span>kAECoreSuite
                                              eventID<span style="color: #002200;">:</span>kAECreateElement
                                              argetDescriptor<span style="color: #002200;">:</span>finderPSNDesc
                                              returnID<span style="color: #002200;">:</span>kAutoGenerateReturnID
                                              transactionID<span style="color: #002200;">:</span>kAnyTransactionID<span style="color: #002200;">&#93;</span>;
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span>finderEventDesc<span style="color: #002200;">&#41;</span>
   <span style="color: #a61390;">break</span>;
  <span style="color: #11740a; font-style: italic;">/* Create and add an event type descriptor: Alias */</span>
  <span style="color: #400080;">NSAppleEventDescriptor</span> <span style="color: #002200;">*</span>osTypeDesc <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSAppleEventDescriptor</span> descriptorWithTypeCode<span style="color: #002200;">:</span>typeAlias<span style="color: #002200;">&#93;</span>;
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span>osTypeDesc<span style="color: #002200;">&#41;</span>
   <span style="color: #a61390;">break</span>;
  <span style="color: #002200;">&#91;</span>finderEventDesc setParamDescriptor<span style="color: #002200;">:</span>osTypeDesc forKeyword<span style="color: #002200;">:</span>keyAEObjectClass<span style="color: #002200;">&#93;</span>;
  <span style="color: #11740a; font-style: italic;">/* Now create the source Alias, which will be attached to the event. */</span>
  err <span style="color: #002200;">=</span> FSNewAliasFromPath<span style="color: #002200;">&#40;</span><span style="color: #a61390;">nil</span>, <span style="color: #002200;">&#91;</span>pstrSrcFile fileSystemRepresentation<span style="color: #002200;">&#93;</span>, <span style="color: #2400d9;">0</span>, <span style="color: #002200;">&amp;</span>hSrcAlias, <span style="color: #2400d9;">0</span><span style="color: #002200;">&#41;</span>;
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>err <span style="color: #002200;">!=</span> noErr<span style="color: #002200;">&#41;</span>
   <span style="color: #a61390;">break</span>;
  <span style="color: #a61390;">char</span> handleState;
  handleState <span style="color: #002200;">=</span> HGetState<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#40;</span>Handle<span style="color: #002200;">&#41;</span>hSrcAlias<span style="color: #002200;">&#41;</span>;
  HLock<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#40;</span>Handle<span style="color: #002200;">&#41;</span>hSrcAlias<span style="color: #002200;">&#41;</span>;
  <span style="color: #400080;">NSAppleEventDescriptor</span> <span style="color: #002200;">*</span>srcAliasDesc <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSAppleEventDescriptor</span>
                                           descriptorWithDescriptorType<span style="color: #002200;">:</span>typeAlias
                                           bytes<span style="color: #002200;">:*</span>hSrcAlias
                                           length<span style="color: #002200;">:</span>GetAliasSize<span style="color: #002200;">&#40;</span>hSrcAlias<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span>srcAliasDesc<span style="color: #002200;">&#41;</span>
   <span style="color: #a61390;">break</span>;
  <span style="color: #002200;">&#91;</span>finderEventDesc setParamDescriptor<span style="color: #002200;">:</span>srcAliasDesc
    forKeyword<span style="color: #002200;">:</span>keyASPrepositionTo<span style="color: #002200;">&#93;</span>;
  HSetState<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#40;</span>Handle<span style="color: #002200;">&#41;</span>hSrcAlias, handleState<span style="color: #002200;">&#41;</span>;
  <span style="color: #11740a; font-style: italic;">/* Next create the target Alias and attach it to the event. */</span>
  err <span style="color: #002200;">=</span> FSNewAliasFromPath<span style="color: #002200;">&#40;</span><span style="color: #a61390;">nil</span>, <span style="color: #002200;">&#91;</span>pstrDstPath fileSystemRepresentation<span style="color: #002200;">&#93;</span>, <span style="color: #2400d9;">0</span>, <span style="color: #002200;">&amp;</span>hDstAlias, <span style="color: #2400d9;">0</span><span style="color: #002200;">&#41;</span>;
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>err <span style="color: #002200;">!=</span> noErr<span style="color: #002200;">&#41;</span>
   <span style="color: #a61390;">break</span>;
  handleState <span style="color: #002200;">=</span> HGetState<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#40;</span>Handle<span style="color: #002200;">&#41;</span>hDstAlias<span style="color: #002200;">&#41;</span>;
  HLock<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#40;</span>Handle<span style="color: #002200;">&#41;</span>hDstAlias<span style="color: #002200;">&#41;</span>;
  <span style="color: #400080;">NSAppleEventDescriptor</span> <span style="color: #002200;">*</span>dstAliasDesc <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSAppleEventDescriptor</span>
                                           descriptorWithDescriptorType<span style="color: #002200;">:</span>t ypeAlias
                                           bytes<span style="color: #002200;">:*</span>hDstAlias
                                           length<span style="color: #002200;">:</span>GetAliasSize<span style="color: #002200;">&#40;</span>hDstAlias<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span>dstAliasDesc<span style="color: #002200;">&#41;</span>
   <span style="color: #a61390;">break</span>;
  <span style="color: #002200;">&#91;</span>finderEventDesc setParamDescriptor<span style="color: #002200;">:</span>dstAliasDesc
    forKeyword<span style="color: #002200;">:</span>keyAEInsertHere<span style="color: #002200;">&#93;</span>;
  HSetState<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#40;</span>Handle<span style="color: #002200;">&#41;</span>hDstAlias, handleState<span style="color: #002200;">&#41;</span>;
  <span style="color: #11740a; font-style: italic;">/* Finally a property descriptor containing the target
   * Alias name. */</span>
  <span style="color: #400080;">NSAppleEventDescriptor</span> <span style="color: #002200;">*</span>finderPropDesc <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSAppleEventDescriptor</span> recordDescriptor<span style="color: #002200;">&#93;</span>;
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span>finderPropDesc<span style="color: #002200;">&#41;</span>
   <span style="color: #a61390;">break</span>;
  <span style="color: #002200;">&#91;</span>finderPropDesc setDescriptor<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSAppleEventDescriptor</span> descriptorWithString<span style="color: #002200;">:</span>pstrName<span style="color: #002200;">&#93;</span>
    forKeyword<span style="color: #002200;">:</span>keyAEName<span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>finderEventDesc setParamDescriptor<span style="color: #002200;">:</span>finderPropDesc forKeyword<span style="color: #002200;">:</span>keyAEPropData<span style="color: #002200;">&#93;</span>;
  <span style="color: #11740a; font-style: italic;">/* Now send the event to the Finder. */</span>
  err <span style="color: #002200;">=</span> AESend<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>finderEventDesc aeDesc<span style="color: #002200;">&#93;</span>,
               <span style="color: #a61390;">NULL</span>,
               kAENoReply,
               kAENormalPriority,
               kNoTimeOut,
               <span style="color: #2400d9;">0</span>,
               <span style="color: #a61390;">nil</span><span style="color: #002200;">&#41;</span>;
 <span style="color: #002200;">&#125;</span> <span style="color: #a61390;">while</span><span style="color: #002200;">&#40;</span><span style="color: #2400d9;">0</span><span style="color: #002200;">&#41;</span>;
 <span style="color: #11740a; font-style: italic;">/* Cleanup */</span>
 <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>hSrcAlias<span style="color: #002200;">&#41;</span>
  DisposeHandle<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#40;</span>Handle<span style="color: #002200;">&#41;</span>hSrcAlias<span style="color: #002200;">&#41;</span>;
 <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>hDstAlias<span style="color: #002200;">&#41;</span>
  DisposeHandle<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#40;</span>Handle<span style="color: #002200;">&#41;</span>hDstAlias<span style="color: #002200;">&#41;</span>;
 <span style="color: #a61390;">return</span> err <span style="color: #002200;">==</span> noErr ? <span style="color: #a61390;">true</span> <span style="color: #002200;">:</span> <span style="color: #a61390;">false</span>;
<span style="color: #002200;">&#125;</span></pre></div></div>

<p>Although the code above looks a little bit scary, it does not much. It fetch the process serial number of the current Finder process, creates an Application event for creating an Alias file and send this event to the Finder.</p>
<h2>Conclusion</h2>
<p>Beside showing how to create file shortcuts on different platforms, this article also shows which work is necessary to create platform independent code. It's a simple example. But it also makes clear that one simple solution for platform one, not necessarily mean it's such simple on platform two.</p>
<p>Making this easy accessible to any developer is the next step. I will leave this exercise to the reader, but have a look at the <a href="http://www.virtualbox.org/browser/trunk/src/VBox/Frontends/VirtualBox/src/platform" target="_blank">platform code of the VirtualBox GUI</a> and the corresponding <a href="http://www.virtualbox.org/browser/trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk" target="_blank">Makefile</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.64k-tec.de/2010/11/creating-file-shortcuts-on-three-different-operation-systems/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Changing the default behavior of built-in Cocoa controls</title>
		<link>http://www.64k-tec.de/2010/06/changing-the-default-behavior-of-built-in-cocoa-controls/</link>
		<comments>http://www.64k-tec.de/2010/06/changing-the-default-behavior-of-built-in-cocoa-controls/#comments</comments>
		<pubDate>Sun, 13 Jun 2010 11:34:47 +0000</pubDate>
		<dc:creator>cp</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[IT]]></category>
		<category><![CDATA[Archive]]></category>
		<category><![CDATA[delegate]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[NSCell]]></category>
		<category><![CDATA[NSControl]]></category>
		<category><![CDATA[NSSearchField]]></category>
		<category><![CDATA[objc]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[search field]]></category>

		<guid isPermaLink="false">http://www.64k-tec.de/?p=251</guid>
		<description><![CDATA[Apple has many task specific controls built into Cocoa. They are all well designed and have most of the functionality a user and a developer expect. One of this controls is the NSSearchField. This control has a special design which allows the user to recognize the provided functionality with ease. It is so well-known that [...]]]></description>
			<content:encoded><![CDATA[<p>Apple has many task specific controls built into Cocoa. They are all well designed and have most of the functionality a user and a developer expect. One of this controls is the <a href="http://developer.apple.com/mac/library/documentation/Cocoa/Reference/ApplicationKit/Classes/NSSearchField_Class/Reference/Reference.html" target="_blank">NSSearchField</a>. This control has a special design which allows the user to recognize the provided functionality with ease. It is so well-known that Apple uses the design even on there website. It has support for menus (e.g. for recent search items), auto completion, a cancel button, and so one. Although this is mostly feature complete, there are sometimes cases where you like to extend it. In this post, I will show how to add another visual hint to this control when a search term isn't found. The aim is to change the background of the underlying text edit to become light red to visual mark the failed search.</p>
<h2>Understanding how Cocoa works</h2>
<p>The NSSearchField class inherits from an <a href="http://developer.apple.com/mac/library/documentation/Cocoa/Reference/ApplicationKit/Classes/NSControl_Class/Reference/Reference.html" target="_blank">NSControl</a>. NSControls are responsible for the interaction with the user. This implies displaying the content in a <a href="http://developer.apple.com/mac/library/documentation/Cocoa/Reference/ApplicationKit/Classes/NSView_Class/Reference/NSView.html" target="_blank">NSView</a>, reacting to user input like mouse or keyboard events and sending actions to other objects in the case the status of the control has changed. Usually a control delegate the first two tasks to a <a href="http://developer.apple.com/mac/library/documentation/Cocoa/Reference/ApplicationKit/Classes/NSCell_Class/Reference/NSCell.html" target="_blank">NSCell</a>. The main reasons for this are to persist on good performance even if there are many cells of the same type (like in the case of a table) and to be able to exchange the behavior of the control easily (like in the case of a combobox which also allow typing in a text field). With this information in mind we know that we need to overwrite the drawing routine of the cell (<a href="http://developer.apple.com/mac/library/documentation/Cocoa/Reference/ApplicationKit/Classes/NSSearchFieldCell_Class/Reference/Reference.html" target="_blank">NSSearchFieldCell</a>) to achieve our goal. The implementation is straight forward and shown in the following:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@interface</span> MySearchFieldCell<span style="color: #002200;">:</span> <span style="color: #400080;">NSSearchFieldCell</span>
<span style="color: #002200;">&#123;</span>
  <span style="color: #400080;">NSColor</span> <span style="color: #002200;">*</span>m_pBGColor;
<span style="color: #002200;">&#125;</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>setBackgroundColor<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSColor</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>pBGColor;
<span style="color: #a61390;">@end</span>
&nbsp;
<span style="color: #a61390;">@implementation</span> MySearchFieldCell
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>init
<span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>self <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>super init<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>
    m_pBGColor <span style="color: #002200;">=</span> <span style="color: #a61390;">Nil</span>;
  <span style="color: #a61390;">return</span> self;
<span style="color: #002200;">&#125;</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>setBackgroundColor<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSColor</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>pBGColor
<span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>m_pBGColor <span style="color: #002200;">!=</span> pBGColor<span style="color: #002200;">&#41;</span>
  <span style="color: #002200;">&#123;</span>
    <span style="color: #002200;">&#91;</span>m_pBGColor release<span style="color: #002200;">&#93;</span>;
    m_pBGColor <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>pBGColor retain<span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>drawInteriorWithFrame<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">NSRect</span><span style="color: #002200;">&#41;</span>cellFrame inView<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSView</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>controlView
<span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>m_pBGColor <span style="color: #002200;">!=</span> <span style="color: #a61390;">Nil</span><span style="color: #002200;">&#41;</span>
  <span style="color: #002200;">&#123;</span>
    <span style="color: #002200;">&#91;</span>m_pBGColor setFill<span style="color: #002200;">&#93;</span>;
    <span style="color: #a61390;">NSRect</span> frame <span style="color: #002200;">=</span> cellFrame;
    <span style="color: #a61390;">double</span> radius <span style="color: #002200;">=</span> MIN<span style="color: #002200;">&#40;</span>NSWidth<span style="color: #002200;">&#40;</span>frame<span style="color: #002200;">&#41;</span>, NSHeight<span style="color: #002200;">&#40;</span>frame<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">/</span> <span style="color: #2400d9;">2.0</span>;
    <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSBezierPath</span> bezierPathWithRoundedRect<span style="color: #002200;">:</span>frame
          xRadius<span style="color: #002200;">:</span>radius yRadius<span style="color: #002200;">:</span>radius<span style="color: #002200;">&#93;</span> fill<span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#125;</span>
  <span style="color: #002200;">&#91;</span>super drawInteriorWithFrame<span style="color: #002200;">:</span>cellFrame inView<span style="color: #002200;">:</span>controlView<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
<span style="color: #a61390;">@end</span></pre></div></div>

<p>The user can set a custom background color by using setBackgroundColor. Also it is possible to reset the background color by passing Nil to this method. The method drawInteriorWithFrame draws a rounded rectangle on the background and forwards the call to the super class afterward.</p>
<h2>Replacing the cell class of a control</h2>
<p>The next step is tell the control to use our own cell class and not the default one. Although there is a <a href="http://developer.apple.com/mac/library/documentation/Cocoa/Reference/ApplicationKit/Classes/NSControl_Class/Reference/Reference.html#//apple_ref/occ/instm/NSControl/setCell:" target="_blank">setCell</a> method defined in NSControl it is not as easy as one might think. Creating an instance of MySearchFieldCell and passing it to setCell after the NSSearchField is created will not have the expected effect. The reason for this comes from the fact that the cell is initialized when the control is created. This includes setting all properties and targets for the actions. If one replaces the cell afterward these setting will be get lost. Later on, I will show a method how to keep this configuration, but for now we will start with an easier approach.</p>
<p>When the control creates a cell object it asks a static method for the class name to use. This method is called <a href="http://developer.apple.com/mac/library/documentation/Cocoa/Reference/ApplicationKit/Classes/NSControl_Class/Reference/Reference.html#//apple_ref/occ/clm/NSControl/cellClass" target="_blank">cellClass</a>. If we overriding this method with our own one, we are able to return MySearchFieldCell. The following code demonstrates this:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@interface</span> MySearchField<span style="color: #002200;">:</span> <span style="color: #400080;">NSSearchField</span>
<span style="color: #002200;">&#123;</span><span style="color: #002200;">&#125;</span>
<span style="color: #a61390;">@end</span>
&nbsp;
<span style="color: #a61390;">@implementation</span> MySearchField
<span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">Class</span><span style="color: #002200;">&#41;</span>cellClass
<span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">return</span> <span style="color: #002200;">&#91;</span>MySearchFieldCell class<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
<span style="color: #a61390;">@end</span></pre></div></div>

<p>Now, if you use MySearchField instead of NSSearchField when creating search fields, you are done. Unfortunately this isn't always possible. First you may not be able to inherit from NSSearchField for whatever reason and second this will not work when you are use the Interface Builder (<em>IB</em>) from Xcode. There you can't easily use your own version of NSSearchField, but you have to stick with the original one. Before we proceed the obligatory screenshot:</p>
<p style="text-align: center;"><a href="/wordpress/wp-content/uploads/MySearchField.png"><img class="aligncenter size-full wp-image-1071" title="MySearchField" src="/wordpress/wp-content/uploads/MySearchField.png" alt="" width="180" height="21" /></a></p>
<h2>The power of Archives</h2>
<p>What we need is a method of setting our own cell class even when the control is already instantiated. In Cocoa it is possible to Archive and Serialize any object which implements the <a href="http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Protocols/NSCoding_Protocol/Reference/Reference.html" target="_blank">NSCoding</a> protocol. Archiving means that the whole class hierarchy, with all properties and connections, is saved into a stream. Xcode makes heavy use of this in the nib file format where all the project data of the IB is written in. This alone doesn't help us much, but additional to the archiving and unarchiving work, it is possible to replace classes in the decoding step. The relevant classes are <a href="http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSKeyedArchiver_Class/Reference/Reference.html" target="_blank">NSKeyedArchiver</a> and <a href="http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSKeyedUnarchiver_Class/Reference/Reference.html" target="_blank">NSKeyedUnarchiver</a>. NSKeyedUnarchiver has a method <a href="http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSKeyedUnarchiver_Class/Reference/Reference.html#//apple_ref/occ/clm/NSKeyedUnarchiver/setClass:forClassName:" target="_blank">setClass:forClassName</a> which allow this inline replacement and the following code shows how to use it:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #400080;">NSSearchField</span> <span style="color: #002200;">*</span>pSearch <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSSearchField</span> alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
<span style="color: #11740a; font-style: italic;">/* Replace the cell class used for the NSSearchField */</span>
<span style="color: #002200;">&#91;</span><span style="color: #400080;">NSKeyedArchiver</span> setClassName<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;MySearchFieldCell&quot;</span>
      forClass<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSSearchFieldCell</span> class<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span>pSearch setCell<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSKeyedUnarchiver</span>
      unarchiveObjectWithData<span style="color: #002200;">:</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSKeyedArchiver</span>
        archivedDataWithRootObject<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>pSearch cell<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
<span style="color: #11740a; font-style: italic;">/* Get the original behavior back */</span>
<span style="color: #002200;">&#91;</span><span style="color: #400080;">NSKeyedArchiver</span> setClassName<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;NSSearchFieldCell&quot;</span>
      forClass<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSSearchFieldCell</span> class<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;</pre></div></div>

<p>Basically this creates an archive of the current NSSearchFieldCell of the NSSearchField, which is instantly unarchived, but with the difference that the NSSearchFieldCell class is replaced by MySearchFieldCell. Because the archiving preserve all settings the new created class will have the same settings like the old one. The last call to NSKeyedArchiver will restore the default behavior.</p>
<h2>Conclusion</h2>
<p>This post should have removed some of the mysteries of the control and cell relationship in Cocoa. Additional to a simple derivation approach, a much more advanced way for setting the cell of a control was shown. This allows the replacement of any class hierarchy without loosing any runtime settings. If you need such replacements much more often or working with the IB, you should have a look at <a href="http://www.mikeash.com/pyblog/custom-nscells-done-right.html" target="_blank">Mike's</a> post which shows a more generic way of the archive/unarchive trick.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.64k-tec.de/2010/06/changing-the-default-behavior-of-built-in-cocoa-controls/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Integrating native Cocoa controls into Qt</title>
		<link>http://www.64k-tec.de/2009/12/integrating-native-cocoa-controls-into-qt/</link>
		<comments>http://www.64k-tec.de/2009/12/integrating-native-cocoa-controls-into-qt/#comments</comments>
		<pubDate>Wed, 30 Dec 2009 13:52:01 +0000</pubDate>
		<dc:creator>cp</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[IT]]></category>
		<category><![CDATA[Qt]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[gcc]]></category>
		<category><![CDATA[help button]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.64k-tec.de/wordpress/?p=15</guid>
		<description><![CDATA[Making applications looking and feeling as native as possible on every supported platform is one of my main responsibilities within the VirtualBox development. Most of the work therefor is done by the Qt framework which we are using for our GUI. Qt does a nice job for Windows and most of the currently popular X11 [...]]]></description>
			<content:encoded><![CDATA[<p>Making applications looking and feeling as native as possible on every supported platform is one of my main responsibilities within the VirtualBox development. Most of the work therefor is done by the Qt framework which we are using for our GUI. Qt does a nice job for Windows and most of the currently popular X11 window toolkits used under Unix and Linux. They are behaving and looking similar in many ways which make it easy to develop for both architectures. Unfortunately this doesn't count in any case for Mac OS X, which often uses very different approaches or uses very specialized controls to reach a specific aim. One of this controls is the Mac OS X help button who every Mac user is familiar with. If an Mac OS X application doesn't use this help button, it breaks the design rules and the application, lets say, smells a little bit "under designed". The following little example shows how to integrate a <a href="http://developer.apple.com/mac/library/documentation/Cocoa/Reference/ApplicationKit/Classes/NSButton_Class/Reference/Reference.html" target="_blank">NSButton</a> seamlessly into your Qt application.</p>
<h2>Qt make it easy</h2>
<p>Nokia added the <a href="http://doc.trolltech.com/latest/qmaccocoaviewcontainer.html" target="_blank">QMacCocoaViewContainer</a> class with Qt 4.5. This class make it easy to integrate any NSView or deviate of the NSView class into the QWidget hierarchy of an application. The best integration is archived if one deviate from QMacCocoaViewContainer. To use Cocoa code and C++ classes at once the Objective-C++ compiler is necessary. The gcc uses the Objective-C++ compiler automatically if the source file ends with mm. We start with the C++ interface which looks like the following:</p>

<div class="wp_syntax"><div class="code"><pre class="cpp-qt" style="font-family:monospace;">ADD_COCOA_NATIVE_REF<span style="color: #006E28;">&#40;</span>NSButton<span style="color: #006E28;">&#41;</span><span style="color: #006E28;">;</span>
<span style="color: #0057AE;">class</span> CocoaHelpButton<span style="color: #006E28;">:</span> <span style="color: #0057AE;">public</span> QMacCocoaViewContainer
<span style="color: #006E28;">&#123;</span>
    <span style="color: #0057AE;">Q_OBJECT</span>
<span style="color: #0057AE;">public</span><span style="color: #006E28;">:</span>
    CocoaHelpButton<span style="color: #006E28;">&#40;</span><span style="color: #22aadd;">QWidget</span> <span style="color: #006E28;">*</span>pParent <span style="color: #006E28;">=</span> <span style="color: #B08000;">0</span><span style="color: #006E28;">&#41;</span><span style="color: #006E28;">;</span>
    <span style="color: #22aadd;">QSize</span> sizeHint<span style="color: #006E28;">&#40;</span><span style="color: #006E28;">&#41;</span> const<span style="color: #006E28;">;</span>
    <span style="color: #0057AE;">void</span> onClicked<span style="color: #006E28;">&#40;</span><span style="color: #006E28;">&#41;</span><span style="color: #006E28;">;</span>
<span style="color: #0057AE;">signals</span><span style="color: #006E28;">:</span>
    <span style="color: #0057AE;">void</span> clicked<span style="color: #006E28;">&#40;</span><span style="color: #006E28;">&#41;</span><span style="color: #006E28;">;</span>
<span style="color: #0057AE;">private</span><span style="color: #006E28;">:</span>
    NativeNSButtonRef m_pButton<span style="color: #006E28;">;</span>
<span style="color: #006E28;">&#125;</span><span style="color: #006E28;">;</span></pre></div></div>

<p>For any Qt programmer this class definition is easy to understand. The only unusual is the ADD_COCOA_NATIVE_REF macro call and the NativeNSButtonRef type itself. One could say NativeNSButtonRef should be NSButton* and you are done, but it's not that easy. The reason for this is that the include file will be included first in the Objective-C++ source code file, where the NSButton* definition wouldn't be a problem, but secondly in every C++ source file which will use the CocoaHelpButton, where on the other side any Cocoa code is forbidden. The ADD_COCOA_NATIVE_REF macro avoid this problem by expanding NativeNSButtonRef to NSButton* if Objective-C++ code is compiled and to void* if C++ code is compiled. The macro itself looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#ifdef __OBJC__</span>
<span style="color: #339900;"># define ADD_COCOA_NATIVE_REF(CocoaClass) \
    @class CocoaClass; \
    typedef CocoaClass *Native##CocoaClass##Ref</span>
<span style="color: #339900;">#else /* __OBJC__ */</span>
<span style="color: #339900;"># define ADD_COCOA_NATIVE_REF(CocoaClass) typedef void *Native##CocoaClass##Ref</span>
<span style="color: #339900;">#endif /* __OBJC__ */</span></pre></div></div>

<p>The advantage of using such a macro is that one can use all methods of the NSButton in the Cocoa part of the source code without any casting.</p>
<h2>A little bit of Cocoa</h2>
<p>The initialization of the CocoaHelpButton class is straight forward as seen in the next code part:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">CocoaHelpButton<span style="color: #002200;">::</span>CocoaHelpButton<span style="color: #002200;">&#40;</span>QWidget <span style="color: #002200;">*</span>pParent <span style="color: #11740a; font-style: italic;">/* = 0 */</span><span style="color: #002200;">&#41;</span>
  <span style="color: #002200;">:</span>QMacCocoaViewContainer<span style="color: #002200;">&#40;</span><span style="color: #2400d9;">0</span>, pParent<span style="color: #002200;">&#41;</span>
<span style="color: #002200;">&#123;</span>
    m_pButton <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSButton</span> alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>m_pButton setTitle<span style="color: #002200;">:</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;&quot;</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>m_pButton setBezelStyle<span style="color: #002200;">:</span> NSHelpButtonBezelStyle<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>m_pButton setBordered<span style="color: #002200;">:</span> <span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>m_pButton setAlignment<span style="color: #002200;">:</span> NSCenterTextAlignment<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>m_pButton sizeToFit<span style="color: #002200;">&#93;</span>;
    <span style="color: #a61390;">NSRect</span> frame <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>m_pButton frame<span style="color: #002200;">&#93;</span>;
    frame.size.width <span style="color: #002200;">+=</span> <span style="color: #2400d9;">12</span>; <span style="color: #11740a; font-style: italic;">/* Margin */</span>
    <span style="color: #002200;">&#91;</span>m_pButton setFrame<span style="color: #002200;">:</span>frame<span style="color: #002200;">&#93;</span>;
    <span style="color: #11740a; font-style: italic;">/* We need a target for the click selector */</span>
    NSButtonTarget <span style="color: #002200;">*</span>bt <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>NSButtonTarget alloc<span style="color: #002200;">&#93;</span> initWithObject<span style="color: #002200;">:</span> this<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>m_pButton setTarget<span style="color: #002200;">:</span> bt<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>m_pButton setAction<span style="color: #002200;">:</span> <span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>clicked<span style="color: #002200;">:</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #11740a; font-style: italic;">/* Make sure all is properly resized */</span>
    resize<span style="color: #002200;">&#40;</span>frame.size.width, frame.size.height<span style="color: #002200;">&#41;</span>;
    setSizePolicy<span style="color: #002200;">&#40;</span>QSizePolicy<span style="color: #002200;">::</span>Fixed, QSizePolicy<span style="color: #002200;">::</span>Fixed<span style="color: #002200;">&#41;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
QSize CocoaHelpButton<span style="color: #002200;">::</span>sizeHint<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span> <span style="color: #a61390;">const</span>
<span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">NSRect</span> frame <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>m_pButton frame<span style="color: #002200;">&#93;</span>;
    <span style="color: #a61390;">return</span> QSize<span style="color: #002200;">&#40;</span>frame.size.width, frame.size.height<span style="color: #002200;">&#41;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #a61390;">void</span> CocoaHelpButton<span style="color: #002200;">::</span>onClicked<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>
<span style="color: #002200;">&#123;</span>
    emit clicked<span style="color: #002200;">&#40;</span><span style="color: #a61390;">false</span><span style="color: #002200;">&#41;</span>;
<span style="color: #002200;">&#125;</span></pre></div></div>

<p>This set up the NSButton object and make sure that everything has the right size. As shown there, to make a standard button a help button the bezel style has been set to NSHelpButtonBezelStyle. To get the click notification the wrapper class NSButtonTarget is necessary.  As highlighted in the code above the target action is set to the selector "clicked".  The NSButtonTarget class looks as follow:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@interface</span> NSButtonTarget<span style="color: #002200;">:</span> <span style="color: #400080;">NSObject</span>
<span style="color: #002200;">&#123;</span>
    CocoaHelpButton <span style="color: #002200;">*</span>m_pTarget;
<span style="color: #002200;">&#125;</span>
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>initWithObject<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>CocoaHelpButton<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>object;
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span>IBAction<span style="color: #002200;">&#41;</span>clicked<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>sender;
<span style="color: #a61390;">@end</span>
<span style="color: #a61390;">@implementation</span> NSButtonTarget
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>initWithObject<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>CocoaHelpButton<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>object
<span style="color: #002200;">&#123;</span>
    self <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>super init<span style="color: #002200;">&#93;</span>;
    m_pTarget <span style="color: #002200;">=</span> object;
    <span style="color: #a61390;">return</span> self;
<span style="color: #002200;">&#125;</span>
<span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span>IBAction<span style="color: #002200;">&#41;</span>clicked<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>sender;
<span style="color: #002200;">&#123;</span>
    m_pTarget<span style="color: #002200;">-</span>&gt;onClicked<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>;
<span style="color: #002200;">&#125;</span>
<span style="color: #a61390;">@end</span></pre></div></div>

<p>If you put all this together and add the CocoaHelpButton class to your project you will get some output like this:</p>
<p style="text-align: left;"><a href="http://www.64k-tec.de/wordpress/wp-content/uploads/help1.png"><img class="size-full wp-image-220  aligncenter" title="help" src="http://www.64k-tec.de/wordpress/wp-content/uploads/help1.png" alt="" width="38" height="37" /></a>More integration could be reached by adding wrapper methods for e.g. setting the tooltip, but this is left out as an exercise for the reader.</p>
<h2>Conclusion</h2>
<p>For more complex controls like a NSSearchField more interaction with Cocoa will be necessary. On the other hand this little excursion to the Cocoa world should make it easy for everyone to add shiny new Mac OS X controls to the own Qt application.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.64k-tec.de/2009/12/integrating-native-cocoa-controls-into-qt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

