Peyman
Peyman

Reputation: 3087

Trying to make this port from Objective-C to MonoMac work

Could anyone help me to make this port from Objective-C to MonoMac work?

CGEventSourceRef eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);

CGEventRef keyEventDown = CGEventCreateKeyboardEvent(eventSource, 0, true); 

NSString * characters = @"ABCD";

UniChar buffer;

for (int i = 0; i < [characters length]; i++)
{
    [characters getCharacters:&buffer range:NSMakeRange(i, 1)];

    keyEventDown = CGEventCreateKeyboardEvent(eventSource, 1, true);

    CGEventKeyboardSetUnicodeString(keyEventDown, 1, &buffer);

    CGEventPost(kCGHIDEventTap, keyEventDown);

    CFRelease(keyEventDown);
}

CFRelease(eventSource);

I have DLL imported it using the following code but I do not know what to do with Objective-C's UniChar. I do not know which type I should use in C# that Objective-C changes. It is a pointer that Obj-C need to change and again I can access it in my C# code.

using System;

using System.Runtime.InteropServices;

using MonoMac;

namespace SomeNameSpace
{

public unsafe static class Native
{
    [DllImport(Constants.CoreGraphicsLibrary)]
    public static extern IntPtr CGEventCreateKeyboardEvent(IntPtr source, ushort virtualKey, bool keyDown);

    [DllImport(Constants.CoreGraphicsLibrary)]
    public static extern void CGEventKeyboardSetUnicodeString(IntPtr @event, ulong stringLength, char* unicodeString);

    [DllImport(Constants.CoreGraphicsLibrary)]
    public static extern IntPtr CGEventSourceCreate(CGEventSourceStateID stateID);

    [DllImport(Constants.CoreGraphicsLibrary)]
    public static extern void CGEventPost(CGEventTapLocation tap, IntPtr @event);

    [DllImport(Constants.CoreFoundationLibrary)]
    public static extern void CFRelease (IntPtr cf);
}

public enum CGEventTapLocation:uint
{
    kCGHIDEventTap = 0,

    kCGSessionEventTap,

    kCGAnnotatedSessionEventTap
}

public enum CGEventSourceStateID:int
{
    kCGEventSourceStatePrivate = -1,

    kCGEventSourceStateCombinedSessionState = 0,

    kCGEventSourceStateHIDSystemState = 1
}
}

public unsafe void SomeMethod()
{
    IntPtr eventSource = Native.CGEventSourceCreate(CGEventSourceStateID.kCGEventSourceStateHIDSystemState);


IntPtr keyEventDown = Native.CGEventCreateKeyboardEvent(cgEventSource,0,true);

string characters = @"ABCD";

char buffer;

for (int i = 0; i < characters.Length; i++)
{
    buffer = characters[i];

    keyEventDown = Native.CGEventCreateKeyboardEvent(eventSource, 1, true);

    Native.CGEventKeyboardSetUnicodeString(keyEventDown, 1, &buffer);

    Native.CGEventPost(CGEventTapLocation.kCGHIDEventTap, keyEventDown);

    Native.CFRelease(keyEventDown);
}

Native.CFRelease(eventSource);
}

Upvotes: 1

Views: 712

Answers (3)

DerGenaue
DerGenaue

Reputation: 11

I've found a solution!

It works for me with just this little change:

public static extern void CGEventKeyboardSetUnicodeString(IntPtr @event, uint stringLength, char* unicodeString);

Instead of

public static extern void CGEventKeyboardSetUnicodeString(IntPtr @event, ulong stringLength, char* unicodeString);

Have a great day ;)

Upvotes: 1

JeremyP
JeremyP

Reputation: 86671

unichar is an unsigned 16 bit type used for holding a single UTF-16 code unit. A UTF-16 character is made of either 1 or 2 unichars (usually 1). In C# it is exactly like char

Upvotes: 1

Ken Thomases
Ken Thomases

Reputation: 90641

In C, a UniChar is equivalent to an unsigned short.

Upvotes: 0

Related Questions