有没有一种合理的方法在Windows上获取平板电脑/笔的压感信息?
使用::GetMessageExtraInfo可以区分鼠标和触控笔,但是您无法获得更多信息。我还在Wacom网站的角落找到了WinTab API,但据我所知,它不是Windows的一部分,并且具有完全独立于消息队列的事件/消息系统。
考虑到我只需要最基本的压力信息,肯定有一个标准的Win32 / COM API,是否有人知道它是什么?
有没有一种合理的方法在Windows上获取平板电脑/笔的压感信息?
使用::GetMessageExtraInfo可以区分鼠标和触控笔,但是您无法获得更多信息。我还在Wacom网站的角落找到了WinTab API,但据我所知,它不是Windows的一部分,并且具有完全独立于消息队列的事件/消息系统。
考虑到我只需要最基本的压力信息,肯定有一个标准的Win32 / COM API,是否有人知道它是什么?
目前的做法是处理WM_POINTERnnn消息。请注意,这适用于Windows 8及以上版本。
请注意,您将收到触摸和笔的消息,因此您需要知道指针类型才能测试笔。 WNDPROC接收到的WPARAM WM_POINTERnnnn消息(例如WM_POINTERUPDATE和其他消息)包含指针ID,您需要该ID以请求更多信息。根据经验,如果指针标志指示按下/抬起,则没有压力信息,而WM_POINTERUPDATE会产生包含压力数据的信息。
const WORD wid = GET_POINTERID_WPARAM(wParam);
POINTER_INFO piTemp = {NULL};
GetPointerInfo(wid, &piTemp);
if (piTemp.pointerType == PT_PEN
{
UINT32 entries = 0;
UINT32 pointers = 0;
GetPointerFramePenInfoHistory(wid, &entries, &pointers, NULL); // how many
// TODO, allocate space needed for the info, process the data in a loop to retrieve it, test pointerInfo.pointerFlags for down/up/update.
}
更新:
我最初提供这个答案已经有好几年了,但现在wintab已经成为事实上的标准,Ntrig公司也基本上倒闭了,最终建立了一个包装器来允许通过这个数位板访问wintab API。
(http://www.tabletpcbuzz.com/showthread.php?37547-N-trig-Posts-WinTAB-Support-Driver)
虽然这是一个相当晚的答复,但最近我和我的妻子购买了一台戴尔XT平板电脑,事实证明它实际上使用的是NTrig,一套接口套件,利用Ink作为Windows XP平板电脑版,然后SP 2以及之后的所有版本已经安装的新Windows API。
许多Wacom数位板和其他设备使用wintab API,该API目前并不开放,也不允许使用。据我所知,维护此API的人非常喜欢起诉别人。
所以这取决于您使用的平板电脑类型以及安装的驱动程序。在我有偏见的看法中,您应该使用Ink,因为它提供了(或者至少通过NTrig和Windows 7将提供)多点触控功能,并且可能成为平板电脑接口的新标准。但是,到目前为止,NTrig设备不能将压力和角度信息转换为常见的基于wintab的应用程序,例如Photoshop或Corel Painter。这些应用程序往往需要至少支持Microsoft的Tablet API才能正常运行。
如果使用 UWP Windows Runtime,那么很简单。PointerEventArgs 事件似乎具有所有必要的数据。
来自 Visual Studio 2019 的修改 Core App (C++/WinRT) 模板项目片段:
void OnPointerMoved(IInspectable const &, PointerEventArgs const &args)
{
if (m_selected)
{
float2 const point = args.CurrentPoint().Position();
m_selected.Offset(
{
point.x + m_offset.x,
point.y + m_offset.y,
0.0f
});
// (new!) Change sprite color based on pen pressure and tilt
auto sprite = m_selected.as<SpriteVisual>();
auto const props = args.CurrentPoint().Properties();
auto const pressure = props.Pressure();
auto const orientation = props.Orientation() / 360.0f;
auto const tiltx = (props.XTilt() + 90) / 180.0f;
auto const tilty = (props.YTilt() + 90) / 180.0f;
Compositor compositor = m_visuals.Compositor();
sprite.Brush(compositor.CreateColorBrush({
(uint8_t)(pressure * 0xFF),
(uint8_t)(tiltx * 0xFF),
(uint8_t)(tilty * 0xFF),
(uint8_t)(orientation * 0xFF)
}));
}
}
类似的代码可能在C#,JavaScript等中也能工作。