トップページ > 記事閲覧
【C++】windows マルチタッチ 3本タッチ検出
名前:maekyo 日時: 2022/10/10 19:55

https://learn.microsoft.com/ja-jp/windows/win32/wintouch/detecting-and-tracking-multiple-touch-points 上記のプログラムを使って、3本指が判別できるかを調べたいのですが、なかなかうまくできません。 どなたか助けてください。 開発環境は、Microsoft visual studio2022です。 // main.cpp #include <windows.h> #include"targetver.h" #include <windowsx.h> // included for point conversion #define MAXPOINTS 10 BOOL InitInstance(HINSTANCE, int); // You will use this array to track touch points int points[MAXPOINTS][2]; // You will use this array to switch the color / track ids int idLookup[MAXPOINTS]; // You can make the touch points larger // by changing this radius value static int radius = 50; // There should be at least as many colors // as there can be touch points so that you // can have different colors for each point COLORREF colors[] = { RGB(153,255,51), RGB(153,0,0), RGB(0,153,0), RGB(255,255,0), RGB(255,51,204), RGB(0,0,0), RGB(0,153,0), RGB(153, 255, 255), RGB(153,153,255), RGB(0,51,153) }; HINSTANCE hInst; LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); ATOM InitApp(HINSTANCE); char szClassName[] = "sample02"; //ウィンドウクラス int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) { MSG msg; BOOL bRet; if (!InitApp(hCurInst)) return FALSE; if (!InitInstance(hCurInst, nCmdShow)) return FALSE; while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0) { if (bRet == -1) { break; } else { TranslateMessage(&msg); DispatchMessage(&msg); } } return (int)msg.wParam; } ATOM InitApp(HINSTANCE hInst) { WNDCLASSEX wc; wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; //プロシージャ名 wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInst;//インスタンス wc.hIcon = NULL; //アプリのアイコン。.icoファイルをリソースファイルに読み込みここに記入 wc.hCursor = (HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);//Windowの背景色を指定。 wc.lpszMenuName = NULL; // メニュー名。リソースファイルで設定した値を記入 wc.lpszClassName = (LPCSTR)szClassName; wc.hIconSm = NULL; //アプリのアイコンの小さい版。タスクバーに表示されるもの return (RegisterClassEx(&wc)); } //ウィンドウの生成 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; hInst = hInstance; // Store instance handle in our global variable hWnd = CreateWindow(szClassName, "Sample Application 1", //Windowのタイトル WS_OVERLAPPEDWINDOW, //ウィンドウの種類 CW_USEDEFAULT, //X座標 (指定なしはCW_USEDEFAULT) CW_USEDEFAULT, //Y座標(指定なしはCW_USEDEFAULT) CW_USEDEFAULT, //幅(指定なしはCW_USEDEFAULT) CW_USEDEFAULT, //高さ(指定なしはCW_USEDEFAULT) NULL, //親ウィンドウのハンドル、親を作るときはNULL NULL, //メニューハンドル、クラスメニューを使うときはNULL hInst, //インスタンスハンドル NULL); if (!hWnd) return FALSE; // register the window for touch instead of gestures RegisterTouchWindow(hWnd, 0); // the following code initializes the points for (int i = 0; i < MAXPOINTS; i++) { points[i][0] = -1; points[i][1] = -1; idLookup[i] = -1; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } // This function is used to return an index given an ID int GetContactIndex(int dwID) { for (int i = 0; i < MAXPOINTS; i++) { if (idLookup[i] == -1) { idLookup[i] = dwID; return i; } else { if (idLookup[i] == dwID) { return i; } } } // Out of contacts return -1; } //ウィンドウプロシージャ //ユーザーがWindowを操作したり、Windowが作られたりした場合、この関数が呼び出されて処理を行う。 LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent, i, x, y; UINT cInputs; PTOUCHINPUT pInputs; POINT ptInput; // For double buffering static HDC memDC = 0; static HBITMAP hMemBmp = 0; HBITMAP hOldBmp = 0; // For drawing / fills PAINTSTRUCT ps; HDC hdc; // For tracking dwId to points int index; switch (msg) { case WM_CREATE: //CreateWindow()でWindowを作成したときに呼び出される。ここでウィジェットを作成する。 break; case WM_DESTROY: //ユーザーがWindow右上の×ボタンを押すとここが実行される PostQuitMessage(0); //終了メッセージ break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); RECT client; GetClientRect(hWnd, &client); // start double buffering if (!memDC) { memDC = CreateCompatibleDC(hdc); } hMemBmp = CreateCompatibleBitmap(hdc, client.right, client.bottom); hOldBmp = (HBITMAP)SelectObject(memDC, hMemBmp); FillRect(memDC, &client, CreateSolidBrush(RGB(255, 255, 255))); //Draw Touched Points for (i = 0; i < MAXPOINTS; i++) { SelectObject(memDC, CreateSolidBrush(colors[i])); x = points[i][0]; y = points[i][1]; if (x > 0 && y > 0) { Ellipse(memDC, x - radius, y - radius, x + radius, y + radius); } } BitBlt(hdc, 0, 0, client.right, client.bottom, memDC, 0, 0, SRCCOPY); EndPaint(hWnd, &ps); break; //画面に図形などを描く処理を実装 case WM_TOUCH: cInputs = LOWORD(wParam); pInputs = new TOUCHINPUT[cInputs]; if (pInputs) { if (GetTouchInputInfo((HTOUCHINPUT)lParam, cInputs, pInputs, sizeof(TOUCHINPUT))) { for (int i = 0; i < static_cast<INT>(cInputs); i++) { TOUCHINPUT ti = pInputs[i]; index = GetContactIndex(ti.dwID); if (ti.dwID != 0 && index < MAXPOINTS) { // Do something with your touch input handle ptInput.x = TOUCH_COORD_TO_PIXEL(ti.x); ptInput.y = TOUCH_COORD_TO_PIXEL(ti.y); ScreenToClient(hWnd, &ptInput); if (ti.dwFlags & TOUCHEVENTF_UP) { points[index][0] = -1; points[index][1] = -1; } else { points[index][0] = ptInput.x; points[index][1] = ptInput.y; } } } } // If you handled the message and don't want anything else done with it, you can close it CloseTouchInputHandle((HTOUCHINPUT)lParam); delete[] pInputs; } else { // Handle the error here } default: return (DefWindowProc(hWnd, msg, wParam, lParam)); } return 0; } 実行した際にタッチのペイントがされません。また、タップを識別できていないのか、ペイントができていないのかもわかりません。 どのようにすればよろしいでしょうか。
メンテ

