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;
}
実行した際にタッチのペイントがされません。また、タップを識別できていないのか、ペイントができていないのかもわかりません。
どのようにすればよろしいでしょうか。