プログラムを書こう!

実務や自作アプリ開発で習得した役に立つソフトウェア技術情報を発信するブログ

C++/CLI のボタンをタッチ対応する

この記事は 2021 年 08 月 19 日に投稿しました。

f:id:paveway:20190914064630j:plain

目次

  1. はじめに
  2. C++/CLI のボタンでタッチ対応する
  3. おわりに

1. はじめに

こんにちは、iOS のエディタアプリPWEditorの開発者の二俣です。
今回は業務で使用している C++/CLI のボタンでタッチ対応する方法についてです。

目次へ

2. C++/CLI のボタンでタッチ対応する

C++/CLI のボタンでタッチ対応するには、以下の様な実装にします。

実装例

TouchButton.h
#pragma once

#include <Windows.h>

namespace TouchButton {
    using namespace System;
    using namespace System::Windows::Forms;
    using namespace System::Diagnostics;
    using namespace System::Drawing;

    public ref class TouchButton : Button {
    public:
        Action^ touchDownCallback;
        Action^ touchUpCallback;

    public:
        // コンストラクタ
        TouchButton()
        {
            // ボタンをタッチ対応として登録します。
            RegisterTouchWindow(reinterpret_cast<HWND>(this->Handle.ToPointer()), 0);
        }

        // デストラクタ
        ~TouchButton()
        {
            // ボタンのタッチ対応の登録を解除します。
            UnregisterTouchWindow(reinterpret_cast<HWND>(this->Handle.ToPointer()));
        }

        // ボタンのウィンドウプロシージャをオーバーライドします。
        virtual void WndProc(Message% m) override
        {
            // メッセージにより処理を振り分けます。
            switch (m.Msg) {
            case WM_TOUCH:
            {
                // タッチメッセージの場合
                // タッチ情報を取得します。
                UINT cInputs = LOWORD((int)m.WParam);
                PTOUCHINPUT pInputs = new TOUCHINPUT[cInputs];
                HTOUCHINPUT hTouchInput = (HTOUCHINPUT)(int)m.LParam;
                int cbSize = sizeof(TOUCHINPUT);
                GetTouchInputInfo(hTouchInput, cInputs, pInputs, cbSize);

                // タッチ動作を示すフラグを取得します。
                DWORD dwFlags = pInputs->dwFlags;

                // タッチされた場合
                if (dwFlags & TOUCHEVENTF_DOWN)
                {
                    // コールバックが設定されている場合
                    if (touchDownCallback != nullptr)
                    {
                        // コールバックを呼び出します。
                        touchDownCallback();
                    }
                }

                // 離された場合
                else if (dwFlags & TOUCHEVENTF_UP)
                {
                    // コールバックが設定されている場合
                    if (touchUpCallback != nullptr)
                    {
                        // コールバックを呼び出します。
                        touchUpCallback();
                    }
                }
                delete pInputs;
                break;
            }

            default:
                // その他のイベントの場合、何もしません。
                break;
            }

            // デフォルトのウィンドウプロシージャを呼び出します。
            Button::WndProc(m);
        }
    };
}
MainForm.h
#pragma once

#include "TouchButton.h"

namespace TouchButton {

    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;

    /// <summary>
    /// MainForm の概要
    /// </summary>
    public ref class MainForm : public System::Windows::Forms::Form
    {
        // コンストラクタ、初期化処理等は書略

    private:
        TouchButton^ button;

    private:
        // フォームがロードされた時に呼び出されます。
        System::Void MainForm_Load(System::Object^  sender, System::EventArgs^  e) {
            // タッチ対応のボタンを生成します。
            // ボタンをコードで生成するのでデザインしづらいため、パネルでデザインしパネルにボタンを貼り付けます。
            button = gcnew TouchButton();
            button->Text = "タッチボタン";
            button->Size = panel->Size;
            // ボタンがタッチされた時のコールバックを登録します。
            button->touchDownCallback = gcnew Action(this, &MainForm::Button_TouchDown);
            // ボタンのタッチから離された時のコールバックを登録します。
            button->touchUpCallback = gcnew Action(this, &MainForm::Button_TouchUp);

            // フォームに配置したパネルにボタンを追加します。
            panel->Controls->Add(button);
        }

    private:
        // ボタンがタッチされた時に呼び出されるコールバック
        void MainForm::Button_TouchDown()
        {
            // ボタンの背景色を赤に設定します。
            button->BackColor = Color::Red;
        }

        // ボタンのタッチが離された時に呼び出されるコールバック
        void MainForm::Button_TouchUp()
        {
            // ボタンの背景色を元に戻します。
            button->BackColor = SystemColors::Control;
        }
    };
}

Reference

RegisterTouchWindow関数

UnregisterTouchWindow関数

GetTouchInputInfo関数

TOUCHINPUT構造体

目次へ

3. おわりに

タッチパネルのPCでボタンの長押しに対応する必要があり、その方法調べました。
通常のボタンクリックイベントはタッチした時はイベントが発生せず、離れるときにイベントが発生するため使えませんでした。

紹介している一部の記事のコードはGitlabで公開しています。
興味のある方は覗いてみてください。

目次へ


私が勤務しているニューラルでは、主に組み込み系ソフトの開発を行っております。
弊社製品のハイブリッド OS Bi-OSは高い技術力を評価されており、特に制御系や通信系を得意としています。
私自身はiOS モバイルアプリウィンドウズアプリを得意としております。
ソフトウェア開発に関して相談などございましたら、お気軽にご連絡ください。

また一緒に働きたい技術者の方も随時募集中です。
興味がありましたらご連絡ください。

EMAIL : info-nr@newral.co.jp / m-futamata@newral.co.jp
TEL : 042-523-3663
FAX : 042-540-1688

目次へ