// @pymethod <o PyIStorage>|PyIStorage|OpenStorage|Opens an existing storage object with the specified name in the specified access mode. PyObject *PyIStorage::OpenStorage(PyObject *self, PyObject *args) { IStorage *pIS = GetI(self); if ( pIS == NULL ) return NULL; // @pyparm string|pwcsName||Name of the storage, or None. // @pyparm <o PyIStorage>|pstgPriority||If the pstgPriority parameter is not None, it is a <o PyIStorage> object to a previous opening of an element of the storage object, // usually one that was opened in priority mode. The storage object should be closed and re-opened // according to grfMode. When the <om PyIStorage.OpenStorage> method returns, pstgPriority is no longer valid - use the result value. // If the pstgPriority parameter is None, it is ignored. // @pyparm int|grfMode||Specifies the access mode to use when opening the storage object. See the STGM enumeration values for descriptions of the possible values. Whatever other modes you may choose, you must at least specify STGM_SHARE_EXCLUSIVE when calling this method. // @pyparm <o SNB>|snbExclude||Reserved for later - Must be None // @pyparm int|reserved|0|Reserved integer param. PyObject *obName; PyObject *obpstgPriority; DWORD grfMode; DWORD reserved = 0; char *temp = NULL; if ( !PyArg_ParseTuple(args, "OOi|zi:OpenStorage", &obName, &obpstgPriority, &grfMode, &temp, &reserved) ) return NULL; IStorage *pstgPriority; IStorage *ppstg; BOOL bPythonIsHappy = TRUE; BSTR bstrName; bPythonIsHappy = PyWinObject_AsBstr(obName, &bstrName, TRUE); if (!PyCom_InterfaceFromPyObject(obpstgPriority, IID_IStorage, (void **)&pstgPriority, TRUE /* bNoneOK */)) bPythonIsHappy = FALSE; if (!bPythonIsHappy) return NULL; PY_INTERFACE_PRECALL; HRESULT hr = pIS->OpenStorage( bstrName, pstgPriority, grfMode, NULL, reserved, &ppstg ); if ( pstgPriority != NULL ) pstgPriority->Release(); PyWinObject_FreeBstr(bstrName); PY_INTERFACE_POSTCALL; if ( FAILED(hr) ) return PyCom_BuildPyException(hr, pIS, IID_IStorage); return PyCom_PyObjectFromIUnknown(ppstg, IID_IStorage, FALSE); }
BOOL CChildFrame::OpenCompositeDocument(LPCTSTR lpszFileName) { USES_CONVERSION; CWaitCursor wait; HRESULT hResult = E_FAIL; IStorage * ptrRootStg = NULL; // root storage HWND hWnd = (HWND)m_hWnd; hResult = ::StgIsStorageFile( T2COLE(m_szFileName) ); if( S_OK != hResult ) { TCHAR szFmt[MAX_PATH] = { 0 }; AtlLoadString(IDS_OPEN_ARCHIVE_ERROR, szFmt, _countof(szFmt)); TCHAR szOut[MAX_PATH*2] = { 0 }; wnsprintf(szOut, _countof(szOut), szFmt, lpszFileName); AtlMessageBox(m_hWnd, szOut, IDS_ERROR, MB_OK|MB_ICONSTOP); return FALSE; } // open the Compound document hResult = ::StgOpenStorage( T2COLE(m_szFileName), NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &ptrRootStg ); if( FAILED(hResult) ) { TCHAR szFmt[MAX_PATH] = { 0 }; AtlLoadString(IDS_OPEN_FILE_ERROR, szFmt, _countof(szFmt)); TCHAR szError[MAX_PATH] = { 0 }; TCHAR szOut[MAX_PATH*2] = { 0 }; wnsprintf(szOut, _countof(szOut), szFmt, lpszFileName, GetErrorString(S_OK, szError, _countof(szError))); AtlMessageBox(m_hWnd, szOut, IDS_ERROR, MB_OK|MB_ICONSTOP); return FALSE; } TREE_ITEM_DATA * pRootData = new TREE_ITEM_DATA(ptrRootStg, STGTY_STORAGE); HTREEITEM hRoot = m_wndCatalog.InsertItem ( TVIF_IMAGE|TVIF_TEXT|TVIF_PARAM|TVIF_SELECTEDIMAGE, PathFindFileName(m_szFileName), 0, 1, TVIS_EXPANDED, 0, reinterpret_cast<LPARAM>(pRootData), NULL, NULL); std::stack < StgInfo > FolderStack; HTREEITEM htiParent = hRoot; IEnumSTATSTG * ptrEnum = NULL; hResult = ptrRootStg->EnumElements( 0, NULL, 0, &ptrEnum ); if( FAILED(hResult) ) { ptrRootStg->Release(); return 0; } TCHAR szSwap[MAX_PATH] = { 0 }; LARGE_INTEGER nStorageLength; nStorageLength.QuadPart = 0; STATSTG StatStg = { 0 }; while( S_OK == hResult ) { hResult = ptrEnum->Next( 1, &StatStg, NULL ); if( S_FALSE == hResult ) { ptrRootStg->Release(); ptrEnum->Release(); // m_wndCatalog.Expand(strFolder); if( !FolderStack.empty() ) { TCHAR szCurText[MAX_PATH] = {0}; m_wndCatalog.GetItemText(htiParent, szCurText, _countof(szCurText)); CString strTotal; strTotal.Format(TEXT("%s(%ld)"), szCurText, nStorageLength); m_wndCatalog.SetItemText(htiParent, strTotal); ptrRootStg = FolderStack.top().pStg; ptrEnum = FolderStack.top().pEnum; htiParent = FolderStack.top().hParent; FolderStack.pop(); hResult = S_OK; } continue; } switch(StatStg.type) { case STGTY_STORAGE: // 是存储对象, "文件夹" { //先清零 nStorageLength.QuadPart = 0; IStorage * ptrChildStg = NULL; HRESULT hr = ptrRootStg->OpenStorage( StatStg.pwcsName, NULL, STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 0, 0, &ptrChildStg ); if( SUCCEEDED(hr) ) { TREE_ITEM_DATA * pData = new TREE_ITEM_DATA(ptrChildStg, StatStg.type); HTREEITEM hFolder = m_wndCatalog.InsertItem ( TVIF_IMAGE|TVIF_TEXT|TVIF_PARAM|TVIF_SELECTEDIMAGE, WCHAR2TCHAR(StatStg.pwcsName, szSwap, _countof(szSwap)), 0, 1, TVIS_EXPANDED, 0, reinterpret_cast<LPARAM>(pData), htiParent, NULL); // 父存储入栈 FolderStack.push( StgInfo(ptrRootStg, ptrEnum, htiParent) ); // 子存储替代父存储 ptrRootStg = ptrChildStg; htiParent = hFolder; hr = ptrChildStg->EnumElements( 0, NULL, 0, &ptrEnum ); } } break; case STGTY_STREAM: // 是流, "文件" { CComPtr<IStream> spStream; HRESULT hr = ptrRootStg->OpenStream(StatStg.pwcsName, NULL, STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 0, &spStream); ATLASSERT(SUCCEEDED(hr)); LARGE_INTEGER nSeekPos; nSeekPos.QuadPart = 0LL; ULARGE_INTEGER nLength = {0}; hr = spStream->Seek(nSeekPos, STREAM_SEEK_END, &nLength); CString strStreamName; WCHAR2TCHAR(StatStg.pwcsName, szSwap, _countof(szSwap)); if (SUCCEEDED(hr)) { nStorageLength.QuadPart += nLength.QuadPart; strStreamName.Format(TEXT("%s(%ld)"), szSwap, nLength); } else { strStreamName.Format(TEXT("%s(0)"), szSwap); } TREE_ITEM_DATA * pData = new TREE_ITEM_DATA(spStream, StatStg.type); m_wndCatalog.InsertItem ( TVIF_IMAGE|TVIF_TEXT|TVIF_PARAM|TVIF_SELECTEDIMAGE, strStreamName, 2, 2, TVIS_EXPANDED, 0, reinterpret_cast<LPARAM>(pData), htiParent, NULL); } break; case STGTY_LOCKBYTES: ATLTRACE(_T("===== STGTY_LOCKBYTES %d ====="), StatStg.type); break; case STGTY_PROPERTY: ATLTRACE(_T("===== STGTY_PROPERTY %d ====="), StatStg.type); break; default: ATLASSERT(!_T("Unknown storage type!!!")); break; } ::CoTaskMemFree( StatStg.pwcsName ); // 释放名称所使用的内存 } return 0; }