Page: 1 |

Re: 【C++】windows マルチタッチ 3本タッチ検出 ( No.1 )
名前:たろう 日時:2022/10/10 20:34

maekyoさんは、そもそもDXライブラリを使っていないように思いますが、 DXライブラリのタッチ用の関数を使う方法ではだめなのでしょうか? サンプルはここ(↓)にあるようです。見当はずれでしたらごめんなさいm(__)m ttps://dxlib.xsrv.jp/function/dxfunc_input.html#R5N38
メンテ
Re: 【C++】windows マルチタッチ 3本タッチ検出 ( No.2 )
名前:maekyo 日時:2022/10/11 12:32

貴重な意見ありがとうございます。 私は、DXライブラリを使わない方法かつ、上記のマイクロソフトの方法で複数のタッチポイントの検出と追跡を行いたいと考えています。 そのうえで、自分の書いたコードがなぜうまくいかないのかがわかりません。ご教授お願いしたいです。
メンテ
Re: 【C++】windows マルチタッチ 3本タッチ検出 ( No.3 )
名前:管理人 日時:2022/10/11 13:12

WM_PAINT にタッチした箇所を描画するコードが書かれていますが、WM_PAINT の箇所に 処理が行くようなコードがどこにもないのが原因だと思います いきなりご自分でコードを組まれると正しく動かなかった場合どこに原因があるのか 調べるのが大変だと思いますので、最初は正常に動くプログラムを手元で動かして みるのが良いと思います 少し検索してみたところ yoggy様が github にマルチタッチのテストプログラムを アップされていましたので、よろしければこちらをダウンロードしてお手元の環境で 実行してみてください <yoggy win32_multitouch_test Win32でWM_TOUCHを取り扱うメモ。> https://github.com/yoggy/win32_multitouch_test
メンテ
Re: 【C++】windows マルチタッチ 3本タッチ検出 ( No.4 )
名前:maekyo 日時:2022/10/14 14:16

管理人さん 私の環境で動かすことができました。 あとは、頑張ってコードを解読して次につなげたいと思います。 答えてくださりありがとうございました。
メンテ
Re: 【C++】windows マルチタッチ 3本タッチ検出 ( No.5 )
名前:maekyo 日時:2022/10/25 12:31

このプログラムを使って、1本指から3本指の時の最初の指の判定と保持と、タップ、上下左右の4方向の判定を行うプログラムを実装したいのですが、あまりわからずできません。どのようにすればよろしいでしょうか。
メンテ
Re: 【C++】windows マルチタッチ 3本タッチ検出 ( No.6 )
名前:管理人 日時:2022/10/27 00:07

すみません、私もタッチ操作については詳しくないのでわかりません
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存