Transfert de contenu de l’appareil vers un PC
Une opération courante effectuée par une application WPD est le transfert de contenu d’un appareil connecté vers le PC.
Les transferts de contenu sont effectués à l’aide des interfaces décrites dans le tableau suivant.
Interface | Description |
---|---|
IPortableDeviceContent, interface | Fournit l’accès à l’interface IPortableDeviceProperties . |
IPortableDeviceProperties, interface | Fournit l’accès aux méthodes spécifiques aux propriétés. |
IPortableDeviceResources, interface | Utilisé pour stocker les clés de propriété pour le profil donné. |
IStream, interface | Utilisé pour lire et écrire les données. |
La TransferContentFromDevice
fonction dans le module ContentTransfer.cpp de l’exemple d’application montre comment une application peut transférer des informations de contact d’un appareil connecté vers un PC.
La première tâche accomplie par la TransferContentFromDevice
fonction consiste à inviter l’utilisateur à entrer un identificateur d’objet pour l’objet parent sur l’appareil (sous lequel le contenu sera transféré).
HRESULT hr = S_OK;
WCHAR szSelection[81] = {0};
CComPtr<IPortableDeviceContent> pContent;
CComPtr<IPortableDeviceResources> pResources;
CComPtr<IPortableDeviceProperties> pProperties;
CComPtr<IStream> pObjectDataStream;
CComPtr<IStream> pFinalFileStream;
DWORD cbOptimalTransferSize = 0;
CAtlStringW strOriginalFileName;
if (pDevice == NULL)
{
printf("! A NULL IPortableDevice interface pointer was received\n");
return;
}
// Prompt user to enter an object identifier on the device to transfer.
printf("Enter the identifer of the object you wish to transfer.\n>");
hr = StringCbGetsW(szSelection,sizeof(szSelection));
if (FAILED(hr))
{
printf("An invalid object identifier was specified, aborting content transfer\n");
}
L’étape suivante consiste à récupérer un objet IPortableDeviceContent que l’exemple utilise pour accéder aux méthodes spécifiques au contenu.
if (SUCCEEDED(hr))
{
hr = pDevice->Content(&pContent);
if (FAILED(hr))
{
printf("! Failed to get IPortableDeviceContent from IPortableDevice, hr = 0x%lx\n",hr);
}
}
L’étape suivante consiste à récupérer un objet IPortableDeviceResources que l’exemple utilise pour accéder aux méthodes spécifiques aux ressources.
if (SUCCEEDED(hr))
{
hr = pContent->Transfer(&pResources);
if (FAILED(hr))
{
printf("! Failed to get IPortableDeviceResources from IPortableDeviceContent, hr = 0x%lx\n",hr);
}
}
L’étape suivante consiste à récupérer un objet IStream que l’exemple utilise pour lire les données qu’il transfère à partir de l’appareil.
if (SUCCEEDED(hr))
{
hr = pResources->GetStream(szSelection, // Identifier of the object we want to transfer
WPD_RESOURCE_DEFAULT, // We are transferring the default resource (which is the entire object's data)
STGM_READ, // Opening a stream in READ mode, because we are reading data from the device.
&cbOptimalTransferSize, // Driver supplied optimal transfer size
&pObjectDataStream);
if (FAILED(hr))
{
printf("! Failed to get IStream (representing object data on the device) from IPortableDeviceResources, hr = 0x%lx\n",hr);
}
}
L’étape suivante consiste à récupérer le nom de fichier de l’objet sur l’appareil. Cette chaîne est utilisée pour créer le nom de fichier correspondant sur le PC. Si l’objet n’a pas de nom de fichier sur l’appareil, l’identificateur de l’objet est converti en chaîne et utilisé pour créer le nom du fichier de destination.
if (SUCCEEDED(hr))
{
hr = pContent->Properties(&pProperties);
if (SUCCEEDED(hr))
{
hr = GetStringValue(pProperties,
szSelection,
WPD_OBJECT_ORIGINAL_FILE_NAME,
strOriginalFileName);
if (FAILED(hr))
{
printf("! Failed to read WPD_OBJECT_ORIGINAL_FILE_NAME on object '%ws', hr = 0x%lx\n", szSelection, hr);
strOriginalFileName.Format(L"%ws.data", szSelection);
printf("* Creating a filename '%ws' as a default.\n", (PWSTR)strOriginalFileName.GetString());
// Set the HRESULT to S_OK, so we can continue with our newly generated
// temporary file name.
hr = S_OK;
}
}
else
{
printf("! Failed to get IPortableDeviceProperties from IPortableDeviceContent, hr = 0x%lx\n", hr);
}
}
Après cela, l’exemple crée un objet IStream de destination.
if (SUCCEEDED(hr))
{
hr = SHCreateStreamOnFile(strOriginalFileName, STGM_CREATE|STGM_WRITE, &pFinalFileStream);
if (FAILED(hr))
{
printf("! Failed to create a temporary file named (%ws) to transfer object (%ws), hr = 0x%lx\n",(PWSTR)strOriginalFileName.GetString(), szSelection, hr);
}
}
Enfin, l’objet IStream source est copié vers la destination sur le PC.
if (SUCCEEDED(hr))
{
DWORD cbTotalBytesWritten = 0;
// Since we have IStream-compatible interfaces, call our helper function
// that copies the contents of a source stream into a destination stream.
hr = StreamCopy(pFinalFileStream, // Destination (The Final File to transfer to)
pObjectDataStream, // Source (The Object's data to transfer from)
cbOptimalTransferSize, // The driver specified optimal transfer buffer size
&cbTotalBytesWritten); // The total number of bytes transferred from device to the finished file
if (FAILED(hr))
{
printf("! Failed to transfer object from device, hr = 0x%lx\n",hr);
}
else
{
printf("* Transferred object '%ws' to '%ws'.\n", szSelection, (PWSTR)strOriginalFileName.GetString());
}
}
Rubriques connexes