Übertragen von Inhalten vom Gerät auf einen PC
Ein gängiger Vorgang einer WPD-Anwendung ist die Übertragung von Inhalten von einem verbundenen Gerät auf den PC.
Inhaltsübertragungen werden mithilfe der in der folgenden Tabelle beschriebenen Schnittstellen durchgeführt.
Schnittstelle | Beschreibung |
---|---|
IPortableDeviceContent-Schnittstelle | Ermöglicht den Zugriff auf die IPortableDeviceProperties-Schnittstelle . |
IPortableDeviceProperties-Schnittstelle | Ermöglicht den Zugriff auf eigenschaftsspezifische Methoden. |
IPortableDeviceResources-Schnittstelle | Dient zum Speichern der Eigenschaftenschlüssel für das angegebene Profil. |
IStream-Schnittstelle | Wird zum Lesen und Schreiben der Daten verwendet. |
Die TransferContentFromDevice
Funktion im Modul ContentTransfer.cpp der Beispielanwendung veranschaulicht, wie eine Anwendung Kontaktinformationen von einem verbundenen Gerät auf einen PC übertragen kann.
Die erste Aufgabe, die von der TransferContentFromDevice
Funktion ausgeführt wird, besteht darin, den Benutzer aufzufordern, einen Objektbezeichner für das übergeordnete Objekt auf dem Gerät einzugeben (unter dem der Inhalt übertragen wird).
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");
}
Der nächste Schritt ist der Abruf eines IPortableDeviceContent-Objekts , das im Beispiel für den Zugriff auf die inhaltsspezifischen Methoden verwendet wird.
if (SUCCEEDED(hr))
{
hr = pDevice->Content(&pContent);
if (FAILED(hr))
{
printf("! Failed to get IPortableDeviceContent from IPortableDevice, hr = 0x%lx\n",hr);
}
}
Der nächste Schritt ist der Abruf eines IPortableDeviceResources-Objekts , das im Beispiel für den Zugriff auf die ressourcenspezifischen Methoden verwendet wird.
if (SUCCEEDED(hr))
{
hr = pContent->Transfer(&pResources);
if (FAILED(hr))
{
printf("! Failed to get IPortableDeviceResources from IPortableDeviceContent, hr = 0x%lx\n",hr);
}
}
Der nächste Schritt ist der Abruf eines IStream-Objekts, das das Beispiel verwendet, um die vom Gerät übertragenen Daten zu lesen.
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);
}
}
Der nächste Schritt ist das Abrufen des Dateinamens des Objekts auf dem Gerät. Diese Zeichenfolge wird verwendet, um den entsprechenden Dateinamen auf dem PC zu erstellen. Wenn das Objekt keinen Dateinamen auf dem Gerät hat, wird der Bezeichner des Objekts in eine Zeichenfolge konvertiert und zum Erstellen des Zieldateinamens verwendet.
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);
}
}
Danach wird im Beispiel ein IStream-Zielobjekt erstellt.
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);
}
}
Schließlich wird das Quell-IStream-Objekt in das Ziel auf dem PC kopiert.
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());
}
}
Zugehörige Themen