如何在C#中使用Windows 8的User32.dll的InjectTouchInput函数? [英] How to use InjectTouchInput function of User32.dll of Windows 8 in C#?
问题描述
我有以下代码,但不起作用。我认为这主要是因为我不知道如何在C#中正确编写以下结构。这一切都与托管和非托管互操作性有关。我不知道是使用Explicit选项还是Sequential。
值得注意的是,这是Windows 8的User32.dll中的新功能,它仍然处于测试阶段,文档将会更改。
I have the following code and it does not work. I think it is mainly because I do not know how to write the following structure in C# properly. It's all about managed and unmanaged interoperability. I do not know whether to use Explicit option or Sequential. It might be noteworthy that this is all new in User32.dll of Windows 8 and it is still under beta and the documentation is due to change.
这是结构我我想我可能在C#中被误解了...
This is the structure I think I might have misinterpreted in C#...
typedef struct tagPOINTER_INFO {
POINTER_INPUT_TYPE pointerType;
UINT32 pointerId;
UINT32 frameId;
HANDLE sourceDevice;
HWND hwndTarget;
POINT ptPixelLocation;
POINT ptHimetricLocation;
POINT ptPixelLocationPredicted;
POINT ptHimetricLocationPredicted;
POINTER_FLAGS pointerFlags;
DWORD dwTime;
UINT32 {
UINT32 inputData;
} historyCount;
DWORD dwKeyStates;
ULONGLONG Reserved;
} POINTER_INFO;
正如您在评论中看到的那样对InjectTouchInput的调用返回false,这意味着注入失败。我环顾四周,发现一个C ++示例正在做同样的事情,但我想在C#中做到这一点。即使我还没有得到C ++示例
来编译。它在Visual Studio 11下,当我打开它时,VS11说你需要安装.NET Framework 4,而且我已经安装了.NET Framework 4 !!!
As you can see in my comment the call to InjectTouchInput returns false which means the injection has failed. I have looked around and I have found a C++ sample that is doing the same thing but I wonna do it in C#. Even though I couldn't get the C++ sample to compile yet. It is under Visual Studio 11 and when I open it, VS11 says you need to install .NET Framework 4 and surprisingly I already have .NET Framework 4 installed !!!
任何想法都会是赞赏。来自Microsoft的C ++示例代码在此处:
Any thoughts would be appreciated. The C++ sample code from Microsoft is here:
http: //code.msdn.microsoft.com/windowsdesktop/Touch-Injection-Sample-444d9bf7
这是我的代码在C#中:
And this is my code in C#:
我正在使用C#和分配内存没有意义!但这就是我要做的事情:
I'm using C# and allocating memory doesn't make sense! But this is what I'm trying to do:
我正在尝试在Windows 8的win32.dll中使用新的InjectTouchInput函数来注入触摸输入。这是整个代码。 msdn中POINTER_INFO结构的文档看起来很糟糕。我希望我能在Windows.h文件中查看它,但我找不到
头文件!有什么想法吗?
I'm trying to use the new InjectTouchInput function in win32.dll of windows 8 to inject touch input. This is the whole code. The documentation in msdn for POINTER_INFO struct looks faulty. I wish I could look at it inside the Windows.h file but I can't find the header file!!! Any thoughts?
using System;
使用System.Collections.Generic;
使用System.ComponentModel;
使用System.Data;
使用System。绘图;
使用System.Linq;
使用System.Text;
使用System.Windows.Forms;
使用System.Runtime.InteropServices;
$
命名空间InjectingTouchInputs
{
  [StructLayout(LayoutKind.Explicit)]
$
  public struct Rect
  {
      [FieldOffset(0)]
      public int left;
      [FieldOffset(4)]
$
      public int top;
      [FieldOffset(8)]
$
      public int right;
      [FieldOffset(12)]
      public int bottom;
  }
  public enum TOUCH_FLAGS {TOUCH_FLAGS_NONE = 0x00000000 / *表示未设置任何标记。* /}
  public enum POINTER_FLAGS
  {
      POINTER_FLAG_NONE         = 0x00000000,
      POINTER_FLAG_NEW         = 0x00000001,
      POINTER_FLAG_INRANGE     = 0x00000002,
      POINTER_FLAG_INCONTACT   = 0x00000004,
      POINTER_FLAG_FIRSTBUTTON = 0x00000010,
      POINTER_FLAG_SECONDBUTTON = 0x00000020,
      POINTER_FLAG_THIRDBUTTON = 0x00000040,
      POINTER_FLAG_OTHERBUTTON = 0x00000080,
      POINTER_FLAG_PRIMARY     = 0x00000100,
      POINTER_FLAG_CONFIDENCE   = 0x00000200,
      POINTER_FLAG_CANCELLED   = 0x00000400,
      POINTER_FLAG_DOWN         = 0x00010000,
      POINTER_FLAG_UPDATE       = 0x00020000,
      POINTER_FLAG_UP           = 0x00040000,
      POINTER_FLAG_WHEEL       = 0x00080000,
      POINTER_FLAG_HWHEEL       = 0x00100000
  }
  [StructLayout(LayoutKind.Sequential)]
  public struct POINT
  {
    public int x;
    public int y;
  }
 公开枚举POINTER_INPUT_TYPE
  {
    PT_POINTER = 0x00000001,
    PT_TOUCH   = 0x00000002,
    PT_PEN     = 0x00000003,
    PT_MOUSE   = 0x00000004
  }
  [StructLayout(LayoutKind.Sequential)]
 公共结构POINTER_INFO
  {
      public POINTER_INPUT_TYPE pointerType;
      public uint pointerId;
      public uint frameId;
      public IntPtr sourceDevice;
      public IntPtr hwndTarget;
      public POINT ptPixelLocation;
      public POINT ptHimetricLocation;
      public POINT ptPixelLocationPredicted;
      public POINT ptHimetricLocationPredicted;
      public POINTER_FLAGS pointerFlags;
      public uint dwTime;
      public uint historyCount;
      public uint inputData;
      public uint dwKeyStates;
      public ulong保留;
  }
  [StructLayout(LayoutKind.Sequential)]
 公共结构POINTER_TOUCH_INFO
  {
      / *
      *包含所有指针类型共有的基本指针信息。
      * /
     公共POINTER_INFO指针信息;
      / *
      *列出触摸标志。
      * /
      public TOUCH_FLAGS touchFlags;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace InjectingTouchInputs
{
[StructLayout(LayoutKind.Explicit)]
public struct Rect
{
[FieldOffset(0)]
public int left;
[FieldOffset(4)]
public int top;
[FieldOffset(8)]
public int right;
[FieldOffset(12)]
public int bottom;
}
public enum TOUCH_FLAGS { TOUCH_FLAGS_NONE = 0x00000000/*Indicates that no flags are set.*/ }
public enum POINTER_FLAGS
{
POINTER_FLAG_NONE = 0x00000000,
POINTER_FLAG_NEW = 0x00000001,
POINTER_FLAG_INRANGE = 0x00000002,
POINTER_FLAG_INCONTACT = 0x00000004,
POINTER_FLAG_FIRSTBUTTON = 0x00000010,
POINTER_FLAG_SECONDBUTTON = 0x00000020,
POINTER_FLAG_THIRDBUTTON = 0x00000040,
POINTER_FLAG_OTHERBUTTON = 0x00000080,
POINTER_FLAG_PRIMARY = 0x00000100,
POINTER_FLAG_CONFIDENCE = 0x00000200,
POINTER_FLAG_CANCELLED = 0x00000400,
POINTER_FLAG_DOWN = 0x00010000,
POINTER_FLAG_UPDATE = 0x00020000,
POINTER_FLAG_UP = 0x00040000,
POINTER_FLAG_WHEEL = 0x00080000,
POINTER_FLAG_HWHEEL = 0x00100000
}
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int x;
public int y;
}
public enum POINTER_INPUT_TYPE
{
PT_POINTER = 0x00000001,
PT_TOUCH = 0x00000002,
PT_PEN = 0x00000003,
PT_MOUSE = 0x00000004
};
[StructLayout(LayoutKind.Sequential)]
public struct POINTER_INFO
{
public POINTER_INPUT_TYPE pointerType;
public uint pointerId;
public uint frameId;
public IntPtr sourceDevice;
public IntPtr hwndTarget;
public POINT ptPixelLocation;
public POINT ptHimetricLocation;
public POINT ptPixelLocationPredicted;
public POINT ptHimetricLocationPredicted;
public POINTER_FLAGS pointerFlags;
public uint dwTime;
public uint historyCount;
public uint inputData;
public uint dwKeyStates;
public ulong Reserved;
}
[StructLayout(LayoutKind.Sequential)]
public struct POINTER_TOUCH_INFO
{
/*
* Contains basic pointer information common to all pointer types.
*/
public POINTER_INFO pointerInfo;
/*
* Lists the touch flags.
*/
public TOUCH_FLAGS touchFlags;
public
uint touchMasks;
public uint touchMasks;
/ *
*像素屏幕坐标中的指针联系区域。
*默认情况下,如果设备未报告联系区域,则
*此字段默认为以指针位置为中心的0 x 0矩形。
* /
public Rect rcContact;
/ *
*指针方向,值介于0和359之间,其中0表示触摸指针 *与x轴对齐并从左向右指向;增加的值表示度数为¥b $ b *顺时针方向的旋转。
*此字段默认为0 i f设备未报告方向。
      * /
      public uint orientation;
$
      / *
      *指针压力标准化范围为0到256.
      * /
     公共压力;
  }
 公共部门类Form1:表格
  {
      const int MAX_TOUCH_COUNT = 256;
$
      //指定默认触摸可视化。
      const int TOUCH_FEEDBACK_DEFAULT = 0x1;
$
      //指定间接触摸可视化。
      const int TOUCH_FEEDBACK_INDIRECT = 0x2;
      //指定无触摸可视化。
      const int TOUCH_FEEDBACK_NONE = 0x3;
$
      [DllImport(" User32.dll")]
$
      static extern bool InitializeTouchInjection(uint maxCount,int dwMode);
      [DllImport(" User32.dll")]
$
      static extern bool InjectTouchInput(int count,ref POINTER_TOUCH_INFO contacts);
      public Form1()
      {
          InitializeComponent();
      }
$
$
      private void button1_Click(object sender,EventArgs e)
      {
          bool flag = false;
          flag = InitializeTouchInjection(10,TOUCH_FEEDBACK_NONE);
$
$
          POINTER_TOUCH_INFO联系人=新POINTER_TOUCH_INFO();
          Rect touchArea = new Rect();
          touchArea.left = 200 - 2;
          touchArea.right = 200 + 2;
          touchArea.top = 200 + 2;
          touchArea.bottom = 200 - 2;
$
          contacts.pointerInfo.pointerType = POINTER_INPUT_TYPE.PT_TOUCH;
          contacts.touchFlags = TOUCH_FLAGS.TOUCH_FLAGS_NONE;
          contacts.rcContact = touchArea;
          contacts.orientation = 90;
          contacts.pressure = 32000;
          contacts.pointerInfo.pointerFlags = POINTER_FLAGS.POINTER_FLAG_UP | POINTER_FLAGS.POINTER_FLAG_INRANGE | POINTER_FLAGS.POINTER_FLAG_INCONTACT;
          contacts.pointerInfo.ptPixelLocation.x = 200;
          contacts.pointerInfo.ptPixelLocation.y = 200;
          contacts.pointerInfo.pointerId = 1;
$
          flag = InjectTouchInput(1,ref contacts); //返回标志为false表示注入失败!
          contacts.pressure = 0;
/*
* Pointer contact area in pixel screen coordinates.
* By default, if the device does not report a contact area,
* this field defaults to a 0-by-0 rectangle centered around the pointer location.
*/
public Rect rcContact;
/*
* A pointer orientation, with a value between 0 and 359, where 0 indicates a touch pointer
* aligned with the x-axis and pointing from left to right; increasing values indicate degrees
* of rotation in the clockwise direction.
* This field defaults to 0 if the device does not report orientation.
*/
public uint orientation;
/*
* Pointer pressure normalized in a range of 0 to 256.
*/
public uint pressure;
}
public partial class Form1 : Form
{
const int MAX_TOUCH_COUNT = 256;
//Specifies default touch visualizations.
const int TOUCH_FEEDBACK_DEFAULT = 0x1;
//Specifies indirect touch visualizations.
const int TOUCH_FEEDBACK_INDIRECT = 0x2;
//Specifies no touch visualizations.
const int TOUCH_FEEDBACK_NONE = 0x3;
[DllImport("User32.dll")]
static extern bool InitializeTouchInjection(uint maxCount, int dwMode);
[DllImport("User32.dll")]
static extern bool InjectTouchInput(int count, ref POINTER_TOUCH_INFO contacts);
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
bool flag = false;
flag = InitializeTouchInjection(10, TOUCH_FEEDBACK_NONE);
POINTER_TOUCH_INFO contacts = new POINTER_TOUCH_INFO();
Rect touchArea = new Rect();
touchArea.left = 200 - 2;
touchArea.right = 200 + 2;
touchArea.top = 200 + 2;
touchArea.bottom = 200 - 2;
contacts.pointerInfo.pointerType = POINTER_INPUT_TYPE.PT_TOUCH;
contacts.touchFlags = TOUCH_FLAGS.TOUCH_FLAGS_NONE;
contacts.rcContact = touchArea;
contacts.orientation = 90;
contacts.pressure = 32000;
contacts.pointerInfo.pointerFlags = POINTER_FLAGS.POINTER_FLAG_UP | POINTER_FLAGS.POINTER_FLAG_INRANGE | POINTER_FLAGS.POINTER_FLAG_INCONTACT;
contacts.pointerInfo.ptPixelLocation.x = 200;
contacts.pointerInfo.ptPixelLocation.y = 200;
contacts.pointerInfo.pointerId = 1;
flag = InjectTouchInput(1, ref contacts);//returned flag is false which means the injection fails!
contacts.pressure = 0;
          if(flag)
          {
              contacts.pointerInfo.pointerFlags = POINTER_FLAGS.POINTER_FLAG_UP;
              InjectTouchInput(1,参考联系人);
          }
      }¥b $ b   } b $ b}
if (flag)
{
contacts.pointerInfo.pointerFlags = POINTER_FLAGS.POINTER_FLAG_UP;
InjectTouchInput(1, ref contacts);
}
}
}
}
推荐答案
我试过几乎一样的节目同样没有乐趣。如果有人对这个问题有答案,我会很高兴收到你的来信。对于我来说,使用Windows 8是一个真正的必需品。
I tried an almost identical program with equally no joy. If anyone has an answer to this issue I'd be thrilled to hear from you. Getting this to work with windows 8 is a real necessity for me atm.
我得到了Initialize以返回true,它的注入返回是的,但我不知道如何调试它,或者上面的内容是完全正确的。我几乎是一样的,只有一些语义差异。我想知道是否有可能在c ++程序中完成这项工作的大部分
并从c#dll import中访问它。我不太了解c ++,所以我不知道可能性
I got the Initialize to return true, its the inject thats returning false but I have no idea how to debug it, or wether the above in its entirety is correct. Mine is virtually the same with a few semantic differences. I wonder if its possible to do most of this work in a c++ program and access that from a c# dll import. I don't know c++ very well so I don't know the possibilities
Windows.h的内部代码是这样的,但我觉得它没有帮助
The internal code for Windows.h is this but I don't think it helps
#include <winapifamily.h>
/*++ BUILD Version: 0001 Increment this if a change has global effects
Copyright (c) Microsoft Corporation. All rights reserved.
Module Name:
windows.h
Abstract:
Master include file for Windows applications.
--*/
#ifndef _WINDOWS_
#define _WINDOWS_
#if defined(_SAL_VERSION_CHECK) && !defined(_SAL2_STRICT)
#undef _SAL_VERSION_CHECK
#define _WINDOWS_H_SAL2
#define _SAL2_STRICT
#define _SAL_VERSION_CHECK(_A) _SAL_VERSION_SAL2(_A)
#endif
#include <sdkddkver.h>
#ifndef _INC_WINDOWS
#define _INC_WINDOWS
#if defined (_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif
#pragma region Application Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
/* If defined, the following flags inhibit definition
* of the indicated items.
*
* NOGDICAPMASKS - CC_*, LC_*, PC_*, CP_*, TC_*, RC_
* NOVIRTUALKEYCODES - VK_*
* NOWINMESSAGES - WM_*, EM_*, LB_*, CB_*
* NOWINSTYLES - WS_*, CS_*, ES_*, LBS_*, SBS_*, CBS_*
* NOSYSMETRICS - SM_*
* NOMENUS - MF_*
* NOICONS - IDI_*
* NOKEYSTATES - MK_*
* NOSYSCOMMANDS - SC_*
* NORASTEROPS - Binary and Tertiary raster ops
* NOSHOWWINDOW - SW_*
* OEMRESOURCE - OEM Resource values
* NOATOM - Atom Manager routines
* NOCLIPBOARD - Clipboard routines
* NOCOLOR - Screen colors
* NOCTLMGR - Control and Dialog routines
* NODRAWTEXT - DrawText() and DT_*
* NOGDI - All GDI defines and routines
* NOKERNEL - All KERNEL defines and routines
* NOUSER - All USER defines and routines
* NONLS - All NLS defines and routines
* NOMB - MB_* and MessageBox()
* NOMEMMGR - GMEM_*, LMEM_*, GHND, LHND, associated routines
* NOMETAFILE - typedef METAFILEPICT
* NOMINMAX - Macros min(a,b) and max(a,b)
* NOMSG - typedef MSG and associated routines
* NOOPENFILE - OpenFile(), OemToAnsi, AnsiToOem, and OF_*
* NOSCROLL - SB_* and scrolling routines
* NOSERVICE - All Service Controller routines, SERVICE_ equates, etc.
* NOSOUND - Sound driver routines
* NOTEXTMETRIC - typedef TEXTMETRIC and associated routines
* NOWH - SetWindowsHook and WH_*
* NOWINOFFSETS - GWL_*, GCL_*, associated routines
* NOCOMM - COMM driver routines
* NOKANJI - Kanji support stuff.
* NOHELP - Help engine interface.
* NOPROFILER - Profiler interface.
* NODEFERWINDOWPOS - DeferWindowPos routines
* NOMCX - Modem Configuration Extensions
*/
#if defined(RC_INVOKED) && !defined(NOWINRES)
#include <winresrc.h>
#else
#if defined(RC_INVOKED)
/* Turn off a bunch of stuff to ensure that RC files compile OK. */
#define NOATOM
#define NOGDI
#define NOGDICAPMASKS
#define NOMETAFILE
#define NOMINMAX
#define NOMSG
#define NOOPENFILE
#define NORASTEROPS
#define NOSCROLL
#define NOSOUND
#define NOSYSMETRICS
#define NOTEXTMETRIC
#define NOWH
#define NOCOMM
#define NOKANJI
#define NOCRYPT
#define NOMCX
#endif
#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && !defined(_ARM_) && defined(_M_IX86)
#define _X86_
#endif
#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && !defined(_ARM_) && defined(_M_AMD64)
#define _AMD64_
#endif
#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && !defined(_ARM_) && defined(_M_ARM)
#define _ARM_
#endif
#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && !defined(_ARM_) && defined(_M_M68K)
#define _68K_
#endif
#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && !defined(_ARM_) && defined(_M_MPPC)
#define _MPPC_
#endif
#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_M_IX86) && !defined(_AMD64_) && !defined(_ARM_) && defined(_M_IA64)
#if !defined(_IA64_)
#define _IA64_
#endif /* !_IA64_ */
#endif
#ifndef _MAC
#if defined(_68K_) || defined(_MPPC_)
#define _MAC
#endif
#endif
#if defined (_MSC_VER)
#if ( _MSC_VER >= 800 )
#ifndef __cplusplus
#pragma warning(disable:4116) /* TYPE_ALIGNMENT generates this - move it */
/* outside the warning push/pop scope. */
#endif
#endif
#endif
#ifndef RC_INVOKED
#if ( _MSC_VER >= 800 )
#pragma warning(disable:4514)
#ifndef __WINDOWS_DONT_DISABLE_PRAGMA_PACK_WARNING__
#pragma warning(disable:4103)
#endif
#if _MSC_VER >= 1200
#pragma warning(push)
#endif
#pragma warning(disable:4001)
#pragma warning(disable:4201)
#pragma warning(disable:4214)
#endif
#include <excpt.h>
#include <stdarg.h>
#endif /* RC_INVOKED */
#include <windef.h>
#include <winbase.h>
#include <wingdi.h>
#include <winuser.h>
#if !defined(_MAC) || defined(_WIN32NLS)
#include <winnls.h>
#endif
#ifndef _MAC
#include <wincon.h>
#include <winver.h>
#endif
#if !defined(_MAC) || defined(_WIN32REG)
#include <winreg.h>
#endif
#ifndef _MAC
#include <winnetwk.h>
#endif
#ifndef WIN32_LEAN_AND_MEAN
#include <cderr.h>
#include <dde.h>
#include <ddeml.h>
#include <dlgs.h>
#ifndef _MAC
#include <lzexpand.h>
#include <mmsystem.h>
#include <nb30.h>
#include <rpc.h>
#endif
#include <shellapi.h>
#ifndef _MAC
#include <winperf.h>
#include <winsock.h>
#endif
#ifndef NOCRYPT
#include <wincrypt.h>
#include <winefs.h>
#include <winscard.h>
#endif
#ifndef NOGDI
#ifndef _MAC
#include <winspool.h>
#ifdef INC_OLE1
#include <ole.h>
#else
#include <ole2.h>
#endif /* !INC_OLE1 */
#endif /* !MAC */
#include <commdlg.h>
#endif /* !NOGDI */
#endif /* WIN32_LEAN_AND_MEAN */
#include <stralign.h>
#ifdef _MAC
#include <winwlm.h>
#endif
#ifdef INC_OLE2
#include <ole2.h>
#endif /* INC_OLE2 */
#ifndef _MAC
#ifndef NOSERVICE
#include <winsvc.h>
#endif
#if(WINVER >= 0x0400)
#ifndef NOMCX
#include <mcx.h>
#endif /* NOMCX */
#ifndef NOIME
#include <imm.h>
#endif
#endif /* WINVER >= 0x0400 */
#endif
#ifndef RC_INVOKED
#if ( _MSC_VER >= 800 )
#if _MSC_VER >= 1200
#pragma warning(pop)
#else
#pragma warning(default:4001)
#pragma warning(default:4201)
#pragma warning(default:4214)
/* Leave 4514 disabled. It's an unneeded warning anyway. */
#endif
#endif
#endif /* RC_INVOKED */
#endif /* RC_INVOKED */
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) */
#pragma endregion
#endif /* _INC_WINDOWS */
#if defined(_WINDOWS_H_SAL2)
#undef _SAL2_STRICT
#undef _WINDOWS_H_SAL2
#undef _SAL_VERSION_CHECK
#define _SAL_VERSION_CHECK(_A)
#endif
#endif /* _WINDOWS_ */
这篇关于如何在C#中使用Windows 8的User32.dll的InjectTouchInput函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!