1

それらを比較するために、異なるスクリーングラバーを実装しています。そのうちの 1 つは、'printscreen' キーとクリップボードを使用する必要があります。

keybd_ eventでキーストロークを送信します。

[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern void keybd_event(byte vVK, byte bScan, int dwFlags,int dwExtraInfo);

public const int KEYEVENTF_EXTENDEDKEY=0x0001; //key down
public const int KEYEVENTF_KEYUP=0x0002; //key up

public const int VK_SNAPSHOT=0x2C; //VirtualKey code for print key

public static void PrintScreen(){
keybd_event(VK_SNAPSHOT,0,KEYEVENTF_EXTENDEDKEY,0);
keybd_event(VK_SNAPSHOT,0,KEYEVENTF_KEYUP,0);
}

私の IEnumerable では、このメソッドを呼び出して、後で画像を取得しようとします。

...
InputController.PrintScreen();
var img=Clipboard.GetImage();
...

返される画像は常に null で、Clipboards.ContainsImage() は常に false です。キーを送信してからしばらく待ってみましたが、うまくいきません。なんらかの設定が欠けているのでしょうか、それとも基本的なエラーがありますか?

PS: プログラムを実行した後、正しい画像をペイントまたは gimp に貼り付けることができます。

4

4 に答える 4

4

コンソールプログラムです

それが最も関連性の高い詳細です。質問に記載する必要があります。クリップボードは、基になる API が COM ベースのシステム オブジェクトです。これにより、API を使用するスレッドのアパートメント状態に敏感になります。.NET クリップボード クラスはこれを少しいじります。スレッドの状態が間違っている場合、実際には例外をスローする必要があります。また、コンソール モード アプリの場合は間違っています。そのメイン スレッドはデフォルトで MTA であり、API を使用するには STA が必要です。

修正は簡単です。Main() メソッドに属性を配置して、STA を要求するだけです。

    [STAThread]
    static void Main(string[] args) {
        // etc...
    }

技術的には、Winforms や WPF アプリのように、STA スレッドもメッセージ ループをポンプする必要があります。ただし、メイン スレッドからメソッド呼び出しを行うだけであれば問題はありません。

于 2013-09-20T12:21:23.550 に答える
0

これは古い質問であることは知っていますが、これに関連しているため、調査結果を共有すると思いました。私が見た問題は、コードにブレークポイントがある限り、上記の投稿されたメソッドが機能することでした。ブレークポイントがない場合、イベントは発生しますが、イベントが含まれていたメソッド呼び出しを終了した後にのみ発生します。

これは次のような意味です

    InputController.PrintScreen();
    var img=Clipboard.GetImage();

このメソッドを終了するまでクリップボードに値が入力されないため、機能しません。これを回避するには、DoEvents() を使用する古い VB トリックを使用します。これにより、アプリケーションはキュー内のすべての Windows メッセージを処理できるようになります。したがって、修正されたコードは機能するはずです。

    InputController.PrintScreen();
    Application.DoEvents();
    var img=Clipboard.GetImage();
于 2014-07-28T17:14:16.863 に答える
0

代わりにSendKeysクラスを使用してみましたか?

public static Image TakeScreenSnapshot(bool activeWindowOnly)
{
    // PrtSc = Print Screen Key
    string keys = "{PrtSc}";
    if (activeWindowOnly)
        keys = "%" + keys; // % = Alt
    SendKeys.SendWait(keys);
    return Clipboard.GetImage();
}

コードサンプルのソース

于 2013-09-20T11:17:59.440 に答える