午後わてんのブログ

ベランダ菜園とWindows用アプリ作成(WPFとC#)

WPF?画面上のどこでもマウスカーソル下の色を取得

イメージ 1
画面上のどこでもマウスカーソル下の色を取得
クリックでもその色を取得
今回のアプリのダウンロード先
自身のウィンドウ内のカーソルの位置や色の取得ならWPFにも用意されているんだけど、自身のウィンドウ外、画面上のどこでもって場合にはWPFだけではできないようで、Windows APIWindows.Formsの関数を使ってできた
 
できたっていっても9割方解説サイトのコピペになった
 
 
デザイン画面

f:id:gogowaten:20191213152604p:plain

色の確認とマウスカーソル位置の表示用に
StackPanelの中にTextBlockを3つ用意
 
using System;
using System.Windows;
using System.Windows.Media;

using System.Windows.Threading;//タイマー用

//System.DrawingとSystem.Windows.Formsを参照に追加する必要がある

//System.Drawingは画面全体をキャプチャするために
//System.Windows.Formsはマウスカーソルの画面上での座標の取得のため
//一定時間ごとにマウスカーソル位置を取得、その座標の1ピクセルをキャプチャして、その色を取得


namespace _20190302_アプリの外でもカーソル下の色取得
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        //クリックされているか判定用
        [System.Runtime.InteropServices.DllImport("user32.dll")] private static extern short GetKeyState(int nVirtkey);

        public MainWindow()
        {
            InitializeComponent();

            //タイトルバーにアプリの名前(アセンブリ名)表示
            var info = System.Diagnostics.FileVersionInfo.GetVersionInfo(System.Reflection.Assembly.GetExecutingAssembly().Location);
            Title = info.ProductName;

            //タイマーの設定、一定時間ごとにマウスカーソルの状態を見る
            var timer = new DispatcherTimer(DispatcherPriority.Normal);
            //timer.Interval = new TimeSpan(100000);//ナノ秒
            timer.Interval = new TimeSpan(0, 0, 0, 0, 10);//10ミリ秒毎(0.01秒毎)
            timer.Start();
            timer.Tick += Timer_Tick;
        }

        //タイマーのTickイベント時
        private void Timer_Tick(object sender, EventArgs e)
        {
            System.Drawing.Point p = System.Windows.Forms.Cursor.Position;//マウスカーソル位置取得
            Color c = GetPixelColor(p.X, p.Y);//マウスカーソル位置の色取得
            var b = new SolidColorBrush(c);
            MyTextBlockColor.Background = b;
            MyTextBlockColor.Text = c.ToString();
            MyTextBlockCursorLocation.Text = $"マウスの位置 = {System.Windows.Forms.Cursor.Position}";

            if (IsClickDown())
            {
                MyTextBlockGetColor.Background = b;
            }
        }
        
        //クリック判定
        private bool IsClickDown()
        {
            //マウス左ボタン(0x01)の状態、押されていたらマイナス値(-127)、なかったら0
            return GetKeyState(0x01) < 0;
        }
        
        //画面上の指定座標の1ピクセルの色を返す
        private Color GetPixelColor(int x, int y)
        {
            //1x1サイズのBitmap作成
            using (System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(
                1, 1, System.Drawing.Imaging.PixelFormat.Format32bppArgb))
            {
                using (var bmpGraphics = System.Drawing.Graphics.FromImage(bitmap))
                {
                    //画面全体をキャプチャして指定座標の1ピクセルだけBitmapにコピー
                    bmpGraphics.CopyFromScreen(x, y, 0, 0, new System.Drawing.Size(1, 1));
                    //ピクセルの色取得
                    System.Drawing.Color color = bitmap.GetPixel(0, 0);
                    //WPF用にSystem.Windows.Media.Colorに変換して返す
                    return Color.FromArgb(color.A, color.R, color.G, color.B);
                }
            }
        }

    }
}
 
 

f:id:gogowaten:20191213152717p:plain

参照に追加する

f:id:gogowaten:20191213152731p:plain

参照に
System.Windows.FormsとSystem.Drawingを追加するのは
 
System.Drawing.GraphicsクラスのCopyFromScreenで画面全体から指定座標の1ピクセルをキャプチャして、1ピクセルSystem.Drawing.Bitmapを作成してBitmapのGetPixelで色を取得
 
指定座標のマウスカーソル位置取得で
System.Windows.Forms.Cursor.Position
 
この2つのためで、WPFでもアプリ上でのキャプチャやカーソル位置取得はあるんだけどねえ、アプリの外になるとないみたいで探したけど見つからなかった
 
マウスの左ボタンが押されたかどうかの判定もWindows APIを利用している
 
なんだかWPF以外の機能ばかりになってしまった
 
ギットハブ
 
 
参照したところ
C# - 【C#】画面上のクリックされた地点のRGB値を取得したい|teratail
https://teratail.com/questions/25722
 
画面のキャプチャ
 
タイマにより一定時間間隔で処理を行うには?(WPFタイマ編):.NET TIPS - @IT
https://www.atmarkit.co.jp/ait/articles/1812/12/news014.html
 
 
 
 

関連記事
4年後、WindowsFormsを使わずにできた
2016/3/3
WPFVB.NETで表示した画像をクリックした場所の色を取得はややこしい ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/13952774.html
ちょうど3年前かあ
 
2016/3/4
WPFVB.NETで表示した画像をクリックした場所の色を取得はややこしい(後編) ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/13955791.html