1

OSXのC++でApplicationServicesとCGEventPostを使用していて、キーを押したままにできるかどうかを確認しようとしていますが、機能しません。

これが私が使用している方法です:

void postKeyboardEvent( int keyCode, bool keyUp = false )
{

    CGEventSourceRef source = CGEventSourceCreate( kCGEventSourceStateHIDSystemState );

    CGEventRef keyEvent = CGEventCreateKeyboardEvent( source, (CGKeyCode) keyCode, !keyUp );
    CGEventPost( kCGAnnotatedSessionEventTap, keyEvent );
    CFRelease( keyEvent );

    CFRelease( source );

}

これが私がそれをテストしている方法です:

postKeyboardEvent( kVK_Command );
postKeyboardEvent( kVK_Tab );
postKeyboardEvent( kVK_Tab, true );
postKeyboardEvent( kVK_Command, true );

私の理解では、これは別のウィンドウに切り替わるはずですが、代わりにコマンドキーを「離して」Tab文字を入力するだけです。

重要:次のようなものは使いたくありません。

CGEventSetFlags( keyEvent, kCGEventFlagMaskCommand );

どのキーコードが修飾キーであるか、またはイベントにフラグを立てるキーコードの数を知らなくても、キーダウンコマンドとキーアップコマンドの「シリアルチェーン」を送信する必要があります。

これを行う方法はありますか?

4

1 に答える 1

1

これが答えです!https://stackoverflow.com/a/8202467/877860投稿者https://stackoverflow.com/users/314546/valexa

このための最も簡単な方法は、現在の修飾子フラグを目的の修飾子のフラグとビット単位でOR演算することです。例:

CGEventFlags flags = kCGEventFlagMaskShift;
CGEventRef ev;
CGEventSourceRef source = CGEventSourceCreate (kCGEventSourceStateCombinedSessionState);

//press down            
ev = CGEventCreateKeyboardEvent (source, keyCode, true);    
CGEventSetFlags(ev,flags | CGEventGetFlags(ev)); //combine flags                        
CGEventPost(kCGHIDEventTap,ev);
CFRelease(ev);              

//press up                                  
ev = CGEventCreateKeyboardEvent (source, keyCode, false);                       
CGEventSetFlags(ev,flags | CGEventGetFlags(ev)); //combine flags                        
CGEventPost(kCGHIDEventTap,ev); 
CFRelease(ev);              

CFRelease(source);

更新: これは私が着陸した方法であり、クリーンアップを使用することもできますが、一連のキーコードをシステムにディスパッチし、それらを予測どおりに発生させるという私の目的には非常にうまく機能します。

(& ~)ここで非常に重要な要素は、シフトが意味を使用してダウンしていない場合にシフトキーマスクを削除するビット単位の操作です。

int shiftKeyCode = 56;
bool shiftIsDown = false;

void postKeyboardEvent( int keyCode, bool keyUp = false )
{

    // Don't send keys while blocked.
    if( blockState == 1 ){

        return;

    }

    if( keyCode == shiftKeyCode ){

        if( keyUp ){

            shiftIsDown = false;

        }else{

            shiftIsDown = true;

        }

    }

    CGEventSourceRef source = CGEventSourceCreate( kCGEventSourceStateHIDSystemState );
    CGEventRef keyEvent = CGEventCreateKeyboardEvent( source, (CGKeyCode) keyCode, !keyUp );

    if( shiftIsDown ){

        // Use Shift flag
        CGEventSetFlags( keyEvent, CGEventGetFlags( keyEvent ) | kCGEventFlagMaskShift );

    }else{

        // Use all existing flag except Shift
        CGEventSetFlags( keyEvent, CGEventGetFlags( keyEvent ) & ~kCGEventFlagMaskShift );

    }

    CGEventPost( kCGHIDEventTap, keyEvent );

    CFRelease( keyEvent );
    CFRelease( source );

}
于 2012-05-23T01:45:11.260 に答える