标签:call sim 步骤 ogg i++ tps finger lob line
分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net
#define MOUSEEVENTF_FROMTOUCH 0xFF515700
if ((GetMessageExtraInfo() & MOUSEEVENTF_FROMTOUCH) == MOUSEEVENTF_FROMTOUCH)
{
// Click was generated by wisptis / Windows Touch
}
else
{
// Click was generated by the mouse.
}
Windows Touch Input的疑难问题
1、问题:我处理WM_TOUCH消息后,没有得到boundary feedback(边界反馈)#ifndef WINVER // Specify that the minimum required platform is Windows 7.
#define WINVER 0x0601
#endif
#ifndef WM_TOUCH
#define WM_TOUCH 0x0240 // 自定义多点触摸消息:来自MSDN
#endif
POINT ptInput;
if (GetTouchInputInfo((HTOUCHINPUT)lParam, cInputs, pInputs, sizeof(TOUCHINPUT)))
{
for (int i=0; i < static_cast<INT>(cInputs); i++)
{
TOUCHINPUT ti = pInputs[i];
if (ti.dwID != 0)
{
// 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);
points[ti.dwID][0] = ptInput.x;
points[ti.dwID][1] = ptInput.y;
}
}
}
// The message map.
BEGIN_MESSAGE_MAP()
ON_WM_CREATE()
... ... ...
ON_MESSAGE(WM_GESTURENOTIFY, OnWindowsGestureNotify)
END_MESSAGE_MAP()
LRESULT CTestWndApp::OnWindowsGestureNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
GESTURECONFIG gc;
gc.dwID = GID_ROTATE; // The gesture identifier.
gc.dwWant = GC_ROTATE; // The gesture command you are enabling for GID_ROTATE.
gc.dwBlock = 0; // Don‘t block anything.
UINT uiGcs = 1; // The number of gestures being set.
BOOL bResult = SetGestureConfig(g_hMainWnd, 0, uiGcs, &gc, sizeof(GESTURECONFIG));
if(!bResult)
{
// Something went wrong, report the error using your preferred logging.
}
return 0;
}
int value = GetSystemMetrics( SM_DIGITIZER )
if ( value & NID_MULTI_INPUT )
{
// 设备支持触摸操作
}
Name ValueDescriptionNID_READY 0x00000080 输入设备准备好输入了
检查NID_* 值是一种很有效的检查用户的设备支持touch pen or no-table input的能力。例如,如果你有一个动态的UI,想要动态地配置一些东西,你可以检查NID_INTEGRATED_TOUCH,NID_MULTITOUCH,在用户第一次运行你的应用程序的时候获得最小的上表中的值。
对于SM_GETSYSTEMMETRICS 有一些固有的限制,不支持即插即用,当用这个函数的时候应该注意这一点。
第二步:注册touch窗口
应用程序必须先注册才能收到多点触摸消息,通过函数RegisterTouchWindow函数,退出时必须卸载,通过函数UnRegisterTouchWindow函数。BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
RegisterTouchWindow(hWnd, 0);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_TOUCH:
......
// you can either pass this to DefWindowProc or can handle it yourself
DefWindowProc(hWnd, message, wParam, lParam);
break;
}
}
// Class implementations within a dialog
LRESULT TestDlg::OnTouch( WPARAM wParam, LPARAM lParam )
{
//Insert handler code here to do something with the message or uncomment the following line to test
//MessageBox(L"touch!", L"touch!", MB_OK);
return 0;
}
// The message map
BEGIN_MESSAGE_MAP()
ON_WM_CREATE()
... ... ...
ON_MESSAGE(WM_TOUCH, OnTouch)
END_MESSAGE_MAP()
BOOL TestDlg::OnInitDialog()
{
CDialog::OnInitDialog();
RegisterTouchWindow(m_hWnd, 0);
... ... ...
}
LRESULT OnTouchHandled(HWND hWnd, WPARAM wParam, LPARAM lParam )
{
BOOL bHandled = FALSE;
UINT cInputs = LOWORD(wParam);
PTOUCHINPUT pInputs = new TOUCHINPUT[cInputs];
if (pInputs){
if (GetTouchInputInfo((HTOUCHINPUT)lParam, cInputs, pInputs, sizeof(TOUCHINPUT))){
for (UINT i=0; i < cInputs; i++){
TOUCHINPUT ti = pInputs[i];
//do something with each touch input entry
}
}else{
}
delete [] pInputs;
}else{
}
if (bHandled){
// if you handled the message, close the touch input handle and return
CloseTouchInputHandle((HTOUCHINPUT)lParam);
return 0;
}else{
// if you didn‘t handle the message, let DefWindowProc handle it
return DefWindowProc(hWnd, WM_TOUCH, wParam, lParam);
}
}
#ifndef WINVER // Specifies that the minimum required platform is Windows 7.
#define WINVER 0x0601 // Change this to the appropriate value to target other versions of Windows.
#endif
#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows 7.
#define _WIN32_WINNT 0x0601 // Change this to the appropriate value to target other versions of Windows.
#endif
#ifndef _WIN32_WINDOWS // Specifies that the minimum required platform is Windows 98.
#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
#endif
#ifndef _WIN32_IE // Specifies that the minimum required platform is Internet Explorer 7.0.
#define _WIN32_IE 0x0700 // Change this to the appropriate value to target other versions of IE.
#endif
#include <windows.h> // included for Windows Touch
#include <windowsx.h> // included for point conversion
#define MAXPOINTS 10
// 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)
};
int wmId, wmEvent, i, x, y;
UINT cInputs;
PTOUCHINPUT pInputs;
POINT ptInput;
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
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);
// 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;
}
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
}
// 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;
}
// 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;
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;
#include <windows.h>
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_GESTURE:
// Insert handler code here to interpret the gesture.
return DecodeGesture(hWnd, message, wParam, lParam);
LRESULT DecodeGesture(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){
// Create a structure to populate and retrieve the extra message info.
GESTUREINFO gi;
ZeroMemory(&gi, sizeof(GESTUREINFO));
gi.cbSize = sizeof(GESTUREINFO);
BOOL bResult = GetGestureInfo((HGESTUREINFO)lParam, &gi);
BOOL bHandled = FALSE;
if (bResult){
// now interpret the gesture
switch (gi.dwID){
case GID_ZOOM:
// Code for zooming goes here
bHandled = TRUE;
break;
case GID_PAN:
// Code for panning goes here
bHandled = TRUE;
break;
case GID_ROTATE:
// Code for rotation goes here
bHandled = TRUE;
break;
case GID_TWOFINGERTAP:
// Code for two-finger tap goes here
bHandled = TRUE;
break;
case GID_PRESSANDTAP:
// Code for roll over goes here
bHandled = TRUE;
break;
default:
// A gesture was not recognized
break;
}
}else{
DWORD dwErr = GetLastError();
if (dwErr > 0){
//MessageBoxW(hWnd, L"Error!", L"Could not retrieve a GESTUREINFO structure.", MB_OK);
}
}
if (bHandled){
return 0;
}else{
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
hWnd = CreateWindow( szWindowClass, szTitle,
WS_OVERLAPPEDWINDOW | WS_VSCROLL, // style
200, 200, 550, 300, NULL, NULL, hInstance, NULL
);
把下面的代码放到你的应用程序的WndProc的开头TEXTMETRIC tm;
SCROLLINFO si;
// These variables are required to display text.
static int xClient; // width of client area
static int yClient; // height of client area
static int xClientMax; // maximum width of client area
static int xChar; // horizontal scrolling unit
static int yChar; // vertical scrolling unit
static int xUpper; // average width of uppercase letters
static int xPos; // current horizontal scrolling position
static int yPos; // current vertical scrolling position
int i; // loop counter
int x, y; // horizontal and vertical coordinates
int FirstLine; // first line in the invalidated area
int LastLine; // last line in the invalidated area
HRESULT hr;
int abcLength = 0; // length of an abc[] item
int lines = 0;
// Create an array of lines to display.
static const int LINES=28;
static LPCWSTR abc[] = {
L"anteater", L"bear", L"cougar",
L"dingo", L"elephant", L"falcon",
L"gazelle", L"hyena", L"iguana",
L"jackal", L"kangaroo", L"llama",
L"moose", L"newt", L"octopus",
L"penguin", L"quail", L"rat",
L"squid", L"tortoise", L"urus",
L"vole", L"walrus", L"xylophone",
L"yak", L"zebra",
L"This line contains words, but no character. Go figure.",
L""
};
case WM_CREATE :
// Get the handle to the client area‘s device context.
hdc = GetDC (hWnd);
// Extract font dimensions from the text metrics.
GetTextMetrics (hdc, &tm);
xChar = tm.tmAveCharWidth;
xUpper = (tm.tmPitchAndFamily & 1 ? 3 : 2) * xChar/2;
yChar = tm.tmHeight + tm.tmExternalLeading;
// Free the device context.
ReleaseDC (hWnd, hdc);
// Set an arbitrary maximum width for client area.
// (xClientMax is the sum of the widths of 48 average
// lowercase letters and 12 uppercase letters.)
xClientMax = 48 * xChar + 12 * xUpper;
return 0;
接下来实现当窗口resized的时候重新计算text blockcase WM_SIZE:
// Retrieve the dimensions of the client area.
yClient = HIWORD (lParam);
xClient = LOWORD (lParam);
// Set the vertical scrolling range and page size
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE;
si.nMin = 0;
si.nMax = LINES - 1;
si.nPage = yClient / yChar;
SetScrollInfo(hWnd, SB_VERT, &si, TRUE);
// Set the horizontal scrolling range and page size.
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE;
si.nMin = 0;
si.nMax = 2 + xClientMax / xChar;
si.nPage = xClient / xChar;
SetScrollInfo(hWnd, SB_HORZ, &si, TRUE);
return 0;
接下来实现vscroll的消息 case WM_VSCROLL:
// Get all the vertical scroll bar information
si.cbSize = sizeof (si);
si.fMask = SIF_ALL;
GetScrollInfo (hWnd, SB_VERT, &si);
// Save the position for comparison later on
yPos = si.nPos;
switch (LOWORD (wParam))
{
// user clicked the HOME keyboard key
case SB_TOP:
si.nPos = si.nMin;
break;
// user clicked the END keyboard key
case SB_BOTTOM:
si.nPos = si.nMax;
break;
// user clicked the top arrow
case SB_LINEUP:
si.nPos -= 1;
break;
// user clicked the bottom arrow
case SB_LINEDOWN:
si.nPos += 1;
break;
// user clicked the scroll bar shaft above the scroll box
case SB_PAGEUP:
si.nPos -= si.nPage;
break;
// user clicked the scroll bar shaft below the scroll box
case SB_PAGEDOWN:
si.nPos += si.nPage;
break;
// user dragged the scroll box
case SB_THUMBTRACK:
si.nPos = si.nTrackPos;
break;
// user positioned the scroll box
// This message is the one used by Windows Touch
case SB_THUMBPOSITION:
si.nPos = HIWORD(wParam);
break;
default:
break;
}
// Set the position and then retrieve it. Due to adjustments
// by Windows it may not be the same as the value set.
si.fMask = SIF_POS;
SetScrollInfo (hWnd, SB_VERT, &si, TRUE);
GetScrollInfo (hWnd, SB_VERT, &si);
// If the position has changed, scroll window and update it
if (si.nPos != yPos)
{
ScrollWindow(hWnd, 0, yChar * (yPos - si.nPos), NULL, NULL);
UpdateWindow (hWnd);
}
break;
case WM_PAINT:
// Prepare the window for painting
hdc = BeginPaint (hWnd, &ps);
// Get vertical scroll bar position
si.cbSize = sizeof (si);
si.fMask = SIF_POS;
GetScrollInfo (hWnd, SB_VERT, &si);
yPos = si.nPos;
// Get horizontal scroll bar position
GetScrollInfo (hWnd, SB_HORZ, &si);
xPos = si.nPos;
// Find painting limits
FirstLine = max (0, yPos + ps.rcPaint.top / yChar);
LastLine = min (LINES - 1, yPos + ps.rcPaint.bottom / yChar);
for (i = FirstLine; i <= LastLine; i++)
{
x = xChar * (1 - xPos);
y = yChar * (i - yPos);
// Note that "55" in the following depends on the
// maximum size of an abc[] item.
//
abcLength = wcslen(abc[i]);
hr = S_OK;
if ((FAILED(hr)))
{
MessageBox(hWnd, L"err", L"err", NULL);
}else{
TextOut(hdc, x, y, abc[i], abcLength);
}
}
// Indicate that painting is finished
EndPaint (hWnd, &ps);
return 0;
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow){
const DWORD_PTR dwHwndTabletProperty =
TABLET_DISABLE_PRESSANDHOLD | // disables press and hold (right-click) gesture
TABLET_DISABLE_PENTAPFEEDBACK | // disables UI feedback on pen up (waves)
TABLET_DISABLE_PENBARRELFEEDBACK | // disables UI feedback on pen button down (circle)
TABLET_DISABLE_FLICKS; // disables pen flicks (back, forward, drag down, drag up)
SetProp(hWnd, MICROSOFT_TABLETPENSERVICE_PROPERTY, reinterpret_cast<HANDLE>(dwHwndTabletProperty));
自定义panning Experience#ifndef WINVER // Specifies that the minimum required platform is Windows Vista.
#define WINVER 0x0601 // Change this to the appropriate value to target other versions of Windows.
#endif
#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista.
#define _WIN32_WINNT 0x0601 // Change this to the appropriate value to target other versions of Windows.
#endif
接下来,加入UXTheme.h文件并且加入uxtheme.lib库文件的引用// The following are used for the custom panning handler
BOOL bResult = FALSE;
static int scale = 8; // altering the scale value will change how fast the page scrolls
static int lastY = 0; // used for panning calculations (initial / previous vertical position)
static int lastX = 0; // used for panning calculations (initial / previous horizontal position)
GESTUREINFO gi;
然后加入WM_GESTURE消息的处理分支,使scrollbar可以通过手势更新case WM_GESTURE:
// Get all the vertial scroll bar information
si.cbSize = sizeof (si);
si.fMask = SIF_ALL;
GetScrollInfo (hWnd, SB_VERT, &si);
yPos = si.nPos;
ZeroMemory(&gi, sizeof(GESTUREINFO));
gi.cbSize = sizeof(GESTUREINFO);
bResult = GetGestureInfo((HGESTUREINFO)lParam, &gi);
if (bResult){
// now interpret the gesture
switch (gi.dwID){
case GID_BEGIN:
lastY = gi.ptsLocation.y;
CloseGestureInfoHandle((HGESTUREINFO)lParam);
break;
// A CUSTOM PAN HANDLER
// COMMENT THIS CASE OUT TO ENABLE DEFAULT HANDLER BEHAVIOR
case GID_PAN:
si.nPos -= (gi.ptsLocation.y - lastY) / scale;
si.fMask = SIF_POS;
SetScrollInfo (hWnd, SB_VERT, &si, TRUE);
GetScrollInfo (hWnd, SB_VERT, &si);
yOverpan -= lastY - gi.ptsLocation.y;
lastY = gi.ptsLocation.y;
if (gi.dwFlags & GF_BEGIN){
BeginPanningFeedback(hWnd);
yOverpan = 0;
} else if (gi.dwFlags & GF_END) {
EndPanningFeedback(hWnd, TRUE);
yOverpan = 0;
}
if (si.nPos == si.nMin || si.nPos >= (si.nMax - si.nPage)){
// we reached the bottom / top, pan
UpdatePanningFeedback(hWnd, 0, yOverpan, gi.dwFlags & GF_INERTIA);
}
ScrollWindow(hWnd, 0, yChar * (yPos - si.nPos), NULL, NULL);
UpdateWindow (hWnd);
return DefWindowProc(hWnd, message, lParam, wParam);
case GID_ZOOM:
// Add Zoom handler
return DefWindowProc(hWnd, message, lParam, wParam);
default:
// You have encountered an unknown gesture
return DefWindowProc(hWnd, message, lParam, wParam);
}
}else{
DWORD dwErr = GetLastError();
if (dwErr > 0){
// something is wrong
// 87 indicates that you are probably using a bad
// value for the gi.cbSize
}
}
return DefWindowProc (hWnd, message, wParam, lParam);
// The following are used for panning feedback (Window Bounce)
static int animCount = 0;
static DWORD dwErr = 0;
static BOOL isOverpan = FALSE;
static long xOverpan = 0;
static long yOverpan = 0;
case GID_PAN:
si.nPos -= (gi.ptsLocation.y - lastY) / scale;
si.fMask = SIF_POS;
SetScrollInfo (hWnd, SB_VERT, &si, TRUE);
GetScrollInfo (hWnd, SB_VERT, &si);
yOverpan -= lastY - gi.ptsLocation.y;
lastY = gi.ptsLocation.y;
if (gi.dwFlags & GF_BEGIN){
BeginPanningFeedback(hWnd);
yOverpan = 0;
} else if (gi.dwFlags & GF_END) {
EndPanningFeedback(hWnd, TRUE);
yOverpan = 0;
}
if (si.nPos == si.nMin){
// we reached the top, pan upwards in y direction
UpdatePanningFeedback(hWnd, 0, yOverpan, gi.dwFlags & GF_INERTIA);
}else if (si.nPos >= (si.nMax - si.nPage)){
// we reached the bottom, pan downwards in y direction
UpdatePanningFeedback(hWnd, 0, yOverpan, gi.dwFlags & GF_INERTIA);
}
ScrollWindow(hWnd, 0, yChar * (yPos - si.nPos), NULL, NULL);
UpdateWindow (hWnd);
return DefWindowProc(hWnd, message, lParam, wParam);
现在,当用户在scrollbar区域的底部pan时,你的程序就会有边界反馈了。// Manipulation Header Files
#include <comdef.h>
#include <manipulations.h>
#include <ocidl.h>
class CManipulationEventSink : _IManipulationEvents
{
public:
CManipulationEventSink(IManipulationProcessor *manip, HWND hWnd);
int GetStartedEventCount();
int GetDeltaEventCount();
int GetCompletedEventCount();
double CManipulationEventSink::GetX();
double CManipulationEventSink::GetY();
~CManipulationEventSink();
//////////////////////////////
// IManipulationEvents methods
//////////////////////////////
virtual HRESULT STDMETHODCALLTYPE ManipulationStarted(float x, float y);
virtual HRESULT STDMETHODCALLTYPE ManipulationDelta(float x, float y,LOAT translationDeltaX,
float translationDeltaY,float scaleDelta,
float expansionDelta,float rotationDelta,
float cumulativeTranslationX,float cumulativeTranslationY,
float cumulativeScale,float cumulativeExpansion,
float cumulativeRotation); virtual HRESULT STDMETHODCALLTYPE ManipulationCompleted(float x,float y,float cumulativeTranslationX,float cumulativeTranslationY,float cumulativeScale,float cumulativeExpansion,float cumulativeRotation);
////////////////////////////////////////////////////////////
// IUnknown methods
////////////////////////////////////////////////////////////
STDMETHOD_(ULONG, AddRef)(void);
STDMETHOD_(ULONG, Release)(void);
STDMETHOD(QueryInterface)(REFIID riid, LPVOID *ppvObj);
private:
double m_fX;
double m_fY;
int m_cRefCount;
int m_cStartedEventCount;
int m_cDeltaEventCount;
int m_cCompletedEventCount;
IManipulationProcessor* m_pManip;
IConnectionPointContainer* m_pConPointContainer;
IConnectionPoint* m_pConnPoint;
HWND m_hWnd;
};
给出了头文件,必须实现事件接口,使类按照你想要的方式让Manipulation处理器去执行。下面的代码是一个最简单的_IManipulationEvents接口event sink。#include "stdafx.h"
#include "cmanipulationeventsink.h"
CManipulationEventSink::CManipulationEventSink(IManipulationProcessor *manip, HWND hWnd)
{
m_hWnd = hWnd;
//Set initial ref count to 1.
m_cRefCount = 1;
m_pManip = manip;
m_pManip->put_PivotRadius(-1);
m_cStartedEventCount = 0;
m_cDeltaEventCount = 0;
m_cCompletedEventCount = 0;
HRESULT hr = S_OK;
//Get the container with the connection points.
IConnectionPointContainer* spConnectionContainer;
hr = manip->QueryInterface(
IID_IConnectionPointContainer,
(LPVOID*) &spConnectionContainer
);
//hr = manip->QueryInterface(&spConnectionContainer);
if (spConnectionContainer == NULL){
// something went wrong, try to gracefully quit
}
//Get a connection point.
hr = spConnectionContainer->FindConnectionPoint(__uuidof(_IManipulationEvents), &m_pConnPoint);
if (m_pConnPoint == NULL){
// something went wrong, try to gracefully quit
}
DWORD dwCookie;
//Advise.
hr = m_pConnPoint->Advise(this, &dwCookie);
}
int CManipulationEventSink::GetStartedEventCount()
{
return m_cStartedEventCount;
}
int CManipulationEventSink::GetDeltaEventCount()
{
return m_cDeltaEventCount;
}
int CManipulationEventSink::GetCompletedEventCount()
{
return m_cCompletedEventCount;
}
double CManipulationEventSink::GetX()
{
return m_fX;
}
double CManipulationEventSink::GetY()
{
return m_fY;
}
CManipulationEventSink::~CManipulationEventSink()
{
//Cleanup.
}
///////////////////////////////////
//Implement IManipulationEvents
///////////////////////////////////
HRESULT STDMETHODCALLTYPE CManipulationEventSink::ManipulationStarted(
float x,
float y)
{
m_cStartedEventCount ++;
return S_OK;
}
HRESULT STDMETHODCALLTYPE CManipulationEventSink::ManipulationDelta(
float x,
float y,
float translationDeltaX,
float translationDeltaY,
float scaleDelta,
float expansionDelta,
float rotationDelta,
float cumulativeTranslationX,
float cumulativeTranslationY,
float cumulativeScale,
float cumulativeExpansion,
float cumulativeRotation)
{
m_cDeltaEventCount ++;
RECT rect;
GetWindowRect(m_hWnd, &rect);
int oldWidth = rect.right-rect.left;
int oldHeight = rect.bottom-rect.top;
// scale and translate the window size / position
MoveWindow(m_hWnd, // the window to move
static_cast<int>(rect.left + (translationDeltaX / 100.0f)), // the x position
static_cast<int>(rect.top + (translationDeltaY/100.0f)), // the y position
static_cast<int>(oldWidth * scaleDelta), // width
static_cast<int>(oldHeight * scaleDelta), // height
TRUE); // redraw
return S_OK;
}
HRESULT STDMETHODCALLTYPE CManipulationEventSink::ManipulationCompleted(
float x,
float y,
float cumulativeTranslationX,
float cumulativeTranslationY,
float cumulativeScale,
float cumulativeExpansion,
float cumulativeRotation)
{
m_cCompletedEventCount ++;
m_fX = x;
m_fY = y;
// place your code handler here to do any operations based on the manipulation
return S_OK;
}
/////////////////////////////////
//Implement IUnknown
/////////////////////////////////
ULONG CManipulationEventSink::AddRef(void)
{
return ++m_cRefCount;
}
ULONG CManipulationEventSink::Release(void)
{
m_cRefCount --;
if(0 == m_cRefCount) {
delete this;
return 0;
}
return m_cRefCount;
}
HRESULT CManipulationEventSink::QueryInterface(REFIID riid, LPVOID *ppvObj)
{
if (IID__IManipulationEvents == riid) {
*ppvObj = (_IManipulationEvents *)(this); AddRef(); return S_OK;
} else if (IID_IUnknown == riid) {
*ppvObj = (IUnknown *)(this); AddRef(); return S_OK;
} else {
return E_NOINTERFACE;
}
}
//Include windows.h for touch events
#include "windows.h"
// Manipulation implementation file
#include <manipulations_i.c>
// Smart Pointer to a global reference of a manipulation processor, event sink
IManipulationProcessor* g_pIManipProc;
HRESULT hr = CoInitialize(0);
hr = CoCreateInstance(CLSID_ManipulationProcessor,
NULL,
CLSCTX_INPROC_SERVER,
IID_IUnknown,
(VOID**)(&g_pIManipProc)
);
//Include your definition of the event sink, CManipulationEventSink.h in this case
#include "CManipulationEventSink.h"
// Set up a variable to point to the manipulation event sink implementation class
CManipulationEventSink* g_pManipulationEventSink;
g_pManipulationEventSink = new CManipulationEventSink(g_pIManipProc, hWnd);
RegisterTouchWindow(hWnd, 0);
注意 实例化event sink的方式依赖于你想通过Manipulation数据做什么。大多数情况下,你会创建一个和当前例子不同的构造函数的Manipulation处理器事件sink。LRESULT OnTouch(HWND hWnd, WPARAM wParam, LPARAM lParam )
{
UINT cInputs = LOWORD(wParam);
PTOUCHINPUT pInputs = new TOUCHINPUT[cInputs];
BOOL bHandled = FALSE;
if (NULL != pInputs) {
if (GetTouchInputInfo((HTOUCHINPUT)lParam,
cInputs,
pInputs,
sizeof(TOUCHINPUT))) {
for (UINT i=0; i<cInputs; i++){
if (pInputs[i].dwFlags & TOUCHEVENTF_DOWN){
g_pIManipProc->ProcessDown(pInputs[i].dwID, static_cast<FLOAT>(pInputs[i].x), static_cast<FLOAT>(pInputs[i].y));
bHandled = TRUE;
}
if (pInputs[i].dwFlags & TOUCHEVENTF_UP){
g_pIManipProc->ProcessUp(pInputs[i].dwID, static_cast<FLOAT>(pInputs[i].x), static_cast<FLOAT>(pInputs[i].y));
bHandled = TRUE;
}
if (pInputs[i].dwFlags & TOUCHEVENTF_MOVE){
g_pIManipProc->ProcessMove(pInputs[i].dwID, static_cast<FLOAT>(pInputs[i].x), static_cast<FLOAT>(pInputs[i].y));
bHandled = TRUE;
}
}
} else {
// GetLastError() and error handling
}
delete [] pInputs;
} else {
// error handling, presumably out of memory
}
if (bHandled){
// if you don‘t want to pass to DefWindowProc, close the touch input handle
if (!CloseTouchInputHandle((HTOUCHINPUT)lParam)) {
// error handling
}
return 0;
}else{
return DefWindowProc(hWnd, WM_TOUCH, wParam, lParam);
}
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
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_TOUCH:
return OnTouch(hWnd, wParam, lParam);
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
if(m_fFactor != 1.0f)
{
// We represent our vectors as an array.
// x: vx[0], y: vx[1]
FLOAT v1[2];
v1[0] = this->get_CenterX() - fOffset[0];
v1[1] = this->get_CenterY() - fOffset[1];
FLOAT v2[2];
v2[0] = v1[0]
再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net
Windows Touch Input WM GESTURE WM TOUCH
标签:call sim 步骤 ogg i++ tps finger lob line
原文地址:https://www.cnblogs.com/sownchz/p/10500553.html