Going through my comments backlog I found a question asking how to send virtual keystrokes on OS X. Short answer is to use the CGEvent functions in MacApi.CoreGraphics – in a nutshell,
Call CGEventSourceCreate to allocate a CGEventSourceRef.
For each keystroke, create a CGEventRef by calling CGEventCreateKeyboardEvent; this takes the CGEventSourceRef just allocated plus an OS X virtual key code. For possible values of the latter, see the MacApi.KeyCodes unit, assuming you have a recent Delphi version, otherwise scan the source for KEY_xxx values. Also, note that you will need separate events for first pressing a key down, then unpressing it.
If required, call CGEventSetFlags on a given CGEventRef to assign a modifier key (alt/shift/ctrl/command); in the case of a character, you’ll typically want to call CGEventKeyboardSetUnicodeString as well rather than messing about trying to figure out the correct key code.
Actually perform the event by passing the CGEventRef to CGEventPost, using kCGHIDEventTap for the first parameter.
Clean up by passing each CGEventRef then the CGEventSourceRef to CFRelease.
The following follows these steps to generate key down and key up events for a Cmd+L shortcut:
System.SysUtils, MacApi.CocoaTypes, MacApi.CoreFoundation, MacApi.CoreGraphics, MacApi.KeyCodes;
KeyDownRef, KeyUpRef: CGEventRef;
KeyDownRef := nil;
KeyUpRef := nil;
EventSourceRef := CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
if EventSourceRef = nil then RaiseLastOSError;
KeyDownRef := CGEventCreateKeyboardEvent(EventSourceRef, KEY_L, 1); //1 = key down
if KeyDownRef = nil then RaiseLastOSError;
KeyUpRef := CGEventCreateKeyboardEvent(EventSourceRef, KEY_L, 0); //0 = key up
if KeyUpRef = nil then RaiseLastOSError;
if KeyDownRef <> nil then CFRelease(KeyDownRef);
if KeyUpRef <> nil then CFRelease(KeyUpRef);
Alternatively, you can use a little cross platform (Mac/Windows) wrapper interface I’ve written… more on which in my next post!
Where the platform allows, supports delayed rendering, virtual files, change notifications, and inter-process TClipboard-based drag and drop. The code originates from the FMX TClipboard I published a few years back, though is much extended, and was refactored to support the VCL too (XE2+). For more info, check out the readme first…
Disclaimer: supporting multiple FMX versions ain’t no fun, so if you come to try it in XE4 or whatever and have an issue, I may not be able to help you. Also, if you’re interested in drag and drop on OS X, consider using my code with any version lower than XE8 a ‘proof of concept’ only…
Just a quick post to say Embarcadero have released hotfix 6 for XE5, which resolves significant issues when attempting to develop iOS apps in conjunction with iOS SDK 7.1 and Xcode 5.1. More info is available here; the hotfix itself is downloadable from CodeCentral here.