你如何检索Windows上的手写笔压力信息?

时间:2009-01-03 06:31:46

标签: winapi tablet stylus-pen

有人知道在Windows上获得平板电脑/手写笔压力信息的明智方法吗?

可以使用:: GetMessageExtraInfo来区分手写笔和鼠标,但除此之外您无法获得更多信息。我还在Wacom网站的一个角落找到了WinTab API,但据我所知,这不是Windows的一部分,并且在消息队列中有一个完全不同的事件/消息系统。

鉴于我想要的是最基本的压力信息肯定有一个标准的Win32 / COM API,是否有人知道它可能是什么?

4 个答案:

答案 0 :(得分:2)

您需要使用Tablet PC笔/墨水API。 API的COM版本位于InkObj.dll中。以下是文档的起点:http://msdn.microsoft.com/en-us/library/ms700664.aspx

如果我没记错的话,无论机器是否是平板电脑,InkObj.dll都可以在Windows XP SP2和所有后来的Windows客户端操作系统上使用。

答案 1 :(得分:2)

<强>更新
自从我最初提供这个答案以来已经有好几年了,但是wintab已经成为事实上的标准,并且Ntrig或多或少地折叠了,最终构建了一个包装器,允许通过这个数字转换器访问wintab API。登记/> (http://www.tabletpcbuzz.com/showthread.php?37547-N-trig-Posts-WinTAB-Support-Driver

这是一个相当晚的回应,但最近我的妻子和我购买了戴尔XT平板电脑,事实证明它实际上使用了NTrig,一套利用墨水的接口,这是Windows XP附带的新Windows API平板电脑版,然后SP 2及其后的所有版本。

许多Wacom平板电脑和其他平板电脑使用的Wintab API目前尚未开放,也未真正允许使用。从我听到的那些维护它的人们非常高兴。

因此,这取决于您使用的平板电脑类型以及为其安装的驱动程序。在我的偏见中,你应该使用Ink,因为它提供(或至少通过NTrig和Windows 7将提供)多点触控功能,并且可能是平板电脑界面的新标准。但截至目前,NTrig设备不会将其压力和角度信息转换为常见的基于Wintab的应用程序,如Photoshop或Corel Painter。这些应用程序往往需要至少一些支持Microsoft的Tablet API才能正常运行。

答案 2 :(得分:2)

目前的做法是处理WM_POINTERnnn消息。 请注意,这适用于Win 8及更高版本。

请注意,您将获得触摸AND笔的这些消息,因此您需要知道pointerType才能测试笔。 WPGAM由WNDPROC收到WM_POINTERnnnn msgs这样的WM_POINTERUPDATE和其他消息包含指针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.

}

一旦您知道自己正在处理笔,就可以从POINTER_PEN_INFO结构中获取压力信息。

这与处理触摸类似,但触摸时您需要手势识别和惯性。有一个Microsoft示例说明了使用这些函数。

它是Build演讲的一部分: https://channel9.msdn.com/Events/Build/2013/4-022

答案 3 :(得分:0)

如果使用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等中运行。