3

Мне нужно разработать приложение C#, которое должно использовать расширенные жесты, чтобы улучшить работу пользователя. Для этого мне нужно получить информацию , когда пользовательский вызов вызывается определенным жестом.C# .NET Embedded Compact 2013 - Как вызвать GetGestureInfo?

Поскольку WndProc является табу в .NET CE, я использую классы OpenNETCE Application2 и IMessageFilter для получения WM-трафика.

В моем MessageFilter я ищу сообщения WM_GESTURE, и вот где Я застрял.

Я просто не получить какой-либо значимый результат, вызвав эту функцию:

https://msdn.microsoft.com/en-us/library/ee503217.aspx

BOOL GetGestureInfo(
     HGESTUREINFO hGestureInfo 
     PGESTUREINFO pGestureInfo 
); 

Вот соответствующий код:

public class TestMessageFilter : IMessageFilter 
{ 
    [DllImport("coredll", SetLastError = true)] 
    public static extern bool GetGestureInfo(IntPtr hGesture, ref GESTUREINFO lGesture); 

    public static uint WM_GESTURE = 0x0119; 

    public bool PreFilterMessage(ref Microsoft.WindowsCE.Forms.Message m) 
    { 
     // ... 
     if (m.Msg == WM_GESTURE) 
     { 
      GESTUREINFO gi = new GESTUREINFO() { 
       cbSize = (uint)Marshal.SizeOf(typeof(GESTUREINFO)) 
      }; 

      bool success = GetGestureInfo(m.LParam, ref gi); 
      if (success) 
      { 
       // ... 
      } 
      else 
      { 
       int x = Marshal.GetLastWin32Error(); // => 87 
      } 
     } 

     // ... 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    public struct POINTS 
    { 
     public short x; 
     public short y; 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    public struct GESTUREINFO 
    { 
     public UInt32 cbSize; 
     public UInt32 dwFlags; 
     public UInt32 dwID; 
     public IntPtr hwndTarget; 
     public POINTS ptsLocation; 
     public UInt32 dwInstanceID; 
     public UInt32 dwSequenceID; 
     public UInt64 ullArguments; 
     public UInt32 cbExtraArguments; 
    } 
} 

Он всегда дает мне код ошибки 87.

ERROR_INVALID_PARAMETER 

Почему это не работает? Что недействительно? Это сводит меня с ума ...

Многие, большое спасибо заранее.

Редактировать: Я нашел этот пост on the msdn forums, который использует IntPtr вместо ссылку на GestureInfo как второй параметр.

[DllImport("coredll.dll")] 
static extern int GetGestureInfo(IntPtr hGestureInfo, [In, Out] IntPtr pGestureInfo); 
// ... 
GESTUREINFO gi = new GESTUREINFO(); 
gi.cbSize = 48; 

IntPtr outGI = Marshal.AllocHGlobal(48); 
Marshal.StructureToPtr(gi, outGI, false); 

bool bResult = (GetGestureInfo(lParam, outGI) == 1); 
bool bHandled = false; 
Marshal.FreeHGlobal(outGI); 
Marshal.PtrToStructure(outGI, gi); 
// ... 

Но для меня это ошибка ERROR_INVALID_PARAMETER.

Неужели никто не имеет решения или другого подхода для получения GestureInfo с C#?

ответ

1

У меня есть опыт работы с Windows Embedded Compact 7, но он не должен сильно отличаться от 2013 года - вы сначала включили жесты?(Вы, вероятно, сделал так вы получаете WM_GESTURE, но вот код в любом случае):

[DllImport(User32Library)] 
public static extern bool EnableGestures(IntPtr hWnd, GestureMask flags, uint scope); 

[Flags] 
public enum GestureMask : ulong 
{ 
    TGF_GID_PAN = 0x10, 
    TGF_GID_SCROLL = 0x100, 
    TGF_GID_HOLD = 0x200, 
    TGF_GID_SELECT = 0x400, 
    TGF_GID_DOUBLESELECT = 0x800, 
    TGF_GID_DIRECTMANIPULATION = 0x1000, 
    TGF_GID_ALL = TGF_GID_PAN | TGF_GID_SCROLL | TGF_GID_HOLD | TGF_GID_SELECT | TGF_GID_DOUBLESELECT,// | TGF_GID_DIRECTMANIPULATION, 
} 

Я решил скопировать вставить наш рабочий пример; не помню, был ли TGF_GID_DIRECTMANIPULATION исключены из TGF_GID_ALL только для нашего удобства или потому, что у нас были проблемы с этим, извините

bool enabled = EnableGestures(Handle, Native.GestureMask.TGF_GID_ALL, 0); 

Следующая сигнатура GetGestureInfo работает для наших устройств:

[DllImport("coredll.dll")] 
public static extern bool GetGestureInfo(IntPtr hGestureInfo, ref GestureInfo pGestureInfo); 

С Структуры GestureInfo:

[StructLayout(LayoutKind.Sequential)] 
public struct GestureInfo 
{ 
    /// <summary> 
    /// Specifies the size of the structure in bytes. This must be set to Marshal.SizeOf(typeof(GESTUREINFO)) 
    /// </summary> 
    public uint Size; 
    /// <summary> 
    /// Gesture Flags 
    /// </summary> 
    public GestureState State; 
    /// <summary> 
    /// Gesture Id 
    /// </summary> 
    public GestureKind Kind; 
    /// <summary> 
    /// HWND of the target winndow 
    /// </summary> 
    public IntPtr TargetWindow; 
    /// <summary> 
    /// Coordinates of start of gesture 
    /// </summary> 
    public short LocationX; 
    /// <summary> 
    /// Coordinates of start of gesture 
    /// </summary> 
    public short LocationY; 
    /// <summary> 
    /// Gesture Instance Id 
    /// </summary> 
    public uint InstanceId; 
    /// <summary> 
    /// Gesture Sequence Id 
    /// </summary> 
    public uint SequenceId; 
    /// <summary> 
    /// Arguments specific to gesture 
    /// </summary> 
    public ulong Arguments; 
    /// <summary> 
    /// Size of extra arguments in bytes 
    /// </summary> 
    public uint ExtraArguments; 
} 

GestureState:

[Flags] 
public enum GestureState : uint 
{ 
    /// <summary> 
    /// The gesture has no associated state 
    /// </summary> 
    None = 0, 
    /// <summary> 
    /// The gesture is the beginning of pan gesture 
    /// </summary> 
    Begin = 1, 
    /// <summary> 
    /// The gesture is the end of a pan gesture that will transition into a scroll gesture 
    /// </summary> 
    Inertia = 2, 
    /// <summary> 
    /// The gesture is the end of a pan gesture 
    /// </summary> 
    End = 4 
} 

и GestureKind:

/// <summary> 
/// The kind of gesture. 
/// </summary> 
public enum GestureKind : uint 
{ 
    /// <summary> 
    /// The beginning of a gesture operation. 
    /// </summary> 
    Begin = 1, 
    /// <summary> 
    /// The end of a gesture operation. 
    /// </summary> 
    End = 2, 
    /// <summary> 
    /// A pan gesture. 
    /// </summary> 
    Pan = 4, 
    /// <summary> 
    /// A scroll gesture. 
    /// </summary> 
    Scroll = 8, 
    /// <summary> 
    /// A hold gesture. 
    /// </summary> 
    Hold = 9, 
    /// <summary> 
    /// A select gesture. 
    /// </summary> 
    Select = 10, 
    /// <summary> 
    /// A double-select gesture. 
    /// </summary> 
    DoubleSelect = 11, 
    /// <summary> 
    /// Direct manipulation. 
    /// </summary> 
    DirectManipulation = 12, 
} 

код для вызова метода:

GestureInfo gesture = new GestureInfo(); 
gesture.Size = (uint)Marshal.SizeOf(typeof(GestureInfo)); 
bool result = GetGestureInfo(lParam, ref gesture); 

Я не вижу большой разницы между этим и вашей первой попытки; и единственное, что выделяется в примере MSDN, - это жесткий код размером 48 (вероятно, предназначенный для чтения любых дополнительных атрибутов).

Мы сделали, чтобы выбрать пользовательскую процедуру окна - но я не понимаю, почему это различие имеет значение.