2011-11-21 25 views
6

Tôi có mã ở đây giới hạn chuột đến một vùng trên màn hình, nó hoạt động tương đối tốt, chỉ với một vấn đề lớn. Con chuột không được di chuyển sạch sẽ/trơn tru khi chạy dọc theo các cạnh của khu vực, thay vào đó nhảy theo một cách rất sặc sỡ, tôi tin rằng điều này có thể do CGWarpMouseCursorPosition gây ra sự chậm trễ cho mỗi "dọc".Tại sao CGWarpMouseCursorPosition gây ra sự chậm trễ? Nếu nó không phải là, những gì được?

Bất cứ ai có thể biết đó là điều gì đó trong mã của tôi gây ra sự chậm trễ này hay thực tế là chức năng của chuột dọc. Nếu đó là chức năng dọc chuột, có cách nào để tôi có thể di chuyển chuột trơn tru không? Tôi đã làm điều tương tự trong flash và nó hoạt động hoàn hảo, tôi biết rằng vòng lặp không chỉ mất quá nhiều thời gian để thực hiện mà nó làm chậm mọi thứ xuống vì nó chỉ chạy có thể 4 hoặc 5 lần.

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


    CGPoint point = CGEventGetLocation(event); 

    float tX = point.x; 
    float tY = point.y; 

    if(tX <= 700 && tX >= 500 && tY <= 800 && tY >= 200){ 
     // target is inside O.K. area, do nothing 
    }else{ 

    CGPoint target; 

    //point inside restricted region: 
    float iX = 600; // inside x 
    float iY = 500; // inside y 

    // delta to midpoint between iX,iY and tX,tY 
    float dX; 
    float dY; 

    float accuracy = .5; //accuracy to loop until reached 

    do { 
     dX = (tX-iX)/2; 
     dY = (tY-iY)/2; 

     if((tX-dX) <= 700 && (tX-dX) >= 500 && (tY-dY) <= 800 && (tY-dY) >= 200){ 
      iX += dX; 
      iY += dY; 
     } else { 
      tX -= dX; 
      tY -= dY; 
     } 

    } while (abs(dX)>accuracy || abs(dY)>accuracy); 

     target = CGPointMake(roundf(tX), roundf(tY)); 
     CGWarpMouseCursorPosition(target); 

    } 



    return event; 
} 

int 
main(int argc, char *argv[]) { 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 
    CFRunLoopSourceRef runLoopSource; 
    CGEventMask event_mask; 
    event_mask = CGEventMaskBit(kCGEventMouseMoved) | CGEventMaskBit(kCGEventLeftMouseDragged) | CGEventMaskBit(kCGEventRightMouseDragged) | CGEventMaskBit(kCGEventOtherMouseDragged); 

    CFMachPortRef eventTap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, 0, event_mask, mouse_filter, NULL); 

    if (!eventTap) { 
     NSLog(@"Couldn't create event tap!"); 
     exit(1); 
    } 

    runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0); 

    CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes); 

    CGEventTapEnable(eventTap, true); 

    CFRunLoopRun(); 

    CFRelease(eventTap); 
    CFRelease(runLoopSource); 
    [pool release]; 

    exit(0); 
} 
+0

Tôi không nghĩ nó chậm; thời gian nó, dài nhất tôi đã nhận nó để có được 0,006 giây. Nó có thể tốt hơn trong một vài cách, mặc dù: Bạn nên xác định khu vực phân cách trong một NS- hoặc CGRect, và tôi nghĩ rằng bạn có thể cắt ra vòng lặp. –

+0

Hình chữ nhật chỉ là một công cụ demo tạm thời. Tôi thực sự sẽ thử nghiệm điều này đối với một bitmap màu đen và trắng, nơi các vùng pixel màu đen thân thiện với chuột và các vùng màu trắng mà chuột không thể di chuyển vào. Hình dạng của khu vực màu đen sẽ khá kỳ lạ, và do đó tôi nghĩ rằng vòng lặp có thể là cần thiết. Trừ khi bạn có một giải pháp tốt hơn? – BumbleShrimp

+0

Điều đó thực sự có thể giúp bạn dễ dàng tìm thấy liệu con chuột có đi ra ngoài khu vực được chấp nhận hay không. Bí quyết sẽ là tìm điểm chấp nhận được gần nhất để di chuyển nó trở lại, nhưng vâng, tôi nghĩ bạn sẽ cần một vòng lặp cho điều đó. Dù sao, tôi ngạc nhiên chỉ đơn giản là sửa đổi vị trí và đồng bằng của sự kiện (hoặc thậm chí sửa đổi và trả lại một bản sao) không hoạt động. –

Trả lời

4

Như bạn khám phá, CGSetLocalEventsSuppressionInterval sửa chữa vấn đề của bạn.

Tuy nhiên, nó không được chấp nhận kể từ 10.6. tài liệu của Apple nêu rõ:

Chức năng này không được khuyến cáo sử dụng chung vì các trường hợp đặc biệt không có giấy tờ và tác dụng phụ không mong muốn. Đề nghị thay thế cho chức năng này là CGEventSourceSetLocalEventsSuppressionInterval, cho phép khoảng thời gian khử được điều chỉnh cho một nguồn sự kiện cụ thể, chỉ ảnh hưởng đến các sự kiện được đăng bằng nguồn sự kiện đó.

Thật không may, thay thế CGEventSourceSetLocalEventsSuppressionInterval không hoạt động với CGWarpMouseCursorPosition chuyển động.

Thay vào đó, sử dụng CGAssociateMouseAndMouseCursorPosition(true) ngay sau khi warp:

CGPoint warpPoint = CGPointMake(42, 42); 
CGWarpMouseCursorPosition(warpPoint); 
CGAssociateMouseAndMouseCursorPosition(true); 

Các tài liệu không đề cập đến hành vi này, nhưng nó dường như hủy khoảng ức chế sau khi warp.

1

Có thể bạn đang tìm kiếm CGSetLocalEventsSuppressionInterval(), một phương pháp không dùng nữa là 10.6 ... nó vẫn hoạt động mặc dù trong 10.7.

http://developer.apple.com/library/mac/#documentation/Carbon/Reference/QuartzEventServicesRef/DeprecationAppendix/AppendixADeprecatedAPI.html#//apple_ref/c/func/CGSetLocalEventsSuppressionInterval

+0

Vâng, tôi thấy rằng ngày khác, nhưng nó hoạt động hoàn hảo, vì vậy tôi sẽ cung cấp cho bạn câu trả lời. Cảm ơn thời gian/công sức của bạn. – BumbleShrimp

Các vấn đề liên quan