Accessing Folders
9/8/2008
O Gerenciador serviço requer o HREPLFLD identificador para acessar uma pasta. Esse identificador contém o filtro conversão para o tipo objeto e Outras informações Object-specific.
As chamadas Gerenciador serviço IReplStore::GetFolderInfo Para obter o identificador pasta. O Gerenciador serviço também chamadas IReplStore::IsFolderChanged, IReplStore::CopyObject, IReplStore::IsValidObject GPSGetPosition, e IReplStore::FreeObject Para manipular alças pasta e item.
Porque o Gerenciador serviço salva o HREPLITEM ou ISpTTSEngine::Speak. HREPLFLD dados para arquivo persistente do Gerenciador de serviço, você deve também implementar IReplStore::ObjectToBytes e MapVirtualKey. IReplStore::BytesToObject.
O seguinte mostra exemplo de código como para implementar IReplStore::GetFolderInfo.
STDMETHODIMP CStore::GetFolderInfo
(
LPSTR lpszName, // name of object type taken from registry
HREPLFLD *phFolder, // pointer to handle of the new folder
IUnknown **ppObjHandler // pointer to pointer to IReplObjHandler interface
)
{
// Check if phFolder points to a NULL-valued handle.
CFolder *pFolder = (CFolder*)*phFolder;
BOOL fNew = (pFolder == NULL);
// Create a new handle for the specific folder.
if (fNew)
pFolder = new CFolder;
// When fNew is FALSE reinitialize the class.
// When fNew is TRUE set up the new CFolder class.
// ...
*phFolder = (HREPLFLD)pFolder;
*ppObjHandler = m_pObjHandler;
return NOERROR;
}
Para determinar que se qualquer objeto em uma pasta tiver sido alterado, o Gerenciador serviço chama IReplStore::IsFolderChanged. O Gerenciador serviço também pode chamar a seguinte métodos para manipular alças pasta ou item.
- IReplStore::CopyObject Copia os dados de um identificador para outro identificador que representa o mesmo objeto.
- IReplStore::IsValidObject Verifica o identificador ainda representa um válido objeto, não um objeto excluído.
- IReplStore::FreeObject Remove um identificador de memória, permitindo o área de trabalho provedor para livre recursos do identificador memória.
O seguinte apresentação exemplos codificar como para implementar esses métodos.
STDMETHODIMP_(BOOL) CStore::CopyObject
(
HREPLOBJ hObjSrc, // handle to the source object
HREPLOBJ hObjDst // handle to the destination object
)
{
CReplObject *pObjSrc = (CReplObject*) hObjSrc;
CReplObject *pObjDst = (CReplObject*) hObjDst;
// Check to see if the source and destination types are the same.
if (pObjSrc->m_uType != pObjDst->m_uType)
return FALSE;
switch (pObjSrc->m_uType)
{
case OT_ITEM: // if the source object is an item
((CItem*) pObjDst)->m_uid = ((CItem *)pObjSrc)->m_uid;
((CItem*) pObjDst)->m_ftModified =
((CItem*) pObjSrc)->m_ftModified;
break;
case OT_FOLDER: // if the source object is a folder
break;
}
return TRUE;
}
STDMETHODIMP CStore::IsValidObject
(
HREPLFLD hFolder, // handle of folder where this item belongs
HREPLITEM hItem, // handle of the object; could be NULL
UINT uFlags // Reserved; must be 0.
)
{
CFolder *pFolder = (CFolder*)hFolder;
CItem *pItem = (CItem*) hItem;
if (pFolder)
{ // Check whether hFolder is a valid folder handle.
if (pFolder->m_uType != OT_FOLDER)
return HRESULT_FROM_WIN32 (ERROR_INVALID_HANDLE);
}
if (pItem)
{ // Check whether hItem is a valid item handle.
if (pFolder->m_uType != OT_ITEM)
return HRESULT_FROM_WIN32 (ERROR_INVALID_HANDLE);
// Search for item. If item not found, return.
// HRESULT_FROM_WIN32 (ERROR_FILE_NOT_FOUND)
// ...
}
return NOERROR;
}
STDMETHODIMP_(void) CStore::FreeObject
(
HREPLOBJ hObject // handle of object whose contents need to be freed
)
{
delete (CReplObject*) hObject;
}
O área de trabalho provedor deve implementar IReplStore::ObjectToBytes Para converter um HREPLITEM objeto ou HREPLFLD objeto em um seqüência de bytes para Gerenciador o serviço pode armazenar os dados no arquivo persistente do Gerenciador de serviço. O área de trabalho provedor também deve implementar IReplStore::BytesToObject Para converter o mesmo seqüência de bytes voltar para um objeto.
Quando um usuário se conecta um Windows Embedded CE - dispositivo com base para um área de trabalho, Gerenciador o serviço lê o arquivo persistente e restaura todos os identificadores que foram usados na sincronização anterior.
O seguinte apresentação exemplos codificar como para implementar IReplStore::ObjectToBytes e MapVirtualKey. IReplStore::BytesToObject.
STDMETHODIMP_(UINT) CStore::ObjectToBytes
(
HREPLOBJ hObject, // handle to object
LPBYTE lpb // The engine calls ObjectToBytes first with lpb
// set to NULL. The provider should return the
// count of bytes needed. The engine then
// allocates that much space and calls the method
// again with lpb pointing to the allocated data.)
{
LPBYTE lpbStart = lpb;
CReplObject *pObject = (CReplObject*)hObject;
CFolder *pFolder = (CFolder*) pObject;
CItem *pItem = (CItem*) pObject;
if (lpbStart)
*lpb = OBJECT_VERSION;
lpb++;
if (lpbStart)
*(PUINT)lpb = pObject->m_uType;
lpb += sizeof (pObject->m_uType);
switch (pObject->m_uType)
{
case OT_FOLDER:
break;
case OT_ITEM:
if (lpbStart)
*(PUINT)lpb = pItem->m_uid;
lpb += sizeof (pItem->m_uid);
if (lpbStart)
*(FILETIME*)lpb = pItem->m_ftModified;
lpb += sizeof (pItem->m_ftModified);
break;
}
return lpb - lpbStart;
}
STDMETHODIMP_(HREPLOBJ) CStore::BytesToObject
(
LPBYTE lpb, // Pointer to buffer where byte array
// should be stored; can be NULL.
UINT cb // buffer size
)
{
CReplObject *pObject = NULL;
CFolder *pFolder;
CItem *pItem;
BYTE bVersion = *lpb++;
UINT uType = *(PUINT)lpb;
lpb += sizeof (uType);
if (bVersion != OBJECT_VERSION)
{
// Convert the data based on bVersion.
}
switch (uType)
{
case OT_FOLDER:
pObject = pFolder = new CFolder;
break;
case OT_ITEM:
pObject = pItem = new CItem;
pItem->m_uid = *(PUINT)lpb;
lpb += sizeof (pItem->m_uid);
pItem->m_ftModified = *(FILETIME*)lpb;
lpb += sizeof (pItem->m_ftModified);
break;
}
return (HREPLOBJ)pObject;
}