#58　Windowsオーバーレイアプリ作り

## 概要
趣味でやっているオンラインゲームで、状況に応じてオーバーレイでガイドを表示してくれるツールがあり、仕組みが気になったので簡易的に真似してみたいと思います。
Windowsフォームの使用は初めてなので、まずは簡単なものから作ってみます。

## 制作物
これが作成したアプリです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3843084/4042d9a8-fd06-00d1-f5fa-f5e16a2c1765.png)

分かりにくいですが、画面左上の金額表示と、画面全体に散らばっている硬貨がオーバーレイアプリです。
一定時間ごとに画面上のランダムな位置に硬貨が現れるので、クリックしてお金をためていくだけのシンプルなアプリです。
最前面に表示され、起動しながらでも裏側のウィンドウが操作できます。
左上にためた金額の合計が表示されます。

## 内容

フレームワーク: Windows フォーム
```cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CoinCollectorApp
{
    public partial class MainForm : Form
    {
        private int money = 0;
        private Label moneyLabel;
        private Random random = new Random();
        private List<Tuple<Image, int>> coins = new List<Tuple<Image, int>>();
        public MainForm()
        {
            InitializeComponent();
            InitializeForm();
            InitializeTimer();
            LoadCoinImages();
        }

        private void InitializeForm()
        {
            // オーバーレイ化
            this.FormBorderStyle = FormBorderStyle.None;
            this.WindowState = FormWindowState.Maximized;
            this.TransparencyKey = this.BackColor;
            this.StartPosition = FormStartPosition.Manual;
            this.Location = new Point(0, 0);
            this.ShowInTaskbar = false;
            this.TopMost = true;

            // 所持金表示用のラベル
            moneyLabel = new Label
            {
                Text = "所持金: ¥" + money,
                Location = new Point(10, 10),
                AutoSize = true,
                Font = new Font("MS UI Gothic", 20f),
                ForeColor = Color.Black,
                BackColor = Color.White
            };
            this.Controls.Add(moneyLabel);
        }

        private void InitializeTimer()
        {
            Timer coinTimer = new Timer
            {
                Interval = 5000
            };
            coinTimer.Tick += CoinTimerTick;
            coinTimer.Start();
        }

        private void LoadCoinImages()
        {
            // 画像と金額の情報を持つ配列を追加
            coins.Add(new Tuple<Image, int>(Properties.Resources._1yen, 1));
            coins.Add(new Tuple<Image, int>(Properties.Resources._5yen, 5));
            coins.Add(new Tuple<Image, int>(Properties.Resources._10yen, 10));
            coins.Add(new Tuple<Image, int>(Properties.Resources._50yen, 50));
            coins.Add(new Tuple<Image, int>(Properties.Resources._100yen, 100));
            coins.Add(new Tuple<Image, int>(Properties.Resources._500yen, 500));
        }

        private void CoinTimerTick(object sender, EventArgs e)
        {
            // 画面上にランダムなコインを表示
            int randomIndex = random.Next(coins.Count);

            PictureBox coinPictureBox = new PictureBox
            {
                Image = coins[randomIndex].Item1,
                Size = new Size(50, 50),
                Location = new Point(random.Next(this.Width - 50), random.Next(this.Height - 50)),
                SizeMode = PictureBoxSizeMode.StretchImage,
                Tag = coins[randomIndex].Item2

            };

            coinPictureBox.Click += CoinPictureBoxClick;
            this.Controls.Add(coinPictureBox);
        }

        private void CoinPictureBoxClick(object sender, EventArgs e)
        {
            // コインがクリックされたときの処理
            this.Controls.Remove((PictureBox)sender);
            PictureBox coinPictureBox = (PictureBox)sender;
            money += (int)coinPictureBox.Tag;
            UpdateMoneyLabel();
        }

        private void UpdateMoneyLabel()
        {
            moneyLabel.Text = "所持金: ¥" + money;
        }
    }
}
```
特に解説するところもないですが、もしオーバーレイアプリを作る方がいれば InitializeForm を参考にしていただければと思います。

## 次にやりたいこと

今度はこのあたりに挑戦してみたいと思います！

* 背面のウィンドウの操作に応じてオーバーレイアプリで何かする
* 特定のウィンドウに追従して、そのウィンドウを開いたときだけオーバーレイする

最後まで読んでいただきありがとうございました！