C/C++ コンソール画面でマウスカーソルを使って遊ぶ

コンソール画面でカーソル入力を取りたい

完成画面イメージ

開発環境

Visual Studio 2022 Community

関数の作成

マウスの座標(コンソール画面内での位置)を取得する関数

※呼び出すたびにGetStdHandleするのはスループットが低下しそうなので、グローバル宣言しています。

void GetCur(int* nX, int* nY)
{
	// ----- 変数宣言 -----
	INPUT_RECORD InputRecord;
	DWORD Events;

	if (PeekConsoleInput(g_InHandle, &InputRecord, 1, &Events) && Events > 0) // 入力がある場合
	{
		SetConsoleMode(g_InHandle, ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT); // コンソールモード設定
		ReadConsoleInput(g_InHandle, &InputRecord, 1, &Events);  // 入力読み取り
		*nX = InputRecord.Event.MouseEvent.dwMousePosition.X; // X座標返し
		*nY = InputRecord.Event.MouseEvent.dwMousePosition.Y; // Y座標返し
	}
}

マウスボタン取得の為の関数

bool IsKeyPress(BYTE In_byKey)
{
    return GetKeyState(In_byKey) & 0x80;
}

カーソル位置を設定する関数

void SetPos(int nX, int nY)
{
	SetConsoleCursorPosition(g_OutHandle, { short(nX), short(nY) }); // カーソル位置設定
}

main関数に組み込む

int main()
{
	// ----- 変数宣言 -----
	int nX = 0, nY = 0;	// マウスカーソルの座標

    while (1) // 無限ループ
	{
		SetPos(0, 0); // カーソル位置設定
		printf("%3d %3d\n", nX, nY); // マウスカーソルの座標出力

		GetCur(&nX, &nY); // マウスカーソルの座標取得

		if (IsKeyPress(MK_LBUTTON)) // 左クリックされたら
		{
			SetPos(nX, nY); // マウスカーソルの座標設定
			SetConsoleTextAttribute(g_OutHandle, rand() % 7); // テキストカラー設定
			printf("Hello Corsor"); // テキスト出力
		}

		if (IsKeyPress(MK_RBUTTON)) // 右クリックされたら
        {
			SetPos(nX, nY); // マウスカーソルの座標設定
			SetConsoleTextAttribute(g_OutHandle, 0x0C); // テキストカラー設定
			printf("End"); // テキスト出力
			break; // ループ終了
		}
	}
	return 0; // プログラム終了
}

左クリックでHello Corsor、右クリックでEndと表示されプログラムが終了します。

コンソール画面の設定

先ずは、実行して、出てきたコンソールウィンドウのタイトルバーを右クリック

プロパティをクリック

編集オプション、テキスト選択の部分のチェックボックスをすべてオフに

実行結果

コード全体

// ------------------------------
//		include
// ------------------------------
#include <stdio.h>
#include <windows.h> // WindowsAPIのヘッダファイル

// ------------------------------
//		プロトタイプ宣言
// ------------------------------
/// <summary>
/// マウスカーソルの座標取得関数
/// </summary>
/// <param name="*nX">X座標</param>
/// <param name="*nY">Y座標</param>
void GetCur(int* nX, int* nY);

/// <summary>
/// マウスボタンの状態取得関数
/// </summary>
/// <param name="In_byKey">キーコード</param>
/// <returns>押されているかどうか</returns>
bool IsKeyPress(BYTE In_byKey);

/// <summary>
/// マウスカーソルの座標設定関数
/// </summary>
/// <param name="nX">X座標</param>
/// <param name="nY">Y座標</param>
void SetPos(int nX, int nY);

// ------------------------------
//		グローバル変数
// ------------------------------
namespace
{
	// ハンドル情報
	HANDLE g_InHandle = GetStdHandle(STD_INPUT_HANDLE);
	HANDLE g_OutHandle = GetStdHandle(STD_OUTPUT_HANDLE);
}

int main()
{
	// ----- 変数宣言 -----
	int nX = 0, nY = 0;	// マウスカーソルの座標

    while (1) // 無限ループ
	{
		SetPos(0, 0); // カーソル位置設定
		printf("%3d %3d\n", nX, nY); // マウスカーソルの座標出力

		GetCur(&nX, &nY); // マウスカーソルの座標取得

		if (IsKeyPress(MK_LBUTTON)) // 左クリックされたら
		{
			SetPos(nX, nY); // マウスカーソルの座標設定
			SetConsoleTextAttribute(g_OutHandle, rand() % 7); // テキストカラー設定
			printf("Hello Corsor"); // テキスト出力
		}

		if (IsKeyPress(MK_RBUTTON)) // 右クリックされたら
        {
			SetPos(nX, nY); // マウスカーソルの座標設定
			SetConsoleTextAttribute(g_OutHandle, 0x0C); // テキストカラー設定
			printf("End"); // テキスト出力
			break; // ループ終了
		}
	}
	return 0; // プログラム終了
}

void GetCur(int* nX, int* nY)
{
	// ----- 変数宣言 -----
	INPUT_RECORD InputRecord;
	DWORD Events;

	if (PeekConsoleInput(g_InHandle, &InputRecord, 1, &Events) && Events > 0) // 入力がある場合
	{
		SetConsoleMode(g_InHandle, ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT); // コンソールモード設定
		ReadConsoleInput(g_InHandle, &InputRecord, 1, &Events);  // 入力読み取り
		*nX = InputRecord.Event.MouseEvent.dwMousePosition.X; // X座標返し
		*nY = InputRecord.Event.MouseEvent.dwMousePosition.Y; // Y座標返し
	}
}

bool IsKeyPress(BYTE In_byKey)
{
    return GetKeyState(In_byKey) & 0x80;
}

void SetPos(int nX, int nY)
{
	SetConsoleCursorPosition(g_OutHandle, { short(nX), short(nY) }); // カーソル位置設定
}

参考にしたサイト

https://learn.microsoft.com/ja-jp/windows/console/setconsolemode

https://learn.microsoft.com/ja-jp/windows/console/readconsoleinput

https://learn.microsoft.com/ja-jp/windows/console/peekconsoleinput

https://learn.microsoft.com/ja-jp/windows/win32/api/winuser/nf-winuser-getkeystate

https://learn.microsoft.com/ja-jp/windows/win32/learnwin32/mouse-clicks

https://learn.microsoft.com/ja-jp/windows/console/setconsolecursorposition

https://learn.microsoft.com/ja-jp/windows/console/setconsoletextattribute