⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ceditdoc.cpp

📁 日本的开源编辑器源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	if( bKillFocus ){
		ExpandParameter( m_pShareData->m_Common.m_szWindowCaptionInactive,
			pszCap, sizeof( pszCap ));
	}
	else {
		ExpandParameter( m_pShareData->m_Common.m_szWindowCaptionActive,
			pszCap, sizeof( pszCap ));
	}
	// To Here Apr. 04, 2003 genta

	::SetWindowText( m_hwndParent, pszCap );

	//@@@ From Here 2003.06.13 MIK
	//タブウインドウのファイル名を通知
	ExpandParameter( m_pShareData->m_Common.m_szTabWndCaption, pszCap, sizeof( pszCap ));
	m_pcEditWnd->ChangeFileNameNotify( pszCap );
	//@@@ To Here 2003.06.13 MIK

	return;
}

/*! バックアップの作成
	@author genta
	@date 2001.06.12 asa-o
		ファイルの時刻を元にバックアップファイル名を作成する機能
	@date 2001.12.11 MIK バックアップファイルをゴミ箱に入れる機能
	@date 2004.06.05 genta バックアップ対象ファイルを引数で与えるように.
		名前を付けて保存の時は自分のバックアップを作っても無意味なので.
		また,バックアップも保存も行わない選択肢を追加.

	@retval 0 バックアップ作成失敗.
	@retval 1 バックアップ作成成功.
	@retval 2 バックアップ作成失敗.保存中断指示.
	@retval 3 ファイル操作エラーによるバックアップ作成失敗.
*/
int CEditDoc::MakeBackUp( const char* target_file )
{
	time_t	ltime;
	struct	tm *today, *gmt, xmas = { 0, 0, 12, 25, 11, 93 };
	char	szTime[64];
	char	szForm[64];
	char	szPath[_MAX_PATH];
	char	szDrive[_MAX_DIR];
	char	szDir[_MAX_DIR];
	char	szFname[_MAX_FNAME];
	char	szExt[_MAX_EXT];
//	int		nLen;
	int		nRet;
	char*	pBase;

	/* バックアップソースの存在チェック */
	if( (_access( target_file, 0 )) == -1 ){
		return 0;
	}

	/* パスの分解 */
	_splitpath( target_file, szDrive, szDir, szFname, szExt );

	if( m_pShareData->m_Common.m_bBackUpFolder ){	/* 指定フォルダにバックアップを作成する */
		strcpy( szPath, m_pShareData->m_Common.m_szBackUpFolder );
		/* フォルダの最後が半角かつ'\\'でない場合は、付加する */
		AddLastYenFromDirectoryPath( szPath );
	}
	else{
		wsprintf( szPath, "%s%s", szDrive, szDir );
	}
	pBase = szPath + strlen( szPath );

	/* バックアップファイル名のタイプ 1=(.bak) 2=*_日付.* */
	switch( m_pShareData->m_Common.GetBackupType() ){
	case 1:
		wsprintf( pBase, "%s.bak", szFname );
		break;
	case 5: //	Jun.  5, 2005 genta 1の拡張子を残す版
		wsprintf( pBase, "%s%s.bak", szFname, szExt );
		break;
	case 2:	//	日付,時刻
		_tzset();
		_strdate( szTime );
		time( &ltime );				/* システム時刻を得ます */
		gmt = gmtime( &ltime );		/* 万国標準時に変換する */
		today = localtime( &ltime );/* 現地時間に変換する */

		strcpy( szForm, "" );
		if( m_pShareData->m_Common.GetBackupOpt(BKUP_YEAR) ){	/* バックアップファイル名:日付の年 */
			strcat( szForm, "%Y" );
		}
		if( m_pShareData->m_Common.GetBackupOpt(BKUP_MONTH) ){	/* バックアップファイル名:日付の月 */
			strcat( szForm, "%m" );
		}
		if( m_pShareData->m_Common.GetBackupOpt(BKUP_DAY) ){	/* バックアップファイル名:日付の日 */
			strcat( szForm, "%d" );
		}
		if( m_pShareData->m_Common.GetBackupOpt(BKUP_HOUR) ){	/* バックアップファイル名:日付の時 */
			strcat( szForm, "%H" );
		}
		if( m_pShareData->m_Common.GetBackupOpt(BKUP_MIN) ){	/* バックアップファイル名:日付の分 */
			strcat( szForm, "%M" );
		}
		if( m_pShareData->m_Common.GetBackupOpt(BKUP_SEC) ){	/* バックアップファイル名:日付の秒 */
			strcat( szForm, "%S" );
		}
		/* YYYYMMDD時分秒 形式に変換 */
		strftime( szTime, sizeof( szTime ) - 1, szForm, today );
		wsprintf( pBase, "%s_%s%s", szFname, szTime, szExt );
		break;
//	2001/06/12 Start by asa-o: ファイルに付ける日付を前回の保存時(更新日時)にする
	case 4:	//	日付,時刻
		{
			HANDLE		hFile;
			FILETIME	LastWriteTime,
						LocalTime;
			SYSTEMTIME	SystemTime;

			hFile = ::CreateFile(target_file,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
			::GetFileTime(hFile,NULL,NULL,&LastWriteTime);			// ファイルのタイプスタンプを取得(更新日時のみ)
			CloseHandle(hFile);
			::FileTimeToLocalFileTime(&LastWriteTime,&LocalTime);	// 現地時刻に変換
			::FileTimeToSystemTime(&LocalTime,&SystemTime);			// システムタイムに変換

			strcpy( szTime, "" );
			if( m_pShareData->m_Common.GetBackupOpt(BKUP_YEAR) ){	/* バックアップファイル名:日付の年 */
				wsprintf(szTime,"%d",SystemTime.wYear);
			}
			if( m_pShareData->m_Common.GetBackupOpt(BKUP_MONTH) ){	/* バックアップファイル名:日付の月 */
				wsprintf(szTime,"%s%02d",szTime,SystemTime.wMonth);
			}
			if( m_pShareData->m_Common.GetBackupOpt(BKUP_DAY) ){	/* バックアップファイル名:日付の日 */
				wsprintf(szTime,"%s%02d",szTime,SystemTime.wDay);
			}
			if( m_pShareData->m_Common.GetBackupOpt(BKUP_HOUR) ){	/* バックアップファイル名:日付の時 */
				wsprintf(szTime,"%s%02d",szTime,SystemTime.wHour);
			}
			if( m_pShareData->m_Common.GetBackupOpt(BKUP_MIN) ){	/* バックアップファイル名:日付の分 */
				wsprintf(szTime,"%s%02d",szTime,SystemTime.wMinute);
			}
			if( m_pShareData->m_Common.GetBackupOpt(BKUP_SEC) ){	/* バックアップファイル名:日付の秒 */
				wsprintf(szTime,"%s%02d",szTime,SystemTime.wSecond);
			}
			wsprintf( pBase, "%s_%s%s", szFname, szTime, szExt );
		}
		break;
// 2001/06/12 End

	case 3: //	?xx : xx = 00~99, ?は任意の文字
	case 6: //	Jun.  5, 2005 genta 3の拡張子を残す版
		//	Aug. 15, 2000 genta
		//	ここでは作成するバックアップファイル名のみ生成する.
		//	ファイル名のRotationは確認ダイアログの後で行う.
		{
			//	Jun.  5, 2005 genta 拡張子を残せるように処理起点を操作する
			char* ptr;
			if( m_pShareData->m_Common.GetBackupType() == 3 ){
				ptr = szExt;
			}
			else {
				ptr = szExt + strlen( szExt );
			}
			*ptr   = '.';
			*++ptr = m_pShareData->m_Common.GetBackupExtChar();
			*++ptr = '0';
			*++ptr = '0';
			*++ptr = '\0';
		}
		wsprintf( pBase, "%s%s", szFname, szExt );
		break;
	}

	//@@@ 2002.03.23 start ネットワーク?リムーバブルドライブの場合はごみ箱に放り込まない
	bool dustflag = false;
	if( m_pShareData->m_Common.m_bBackUpDustBox ){
		if( szPath[0] == '\\' && szPath[1] == '\\' ) dustflag = true;
		else if( isalpha(szPath[0]) ){
			char	szDriveType[_MAX_DRIVE+1];	// "A:\"登録用
			long	lngRet;
			sprintf(szDriveType, "%c:\\", toupper(szPath[0]));
			lngRet = GetDriveType( szDriveType );
			if( lngRet == DRIVE_REMOVABLE || lngRet == DRIVE_CDROM || lngRet == DRIVE_REMOTE ) dustflag = true;
		}
	}
	//@@@ 2002.03.23 end

	if( m_pShareData->m_Common.m_bBackUpDialog ){	/* バックアップの作成前に確認 */
		::MessageBeep( MB_ICONQUESTION );
//From Here Feb. 27, 2001 JEPROtest キャンセルもできるようにし、メッセージを追加した
//		if( IDYES != MYMESSAGEBOX(
//			m_hWnd,
//			MB_YESNO | MB_ICONQUESTION | MB_TOPMOST,
//			"バックアップ作成の確認",
//			"変更される前に、バックアップファイルを作成します。\nよろしいですか?\n\n%s\n    ↓\n%s\n\n",
//			IsFilePathAvailable() ? GetFilePath() : "(未命名)",
//			szPath
//		) ){
//			return FALSE;
//		}
		if( m_pShareData->m_Common.m_bBackUpDustBox && dustflag == false ){	//@@@ 2001.12.11 add start MIK	//2002.03.23
			nRet = ::MYMESSAGEBOX(
				m_hWnd,
				MB_YESNO/*CANCEL*/ | MB_ICONQUESTION | MB_TOPMOST,
				"バックアップ作成の確認",
				"変更される前に、バックアップファイルを作成します。\nよろしいですか?  [いいえ(N)] を選ぶと作成せずに上書き(または名前を付けて)保存になります。\n\n%s\n    ↓\n%s\n\n作成したバックアップファイルをごみ箱に放り込みます。\n",
				target_file,
				szPath
			);
		}else{	//@@@ 2001.12.11 add end MIK
			nRet = ::MYMESSAGEBOX(
				m_hWnd,
				MB_YESNOCANCEL | MB_ICONQUESTION | MB_TOPMOST,
				"バックアップ作成の確認",
				"変更される前に、バックアップファイルを作成します。\nよろしいですか?  [いいえ(N)] を選ぶと作成せずに上書き(または名前を付けて)保存になります。\n\n%s\n    ↓\n%s\n\n",
				IsFilePathAvailable() ? GetFilePath() : "(未命名)",
				szPath
			);	//Jul. 06, 2001 jepro [名前を付けて保存] の場合もあるのでメッセージを修正
		}	//@@@ 2001.12.11 add MIK
		//	Jun.  5, 2005 genta 戻り値変更
		if( IDNO == nRet ){
			return 0;//	保存継続
		}else if( IDCANCEL == nRet ){
			return 2;// 保存中断
		}
//To Here Feb. 27, 2001
	}

	//	From Here Aug. 16, 2000 genta
	//	Jun.  5, 2005 genta 1の拡張子を残す版を追加
	if( m_pShareData->m_Common.GetBackupType() == 3 ||
		m_pShareData->m_Common.GetBackupType() == 6 ){
		//	既に存在するBackupをずらす処理
		int				i;

		//	ファイル検索用
		HANDLE			hFind;
		WIN32_FIND_DATA	fData;

		pBase = pBase + strlen( pBase ) - 2;	//	2: 拡張子の最後の2桁の意味
		//::MessageBox( NULL, pBase, "書き換え場所", MB_OK );

		//------------------------------------------------------------------
		//	1. 該当ディレクトリ中のbackupファイルを1つずつ探す
		for( i = 0; i <= 99; i++ ){	//	最大値に関わらず,99(2桁の最大値)まで探す
			//	ファイル名をセット
			wsprintf( pBase, "%02d", i );

			hFind = ::FindFirstFile( szPath, &fData );
			if( hFind == INVALID_HANDLE_VALUE ){
				//	検索に失敗した == ファイルは存在しない
				break;
			}
			::FindClose( hFind );
			//	見つかったファイルの属性をチェック
			//	は面倒くさいからしない.
			//	同じ名前のディレクトリがあったらどうなるのだろう...
		}
		--i;

		//------------------------------------------------------------------
		//	2. 最大値から制限数-1番までを削除
		int boundary = m_pShareData->m_Common.GetBackupCount();
		boundary = boundary > 0 ? boundary - 1 : 0;	//	最小値は0
		//::MessageBox( NULL, pBase, "書き換え場所", MB_OK );

		for( ; i >= boundary; --i ){
			//	ファイル名をセット
			wsprintf( pBase, "%02d", i );
			if( ::DeleteFile( szPath ) == 0 ){
				::MessageBox( m_hWnd, szPath, "削除失敗", MB_OK );
				//	Jun.  5, 2005 genta 戻り値変更
				//	失敗しても保存は継続
				return 0;
				//	失敗した場合
				//	後で考える
			}
		}

		//	この位置でiは存在するバックアップファイルの最大番号を表している.

		//	3. そこから0番まではコピーしながら移動
		char szNewPath[MAX_PATH];
		char *pNewNrBase;

		strcpy( szNewPath, szPath );
		pNewNrBase = szNewPath + strlen( szNewPath ) - 2;

		for( ; i >= 0; --i ){
			//	ファイル名をセット
			wsprintf( pBase, "%02d", i );
			wsprintf( pNewNrBase, "%02d", i + 1 );

			//	ファイルの移動
			if( ::MoveFile( szPath, szNewPath ) == 0 ){
				//	失敗した場合
				//	後で考える
				::MessageBox( m_hWnd, szPath, "移動失敗", MB_OK );
				//	Jun.  5, 2005 genta 戻り値変更
				//	失敗しても保存は継続
				return 0;
			}
		}
	}
	//	To Here Aug. 16, 2000 genta

	//::MessageBox( NULL, szPath, "直前のバックアップファイル", MB_OK );
	/* バックアップの作成 */
	if( ::CopyFile( GetFilePath(), szPath, FALSE ) ){
		/* 正常終了 */
		//@@@ 2001.12.11 start MIK
		if( m_pShareData->m_Common.m_bBackUpDustBox && dustflag == false ){	//@@@ 2002.03.23 ネットワーク?リムーバブルドライブでない
			char	szDustPath[_MAX_PATH+1];
			strcpy(szDustPath, szPath);
			szDustPath[strlen(szDustPath) + 1] = '\0';
			SHFILEOPSTRUCT	fos;
			fos.hwnd   = m_hWnd;
			fos.wFunc  = FO_DELETE;
			fos.pFrom  = szDustPath;
			fos.pTo    = NULL;
			fos.fFlags = FOF_ALLOWUNDO | FOF_SIMPLEPROGRESS | FOF_NOCONFIRMATION;	//ダイアログなし
			//fos.fFlags = FOF_ALLOWUNDO | FOF_FILESONLY;
			//fos.fFlags = FOF_ALLOWUNDO;	//ダイアログが表示される。
			fos.fAnyOperationsAborted = true; //false;
			fos.hNameMappings = NULL;
			fos.lpszProgressTitle = NULL; //"バックアップファイルをごみ箱に移動しています...";
			if( ::SHFileOperation(&fos) == 0 ){
				/* 正常終了 */
			}else{
				/* エラー終了 */
			}
		}
		//@@@ 2001.12.11 end MIK
	}else{
		/* エラー終了 */
		//	Jun.  5, 2005 genta 戻り値変更
		return 3;
	}
	//	Jun.  5, 2005 genta 戻り値変更
	return 1;
}




/* ファイルの排他ロック */
void CEditDoc::DoFileLock( void )
{
	char*	pszMode;
	int		nAccessMode;
	BOOL	bCheckOnly;

	/* ロックしている */
	if( NULL != m_hLockedFile ){
		/* ロック解除 */
		::_lclose( m_hLockedFile );
		m_hLockedFile = NULL;
	}

	/* ファイルが存在しない */
	if( -1 == _access( GetFilePath(), 0 ) ){
		/* ファイルの排他制御モード */
		m_nFileShareModeOld = 0;
		return;
	}else{
		/* ファイルの排他制御モード */
		m_nFileShareModeOld = m_pShareData->m_Common.m_nFileShareMode;
	}


	/* ファイルを開いていない */
	if( ! IsFilePathAvailable() ){
		return;
	}
	/* 読み取り専用モード */
	if( TRUE == m_bReadOnly ){
		return;
	}


	nAccessMode = 0;
	if( m_pShareData->m_Common.m_nFileShareMode == OF_SHARE_DENY_WRITE ||
		m_pShareData->m_Common.m_nFileShareMode == OF_SHARE_EXCLUSIVE ){
		bCheckOnly = FALSE;
	}else{
		/* 排他制御しないけどロックされているかのチェックは行うのでreturnしない */
//		return;
		bCheckOnly = TRUE;
	}
	/* 書込み禁止かどうか調べる */
	if( -1 == _access( GetFilePath(), 2 ) ){	/* アクセス権:書き込み許可 */
#if 0
		// Apr. 28, 2000 genta: Request from Koda

		::MessageBeep( MB_ICONEXCLAMATION );
		MYMESSAGEBOX(
			m_hWnd,
			MB_OK | MB_ICONEXCLAMATION | MB_TOPMOST,
			GSTR_APPNAME,
			"現在\n%s\nは読取専用に設定されています。 または、書き込みのアクセス権がありません。",
			IsFilePathAvailable() ? GetFilePath() : "(未命名)"
		);
#endif
		m_hLockedFile = NULL;
		/* 親ウィンドウのタイトルを更新 */
		SetParentCaption();
		return;
	}


	m_hLockedFile = ::_lopen( GetFilePath(), OF_READWRITE );
	_lclose( m_hLockedFile );
	if( HFILE_ERROR == m_hLockedFile ){
		::MessageBeep( MB_ICONEXCLAMATION );
		MYMESSAGEBOX(

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -