タッチサンプル


※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。


参考にして作成したソフトウェア
// TouchTestCircle.cpp : アプリケーションのエントリ ポイントを定義します。
//
 
 
#include "stdafx.h"
#include "TouchTestCircle.h"

#define MAX_LOADSTRING 100
#define MAXPOINTS 10

// グローバル変数:
HINSTANCE hInst;								// 現在のインターフェイス
TCHAR szTitle[MAX_LOADSTRING];					// タイトル バーのテキスト
TCHAR szWindowClass[MAX_LOADSTRING];			// メイン ウィンドウ クラス名
 
int points[MAXPOINTS][2];
int idLookup[MAXPOINTS];
 
static int radius = 50;
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)
};
 
// このコード モジュールに含まれる関数の宣言を転送します:
ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK	About(HWND, UINT, WPARAM, LPARAM);
int GetContactIndex(int dwID);
 
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPTSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);
 
 	// TODO: ここにコードを挿入してください。
	MSG msg;
	HACCEL hAccelTable;
 
	// グローバル文字列を初期化しています。
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	LoadString(hInstance, IDC_TOUCHTESTCIRCLE, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance);
 
	// アプリケーションの初期化を実行します:
	if (!InitInstance (hInstance, nCmdShow))
	{
		return FALSE;
	}
 
	hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TOUCHTESTCIRCLE));
 
	// メイン メッセージ ループ:
	while (GetMessage(&msg, NULL, 0, 0))
	{
		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}
 
	return (int) msg.wParam;
}
 
 
 
//
//  関数: MyRegisterClass()
//
//  目的: ウィンドウ クラスを登録します。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;
 
	wcex.cbSize = sizeof(WNDCLASSEX);
 
	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TOUCHTESTCIRCLE));
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= MAKEINTRESOURCE(IDC_TOUCHTESTCIRCLE);
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
 
	return RegisterClassEx(&wcex);
}
 
//
//   関数: InitInstance(HINSTANCE, int)
//
//   目的: インスタンス ハンドルを保存して、メイン ウィンドウを作成します。
//
//   コメント:
//
//        この関数で、グローバル変数でインスタンス ハンドルを保存し、
//        メイン プログラム ウィンドウを作成および表示します。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;
 
   hInst = hInstance; // グローバル変数にインスタンス処理を格納します。
 
   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
 
   if (!hWnd)
   {
      return FALSE;
   }
 
   //register the window for touch instead of gestures
   RegisterTouchWindow(hWnd,0);
 
   //initialize 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;
}
 
//
//  関数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  目的:  メイン ウィンドウのメッセージを処理します。
//
//  WM_COMMAND	- アプリケーション メニューの処理
//  WM_PAINT	- メイン ウィンドウの描画
//  WM_DESTROY	- 中止メッセージを表示して戻る
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent,x,y;
	UINT cInputs;
	PTOUCHINPUT pInputs;
	POINT ptInput;
 
	PAINTSTRUCT ps;
	static HDC memDC = 0;
	static HBITMAP hMemBmp = 0;
	static HBITMAP hOldBmp = 0;
	int index;
	BOOL bUpdate;
 
	switch (message)
	{
	case WM_TOUCH:
		cInputs=LOWORD(wParam);
		pInputs = new TOUCHINPUT[cInputs];
		if(pInputs){
			bUpdate = FALSE;
			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 >= 0) && (index < MAXPOINTS)){
						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;
							idLookup[index] = -1;  /* idLookupも削除が必要 */
							bUpdate = TRUE;
						}else{
							if((points[index][0] != ptInput.x) || (points[index][1] != ptInput.y)){
								/* 低い割合で(x,y)にマイナスが入ることがあった。*/
								if((ptInput.x >= 0) && (ptInput.y >= 0)){
									points[index][0] = ptInput.x;
									points[index][1] = ptInput.y;
									bUpdate=TRUE;
								}else{
									idLookup[index] = -1; /* 異常座標の場合は登録を取りやめる */
								}
							}
						}
					}
				}
				/* 接触点の追加、削除、移動を検出し円を描く */
				if(bUpdate){
					HDC hdc;
					RECT client;
					HBRUSH hBrush;
 
					hdc = GetDC(hWnd);
					GetClientRect(hWnd,&client);
					if(!memDC){
						memDC = CreateCompatibleDC(hdc);
					}
					hMemBmp = CreateCompatibleBitmap(hdc, client.right, client.bottom);
					SelectObject(memDC, hMemBmp);
 
					FillRect(memDC, &client, (HBRUSH)GetStockObject(WHITE_BRUSH)); /* 一度全て白で塗りつぶし */
					for(int i=0;i<MAXPOINTS;i++){
						x = points[i][0];
						y = points[i][1];
						if((x > radius) && (y > radius) && 
							((x+radius) < client.right) && ((y+radius) < client.bottom)){
							hBrush = CreateSolidBrush(colors[i]);
							SelectObject(memDC,hBrush);
							Ellipse(memDC, x-radius, y-radius, x+radius, y+radius);
							DeleteObject(hBrush);
						}
					}
					hOldBmp = (HBITMAP)SelectObject(memDC, hMemBmp);
					InvalidateRect(hWnd, NULL, TRUE); /* これがないとWM_PAINTが呼ばれない。MSのサンプルには無い */
					ReleaseDC(hWnd, hdc);
				}
			}
			CloseTouchInputHandle((HTOUCHINPUT)lParam);
			delete [] pInputs;
		}else{
			//Error.
		}
 
		break;
	case WM_COMMAND:
		wmId    = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		// 選択されたメニューの解析:
		switch (wmId)
		{
		case IDM_ABOUT:
			DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
			break;
		case IDM_EXIT:
			DestroyWindow(hWnd);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		break;
	case WM_ERASEBKGND: /* ちらつき抑制 */
		break;
	case WM_PAINT:
		HDC hdc;
		RECT client;
		GetClientRect(hWnd,&client);
 
		hdc = BeginPaint(hWnd, &ps);
		BitBlt(hdc, 0, 0, client.right, client.bottom, memDC, 0, 0, SRCCOPY);
		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		if(!memDC) DeleteDC(memDC);
		if(!hMemBmp) DeleteObject(hMemBmp);
		if(!hOldBmp) DeleteObject(hOldBmp);
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}
 
// バージョン情報ボックスのメッセージ ハンドラーです。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	UNREFERENCED_PARAMETER(lParam);
	switch (message)
	{
	case WM_INITDIALOG:
		return (INT_PTR)TRUE;
 
	case WM_COMMAND:
		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
		{
			EndDialog(hDlg, LOWORD(wParam));
			return (INT_PTR)TRUE;
		}
		break;
	}
	return (INT_PTR)FALSE;
}
 
//
//  関数: GetContactIndex(int dwID)
//
//  目的: 接触点が新規のIDかどうか確認する。上限はMAXPOINTS
//
//  int	- 接触点のindex値
//	-1	- エラー
//
//
int GetContactIndex(int dwID)
{
	//最初にIDが登録済みかどうか確認する
	for(int i=0;i<MAXPOINTS;i++){
		if(idLookup[i] == dwID){
			return i;
		}
	}
 
	//idLookupに空きを見つけ登録する
	for(int i=0;i<MAXPOINTS;i++) {
		if(idLookup[i] == -1){
			idLookup[i]=dwID;
			return i;
		}
	}
 
	// FULL
	return -1;
}