キャプチャー

Windowsのスクリーンショット[Win]+[shift]+S をプログラムからボタンのクリックで実行しようとSendKeys.Sendを使おうとしたのだけど、Windowsキー+コンビネーション・キー(Shift, Ctrl, Alt)は、Windowsキー専用の定義がない??と困っていた。
Windowsキー + ← だったら、SendKeys.Send(“^{ESC}{LEFT}”) とできるので同じ様にすればと思っていたが、Windowsキーが内部的に Ctrl+ESC のコンビネーションでしか表現できないようだった。
結局、以下のような方法で対処した。

        private void button1_Click(object sender, EventArgs e)
        {
            // キャプチャするためにWindowsにキーボードショートカット( [Win]+{shift}+S )を送る方法
            InputSimulator sim = new InputSimulator();
            sim.Keyboard.ModifiedKeyStroke(new[] { VirtualKeyCode.SHIFT, VirtualKeyCode.LWIN }, VirtualKeyCode.VK_S );
        }

こうすることでスクリーンショットは可能になったが、可能になったらクリップボードの画像データを取得したい。どうするか・・

クリップボードを監視してクリップボードに変化があれば知る方法

AddClipboardFormatListener関数とRemoveClipboardFormatListener関数を使い、WM_CLIPBOARDUPDATEメッセージを捉えて予め用意したイメージボックスにデータを読み込めば良い。
実際の方法としては、フォームにpictureBox1とbutton1を配置して

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
 
    [DllImport("user32.dll", SetLastError = true)]
    private extern static void AddClipboardFormatListener(IntPtr hwnd);
 
    [DllImport("user32.dll", SetLastError = true)]
    private extern static void RemoveClipboardFormatListener(IntPtr hwnd);
 
    private const int WM_CLIPBOARDUPDATE = 0x31D;
 
    private void Form1_Load(object sender, EventArgs e)
    {
        AddClipboardFormatListener(Handle);
    }
 
    protected override void WndProc(ref Message m)
    {
        if (m.Msg == WM_CLIPBOARDUPDATE)
        {
            OnClipboardUpdate();
            m.Result = IntPtr.Zero;
        }
        else
            base.WndProc(ref m);
    }
 
    private void Form1_FormClosed(object sender, FormClosedEventArgs e)
    {
        RemoveClipboardFormatListener(Handle);
    }
 
    void OnClipboardUpdate()
    {
        // クリップボードのデータが変更された時の処理
        //   PictureBoxに読み込む
        
        //クリップボードのデータを取得する
        IDataObject data = Clipboard.GetDataObject();
        //クリップボードにデータが無いときはnullを返すので
        if (data != null)
        {
            //DataFormats.Bitmapに関連付けられたデータがあれば読み込む
            if (data.GetDataPresent(DataFormats.Bitmap))
            {
                pictureBox1.Image = (Bitmap)Clipboard.GetDataObject().GetData(DataFormats.Bitmap);
            }
        }
    }
    private void button1_Click(object sender, EventArgs e)
    {
        // キャプチャするためにWindowsにキーボードショートカット( [Win]+{shift}+S )を送る方法
        InputSimulator sim = new InputSimulator();
        sim.Keyboard.ModifiedKeyStroke(new[] { VirtualKeyCode.SHIFT, VirtualKeyCode.LWIN }, VirtualKeyCode.VK_S );
    }
}

で簡単に出来るので便利だ!!

関連記事

Windows10、Windows11でネットワーク共有ホルダが見えない

LinuxでNTFSファイルシステムのマウントでアクセス権限やファイルの所有者変更で悩まないために

前回作成したUDP通信コンポーネントでチャットソフトを作ってみる

C# UDP通信のためのコンポーネントの作成

C# 既定のブラウザでURLを開けずエラーの対処

DSO-TC3を買ってみた!!