Accessing the System Clipboard in C++

The other day I needed to do something that should be very easy, but I ran into some problems.  Lots of google searching and I eventually was able to scrounge together enough to make it work, and I’d like to save others the trouble.

One of the feature requests  we had recently for Hexels was copy and paste across multiple instances of the application.  Hexels always did have copy and paste, but it just stored the data in application memory rather than using the system clipboard, so it couldn’t go across difference instances and it vanished when you quit the app.

I suppose I could have just saved the data to a file in Hexels’ temp directory, and that would have served my purposes.  Probably better than using the clipboard, even, since then it wouldn’t overwrite what was already on there.  But I wanted to use the system clipboard.  Besides, eventually I’d like to also convert the selection to an image for pasting into other apps.

So anyway, Hexels is built on the QT framework, which is pretty awesome and does support clipboard operations.  In fact, it’s this simple:
void copyToClipboard(unsigned char* genericData, int size)
{
QByteArray a((char*)genericData, size);
QMimeData* qmd = new QMimeData;
qmd->setData("HEXELS", a);
QApplication::clipboard()->clear();
QApplication::clipboard()->setMimeData(qmd);
}

Easy, right?  Except it doesn’t persist when the app exits.  So what good is that?  It’s probably all most people would need, but it’s sort of like breaking a promise if your clipboard data doesn’t stick around, isn’t it?  By the way, I swear I properly indent my code, the formatting is just from WordPress.  I’m not sure good with it yet.

So I did what any good programmer does, and I googled it.  Something about clipboard ownership and flushing and whatnot.  Not many results, though, which is actually the reason I’m writing a blog post about such a mundane topic that I, as you’ll see, solved very inelegantly.

On Windows, it turns out that flushing the clipboard to the system such that it persists upon exit is easy.  Just call

OleFlushClipboard(); //needed to retain clipboard between app launches
Then later you can grab the data like this:
unsigned char* getDataFromClipboard(int& size)
{
size = 0;

//grab the clipboard and a pointer to all its data
const QMimeData* data = QApplication::clipboard()->mimeData();
if(!data) return NULL;

//is there HEXELS data here?
QByteArray a = data->data(“HEXELS”);

size = a.size();
if(!a.size()) return NULL;

//the pointer might not be good after we leave the function, so make a copy of the data
//you’ll have to delete it yourself later
unsigned char* newData = new unsigned char[a.size()];
memcpy(newData, a.data(), a.size());
return newData;

}

And that’s it!

 

Except on Mac.  Macs don’t have OleFlushClipboard, and Google couldn’t offer me an alternative.  For Mac I had to  go a somewhat more format route and use Objective-C.  Looking at Apple dev docs, I put together the following:

void copyToClipboard(unsigned char* genericData, int size)
{

//establish clipboard ownership on Mac
NSPasteboard* pb = [NSPasteboard generalPasteboard];
[pb clearContents];
NSData* cpdata = [[NSData alloc] initWithBytes:genericData       length:size];
[pb setData:cpdata forType:@”HEXELS”];

}

unsigned char* getDataFromClipboard(int& size)
{
size = 0;
NSPasteboard* pb = [NSPasteboard generalPasteboard];
NSData* cpdata = [pb dataForType:@”HEXELS”];
if(cpdata)
{
size = [cpdata length];
unsigned char* dater = new unsigned char[size];
memcpy(dater, [cpdata bytes], size);
return dater;
}
return NULL;
}

You might be wondering why the getDataFromClipboard function has to be different on Mac.  I’m wondering the same thing.  For some reason, Hexels data copied straight to the Mac system clipboard wasn’t accessible to Qt.

So there you go, everything you need to use the clipboard on Windows and Mac.  I suspect these functions could be modified to put data on the clipboard in multiple formats simultaneously, like pasting Hexels data into Hexels or pasting an image into Photoshop.  Is this the “correct” way to do this?  I doubt it. But it works for me, on both Mac (OSX 10.9) and Windows 7.  It also gets around some issues that Google wasn’t very helpful with, and those things are what matter.  Enjoy!

 

Hello!

Hey folks,

I’m Ken Kopecky.  I finally managed to get this domain off of Google’s hosting, where I couldn’t figure out how to do anything with it, and transferred it to DreamHost.  It was a huge pain that, ironically, required a lot of googling.

I’ll start with some words that describe me.  Sometimes it’s nice just to look at a list of words rather than wade through prose.  So here goes

Indie Game Developer, PhD Candidate, VR Expert, Animal Lover, Black Belt, Wannabe/Future Dad, Self-Taught Awesome Coder, Outdoors Lover

See something you like in there?  Then keep reading.

I love to make things.   Usually I accomplish this by programming, but sometimes I make things out of wood, PVC, or other materials.  I’m also the co-founder of (and programmer/designer at) Hex-Ray Studios.  We made Hexels, which is a one-of-a-kind (so far…) art tool based on shapes that aren’t always square pixels.  People love the Trixel mode for drawing isometric 3D stuff, so if that sounds like fun, you should check it out.

I like to pretend I’m a game developer.  In fact, when I go to the Game Developer’s Conference or other game dev shindigs, I fit in with game developers so well, most of them are none the wiser.  I do make games, but I’ve never released one widely.  My real talents lie in what I like to call “artist enablement”.   I love making tools to help artists and other content-creators create their content!  For games.

So I’m sort of a game developer.

I also do virtual reality.  I’ve been doing it for quite a while, and I’d like to think I’m pretty good with it.  My VR facility of choice is the C6 at Iowa State University, because being surrounded by 100 million pixels of your app is rather amazing.  I’ve written a number of demos (games) for it, and I plan on talking about them more on this site.  Maybe I’ve done that between the time I’m writing this and the time you’re reading it.  You should poke around and see if they’re up.

I also have a dog named Emmy.  She’s my best friend, and she goes everywhere with me.  She’s even been to a game jam or two.

Rock Crop

I think that covers most of the “who’s Ken?” section. I’ll add other sections soon, talking about my projects and where I want to go in the future.  Thanks for reading!