パソコン活用研究シリコンバレー(C、C++、の活用研究)

マウス入力1

=============================================================================

=============================================================================


前回は何もしないウィンドウを表示するプログラムを作ってみましたが(ー>ウィンドウプログラムの雛型完成形)、
ただウィンドウを表示するだけでも結構面倒なプログラムでした。
今回は、何もしない(ただ表示するだけ)つまらないプログラムから半歩だけ進んで、マウスの入力を受け取る
プログラムにしてみます。

ひとつめは、マウスの左ボタン、右ボタンのクリックでマウスカーソルの形を変えるプログラム。
2つめは、マウスを左クリックすると、マウスをクリックした場所(座標位置)をメッセージボックスで表示するプログラムです。
・・たったそれだけ・・ですが、今後のウィンドウプログラムの1歩目ということで。

マウスの入力を受け取って処理するためには、ウィンドウプロシージャで以下のメッセージに対する処理を記述します。
WM_LBUTTONDOWN 左マウスが押された(DOWN)とき
WM_LBUTTONUP   左マウスが離された(UP)とき
WM_LBUTTONDOWN 右マウスが押された時
WM_LBUTTONDOWN 右マウスが離された(UP)とき

1. カーソルの形を変える

マウスを左クリックするとカーソルの形を禁止マークにし、右クリックすると+の形にする
プログラム



ウィンドウプロシージャのWM_LBUTTONDOWNというメッセージは、マウスの左ボタンがクリックされた時の処理ですが、
hcur=SetCursor(LoadCursor(NULL, IDC_NO));
としています。
これでカーソルの形に禁止マークを設定しています。

Setcursorはuser32.dllにある関数で、マウスノカーソルに形状を設定します。
引数にはカーソルのハンドルを指定します。
LoadCursor(NULL, IDC_NO) は禁止マークの形のカーソルのハンドルをロードします。

同様にWM_RBUTTONDOWNというメッセージの処理では、
クロスの形のカーソルを設定しています。

#include "windows.h"

// 関数のプロトタイプ宣言
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

// エントリポイント
int APIENTRY WinMain(HINSTANCE hInstance,
                        HINSTANCE hPrevInstance,
                        LPSTR lpCmdLine,
                        int nCmdShow )
{
        WNDCLASSEX wcex;        // ウインドウクラス構造体
        HWND hWnd;              // ウインドウハンドル
        MSG msg;                // メッセージ構造体

        // ウィンドウクラス構造体を設定します。
        wcex.cbSize = sizeof(WNDCLASSEX); 
        wcex.style = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc = (WNDPROC)WndProc;
        wcex.cbClsExtra = 0;
        wcex.cbWndExtra = 0;
        wcex.hInstance = hInstance;
        wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
        wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
        wcex.lpszMenuName = NULL;
        wcex.lpszClassName = "ModelApp";
        wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
        
        // ウインドウクラスを登録します。
        RegisterClassEx(&wcex);

        // ウインドウを作成します。
        hWnd = CreateWindow(wcex.lpszClassName, // ウインドウクラス名
                "Cursor",               // キャプション文字列
                WS_OVERLAPPEDWINDOW,            // ウインドウのスタイル
                CW_USEDEFAULT,                  // 水平位置
                CW_USEDEFAULT,                  // 垂直位置
                CW_USEDEFAULT,                  // 幅
                CW_USEDEFAULT,                  // 高さ
                NULL,                                   // 親ウインドウ
                NULL,                                   // ウインドウメニュー
                hInstance,                              // インスタンスハンドル
                NULL);                                  // WM_CREATE情報

                // ウインドウを表示します。
                ShowWindow(hWnd, nCmdShow);
                UpdateWindow(hWnd);

        // メッセージループ
        while(GetMessage(&msg, NULL, 0, 0)) 
        {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
        }

        // 戻り値を返します。
        return msg.wParam;
}

// ウインドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd,
                               UINT message,
                               WPARAM wParam,
                               LPARAM lParam)
{
        // メッセージの種類に応じて処理を分岐します。
        switch (message) 
        {
      HCURSOR hcur;
        case WM_LBUTTONDOWN:
        //        ShowCursor(false);

       hcur=SetCursor(LoadCursor(NULL, IDC_NO));
       ShowCursor(true);
       return 0;
        case WM_RBUTTONDOWN:
        //        ShowCursor(false);

       hcur=SetCursor(LoadCursor(NULL, IDC_CROSS));
       ShowCursor(true);
           return 0;



                case WM_DESTROY:
                        // ウインドウが破棄されたときの処理
                        PostQuitMessage(0);
                        return 0;
                default:
                        // デフォルトの処理
                        return DefWindowProc(hWnd, message, wParam, lParam);
        }



2.マウスのクリック位置(座標)を表示

マウスを左クリックすると、クリックした位置(座標)をMessageBoxに表示します。
また右クリックでマウスアップしたときにプログラムを終了させます。



プロシージャウインドウの部分だけ説明します。
宣言部分に以下を宣言します。
PAINTSTRUCT構造体として 構造体変数psを宣言
表示する文字として、*txtに"X"を宣言
マウスの座標位置を入れる変数として、x,y

WM_LBUTTONDOWNメッセージの処理
マウスを左クリックしたときの処理になります。
マウスのクリック位置はlParamに保存されているので、取り出してx,yに代入します。
x=LOWORD(lParam);
y=HIWORD(lParam);

sprintfで文字列に変換して、MessageBoxで表示します。
sprintf(txt, "X:%d,Y:%d",x,y);
MessageBox(NULL,txt,"x,y",MB_OK);


WM_RBUTTONUPメッセージの処理
PostMessage関数でWM_DESTROYをメッセージを送ります。これによりプログラムは終了処理に移行します。
PostMessage(hWnd,(UINT)WM_DESTROY, 0,0)

#include "windows.h"
#include <stdio.h>

// 関数のプロトタイプ宣言
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

// エントリポイント
int APIENTRY WinMain(HINSTANCE hInstance,
                        HINSTANCE hPrevInstance,
                        LPSTR lpCmdLine,
                        int nCmdShow )
{
        WNDCLASSEX wcex;        // ウインドウクラス構造体
        HWND hWnd;              // ウインドウハンドル
        MSG msg;                // メッセージ構造体

        // ウィンドウクラス構造体を設定します。
        wcex.cbSize = sizeof(WNDCLASSEX); 
        wcex.style = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc = (WNDPROC)WndProc;
        wcex.cbClsExtra = 0;
        wcex.cbWndExtra = 0;
        wcex.hInstance = hInstance;
        wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
        wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
        wcex.lpszMenuName = NULL;
        wcex.lpszClassName = "ModelApp";
        wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
        
        // ウインドウクラスを登録します。
        RegisterClassEx(&wcex);

        // ウインドウを作成します。
        hWnd = CreateWindow(wcex.lpszClassName, // ウインドウクラス名
                "Cursor0",              // キャプション文字列
                WS_OVERLAPPEDWINDOW,            // ウインドウのスタイル
                CW_USEDEFAULT,                  // 水平位置
                CW_USEDEFAULT,                  // 垂直位置
                CW_USEDEFAULT,                  // 幅
                CW_USEDEFAULT,                  // 高さ
                NULL,                                   // 親ウインドウ
                NULL,                                   // ウインドウメニュー
                hInstance,                              // インスタンスハンドル
                NULL);                                  // WM_CREATE情報

                // ウインドウを表示します。
                ShowWindow(hWnd, nCmdShow);
                UpdateWindow(hWnd);

        // メッセージループ
        while(GetMessage(&msg, NULL, 0, 0)) 
        {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
        }

        // 戻り値を返します。
        return msg.wParam;
}

// ウインドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd,
                               UINT message,
                               WPARAM wParam,
                               LPARAM lParam)
{
        PAINTSTRUCT ps;
        char txt[20];
        static int x=0;
        static int y=0;
        
        // メッセージの種類に応じて処理を分岐します。
        switch (message) 
        {
      HCURSOR hcur;
        case WM_LBUTTONDOWN:
        //        ShowCursor(false);

                x=LOWORD(lParam);
                y=HIWORD(lParam);
                sprintf(txt, "X:%d,Y:%d",x,y);
                MessageBox(NULL,txt,"x,y",MB_OK);
       return 0;

        case WM_RBUTTONUP:
                PostMessage(hWnd,(UINT)WM_DESTROY, 0,0);
                return 0;
                

                case WM_DESTROY:
                        // ウインドウが破棄されたときの処理
                        PostQuitMessage(0);
                        return 0;
                default:
                        // デフォルトの処理
                        return DefWindowProc(hWnd, message, wParam, lParam);
        }
}

 


TopPage