Windows Touch Scratchpad à l’aide de l’exemple de stylet en temps réel (C++)
L’exemple Windows Touch Scratchpad (MTScratchpadRTStylus) montre comment utiliser des messages Windows Touch pour dessiner des traces des points tactiles vers une fenêtre. La trace du doigt primaire, celui qui a été placé en premier sur le numériseur, est dessinée en noir. Les doigts secondaires sont dessinés dans six autres couleurs : rouge, vert, bleu, cyan, magenta et jaune. La capture d’écran suivante montre à quoi l’application peut ressembler lors de l’exécution.
Pour cet exemple, l’objet RTS (Real-time Stylus) est créé et la prise en charge de plusieurs points de contact est activée. Un plug-in DynamicRenderer est ajouté au RTS pour afficher le contenu. Un plug-in, CSyncEventHandlerRTS, est implémenté pour suivre le nombre de doigts et modifier la couleur que dessine le convertisseur dynamique. Avec les deux plug-ins dans la pile de plug-ins RTS, l’application Windows Touch Scratchpad affiche le contact principal en noir et le reste des contacts dans les différentes couleurs.
Le code suivant montre comment l’objet RTS est créé avec prise en charge de plusieurs points de contact.
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;
}
Le code suivant montre comment le plug-in de renderer dynamique est créé et ajouté au 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;
}
Le code suivant modifie la couleur du trait du stylet pour le gestionnaire d’événements StylusDown dans CSyncEventHandlerRTS, un plug-in RTS personnalisé.
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;
}
Lorsque la valeur m_nContacts est incrémentée, elle modifie le jeu de couleurs dans le convertisseur dynamique. Les traits qui ne sont pas le contact principal sont dessinés avec des couleurs différentes.
Rubriques connexes
Application Multi-touch Scratchpad (RTS/C#),Application de bloc d’action multipoint (RTS/C++), Exemples Windows Touch