Modifying Part Content
This topic shows how to use the Packaging APIs to modify the content of a part in a package.
This topic contains the following sections.
Introduction
The following code examples show the SetAuthorAndModifiedBy
function details. This function uses the Packaging APIs to modify the content of a part in a package.
SetAuthorAndModifiedBy
is declared in the opclib.h header file and defined in the opclib.cpp implementation file of the Set Author Sample. For the complete program, which can load, modify and save a package, see the Set Author Sample.
Modifying Core Properties Part Content
The SetAuthorAndModifiedBy
function shown in the following sections modifies the content of the Core Properties part for a package that has been loaded by using the Packaging APIs. For a demonstration of package loading, see Loading a Package to be Read.
SetAuthorAndModifiedBy
changes the Author and Modified By properties to values that are specified by the user. Because the content of the part is XML markup, SetAuthorAndModifiedBy
uses the XML DOM APIs to represent and modify the content. For more information about how the XML DOM APIs are used, see the Set Author Sample.
The SetAuthorAndModifiedBy
function declaration that is found in opclib.h:
HRESULT
SetAuthorAndModifiedBy(
IOpcPackage *package,
LPCWSTR AuthorName
);
Steps to Modify Core Properties Part Content
Declare the variables that are needed to change part content:
IOpcPart * corePropertiesPart = NULL; IXMLDOMDocument2 * corePropertiesDom = NULL; IXMLDOMNode * creatorNode = NULL; IXMLDOMNode * modifiedName = NULL; IStream * stream = NULL;
Get a pointer to the part to be changed—in this case, the Core Properties part:
HRESULT hr = FindCorePropertiesPart( package, &corePropertiesPart );
For information about finding a part in a package, see the Parts Overview. For a demonstration of how to find the Core Properties part, see Finding the Core Properties Part.
Retrieve and change the content as needed for the application:
if (SUCCEEDED(hr)) { hr = DOMFromPart( corePropertiesPart, g_corePropertiesSelectionNamespaces, &corePropertiesDom ); } // Change text of the author and modified by properties to the specified // author in the DOM. if (SUCCEEDED(hr)) { hr = corePropertiesDom->selectSingleNode( L"//dc:creator", &creatorNode ); } if (SUCCEEDED(hr) && creatorNode != NULL) { hr = creatorNode->put_text((BSTR)author); } if (SUCCEEDED(hr)) { hr = corePropertiesDom->selectSingleNode( L"//cp:lastModifiedBy", &modifiedName ); } if (SUCCEEDED(hr) && modifiedName != NULL) { hr = modifiedName->put_text((BSTR)author); }
In the Set Author Sample, where these code examples originate, a helper function is used to create a DOM to represent part content because the content of the Core Properties part is XML markup. Using the XML DOM APIs in this way facilitates the use of XPath queries to locate content that is to be changed. For the implementation details of
DOMFromPart
, see opclib.cpp of the Set Author Sample.If the part content is not XML markup, retrieve the part content stream by calling the IOpcPart::GetContentStream method and change the data as needed for the application.
The changes made by using the XML DOM APIs must be explicitly applied to part content by using the part content stream.
Clear content from the part content stream and write the changes to the stream:
// Write the changes to part content of the Core Properties part. if (SUCCEEDED(hr)) { // Get the read/write part content stream hr = corePropertiesPart->GetContentStream(&stream); } if (SUCCEEDED(hr)) { // Clear old part content from the stream. ULARGE_INTEGER zero = {0}; hr = stream->SetSize(zero); } if (SUCCEEDED(hr)) { AutoVariant vStream; vStream.SetObjectValue(stream); // Write changes made to core properties data to the part content // stream of the Core Properties part. hr = corePropertiesDom->save(vStream); }
In the Set Author Sample, where these code examples originate, the changes are written by using the XML DOM APIs; however, the application may write directly to the part content stream by using IStream interface methods.
Release resources:
if (corePropertiesPart) { corePropertiesPart->Release(); corePropertiesPart = NULL; } if (corePropertiesDom) { corePropertiesDom->Release(); corePropertiesDom = NULL; } if (creatorNode) { creatorNode->Release(); creatorNode = NULL; } if (modifiedName) { modifiedName->Release(); modifiedName = NULL; } if (stream) { stream->Release(); stream = NULL; }
SetAuthorAndModifiedBy
Code Details
The following code example shows the SetAuthorAndModifiedBy
function definition in one convenient block that is found in opclib.cpp.
The SetAuthorAndModifiedBy
function definition:
//////////////////////////////////////////////////////////////////////////////
// Description:
// Set the modified by and author core properties of a specified package to a
// specified author.
//////////////////////////////////////////////////////////////////////////////
HRESULT
SetAuthorAndModifiedBy(
IOpcPackage *package,
LPCWSTR author
)
{
IOpcPart * corePropertiesPart = NULL;
IXMLDOMDocument2 * corePropertiesDom = NULL;
IXMLDOMNode * creatorNode = NULL;
IXMLDOMNode * modifiedName = NULL;
IStream * stream = NULL;
HRESULT hr = FindCorePropertiesPart(
package,
&corePropertiesPart
);
if (SUCCEEDED(hr))
{
hr = DOMFromPart(
corePropertiesPart,
g_corePropertiesSelectionNamespaces,
&corePropertiesDom
);
}
// Change text of the author and modified by properties to the specified
// author in the DOM.
if (SUCCEEDED(hr))
{
hr = corePropertiesDom->selectSingleNode(
L"//dc:creator",
&creatorNode
);
}
if (SUCCEEDED(hr) && creatorNode != NULL)
{
hr = creatorNode->put_text((BSTR)author);
}
if (SUCCEEDED(hr))
{
hr = corePropertiesDom->selectSingleNode(
L"//cp:lastModifiedBy",
&modifiedName
);
}
if (SUCCEEDED(hr) && modifiedName != NULL)
{
hr = modifiedName->put_text((BSTR)author);
}
// Note: Changes made using the DOM are not automatically applied to
// part content.
// Write the changes to part content of the Core Properties part.
if (SUCCEEDED(hr))
{
// Get the read/write part content stream
hr = corePropertiesPart->GetContentStream(&stream);
}
if (SUCCEEDED(hr))
{
// Clear old part content from the stream.
ULARGE_INTEGER zero = {0};
hr = stream->SetSize(zero);
}
if (SUCCEEDED(hr))
{
AutoVariant vStream;
vStream.SetObjectValue(stream);
// Write changes made to core properties data to the part content
// stream of the Core Properties part.
hr = corePropertiesDom->save(vStream);
}
// Release resources
if (corePropertiesPart)
{
corePropertiesPart->Release();
corePropertiesPart = NULL;
}
if (corePropertiesDom)
{
corePropertiesDom->Release();
corePropertiesDom = NULL;
}
if (creatorNode)
{
creatorNode->Release();
creatorNode = NULL;
}
if (modifiedName)
{
modifiedName->Release();
modifiedName = NULL;
}
if (stream)
{
stream->Release();
stream = NULL;
}
return hr;
}
Disclaimer
Code examples are not intended to be complete and working programs. The code examples that are referenced on this page, for example, do not perform parameter checking, error checking, or error handling. Use these examples as a starting point, then add the code necessary to create a robust application. For more information about error handling in COM, see the Error Handling (COM) topic.
Related topics
-
Overviews
-
Reference