使用实时触笔的 Windows Touch 便笺簿示例 (MTScratchpadRTStylus)
Windows Touch 便笺簿示例演示如何使用 Windows Touch 消息在窗口上绘制触控点的踪迹。主手指(最先放置到数字化器上的手指)的踪迹是用黑色绘制的。辅助手指的踪迹用其他六种颜色绘制:红色、绿色、蓝色、蓝绿色、洋红色和黄色。下图演示了应用程序在运行时的可能外观。
在此示例中,将创建实时触笔 (RTS) 对象,并启用对多个触控点的支持。将 DynamicRenderer 插件添加到 RTS 以呈现内容。实现 CSyncEventHandlerRTS 插件以跟踪手指的数量,并更改动态呈现器正在绘制的颜色。通过 RTS 插件堆栈中的两个插件,Windows Touch 便笺簿应用程序将主触控点呈现为黑色,而将其余触控点呈现为各种颜色。
以下代码演示如何创建 RTS 对象并支持多个触控点。
IRealTimeStylus* CreateRealTimeStylus(HWND hWnd) { // Check input argument if (hWnd == NULL) { ASSERT(hWnd && L"CreateRealTimeStylus: invalid argument hWnd"); return NULL; } // Create RTS object IRealTimeStylus* pRealTimeStylus = NULL; HRESULT hr = CoCreateInstance(CLSID_RealTimeStylus, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pRealTimeStylus)); if (FAILED(hr)) { ASSERT(SUCCEEDED(hr) && L"CreateRealTimeStylus: failed to CoCreateInstance of RealTimeStylus"); return NULL; } // Attach RTS object to a window hr = pRealTimeStylus->put_HWND((HANDLE_PTR)hWnd); if (FAILED(hr)) { ASSERT(SUCCEEDED(hr) && L"CreateRealTimeStylus: failed to set window handle"); pRealTimeStylus->Release(); return NULL; } // Register RTS object for receiving multi-touch input. IRealTimeStylus3* pRealTimeStylus3 = NULL; hr = pRealTimeStylus->QueryInterface(&pRealTimeStylus3); if (FAILED(hr)) { ASSERT(SUCCEEDED(hr) && L"CreateRealTimeStylus: cannot access IRealTimeStylus3"); pRealTimeStylus->Release(); return NULL; } hr = pRealTimeStylus3->put_MultiTouchEnabled(TRUE); if (FAILED(hr)) { ASSERT(SUCCEEDED(hr) && L"CreateRealTimeStylus: failed to enable multi-touch"); pRealTimeStylus->Release(); pRealTimeStylus3->Release(); return NULL; } pRealTimeStylus3->Release(); return pRealTimeStylus; }
以下代码演示如何创建动态呈现器插件并将其添加到 RTS。
IDynamicRenderer* CreateDynamicRenderer(IRealTimeStylus* pRealTimeStylus) { // Check input argument if (pRealTimeStylus == NULL) { ASSERT(pRealTimeStylus && L"CreateDynamicRenderer: invalid argument RealTimeStylus"); return NULL; } // Get window handle from RTS object HWND hWnd = NULL; HRESULT hr = pRealTimeStylus->get_HWND((HANDLE_PTR*)&hWnd); if (FAILED(hr)) { ASSERT(SUCCEEDED(hr) && L"CreateDynamicRenderer: failed to get window handle"); return NULL; } // Create DynamicRenderer object IDynamicRenderer* pDynamicRenderer = NULL; hr = CoCreateInstance(CLSID_DynamicRenderer, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pDynamicRenderer)); if (FAILED(hr)) { ASSERT(SUCCEEDED(hr) && L"CreateDynamicRenderer: failed to CoCreateInstance of DynamicRenderer"); return NULL; } // Add DynamicRenderer to the RTS object as a synchronous plugin IStylusSyncPlugin* pSyncDynamicRenderer = NULL; hr = pDynamicRenderer->QueryInterface(&pSyncDynamicRenderer); if (FAILED(hr)) { ASSERT(SUCCEEDED(hr) && L"CreateDynamicRenderer: failed to access IStylusSyncPlugin of DynamicRenderer"); pDynamicRenderer->Release(); return NULL; } hr = pRealTimeStylus->AddStylusSyncPlugin( 0, // insert plugin at position 0 in the sync plugin list pSyncDynamicRenderer); // plugin to be inserted - DynamicRenderer if (FAILED(hr)) { ASSERT(SUCCEEDED(hr) && L"CreateDynamicRenderer: failed to add DynamicRenderer to the RealTimeStylus plugins"); pDynamicRenderer->Release(); pSyncDynamicRenderer->Release(); return NULL; } // Attach DynamicRenderer to the same window RTS object is attached to hr = pDynamicRenderer->put_HWND((HANDLE_PTR)hWnd); if (FAILED(hr)) { ASSERT(SUCCEEDED(hr) && L"CreateDynamicRenderer: failed to set window handle"); pDynamicRenderer->Release(); pSyncDynamicRenderer->Release(); return NULL; } pSyncDynamicRenderer->Release(); return pDynamicRenderer; }
以下代码更改自定义 RTS 插件 CSyncEventHandlerRTS 中的 StylusDown 事件处理程序的触笔笔画颜色。
HRESULT CSyncEventHandlerRTS::StylusDown( IRealTimeStylus* /* piRtsSrc */, const StylusInfo* /* pStylusInfo */, ULONG /* cPropCountPerPkt */, LONG* /* pPacket */, LONG** /* ppInOutPkt */) { // Get DrawingAttributes of DynamicRenderer IInkDrawingAttributes* pDrawingAttributesDynamicRenderer; HRESULT hr = g_pDynamicRenderer->get_DrawingAttributes(&pDrawingAttributesDynamicRenderer); if (FAILED(hr)) { ASSERT(SUCCEEDED(hr) && L"CSyncEventHandlerRTS::StylusDown: failed to get RTS's drawing attributes"); return hr; } // Set new stroke color to the DrawingAttributes of the DynamicRenderer // If there are no fingers down, this is a primary contact hr = pDrawingAttributesDynamicRenderer->put_Color(GetTouchColor(m_nContacts == 0)); if (FAILED(hr)) { ASSERT(SUCCEEDED(hr) && L"CSyncEventHandlerRTS::StylusDown: failed to set color"); pDrawingAttributesDynamicRenderer->Release(); return hr; } pDrawingAttributesDynamicRenderer->Release(); ++m_nContacts; // Increment finger-down counter return S_OK; }
当 m_nContacts 值递增时,它将更改在动态呈现器中设置的颜色。将使用不同颜色绘制非主触控点的笔画。