// If object was opened from a file, get the full path and file name...
if (_pmkfile)
{
hr = _pmkfile->GetDisplayName(_pbctx, NULL, &pwszDisplayName);
if (FAILED(hr)) return FALSE;
}
// If the user pressed SaveAs, or if there is no associated file with
// the embedded object, then prompt for a file name & location...
if ((fPrompt) || (!_pmkfile))
{
// Save the file to disk using IPersistFile...
if (bstrFileName)
{
IPersistFile* ppf = 0;
hr = _poleobj->QueryInterface(IID_IPersistFile, (void**)&ppf);
if (SUCCEEDED(hr))
{
hr = ppf->Save(bstrFileName, FALSE);
if (SUCCEEDED(hr) && (NULL == _pmkfile))
{
// If we don't have one already, create a moniker so we don't
// need to ask for the file name again during simple save...
CreateFileMoniker(bstrFileName, &_pmkfile);
SaveDocTitle(bstrFileName);
UpdateTitleBar();
}
ppf->Release();
}
SysFreeString(bstrFileName);
}
if (pwszDisplayName)
CoTaskMemFree(pwszDisplayName);
HBITMAP _hbmDeactive; // Bitmap image of document (when deactive)
HMENU _hmenuHidden; // Merged menu that should be hidden when in Print Preview
BSTR _bstrDocName; // Name of the file opened
if ((NULL == pbstrFile) || (SysStringLen(*pbstrFile) == 0))
return E_INVALIDARG;
// Take the file path and create a moniker for binding...
HRESULT hr = CreateFileMoniker(*pbstrFile, &_pmkfile);
if (FAILED(hr)) return FALSE;
// If the file is not a Stg file, assume it is HTML document
// and just display it as read-only web page...
if (StgIsStorageFile(*pbstrFile) != S_OK)
{
_fIsHTMLFile = TRUE;
SaveDocTitle(*pbstrFile);
return CreateNewDocObject(CLSID_HTMLDOCUMENT);
}
// Bind to the file and copy the data from the file into a storage as if
// the document is an embedded OLE object. (This is needed since EXCEL won't
// let you ip activate anything loaded with IPersistFile.)
hr = _pmkfile->BindToObject(_pbctx, NULL, IID_IPersistStorage, (void**)&pipstg);
if (SUCCEEDED(hr))
{
hr = pipstg->GetClassID(&clsid);
if (SUCCEEDED(hr))
hr = pipstg->Save(_pstgfile, FALSE);
pipstg->Release();
}
// If the copy worked and we know the CLSID for the server, we can
// proceed to ip activation. Otherwise, bail out now...
if (FAILED(hr)) return FALSE;
// We'll save the name of the file (minus the path) for display...
SaveDocTitle(*pbstrFile);
// Call CreateNewDocObject to actually start the inplace session and
// load from the data saved...
return CreateNewDocObject(clsid);
// Don't load if an object has already been loaded...
if ((!_pstgfile) || (_poleobj)) return FALSE;
// Create an inproc handler and load the data from IStorage...
HRESULT hr = CoCreateInstance(rclsid, NULL, CLSCTX_ALL, IID_IUnknown, (void**)&punk);
if (FAILED(hr) || (NULL == punk)) return FALSE;
// Load the data using IPersistStorage...
hr = punk->QueryInterface(IID_IPersistStorage, (void**)&pipstg);
if (SUCCEEDED(hr))
{
// If we opened a file and have moniker, load from exisitng data...
if (_pmkfile)
hr = pipstg->Load(_pstgfile);
else
hr = pipstg->InitNew(_pstgfile);
// Check if the object could not be initialized...
if (FAILED(hr)) {punk->Release(); return FALSE;}
// We need IOleObject so ask. If object doesn't support it we should fail...
hr = punk->QueryInterface(IID_IOleObject, (void **)&_poleobj);
punk->Release(); // Release punk here just in case...
if (FAILED(hr)) return FALSE;
// Fudge factor -- if you make the following calls too quickly, PPT will hang...
Sleep(250);
// Run the object (object must support IRunnableObject)...
OleRun(_poleobj);
// SetClientSite is critical for DocObjects. If this fails the
// object doesn't support inplace activation!!
hr = _poleobj->SetClientSite(static_cast<IOleClientSite*>(this));
if (FAILED(hr))
{
_poleobj->Release();
_poleobj = NULL;
return FALSE;
}
// Lock the object in memory and make a few housekeeping calls...
OleLockRunning(_poleobj, TRUE, FALSE);