//! 同一ファイルの再オープン void CDocFileOperation::ReloadCurrentFile( ECodeType nCharCode //!< [in] 文字コード種別 ) { //プラグイン:DocumentCloseイベント実行 CPlug::Array plugs; CWSHIfObj::List params; CJackManager::getInstance()->GetUsablePlug( PP_DOCUMENT_CLOSE, 0, &plugs ); for( CPlug::ArrayIter it = plugs.begin(); it != plugs.end(); it++ ){ (*it)->Invoke(&m_pcDocRef->m_pcEditWnd->GetActiveView(), params); } if( !fexist(m_pcDocRef->m_cDocFile.GetFilePath()) ){ /* ファイルが存在しない */ // Jul. 26, 2003 ryoji BOMを標準設定に // IsBomDefOn使用 2013/5/17 Uchi m_pcDocRef->m_cDocFile.SetCodeSet( nCharCode, CCodeTypeName( nCharCode ).IsBomDefOn() ); // カーソル位置表示を更新する // 2008.07.22 ryoji m_pcDocRef->m_pcEditWnd->GetActiveView().GetCaret().ShowCaretPosInfo(); return; } //カーソル位置保存 CLayoutInt nViewTopLine = m_pcDocRef->m_pcEditWnd->GetActiveView().GetTextArea().GetViewTopLine(); /* 表示域の一番上の行(0開始) */ CLayoutInt nViewLeftCol = m_pcDocRef->m_pcEditWnd->GetActiveView().GetTextArea().GetViewLeftCol(); /* 表示域の一番左の桁(0開始) */ CLayoutPoint ptCaretPosXY = m_pcDocRef->m_pcEditWnd->GetActiveView().GetCaret().GetCaretLayoutPos(); //ロード SLoadInfo sLoadInfo; sLoadInfo.cFilePath=m_pcDocRef->m_cDocFile.GetFilePath(); sLoadInfo.eCharCode=nCharCode; sLoadInfo.bViewMode=CAppMode::getInstance()->IsViewMode(); // 2014.06.13 IsEditable->IsViewModeに戻す。かわりに bForceNoMsgを追加 sLoadInfo.bWritableNoMsg = !m_pcDocRef->IsEditable(); // すでに編集できない状態ならファイルロックのメッセージを表示しない sLoadInfo.bRequestReload=true; bool bRet = this->DoLoadFlow(&sLoadInfo); // カーソル位置復元 (※ここではオプションのカーソル位置復元(=改行単位)が指定されていない場合でも復元する) // 2007.08.23 ryoji 表示領域復元 if( ptCaretPosXY.GetY2() < m_pcDocRef->m_cLayoutMgr.GetLineCount() ){ m_pcDocRef->m_pcEditWnd->GetActiveView().GetTextArea().SetViewTopLine(nViewTopLine); m_pcDocRef->m_pcEditWnd->GetActiveView().GetTextArea().SetViewLeftCol(nViewLeftCol); } m_pcDocRef->m_pcEditWnd->GetActiveView().GetCaret().MoveCursorProperly( ptCaretPosXY, true ); // 2007.08.23 ryoji MoveCursor()->MoveCursorProperly() m_pcDocRef->m_pcEditWnd->GetActiveView().GetCaret().m_nCaretPosX_Prev = m_pcDocRef->m_pcEditWnd->GetActiveView().GetCaret().GetCaretLayoutPos().GetX2(); // 2006.09.01 ryoji オープン後自動実行マクロを実行する if( bRet ){ m_pcDocRef->RunAutoMacro( GetDllShareData().m_Common.m_sMacro.m_nMacroOnOpened ); //プラグイン:DocumentOpenイベント実行 CPlug::Array plugs; CWSHIfObj::List params; CJackManager::getInstance()->GetUsablePlug( PP_DOCUMENT_OPEN, 0, &plugs ); for( CPlug::ArrayIter it = plugs.begin(); it != plugs.end(); it++ ){ (*it)->Invoke(&m_pcDocRef->m_pcEditWnd->GetActiveView(), params); } } }
/* 閉じて(無題)。 ユーザキャンセル操作等によりクローズされなかった場合は false を返す。 @date 2006.12.30 ryoji CEditView::Command_FILESAVEAS()から処理本体を切り出し */ bool CDocFileOperation::FileClose() { /* ファイルを閉じるときのMRU登録 & 保存確認 & 保存実行 */ if( !m_pcDocRef->OnFileClose(false) ){ return false; } //プラグイン:DocumentCloseイベント実行 CPlug::Array plugs; CWSHIfObj::List params; CJackManager::getInstance()->GetUsablePlug( PP_DOCUMENT_CLOSE, 0, &plugs ); for( CPlug::ArrayIter it = plugs.begin(); it != plugs.end(); it++ ){ (*it)->Invoke(&m_pcDocRef->m_pcEditWnd->GetActiveView(), params); } /* 既存データのクリア */ m_pcDocRef->InitDoc(); /* 全ビューの初期化 */ m_pcDocRef->InitAllView(); m_pcDocRef->SetCurDirNotitle(); // 無題番号取得 CAppNodeManager::getInstance()->GetNoNameNumber( m_pcDocRef->m_pcEditWnd->GetHwnd() ); /* 親ウィンドウのタイトルを更新 */ m_pcDocRef->m_pcEditWnd->UpdateCaption(); // 2006.09.01 ryoji オープン後自動実行マクロを実行する m_pcDocRef->RunAutoMacro( GetDllShareData().m_Common.m_sMacro.m_nMacroOnOpened ); return true; }
/*! 名前を付けて保存フロー @date 2006.12.30 ryoji CEditView::Command_FILESAVEAS_DIALOG()から処理本体を切り出し */ bool CDocFileOperation::FileSaveAs( const WCHAR* filename,ECodeType eCodeType, EEolType eEolType, bool bDialog ) { //セーブ情報 SSaveInfo sSaveInfo; m_pcDocRef->GetSaveInfo(&sSaveInfo); sSaveInfo.cEol = EOL_NONE; // 初期値は変換しない if( filename ){ // ダイアログなし保存、またはマクロの引数あり sSaveInfo.cFilePath = to_tchar(filename); if( EOL_NONE <= eEolType && eEolType < EOL_CODEMAX ){ sSaveInfo.cEol = eEolType; } if( IsValidCodeType(eCodeType) && eCodeType != sSaveInfo.eCharCode ){ sSaveInfo.eCharCode = eCodeType; sSaveInfo.bBomExist = CCodeTypeName(eCodeType).IsBomDefOn(); } } if( bDialog ){ if(!filename && CAppMode::getInstance()->IsViewMode()){ sSaveInfo.cFilePath = _T(""); //※読み込み専用モードのときはファイル名を指定しない } //ダイアログ表示 if(!SaveFileDialog(&sSaveInfo))return false; } //セーブ処理 if( DoSaveFlow(&sSaveInfo) ){ // オープン後自動実行マクロを実行する(ANSI版ではここで再ロード実行→自動実行マクロが実行される) // 提案時の Patches#1550557 に、「名前を付けて保存」でオープン後自動実行マクロが実行されることの是非について議論の経緯あり // →”ファイル名に応じて表示を変化させるマクロとかを想定すると、これはこれでいいように思います。” m_pcDocRef->RunAutoMacro( GetDllShareData().m_Common.m_sMacro.m_nMacroOnOpened ); //プラグイン:DocumentOpenイベント実行 CPlug::Array plugs; CWSHIfObj::List params; CJackManager::getInstance()->GetUsablePlug( PP_DOCUMENT_OPEN, 0, &plugs ); for( CPlug::ArrayIter it = plugs.begin(); it != plugs.end(); it++ ){ (*it)->Invoke(&m_pcDocRef->m_pcEditWnd->GetActiveView(), params); } return true; } return false; }
//! ファイルを開く bool CDocFileOperation::FileLoad( SLoadInfo* pLoadInfo //!< [in,out] ) { bool bRet = DoLoadFlow(pLoadInfo); // 2006.09.01 ryoji オープン後自動実行マクロを実行する if( bRet ){ m_pcDocRef->RunAutoMacro( GetDllShareData().m_Common.m_sMacro.m_nMacroOnOpened ); //プラグイン:DocumentOpenイベント実行 CPlug::Array plugs; CWSHIfObj::List params; CJackManager::getInstance()->GetUsablePlug( PP_DOCUMENT_OPEN, 0, &plugs ); for( CPlug::ArrayIter it = plugs.begin(); it != plugs.end(); it++ ){ (*it)->Invoke(&m_pcDocRef->m_pcEditWnd->GetActiveView(), params); } } return bRet; }
/*! GREP実行 @date 2005.01.10 genta CEditView_Commandより移動 */ void CViewCommander::Command_GREP( void ) { CNativeW cmWork1; CNativeT cmWork2; CNativeT cmWork3; CNativeW cmWork4; cmWork1.SetString( GetEditWindow()->m_cDlgGrep.m_strText.c_str() ); cmWork2.SetString( GetEditWindow()->m_cDlgGrep.m_szFile ); cmWork3.SetString( GetEditWindow()->m_cDlgGrep.m_szFolder ); /* 今のEditViewにGrep結果を表示する。 Grepモードのとき、または未編集で無題かつアウトプットでない場合。 自ウィンドウがGrep実行中も、(異常終了するので)別ウィンドウにする */ if( ( CEditApp::getInstance()->m_pcGrepAgent->m_bGrepMode && !CEditApp::getInstance()->m_pcGrepAgent->m_bGrepRunning ) || ( !GetDocument()->m_cDocEditor.IsModified() && !GetDocument()->m_cDocFile.GetFilePathClass().IsValidPath() && /* 現在編集中のファイルのパス */ !CAppMode::getInstance()->IsDebugMode() ) ){ // 2011.01.23 Grepタイプ別適用 if( !GetDocument()->m_cDocEditor.IsModified() && GetDocument()->m_cDocLineMgr.GetLineCount() == 0 ){ CTypeConfig cTypeGrep = CDocTypeManager().GetDocumentTypeOfExt( _T("grepout") ); const STypeConfigMini* pConfig; CDocTypeManager().GetTypeConfigMini( cTypeGrep, &pConfig ); GetDocument()->m_cDocType.SetDocumentTypeIdx( pConfig->m_id ); GetDocument()->m_cDocType.LockDocumentType(); GetDocument()->OnChangeType(); } CEditApp::getInstance()->m_pcGrepAgent->DoGrep( m_pCommanderView, false, &cmWork1, &cmWork4, &cmWork2, &cmWork3, false, GetEditWindow()->m_cDlgGrep.m_bSubFolder, false, true, // Header GetEditWindow()->m_cDlgGrep.m_sSearchOption, GetEditWindow()->m_cDlgGrep.m_nGrepCharSet, GetEditWindow()->m_cDlgGrep.m_nGrepOutputLineType, GetEditWindow()->m_cDlgGrep.m_nGrepOutputStyle, GetEditWindow()->m_cDlgGrep.m_bGrepOutputFileOnly, GetEditWindow()->m_cDlgGrep.m_bGrepOutputBaseFolder, GetEditWindow()->m_cDlgGrep.m_bGrepSeparateFolder, false, false ); //プラグイン:DocumentOpenイベント実行 CPlug::Array plugs; CWSHIfObj::List params; CJackManager::getInstance()->GetUsablePlug( PP_DOCUMENT_OPEN, 0, &plugs ); for( CPlug::ArrayIter it = plugs.begin(); it != plugs.end(); it++ ){ (*it)->Invoke(&GetEditWindow()->GetActiveView(), params); } } else{ // 編集ウィンドウの上限チェック if( GetDllShareData().m_sNodes.m_nEditArrNum >= MAX_EDITWINDOWS ){ //最大値修正 //@@@ 2003.05.31 MIK OkMessage( m_pCommanderView->GetHwnd(), LS(STR_MAXWINDOW), MAX_EDITWINDOWS ); return; } /*======= Grepの実行 =============*/ /* Grep結果ウィンドウの表示 */ CControlTray::DoGrepCreateWindow(G_AppInstance(), m_pCommanderView->GetHwnd(), GetEditWindow()->m_cDlgGrep); } return; }
/*! 初期化 pcmemHokanWord == NULLのとき、補完候補がひとつだったら、補完ウィンドウを表示しないで終了します。 Search()呼び出し元で確定処理を進めてください。 @date 2002.2.17 YAZAKI CShareDataのインスタンスは、CProcessにひとつあるのみ。 */ int CHokanMgr::Search( POINT* ppoWin, int nWinHeight, int nColumnWidth, const wchar_t* pszCurWord, const TCHAR* pszHokanFile, bool bHokanLoHiCase, // 入力補完機能:英大文字小文字を同一視する 2001/06/19 asa-o bool bHokanByFile, // 編集中データから候補を探す 2003.06.23 Moca int nHokanType, bool bHokanByKeyword, CNativeW* pcmemHokanWord // 2001/06/19 asa-o ) { CEditView* pcEditView = reinterpret_cast<CEditView*>(m_lParam); /* 共有データ構造体のアドレスを返す */ m_pShareData = &GetDllShareData(); /* || 補完キーワードの検索 || || ・見つかった候補をすべて返す(改行で区切って返す) || ・指定された候補の最大数を超えると処理を中断する || ・見つかった数を返す || */ m_vKouho.clear(); CDicMgr::HokanSearch( pszCurWord, bHokanLoHiCase, // 引数からに変更 2001/06/19 asa-o m_vKouho, 0, //Max候補数 pszHokanFile ); // 2003.05.16 Moca 追加 編集中データ内から候補を探す if( bHokanByFile ){ pcEditView->HokanSearchByFile( pszCurWord, bHokanLoHiCase, m_vKouho, 1024 // 編集中データからなので数を制限しておく ); } // 2012.10.13 Moca 強調キーワードから候補を探す if( bHokanByKeyword ){ HokanSearchByKeyword( pszCurWord, bHokanLoHiCase, m_vKouho ); } { int nOption = ( (bHokanLoHiCase ? 0x01 : 0) | (bHokanByFile ? 0x02 : 0) ); CPlug::Array plugs; CPlug::Array plugType; CJackManager::getInstance()->GetUsablePlug( PP_COMPLEMENTGLOBAL, 0, &plugs ); if( nHokanType != 0 ){ CJackManager::getInstance()->GetUsablePlug( PP_COMPLEMENT, nHokanType, &plugType ); if( 0 < plugType.size() ){ plugs.push_back( plugType[0] ); } } for( auto it = plugs.begin(); it != plugs.end(); ++it ){ //インタフェースオブジェクト準備 CWSHIfObj::List params; std::wstring curWord = pszCurWord; CComplementIfObj* objComp = new CComplementIfObj( curWord , this, nOption ); objComp->AddRef(); params.push_back( objComp ); //プラグイン呼び出し (*it)->Invoke( pcEditView, params ); objComp->Release(); } } if( 0 == m_vKouho.size() ){ m_nCurKouhoIdx = -1; return 0; } // 2001/06/19 asa-o 候補が1つの場合補完ウィンドウは表示しない(逐次補完の場合は除く) if( 1 == m_vKouho.size() ){ if(pcmemHokanWord != NULL){ m_nCurKouhoIdx = -1; pcmemHokanWord->SetString( m_vKouho[0].c_str() ); return 1; } } // m_hFont = hFont; m_poWin.x = ppoWin->x; m_poWin.y = ppoWin->y; m_nWinHeight = nWinHeight; m_nColumnWidth = nColumnWidth; // m_cmemCurWord.SetData( pszCurWord, lstrlen( pszCurWord ) ); m_cmemCurWord.SetString( pszCurWord ); m_nCurKouhoIdx = 0; // SetCurKouhoStr(); // ::ShowWindow( GetHwnd(), SW_SHOWNA ); HWND hwndList; hwndList = GetItemHwnd( IDC_LIST_WORDS ); List_ResetContent( hwndList ); { size_t kouhoNum = m_vKouho.size(); for( size_t i = 0; i < kouhoNum; ++i ){ ::List_AddString( hwndList, m_vKouho[i].c_str() ); } } List_SetCurSel( hwndList, 0 ); //@@ ::EnableWindow( ::GetParent( ::GetParent( m_hwndParent ) ), FALSE ); int nX; int nY; int nCX; int nCY; RECT rcDesktop; // May 01, 2004 genta マルチモニタ対応 ::GetMonitorWorkRect( GetHwnd(), &rcDesktop ); nX = m_poWin.x - m_nColumnWidth; nY = m_poWin.y + m_nWinHeight + 4; nCX = m_nWidth; nCY = m_nHeight; /* 下に入るなら */ if( nY + nCY < rcDesktop.bottom ){ /* 何もしない */ }else /* 上に入るなら */ if( rcDesktop.top < m_poWin.y - m_nHeight - 4 ){ /* 上に出す */ nY = m_poWin.y - m_nHeight - 4; }else /* 上に出すか下に出すか(広いほうに出す) */ if( rcDesktop.bottom - nY > m_poWin.y ){ /* 下に出す */ // m_nHeight = rcDesktop.bottom - nY; nCY = rcDesktop.bottom - nY; }else{ /* 上に出す */ nY = rcDesktop.top; nCY = m_poWin.y - 4 - rcDesktop.top; } // 2001/06/19 Start by asa-o: 表示位置補正 // 右に入る if(nX + nCX < rcDesktop.right ){ // そのまま }else // 左に入る if(rcDesktop.left < nX - nCX + 8){ // 左に表示 nX -= nCX - 8; }else{ // サイズを調整して右に表示 nCX = t_max((int)(rcDesktop.right - nX) , 100); // 最低サイズを100くらいに } // 2001/06/19 End // 2001/06/18 Start by asa-o: 補正後の位置・サイズを保存 m_poWin.x = nX; m_poWin.y = nY; m_nHeight = nCY; m_nWidth = nCX; // 2001/06/18 End /* はみ出すなら小さくする */ // if( rcDesktop.bottom < nY + nCY ){ // /* 下にはみ出す */ // if( m_poWin.y - 4 - nCY < 0 ){ // /* 上にはみ出す */ // /* →高さだけ調節 */ // nCY = rcDesktop.bottom - nY - 4; // }else{ // // } // // } ::MoveWindow( GetHwnd(), nX, nY, nCX, nCY, TRUE ); ::ShowWindow( GetHwnd(), SW_SHOWNA ); // 2001/06/18 asa-o: ShowTip(); // 補完ウィンドウで選択中の単語にキーワードヘルプを表示 // 2003.06.25 Moca 他のメソッドで使っていないので、とりあえず削除しておく int kouhoNum = m_vKouho.size(); m_vKouho.clear(); return kouhoNum; }
/* 閉じて開く @date 2006.12.30 ryoji CEditView::Command_FILESAVEAS()から処理本体を切り出し */ void CDocFileOperation::FileCloseOpen( const SLoadInfo& _sLoadInfo ) { /* ファイルを閉じるときのMRU登録 & 保存確認 & 保存実行 */ if( !m_pcDocRef->OnFileClose(false) ){ return; } //プラグイン:DocumentCloseイベント実行 CPlug::Array plugs; CWSHIfObj::List params; CJackManager::getInstance()->GetUsablePlug( PP_DOCUMENT_CLOSE, 0, &plugs ); for( CPlug::ArrayIter it = plugs.begin(); it != plugs.end(); it++ ){ (*it)->Invoke(&m_pcDocRef->m_pcEditWnd->GetActiveView(), params); } //ファイル名指定が無い場合はダイアログで入力させる SLoadInfo sLoadInfo = _sLoadInfo; if( sLoadInfo.cFilePath.Length()==0 ){ std::vector<std::tstring> files; if( !OpenFileDialog( CEditWnd::getInstance()->GetHwnd(), NULL, &sLoadInfo, files ) ){ return; } sLoadInfo.cFilePath = files[0].c_str(); // 他のファイルは新規ウィンドウ size_t nSize = files.size(); for( size_t i = 1; i < nSize; i++ ){ SLoadInfo sFilesLoadInfo = sLoadInfo; sFilesLoadInfo.cFilePath = files[i].c_str(); CControlTray::OpenNewEditor( G_AppInstance(), CEditWnd::getInstance()->GetHwnd(), sFilesLoadInfo, NULL, true ); } } /* 既存データのクリア */ m_pcDocRef->InitDoc(); /* 全ビューの初期化 */ m_pcDocRef->InitAllView(); //開く FileLoadWithoutAutoMacro(&sLoadInfo); if( !m_pcDocRef->m_cDocFile.GetFilePathClass().IsValidPath() ){ m_pcDocRef->SetCurDirNotitle(); CAppNodeManager::getInstance()->GetNoNameNumber( m_pcDocRef->m_pcEditWnd->GetHwnd() ); } /* 親ウィンドウのタイトルを更新 */ m_pcDocRef->m_pcEditWnd->UpdateCaption(); // オープン後自動実行マクロを実行する // ※ロードしてなくても(無題)には変更済み m_pcDocRef->RunAutoMacro( GetDllShareData().m_Common.m_sMacro.m_nMacroOnOpened ); //プラグイン:DocumentOpenイベント実行 plugs.clear(); CJackManager::getInstance()->GetUsablePlug( PP_DOCUMENT_OPEN, 0, &plugs ); for( CPlug::ArrayIter it = plugs.begin(); it != plugs.end(); it++ ){ (*it)->Invoke(&m_pcDocRef->m_pcEditWnd->GetActiveView(), params); } }
bool CDocFileOperation::DoSaveFlow(SSaveInfo* pSaveInfo) { ESaveResult eSaveResult = SAVED_FAILURE; try{ //オプション:無変更でも上書きするか // 2009.04.12 ryoji CSaveAgent::OnCheckSave()から移動 // ### 無変更なら上書きしないで抜ける処理はどの CDocListener の OnCheckSave() よりも前に // ### (保存するかどうか問い合わせたりするよりも前に)やるぺきことなので、 // ### スマートじゃない?かもしれないけど、とりあえずここに配置しておく if( !GetDllShareData().m_Common.m_sFile.m_bEnableUnmodifiedOverwrite ){ // 上書きの場合 if(pSaveInfo->bOverwriteMode){ // 無変更の場合は警告音を出し、終了 if (!m_pcDocRef->m_cDocEditor.IsModified() && pSaveInfo->cEol==EOL_NONE && //※改行コード指定保存がリクエストされた場合は、「変更があったもの」とみなす !pSaveInfo->bChgCodeSet) { // 文字コードセットの変更が有った場合は、「変更があったもの」とみなす CEditApp::getInstance()->m_cSoundSet.NeedlessToSaveBeep(); throw CFlowInterruption(); } } } //セーブ前チェック if(CALLBACK_INTERRUPT==m_pcDocRef->NotifyCheckSave(pSaveInfo))throw CFlowInterruption(); //セーブ前おまけ処理 if(CALLBACK_INTERRUPT==m_pcDocRef->NotifyPreBeforeSave(pSaveInfo))throw CFlowInterruption(); // 2006.09.01 ryoji 保存前自動実行マクロを実行する m_pcDocRef->RunAutoMacro( GetDllShareData().m_Common.m_sMacro.m_nMacroOnSave, pSaveInfo->cFilePath ); //プラグイン:DocumentBeforeSaveイベント実行 CPlug::Array plugs; CWSHIfObj::List params; CJackManager::getInstance()->GetUsablePlug( PP_DOCUMENT_BEFORE_SAVE, 0, &plugs ); for( CPlug::ArrayIter it = plugs.begin(); it != plugs.end(); it++ ){ (*it)->Invoke(&m_pcDocRef->m_pcEditWnd->GetActiveView(), params); } if(!pSaveInfo->bOverwriteMode){ //上書きでなければ前文書のクローズイベントを呼ぶ //プラグイン:DocumentCloseイベント実行 plugs.clear(); CJackManager::getInstance()->GetUsablePlug( PP_DOCUMENT_CLOSE, 0, &plugs ); for( CPlug::ArrayIter it = plugs.begin(); it != plugs.end(); it++ ){ (*it)->Invoke(&m_pcDocRef->m_pcEditWnd->GetActiveView(), params); } } //セーブ処理 m_pcDocRef->NotifyBeforeSave(*pSaveInfo); //前処理 m_pcDocRef->NotifySave(*pSaveInfo); //本処理 m_pcDocRef->NotifyAfterSave(*pSaveInfo); //後処理 //プラグイン:DocumentAfterSaveイベント実行 plugs.clear(); CJackManager::getInstance()->GetUsablePlug( PP_DOCUMENT_AFTER_SAVE, 0, &plugs ); for( CPlug::ArrayIter it = plugs.begin(); it != plugs.end(); it++ ){ (*it)->Invoke(&m_pcDocRef->m_pcEditWnd->GetActiveView(), params); } //結果 eSaveResult = SAVED_OK; //###仮 } catch(CFlowInterruption){ eSaveResult = SAVED_INTERRUPT; } catch(...){ //予期せぬ例外が発生した場合も NotifyFinalSave は必ず呼ぶ! m_pcDocRef->NotifyFinalSave(SAVED_FAILURE); throw; } //最終処理 m_pcDocRef->NotifyFinalSave(eSaveResult); return eSaveResult==SAVED_OK; }