2011-11-21 13 views
6

मेरे पास कोड है जो माउस पर स्क्रीन पर किसी क्षेत्र को प्रतिबंधित करता है, यह अपेक्षाकृत अच्छी तरह से काम कर रहा है, केवल एक बड़ी समस्या के साथ। क्षेत्र के किनारों पर चलते समय माउस साफ-सुथरा/सुचारु रूप से स्थानांतरित नहीं होता है, बल्कि यह बहुत ही चतुर तरीके से कूदता है, मेरा मानना ​​है कि यह CGWarpMouseCursorPosition के कारण हो सकता है क्योंकि प्रत्येक "वार" पर देरी हो रही है।CGWarpMouseCursorPosition देरी क्यों कर रहा है? यदि यह नहीं है, तो क्या है?

क्या कोई यह बता सकता है कि यह मेरे कोड में कुछ है जो इस देरी का कारण बन रहा है, या यदि यह वास्तव में माउस वार फ़ंक्शन है। यदि यह माउस वार फ़ंक्शन है, तो क्या कोई तरीका है कि मैं माउस का चिकनी स्थानांतरण प्राप्त कर सकता हूं? मैंने फ्लैश में वही काम किया है और यह बेकार ढंग से काम करता है, मुझे पता है कि लूप को निष्पादित करने में इतना समय नहीं लग रहा है कि यह चीजों को धीमा कर रहा है क्योंकि यह केवल 4 या 5 बार चलता है।

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

मुझे नहीं लगता कि यह धीमा है; इसे समय देने के लिए, मुझे सबसे लंबे समय तक यह लेने के लिए 0.006 सेकंड था। यह कुछ तरीकों से बेहतर हो सकता है, यद्यपि: आपको एनएस- या सीजीआरईटीटी में सीमित क्षेत्र को परिभाषित करना चाहिए, और मुझे लगता है कि आप लूप को काट सकते हैं। –

+0

आयताकार सिर्फ एक अस्थायी डेमो उपकरण है। मैं वास्तव में एक काले और सफेद बिटमैप के खिलाफ इसका परीक्षण करने जा रहा हूं, जहां काले पिक्सेल जोन माउस-अनुकूल हैं, और सफेद जोनों में माउस नहीं जा सकता है। काले क्षेत्र का आकार बहुत विचित्र होगा, और इस प्रकार मुझे लगता है कि लूप आवश्यक हो सकता है। जब तक आपके पास कोई बेहतर समाधान न हो? – BumbleShrimp

+0

इससे वास्तव में यह पता लगाना आसान हो सकता है कि माउस स्वीकार्य क्षेत्र से बाहर चला गया है या नहीं। इस चाल को वापस ले जाने के लिए निकटतम स्वीकार्य बिंदु मिल जाएगा, लेकिन हाँ, मुझे लगता है कि इसके लिए आपको एक लूप की आवश्यकता होगी। वैसे भी, मैं आश्चर्यचकित हूं कि घटना के स्थान और डेल्टा को संशोधित करना (या यहां तक ​​कि प्रतिलिपि बनाना और प्रतिलिपि बनाना) काम नहीं करता है। –

उत्तर

4

आप की खोज की है, CGSetLocalEventsSuppressionInterval आपकी समस्या को ठीक करता है।

हालांकि, यह 10.6 के रूप में बहिष्कृत है। ऐप्पल दस्तावेज़ राज्य:

यह फ़ंक्शन सामान्य उपयोग के लिए अनुशंसित विशेष मामलों और अवांछित साइड इफेक्ट्स के कारण अनुशंसित नहीं है। इस फ़ंक्शन के लिए अनुशंसित प्रतिस्थापन CGEventSourceSetLocalEventsSuppressionInterval है, जो दमन अंतराल को किसी विशिष्ट ईवेंट स्रोत के लिए समायोजित करने की अनुमति देता है, जो उस ईवेंट स्रोत का उपयोग करके पोस्ट की गई घटनाओं को प्रभावित करता है।

दुर्भाग्य से, प्रतिस्थापन CGEventSourceSetLocalEventsSuppressionIntervalCGWarpMouseCursorPosition आंदोलनों के साथ काम नहीं करता।

इसके बजाय, तुरंत ताना के बाद CGAssociateMouseAndMouseCursorPosition(true) का उपयोग करें:

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

प्रलेखन इस व्यवहार का कोई जिक्र नहीं है, लेकिन यह ताना के बाद दमन अंतराल रद्द करने के लिए प्रकट होता है।

1

आप शायद CGSetLocalEventsSuppressionInterval लिए देख रहे हैं(), एक विधि 10.6 के रूप में पदावनत ... यह अभी भी 10.7 में हालांकि काम करता है।

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

+0

हाँ, मैंने पाया कि दूसरे दिन, लेकिन यह पूरी तरह से काम करता है, इसलिए मैं आपको जवाब देने जा रहा हूं। आपके समय/प्रयास के लिए धन्यवाद। – BumbleShrimp

संबंधित मुद्दे

 संबंधित मुद्दे