2011-04-30 42 views
8

我已經安裝了一個鍵盤鉤子:如何區分用戶輕敲的鍵盤事件和生成的鍵盤事件之間的區別?

CGEventRef myCGEventCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {

基本上我想利用用戶的鍵盤水龍頭,吃的輸入,並發表我自己的,而不是輸入。

所以,如果他點擊「g」我可能想發佈「富」到文本字段。 http://www.mail-archive.com/[email protected]/msg23343.html

的問題是,我的每一個編程輸入的字符被擊打鍵盤鉤子:

如發現我在這裏寫的文本框與CGEventPostCGEventSetUnicodeString。所以我不能在return NULL的鍵盤掛鉤中阻止用戶輸入...這也阻止了所有程序的輸入!

我區分他們在Windows方在C#中的「注射」標誌,看到我的問題一年前在這裏:How do I use low-level 8 bit flags as conditionals?

尋找在Objective-C類似的東西。

回答

6

查看CGEventSource.h中的註釋。將信息放在一起比使用Event Services Reference要容易一些。長,但更多的是正確的,倒過來的樣子creating an event source(這是受內存管理規則,你需要CFRelease它,如果你正在計劃終止前使用完畢):

myEventSource = CGEventSourceCreate(kCGEventSourceStatePrivate); 

這將創建自己的具有唯一ID的私人活動來源;那麼表明您創建的事件來自那裏:

CGEventRef myKeyboardEvent = CGEventCreateKeyboardEvent(myEventSource, 
                 keyCode, true); 

當一個事件到來時,檢查,看它是否是從自己:

if((CGEventGetType(newEvent) == kCGEventKeyDown) && 
    (CGEventGetIntegerValueField(newEvent, kCGEventSourceStateID) == CGEventSourceGetSourceStateID(myEventSource)) { 

還有的,可以讓你通過源user data field圍繞任意的64位,你應該需要。

的快速和骯髒的方法是儘量挑選一個事件現場,是不是可能成爲一個鍵盤事件一個有意義的值,如kCGMouseEventPressure並把它變成一個簽名:

CGEventSetIntegerValueField(myKeyboardEvent, 
          kCGMouseEventPressure, 
          0xFEEDFACE); 
// The field is an int_64 so you could make the sig longer 
+0

嗯,對'快速和骯髒'編輯的MouseEventPressure如下所示給我以下:kCGErrorIllegalArgument:CGEventSetIntegerValueField:無效的事件 – cksubs 2011-08-12 15:28:59

+0

@cksubs:你是否嘗試了我提到的使用用戶數據字段作爲事件源的真實方法? – 2011-08-24 19:33:00

+0

今晚我會再看一次。當我最初問這個問題時,我陷入了困境,但現在不記得爲什麼。你對這個錯誤有任何想法嗎? http://stackoverflow.com/questions/7102883/using-cgeventsetintegervaluefield-to-edit-a-keyboard-event-gives-error – cksubs 2011-08-24 22:59:35