Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Este programa demonstra como você pode criar um aplicativo que captura eventos InkCollector usando apenas C++. Este programa co-cria um objeto InkCollector para aplicar tinta à janela -enable. Exibe uma caixa de mensagem sempre que um evento de traçado é recebido.
Definição de um envelope para eventos do coletor de tinta
A classe InkCollectorEvents manipula a passagem de eventos do coletor de tinta do coletor de tinta para o usuário dessa classe. O método AdviseInkCollector configura a conexão entre o InkCollector objeto e esta classe. O método Invoke converte o IDispatch notificação de evento numa chamada para uma função virtual que o utilizador desta classe pode sobrescrever para processar um evento específico.
Observação
Para capturar esse evento, precisa fazer mais do que apenas substituir a função virtual do manipulador. Para todos os eventos, exceto os padrão, é necessário chamar o método SetEventInterest do coletor de tinta para garantir a obtenção de um evento. Em segundo lugar, este objeto organiza-se de forma multiencadeada, logo todos os manipuladores de eventos implementados precisam ser também multiencadeados. De particular importância é o uso de APIs do Windows, o que pode causar uma mudança para outro thread, pois não é garantido que o manipulador de eventos esteja sendo executado no mesmo thread que a janela conectada com o coletor de tinta.
// Invoke translates from IDispatch to an event callout
// that can be overridden by a subclass of this class.
STDMETHOD(Invoke)(
DISPID dispidMember,
REFIID riid,
LCID lcid,
WORD /*wFlags*/,
DISPPARAMS* pdispparams,
VARIANT* pvarResult,
EXCEPINFO* /*pexcepinfo*/,
UINT* /*puArgErr*/)
{
switch(dispidMember)
{
case DISPID_ICEStroke:
Stroke(
(IInkCursor*) pdispparams->rgvarg[2].pdispVal,
(IInkStrokeDisp*) pdispparams->rgvarg[1].pdispVal,
(VARIANT_BOOL *)pdispparams->rgvarg[0].pboolVal);
break;
...
}
return S_OK;
}
virtual void Stroke(
IInkCursor* Cursor,
IInkStrokeDisp* Stroke,
VARIANT_BOOL *Cancel)
{
// This is a place holder designed to be overridden by
// user of this class.
return;
}
...
O método Init chama CoCreateFreeThreadedMarshaler para configurar um marshaler de execução livre.
// Init: set up free threaded marshaller.
HRESULT Init()
{
return CoCreateFreeThreadedMarshaler(this, &m_punkFTM);
}
O método AdviseInkCollector configura a conexão entre o InkCollector objeto e esta classe. Primeiro, ele recupera um ponto de conexão com o coletor de tinta. Em seguida, ele recupera um ponteiro para o IInkCollectorEvents para que ele possa estabelecer uma conexão consultiva com o controle.
// Set up connection between sink and InkCollector
HRESULT AdviseInkCollector(
IInkCollector *pIInkCollector)
{
// Get the connection point container
IConnectionPointContainer *pIConnectionPointContainer;
HRESULT hr = pIInkCollector->QueryInterface(IID_IConnectionPointContainer, (void **) &pIConnectionPointContainer);
if (FAILED(hr))
...
// Find the connection point for Ink Collector events
hr = pIConnectionPointContainer->FindConnectionPoint(__uuidof(_IInkCollectorEvents), &m_pIConnectionPoint);
if (SUCCEEDED(hr))
{
// Hook up sink to connection point
hr = m_pIConnectionPoint->Advise(this, &m_dwCookie);
}
if (FAILED(hr))
...
// Don't need the connection point container any more.
pIConnectionPointContainer->Release();
return hr;
}
O método UnadviseInkCollector libera as conexões que o objeto tem com o controle.
// Remove the connection of the sink to the Ink Collector
HRESULT UnadviseInkCollector()
{
HRESULT hr = m_pIConnectionPoint->Unadvise(m_dwCookie);m_pIConnectionPoint->Release();
m_pIConnectionPoint = NULL;
return hr;
}
Definindo um manipulador de eventos do coletor de tinta
A classe CMyInkEvents substitui o comportamento padrão do manipulador de eventos Stroke da classe InkCollectorEvents. O método Stroke exibe uma caixa de mensagem quando o InkCollector recebe um Stroke evento.
class CMyInkEvents : public InkCollectorEvents
{
public:
// Event: Stroke
virtual void Stroke(
IInkCursor* Cursor,
IInkStrokeDisp* Stroke,
VARIANT_BOOL *Cancel)
{
// Demonstrate that the event notification was received.
MessageBox(m_hWnd, "Stroke Event", "Event Received", MB_OK);
}
CMyInkEvents()
{
m_hWnd = NULL;
}
HRESULT Init(
HWND hWnd)
{
m_hWnd = hWnd;
return InkCollectorEvents::Init();
}
HWND m_hWnd;
};
Definindo um invólucro de coletor de tinta
O método Init da classe CMyInkCollector declara e inicializa um objeto CMyInkEvents. Em seguida, cria um objeto InkCollector e associa o coletor de tinta e o manipulador de eventos. Finalmente, o InkCollector é anexado à janela e habilitado.
// Handle all initialization
HRESULT Init(
HWND hWnd)
{
// Initialize event sink. This consists of setting
// up the free threaded marshaler.
HRESULT hr = m_InkEvents.Init(hWnd);
if (FAILED(hr))
...
// Create the ink collector
hr = CoCreateInstance(CLSID_InkCollector, NULL, CLSCTX_ALL, IID_IInkCollector, (void **) &m_pInkCollector);
if (FAILED(hr))
...
// Set up connection between Ink Collector and our event sink
hr = m_InkEvents.AdviseInkCollector(m_pInkCollector);
if (FAILED(hr))
...
// Attach Ink Collector to window
hr = m_pInkCollector->put_hWnd((long) hWnd);
if (FAILED(hr))
...
// Allow Ink Collector to receive input.
return m_pInkCollector->put_Enabled(VARIANT_TRUE);
}
Acedendo às interfaces do Tablet PC e às classes Wrapper
Primeiro, inclua os cabeçalhos para as interfaces de automação do Tablet PC. Estes são instalados com o Microsoft<entity type="reg"/> Windows<entity type="reg"/> XP Tablet PC Edition Development Kit 1.7.
#include <msinkaut.h>
#include <msinkaut_i.c>
Em seguida, inclua os cabeçalhos para as classes de wrapper, e o manipulador de eventos InkCollector foi definido.
#include "TpcConpt.h"
#include "EventSink.h"
Chamando as Classes de Wrapper
Quando a janela é criada, o procedimento Window cria um wrapper de coletor de tinta e inicializa o wrapper. Quando a janela é destruída, o procedimento Janela exclui o invólucro do coletor de tinta. O wrapper do coletor de tinta lida com a criação e a exclusão de seu manipulador de eventos associado.
case WM_CREATE:
// Allocate and initialize memory for object
pmic = new CMyInkCollector();
if (pmic != NULL)
{
// Real initialization. This consists of creating
// an ink collector object and attaching it to
// the current window.
if (SUCCEEDED(pmic->Init(hWnd)))
{
return 0;
}
// Failure free resources.
delete pmic;
pmic = NULL;
}
return -1;
...
case WM_DESTROY:
// The destructor for the object handles releasing the
// InkCollector and disconnecting the InkCollector
// from the object's event sink.
delete pmic;
pmic = NULL;
PostQuitMessage(0);
break;