Windows Touch Scratchpad mithilfe des Echtzeiteingabestiftbeispiels (C++)
Das Windows Touch Scratchpad-Beispiel (MTScratchpadRTStylus) zeigt, wie Sie Windows Touch-Nachrichten verwenden, um Ablaufverfolgungen der Touchpunkte in einem Fenster zu zeichnen. Die Spur des primären Fingers, der zuerst auf den Digitizer gelegt wurde, ist schwarz gezeichnet. Sekundäre Finger werden in sechs weiteren Farben gezeichnet: Rot, Grün, Blau, Cyan, Magenta und Gelb. Der folgende Screenshot zeigt, wie die Anwendung während der Ausführung aussehen könnte.
In diesem Beispiel wird das RTS-Objekt (Real-time Stylus) erstellt, und die Unterstützung für mehrere Kontaktpunkte ist aktiviert. Zum Rendern von Inhalten wird dem RTS ein DynamicRenderer-Plug-In hinzugefügt. Ein Plug-In, CSyncEventHandlerRTS, wird implementiert, um die Anzahl der Finger nachzuverfolgen und die Farbe zu ändern, die der dynamische Renderer zeichnet. Mit beiden Plug-Ins im RTS-Plug-In-Stapel rendert die Windows Touch Scratchpad-Anwendung den primären Kontakt in Schwarz und die restlichen Kontakte in den verschiedenen Farben.
Der folgende Code zeigt, wie das RTS-Objekt mit Unterstützung für mehrere Kontaktpunkte erstellt wird.
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;
}
Der folgende Code zeigt, wie das dynamische Renderer-Plug-In erstellt und dem RTS hinzugefügt wird.
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;
}
Der folgende Code ändert die Strichfarbe für den StylusDown-Ereignishandler im benutzerdefinierten RTS-Plug-In CSyncEventHandlerRTS.
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;
}
Wenn der m_nContacts Wert erhöht wird, ändert er die im dynamischen Renderer festgelegte Farbe. Striche, die nicht der primäre Kontakt sind, werden mit unterschiedlichen Farben gezeichnet.
Zugehörige Themen
Multitouch Scratchpad-Anwendung (RTS/C#),Multitouch Scratchpad-Anwendung (RTS/C++),Windows Touch Samples