2011-06-13 72 views
4

當用戶單擊某個鍵盤鍵(CapsLock)時,我編程生成鼠標點擊。 因此,當CapsLock打開時,我會做一個鼠標左鍵,然後當CapsLock關閉時,向上鼠標左鍵。cocoa - CGEventPost鼠標點擊後不刷新屏幕

如果我將鼠標放在窗口標題欄上,單擊CapsLock,然後移動鼠標,然後單擊CapsLock,窗口會正確移動,則表現正確。即我正確地「拖動」窗口,就好像我在移動鼠標的同時按住了鼠標左鍵。

但是,有一個問題 - 當我移動鼠標時,窗口不移動,它只在第二次單擊CapsLock後才移動到最終位置。即在「釋放」鼠標按鈕之後。

我需要做些什麼來確保在鼠標移動過程中刷新屏幕?

有趣的是,我也迷上到

[NSEvent addGlobalMonitorForEventsMatchingMask:NSLeftMouseDraggedMask

,發現我的NSLog語句只輸出後,我釋放鼠標左鍵(真正的鼠標左鍵)

鼠標點擊代碼如下,我可以發佈所有的代碼,如果有必要,沒有太多它..

// simulate mouse down 

// get current mouse pos 
CGEventRef ourEvent = CGEventCreate(NULL); 
CGPoint point = CGEventGetLocation(ourEvent); 
NSLog(@"Location? x= %f, y = %f", (float)point.x, (float)point.y); 

CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateCombinedSessionState); 
CGEventRef theEvent = CGEventCreateMouseEvent(source, kCGEventLeftMouseDown, point, kCGMouseButtonLeft); 
CGEventSetType(theEvent, kCGEventLeftMouseDown); 
CGEventPost(kCGHIDEventTap, theEvent); 
CFRelease(theEvent); 


// simulate mouse up 

// get current mouse pos 
CGEventRef ourEvent = CGEventCreate(NULL); 
CGPoint point = CGEventGetLocation(ourEvent); 
NSLog(@"Location? x= %f, y = %f", (float)point.x, (float)point.y); 

CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateCombinedSessionState); 
CGEventRef theEvent = CGEventCreateMouseEvent(source, kCGEventLeftMouseUp, point, kCGMouseButtonLeft); 
CGEventSetType(theEvent, kCGEventLeftMouseUp); 
CGEventPost(kCGHIDEventTap, theEvent); 
CFRelease(theEvent); 
+0

你是如何檢索左鍵鎖定鍵的關鍵事件?它的事件循環在哪裏? – Huperniketes 2011-06-21 16:49:14

回答

7

如果您希望能夠拖動窗口,問題是您還需要發佈LeftMouseDragged事件。

只需撥打beginEventMonitoring開始監聽大寫鎖定鍵事件和鼠標移動事件。事件處理程序將模擬鼠標左鍵和移動,就像你想要的一樣。這裏是我的博客的鏈接,您可以在此下載Xcode 4的完整工作示例:http://www.jakepetroules.com/2011/06/25/simulating-mouse-events-in-cocoa

該示例位於公共領域,可以隨意使用它。 :)

根據蘋果公司(NSEvent documentation),「啓用訪問輔助設備」需要在系統偏好設置>普遍訪問檢查這個工作,但我沒有選中它,這不是一個問題。只是一個頭。

如果您有任何其他問題,請讓我知道,我會盡我所能提供幫助。

// Begin listening for caps lock key presses and mouse movements 
- (void)beginEventMonitoring 
{ 
    // Determines whether the caps lock key was initially down before we started listening for events 
    wasCapsLockDown = CGEventSourceKeyState(kCGEventSourceStateHIDSystemState, kVK_CapsLock); 

    capsLockEventMonitor = [NSEvent addGlobalMonitorForEventsMatchingMask:(NSFlagsChangedMask) handler: ^(NSEvent *event) 
    { 
     // Determines whether the caps lock key was pressed and posts a mouse down or mouse up event depending on its state 
     bool isCapsLockDown = [event modifierFlags] & NSAlphaShiftKeyMask; 
     if (isCapsLockDown && !wasCapsLockDown) 
     { 
      [self simulateMouseEvent: kCGEventLeftMouseDown]; 
      wasCapsLockDown = true; 
     } 
     else if (wasCapsLockDown) 
     { 
      [self simulateMouseEvent: kCGEventLeftMouseUp]; 
      wasCapsLockDown = false; 
     } 
    }]; 

    mouseMovementEventMonitor = [NSEvent addGlobalMonitorForEventsMatchingMask:(NSMouseMovedMask) handler:^(NSEvent *event) 
    { 
     [self simulateMouseEvent: kCGEventLeftMouseDragged]; 
    }]; 
} 

// Cease listening for caps lock key presses and mouse movements 
- (void)endEventMonitoring 
{ 
    if (capsLockEventMonitor) 
    { 
     [NSEvent removeMonitor: capsLockEventMonitor]; 
     capsLockEventMonitor = nil; 
    } 

    if (mouseMovementEventMonitor) 
    { 
     [NSEvent removeMonitor: mouseMovementEventMonitor]; 
     mouseMovementEventMonitor = nil; 
    } 
} 

-(void)simulateMouseEvent:(CGEventType)eventType 
{ 
    // Get the current mouse position 
    CGEventRef ourEvent = CGEventCreate(NULL); 
    CGPoint mouseLocation = CGEventGetLocation(ourEvent); 

    // Create and post the event 
    CGEventRef event = CGEventCreateMouseEvent(CGEventSourceCreate(kCGEventSourceStateHIDSystemState), eventType, mouseLocation, kCGMouseButtonLeft); 
    CGEventPost(kCGHIDEventTap, event); 
    CFRelease(event); 
} 
+0

完美。謝謝! – zadam 2011-06-23 18:18:05

+1

沒問題,很高興有幫助。 :)又添加了一點到我的樣本代碼庫! – 2011-06-23 19:02:49