/********************************************************************************
*	ファイル名：System.h														*
*	用　　　途：処理系依存型情報の取り扱い										*
*	備　　　考：Ｗｉｎｄｏｗｓ（ＮＴ以降）用Ｃライブラリ						*
*	履　　　歴：																*
********************************************************************************/
/****************************
*	 コンパイル環境設定		*
****************************/
/****************************
*	 プリコンパイル設定		*
****************************/
#include "stdafx.h"
/****************************
*	インクルードファイル	*
****************************/
#include "System.h"
/****************************
*		 マクロ定数			*
****************************/
/****************************
*		 構造体定義			*
****************************/
/***** ShowAndEnableCtrls関数用構造体 *****/
typedef struct tagSEFINFO
{ 
	INT32	nMode;		/* モード(SEC_SHOW/SEC_ENABLE)	*/
	BOOL	bFlg;		/* (表示/非表示) / (有効/無効)	*/ 
	RECT	rect;		/* 矩形							*/
} SEFINFO;

/****************************
*		 クラス定義			*
****************************/
/****************************
*		 関数　宣言			*
****************************/
static INT32	GetPathString(TCHAR *szDst, TCHAR *szSrc, INT32 nSkip);
static BOOL		SetPrivilege(LPCTSTR szName, BOOL bAdd);
static BOOL		CALLBACK ShowAndEnableFunc(HWND hWnd, LPARAM nSefInfo);
/****************************
*		 変数　宣言			*
****************************/
static	SIZE_T			m_uDefWorkMemMin	= 0;	/* デフォルトワーキングセット（最小）	*/	
static	SIZE_T			m_uDefWorkMemMax	= 0;	/* ワーキングセットデフォルト（最大）	*/
/********************************************************************************
*	関　数　名：SetWorkingSet													*
*	用　　　途：ワーキングセットのサイズを設定する								*
*	引　き　数：最小ワーキングセット、最大ワーキングセット						*
*	戻　り　値：																*
*	備　　　考：Windows(NT以降）専用											*
********************************************************************************/
BOOL SetWorkingSet(SIZE_T uMinSize, SIZE_T uMaxSize)
{
	HANDLE	vpProcess;
	BOOL	bRet;

	vpProcess = GetCurrentProcess();

	/***** 現状のワーキングセットを取得し設定を保存 *****/
	if ( m_uDefWorkMemMin == 0 && m_uDefWorkMemMax == 0 )
	{
		GetProcessWorkingSetSize(vpProcess, &m_uDefWorkMemMin, &m_uDefWorkMemMax);
	}

	/***** 指定サイズ０で初期状態に戻す *****/
	if ( uMinSize == 0 && uMaxSize == 0 )
	{
		bRet = SetProcessWorkingSetSize(vpProcess, m_uDefWorkMemMin, m_uDefWorkMemMax);
	}
	else
	{
		bRet = SetProcessWorkingSetSize(vpProcess, uMinSize, uMaxSize);
	}

	return bRet;
}

/********************************************************************************
*	関　数　名：ShutDown														*
*	用　　　途：シャットダウン													*
*	引　き　数：ウインドウ終了オプション										*
*	戻　り　値：																*
*	備　　　考：Windows(NT以降）専用											*
********************************************************************************/
void ShutDown(UINT32 uFlags)
{
	/***** 特権を付加する *****/
	SetPrivilege(SE_SHUTDOWN_NAME, TRUE);

	/***** Windowsを終了 ******/
		/********************************************************************
		*	EWX_POWEROFF	: Windowsを終了(シャットダウン後、電源を切る)	*
		*	EWX_FORCE		: プロセスを強制的に終了する					*
		*	EWX_FORCEIFHUNG	: ハングしたプロセスを強制的に終了する			*
		*	EWX_REBOOT		: Windowsを再起動								*
		*	EWX_SHUTDOWN	: Windowsをシャットダウン						*
		********************************************************************/

	ExitWindowsEx(uFlags, 0);

	/***** 特権を削除する *****/
	SetPrivilege(SE_SHUTDOWN_NAME, FALSE);
}

/********************************************************************************
*	関　数　名：Restart															*
*	用　　　途：再起動															*
*	引　き　数：ウインドウ終了オプション										*
*	戻　り　値：																*
*	備　　　考：Windows(NT以降）専用											*
********************************************************************************/
void Restart(UINT32 uFlags)
{
	/***** 特権を付加する *****/
	SetPrivilege(SE_SHUTDOWN_NAME, TRUE);

	/***** Windowsを終了 *****/
		/********************************************************************
		*	EWX_POWEROFF	: Windowsを終了(シャットダウン後、電源を切る)	*
		*	EWX_FORCE		: プロセスを強制的に終了する					*
		*	EWX_FORCEIFHUNG	: ハングしたプロセスを強制的に終了する			*
		*	EWX_REBOOT		: Windowsを再起動								*
		*	EWX_SHUTDOWN	: Windowsをシャットダウン						*
		********************************************************************/
	ExitWindowsEx(uFlags, 0);

	/***** 特権を削除する *****/
	SetPrivilege(SE_SHUTDOWN_NAME, FALSE);
}

/********************************************************************************
*	関　数　名：GetMyPath														*
*	用　　　途：実行ディレクトリ名の取得										*
*	引　き　数：ディレクトリ名格納場所、取得フラグ								*
*	戻　り　値：																*
*	備　　　考：格納先は十分なサイズを用意すること								*
********************************************************************************/
void GetMyPath(TCHAR *szDst , INT32 nFlag)
{
	TCHAR	szPath[_MAX_PATH];
	TCHAR	szDrive[_MAX_DRIVE];
	TCHAR	szDir[_MAX_DIR];

	switch(nFlag)
	{
	case GET_EXEPATH:

		/***** 実行ディレクトリ名の取得 *****/
		GetModuleFileName(GetModuleHandle(AfxGetAppName()), szPath, sizeof szPath);
		_tsplitpath(szPath, szDrive, szDir, 0, 0);
		_tcscpy(szDst, szDrive);
		_tcscat(szDst, szDir);
		break;

	case GET_CURRENTPATH:

		/***** カレントディレクトリ名の取得 *****/
		GetCurrentDirectory(sizeof szPath , szPath);
		_tcscat(szPath, _T("\\"));
		_tcscpy(szDst, szPath);
		break;
	}
}

/********************************************************************************
*	関　数　名：PhysicalMemoryLock												*
*	用　　　途：物理メモリのロック												*
*	引　き　数：物理メモリロック情報格納場所									*
*	戻　り　値：成功でＴＲＵＥ、失敗でＦＡＬＳＥ								*
*	備　　　考：このプログラムを動かすユーザーにページメモリロック権限が必要。	*
*				ローカルポリシーにて設定すること。								*
*				引数の構造体のnDemandSizeに要求サイズを指定しておくこと			*
********************************************************************************/
BOOL PhysicalMemoryLock(PHYSMEMLOCK *tpInfo)
{
	SIZE_T		uSize;			/* 要求サイズ（バイト）			*/
	ULONG_PTR	uDemandPages;	/* 要求ページ数					*/
	ULONG_PTR	uRealPages;		/* 実際に取得できたページ数		*/
	SIZE_T		uPFNArraySize;	/* ＰＦＮ配列サイズ				*/
	PULONG_PTR	upPFN;			/* ＰＦＮ配列					*/
	PVOID		vpReserved;		/* アドレスウインドウ拡張(AWE)	*/
	HANDLE		vpProcess;		/* プロセスハンドル				*/
	HANDLE		vpHeap;			/* ヒープハンドル				*/
	SYSTEM_INFO tSysInfo;		/* システム情報					*/

	/***** 前提条件 *****/
	if (tpInfo == 0) return FALSE;

	if (tpInfo->uDemandSize <= 0) return FALSE;

	/***** 回答領域初期化 *****/
	tpInfo->uPFNArraySize	= 0;
	tpInfo->upPFN			= 0;
	tpInfo->uRealPages		= 0;
	tpInfo->vpReserved		= 0;

	/***** 初期化 *****/
	uSize			= tpInfo->uDemandSize;

	GetSystemInfo(&tSysInfo);

	/***** 必要なページ数を計算 *****/
	uDemandPages	= (uSize + tSysInfo.dwPageSize - 1) / tSysInfo.dwPageSize;

	/***** プロセスのヒープハンドルを取得 *****/
	vpHeap			= GetProcessHeap();

	/***** ページフレーム番号配列の生成 *****/
	uPFNArraySize	= uDemandPages * sizeof (ULONG_PTR);
	upPFN			= (PULONG_PTR)HeapAlloc(vpHeap, 0, uPFNArraySize);

	if (upPFN == 0)
	{
		return FALSE;
	}

	/***** メモリロック権限追加 *****/
	if ( !SetPrivilege(SE_LOCK_MEMORY_NAME, TRUE) )
	{
		HeapFree(vpHeap, 0, upPFN);
		return FALSE;
	}

	/***** プロセスハンドルの取得 *****/
	vpProcess = GetCurrentProcess();

	/***** 物理メモリの取得 *****/
	uRealPages = uDemandPages;

	if ( !AllocateUserPhysicalPages(vpProcess, &uRealPages, upPFN) )
	{
		HeapFree(vpHeap, 0, upPFN);
		return FALSE;
	}

	/***** 要求量取れなかった？ *****/
	if( uRealPages < uDemandPages ) 
	{
		FreeUserPhysicalPages(vpProcess, &uRealPages, upPFN);
		HeapFree(vpHeap, 0, upPFN);
		uRealPages = 0;
		return FALSE;
	}

	/***** 取得した物理メモリを仮想メモリにアドオン *****/
	vpReserved	= VirtualAlloc(
								0,
								uSize,
								MEM_RESERVE | MEM_PHYSICAL,
								PAGE_READWRITE
							  );

	if (vpReserved == 0) 
	{
		FreeUserPhysicalPages(vpProcess, &uRealPages, upPFN);
		HeapFree(vpHeap, 0, upPFN);
		return FALSE;
	}

	/***** 物理メモリをウインドウにマッピング *****/
	if ( !MapUserPhysicalPages(vpReserved, uRealPages, upPFN) )
	{
		FreeUserPhysicalPages(vpProcess, &uRealPages, upPFN);
		HeapFree(vpHeap, 0, upPFN);
		return FALSE;
	}

	/***** 回答設定 *****/
	tpInfo->uPFNArraySize	= uPFNArraySize;
	tpInfo->upPFN			= upPFN;
	tpInfo->uRealPages		= uRealPages;
	tpInfo->vpReserved		= vpReserved;

	return TRUE;
}

/********************************************************************************
*	関　数　名：PhysicalMemoryUnlock											*
*	用　　　途：物理メモリの開放												*
*	引　き　数：物理メモリロック情報格納場所									*
*	戻　り　値：成功でＴＲＵＥ、失敗でＦＡＬＳＥ								*
*	備　　　考：開放処理は失敗したところでどうにもならない						*
********************************************************************************/
BOOL PhysicalMemoryUnlock(PHYSMEMLOCK *tpInfo)
{
	HANDLE		vpProcess;		/* プロセスハンドル				*/
	HANDLE		vpHeap;			/* ヒープハンドル				*/

	/***** 引数異常 *****/
	if (tpInfo == 0) return FALSE;

	/***** 現時点でロックされていないものと考えられる *****/	
	if (tpInfo->vpReserved == 0 || tpInfo->uRealPages == 0)
	{
		return FALSE;
	}

	/***** マップ情報を解除 *****/
	if ( !MapUserPhysicalPages(tpInfo->vpReserved, tpInfo->uRealPages, 0) )
	{
		return FALSE;
	}

	/***** プロセスハンドルの取得 *****/
	vpProcess = GetCurrentProcess();

	/***** 物理メモリの開放 *****/
	if ( !FreeUserPhysicalPages(vpProcess, &(tpInfo->uRealPages), tpInfo->upPFN) )
	{
		return FALSE;
	}

	/***** 仮想メモリ解除 *****/
	if ( !VirtualFree(tpInfo->vpReserved, 0, MEM_RELEASE) )
	{
		return FALSE;
	}

	/***** プロセスのヒープハンドルを取得 *****/
	vpHeap = GetProcessHeap();

	/***** ページフレーム番号配列の開放 *****/
	HeapFree(vpHeap, 0, tpInfo->upPFN);

	/***** メンバー初期化 *****/
	tpInfo->uRealPages		= 0;
	tpInfo->uPFNArraySize	= 0;
	tpInfo->upPFN			= 0;
	tpInfo->vpReserved		= 0;

	return TRUE;
}

/********************************************************************************
*	関　数　名：TraceLastError													*
*	用　　　途：GetLastErrorで取得できるエラーのダンプ出力						*
*	引　き　数：																*
*	戻　り　値：																*
*	備　　　考：デバッグモード時はトレース出力									*
*				リリース時にはメッセージボックスで表示							*
********************************************************************************/
void TraceLastError()
{
	LPVOID lpErrMsg;

	FormatMessage(
					FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
					NULL,
					GetLastError(),
					MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
					(LPTSTR)&lpErrMsg,
					0,
					NULL
				);

#ifdef _DEBUG
	TRACE("SysErr(%s)\n", (LPCTSTR)lpErrMsg);
#else
	MessageBox(0, (LPCTSTR)lpErrMsg, _T("System Dump"), MB_OK);
#endif

	LocalFree(lpErrMsg);
}

/********************************************************************************
*	関　数　名：SetPrivilege													*
*	用　　　途：特権の設定														*
*	引　き　数：特権名、追加／削除フラグ										*
*	戻　り　値：成功でＴＲＵＥ、失敗でＦＡＬＳＥ								*
*	備　　　考：追加／削除フラグは追加時はＴＲＵＥ、削除時はＦＡＬＳＥ			*
********************************************************************************/
static BOOL SetPrivilege(LPCTSTR szName, BOOL bAdd)
{
    HANDLE				vpProcess;			/* プロセスＩＤ					*/
    HANDLE				vpToken;			/* トークンハンドル				*/
    LUID				tLuid;				/* ローカルユニークＩＤ			*/
    TOKEN_PRIVILEGES    tNew;				/* 新たに設定した特権			*/
	BOOL				bOk;

	/***** 初期化 *****/
	bOk = FALSE;

	/***** LUIDを取得し、指定された特権名をローカルで表現 *****/
	if (!LookupPrivilegeValue(0, szName, &tLuid))
	{
		return FALSE;
	}

	/***** 現在のプロセスに対応する擬似ハンドラを取得 *****/
    vpProcess = GetCurrentProcess();

	/***** アクセストークンを開く *****/
    if ( !OpenProcessToken(vpProcess, TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &vpToken) )
	{
		return FALSE;
	}

	tNew.PrivilegeCount					= 1;
    tNew.Privileges[0].Luid				= tLuid;
	tNew.Privileges[0].Attributes		= (bAdd) ? SE_PRIVILEGE_ENABLED : 0;

	/***** 特権の追加/削除 *****/
	AdjustTokenPrivileges(vpToken, FALSE, &tNew, 0, 0, 0);
    if( GetLastError() == ERROR_SUCCESS ) 
    {
		bOk = TRUE;
	}

	CloseHandle(vpToken);

	return bOk;
}

/********************************************************************************
*	関数名：GetPathString														*
*	用　途：部分パスの取得														*
*	引き数：部分パス格納バッファ、元パス、区切り読み飛ばし数					*
*	戻り値：取得成功でＴＲＵＥ，失敗でＦＡＬＳＥ								*
*	備　考：																	*
********************************************************************************/
static INT32 GetPathString(TCHAR *szDst, TCHAR *szSrc, INT32 nSkip)
{
	INT32 i, j, k;

	for ( i = j = k = 0; i < (int)_tcslen(szSrc); i++, j++ )
    {
		if ( szSrc[i] == _T('\\') )
        {
            if ( k >= nSkip ) break;
            k++;
        }
		szDst[j] = szSrc[i];
    }

    szDst[j] = _T('\0');
	if ( k < nSkip ) return FALSE;

	return TRUE;
}

/********************************************************************************
*	関数名：MakeSureDirectoryPathExists											*
*	用　途：ディレクトリの作成													*
*	引き数：作成ディレクトリ													*
*	戻り値：作成成功でＴＲＵＥ，失敗でＦＡＬＳＥ								*
*	備　考：途中のディレクトリが存在しない場合、それも作成する					*
********************************************************************************/
BOOL MakeSureDirectoryPathExists(TCHAR *szTargetPath)
{
	CFileFind	find;
    TCHAR		szFullPath[_MAX_PATH];
	TCHAR		szPath[_MAX_PATH];
	BOOL		bRet;
	BOOL		bFind;
	INT32		i;

	if (_tfullpath(szFullPath, szTargetPath, _MAX_PATH) == 0)
	{
		return FALSE;
	}

	bRet = TRUE;

	for (i = 1; GetPathString(szPath, szFullPath, i); i++)
    {
		bFind	= find.FindFile((LPCTSTR)szPath);

		find.Close();

		if(bFind) continue;

		if(CreateDirectory(szPath, 0) == 0)
		{
			bRet = FALSE;
		}
    }

	return bRet;
}

/********************************************************************************
*	関数名：GetFolder															*
*	用　途：フォルダの取得														*
*	引き数：ウインドウハンドル、フォルダ名格納場所								*
*	戻り値：取得した場合ＴＲＵＥ、しなかった場合ＦＡＬＳＥ						*
*	備　考：																	*
********************************************************************************/
BOOL GetFolder(HWND hWnd, TCHAR *szPath)
{
	LPMALLOC		pMalloc;
	LPITEMIDLIST	pidlRoot, pidlBrowse;
	BROWSEINFO		bi;
	BOOL			bRet;
	TCHAR			szBuf[_MAX_PATH];
	size_t	nLen;

	if (szPath == 0) return FALSE;

	if (SHGetMalloc(&pMalloc) != NOERROR) return FALSE;

	SHGetSpecialFolderLocation(hWnd, CSIDL_DRIVES, &pidlRoot);

	ZeroMemory(&bi, sizeof(BROWSEINFO));

	bi.hwndOwner		= hWnd;
	bi.pidlRoot			= pidlRoot; // NULL の時マイコンピュータから表示
	bi.pszDisplayName	= szBuf;
	bi.lpszTitle		= _T("Please select folder.");
	bi.ulFlags			= BIF_RETURNONLYFSDIRS;
	bi.lpfn				= NULL;
	//bi.lParam
	//bi.iImage
	
	pidlBrowse			= SHBrowseForFolder(&bi);
	bRet				= SHGetPathFromIDList(pidlBrowse, szBuf);

	if( pidlRoot != NULL )	 pMalloc->Free(pidlRoot);
	if( pidlBrowse != NULL ) pMalloc->Free(pidlBrowse);

	pMalloc->Release();

	if ( !bRet )  return FALSE;

	nLen = _tcslen(szBuf) - 1;
	if ( szBuf[nLen] != _T('\\') )
	{
		if ( nLen >= _MAX_PATH - 2)
		{
			szBuf[_MAX_PATH - 2] = _T('\0');
			nLen = _MAX_PATH - 3;
		}
		szBuf[nLen+1] = _T('\\');
		szBuf[nLen+2] = _T('\0');
	}

	_tcscpy(szPath, szBuf);

	return TRUE;
}

/********************************************************************************
*	関数名：DeleteDirectory														*
*	用　途：フォルダの削除														*
*	引き数：削除したいフォルダパス												*
*	戻り値：削除成功でＴＲＵＥ、失敗でＦＡＬＳＥ								*
*	備　考：フォルダは空でなくてもよい											*
*			隠しファイルも削除するが権限が必要な場合は失敗する					*
********************************************************************************/
BOOL DeleteDirectory(CString &strPath)
{
    CFileFind	find;
	CString		str, strFind, strDeleteFile;
	BOOL		bFind;

	str		= strPath;
	str.TrimRight(_T('\\'));
	strFind	= str + _T("\\*.*");

	bFind	= find.FindFile(strFind); 

	while(bFind)
	{
		bFind = find.FindNextFile();

		if ( find.IsDots() ) continue;

		strDeleteFile = find.GetFilePath();
	
		if( find.IsDirectory() )
		{
			DeleteDirectory(strDeleteFile);
		}
		else
		{
			::SetFileAttributes(strDeleteFile, FILE_ATTRIBUTE_NORMAL);
			::DeleteFile(strDeleteFile);
		}
	}

	find.Close();
	return ::RemoveDirectory(str);
}

/********************************************************************************
*	関数名：DeleteDeadLineFile													*
*	用　途：期限前のファイルを削除												*
*	引き数：削除したいファイルの存在するパス、期日（日）						*
*	戻り値：削除成功でＴＲＵＥ、失敗でＦＡＬＳＥ								*
*	備　考：フォルダは削除しない												*
*			隠しファイルも削除するが権限が無い場合は失敗する。					*
********************************************************************************/
BOOL DeleteDeadLineDirectory(CString &strPath, INT32 nDaysOfDeadLine)
{
	CFileFind	find;
	CTime		CurrentTime, DeadLine, TimeStamp;
	CString		str, strFind, strDeleteFile;
	BOOL		bFind;

	if ( nDaysOfDeadLine <= 0 ) return FALSE; 

	/***** 初期化 *****/
	CurrentTime	= CTime::GetTickCount();
	DeadLine	= CurrentTime - CTimeSpan(nDaysOfDeadLine, 0, 0, 0);

	str		= strPath;
	str.TrimRight(_T('\\'));
	strFind	= str + _T("\\*.*");

	bFind	= find.FindFile(strFind); 

	while(bFind)
	{
		bFind = find.FindNextFile();
		if( find.IsDots() ) continue;

		strDeleteFile = find.GetFilePath();
		find.GetLastWriteTime(TimeStamp);
		if( TimeStamp <= DeadLine )
		{
			if (find.IsDirectory())
			{
				DeleteDirectory(strDeleteFile);
			}
			else
			{
				::SetFileAttributes(strDeleteFile, FILE_ATTRIBUTE_NORMAL);
				::DeleteFile(strDeleteFile);
			}
		}
	};

	find.Close();

	return TRUE;
}

/********************************************************************************
*	関数名：GetDiskSize															*
*	用　途：ディスクサイズの取得												*
*	引き数：ドライブ名、ディスクサイズ格納場所、ネットワーク指定フラグ			*
*	戻り値：取得成功でＴＲＵＥ、失敗でＦＡＬＳＥ								*
*	備　考：																	*
********************************************************************************/
BOOL GetDiskSize(LPCTSTR szPath, DISK_INFO *tpInf, BOOL bNet)
{
	ULARGE_INTEGER	tAvailable;
	ULARGE_INTEGER	tTotal;
	ULARGE_INTEGER	tFree;
	TCHAR			szDrive[_MAX_DRIVE];
	BOOL			bRet;

	if ( szPath == 0 || tpInf == 0 ) return FALSE;

	if ( bNet )
	{
		bRet = GetDiskFreeSpaceEx(szPath, &tAvailable, &tTotal, &tFree);
	}
	else
	{
		_tsplitpath(szPath, szDrive, 0, 0, 0);
		bRet = GetDiskFreeSpaceEx(szDrive, &tAvailable, &tTotal, &tFree);
	}

	if ( bRet )
	{
		tpInf->uTotalSize	= tTotal.QuadPart;
		tpInf->uFreeSize	= tFree.QuadPart;
		tpInf->uAvailable	= tAvailable.QuadPart;
	}
	else
	{
		tpInf->uTotalSize	= 0;
		tpInf->uFreeSize	= 0;
		tpInf->uAvailable	= 0;
	}

	return bRet;
}

/********************************************************************************
*	関数名：ShowAndEnableFunc													*
*	用　途：ShowAndEnableCtrls関数用コールバック関数							*
*	引き数：ウインドウハンドル、コントロール情報								*
*	戻り値：常にＴＲＵＥ														*
*	備　考：																	*
********************************************************************************/
static BOOL CALLBACK ShowAndEnableFunc(HWND hWnd, LPARAM lSefInfo)
{ 
	SEFINFO*	pSefInfo = (SEFINFO*)lSefInfo ;		// 構造体へのポインタ
	RECT*		pRect    = &pSefInfo->rect    ;		// 指定矩形へのポインタ
	RECT		rcChild  ;							// 子ウィンドウの矩形

	// 子ウィンドウ矩形取得
	::GetWindowRect( hWnd, &rcChild ) ;

	// 領域チェック
	if( pRect->left	   <= rcChild.left  && 
		pRect->top	   <= rcChild.top   && 
		rcChild.right  <= pRect->right  && 
		rcChild.bottom <= pRect->bottom ) { 

		if( pSefInfo->nMode == SEC_ENABLE ) { 
			::EnableWindow( hWnd, pSefInfo->bFlg ) ;
		}
		else { 
			::ShowWindow( hWnd, ( pSefInfo->bFlg )? SW_SHOW:SW_HIDE ) ;
		}
	}

	return TRUE;
}

/********************************************************************************
*	関数名：ShowAndEnableCtrls													*
*	用　途：指定ウィンドウ矩形内のコントロールの属性を一括変更					*
*	引き数：ウインドウハンドル、設定属性選択、設定値、オーナーウインドウ		*
*	戻り値：戻り値にはあまり意味がない											*
*	備　考：																	*
********************************************************************************/
BOOL ShowAndEnableCtrls(CWnd* pWnd, INT32 nMode, BOOL bFlg, CWnd* pOwner)
{ 
	SEFINFO	SefInfo;
	BOOL	bRet;

	if( pOwner == NULL ) pOwner = pWnd->GetParent();
	if( pOwner == NULL ) pOwner = pWnd;
	SefInfo.nMode = nMode;
	SefInfo.bFlg  = bFlg;
	pWnd->GetWindowRect( &SefInfo.rect );

	/***** 子ウィンドウの列挙 *****/
	bRet = ::EnumChildWindows(pOwner->m_hWnd, ShowAndEnableFunc, (LPARAM)&SefInfo);

	return bRet;
}

/********************************************************************************
*	関数名：GetCurrentDirectory													*
*	用　途：カレントディレクトリの取得											*
*	引き数：カレントディレクトリ格納場所										*
*	戻り値：取得成功でＴＲＵＥ、失敗でＦＡＬＳＥ								*
*	備　考：																	*
********************************************************************************/
BOOL GetCurrentDirectory(CString *str)
{ 
	TCHAR	szPath[_MAX_PATH];

	if ( str == 0 ) return FALSE;

	GetCurrentDirectory(_MAX_PATH, szPath);

	*str = szPath;

	return TRUE;
}

/********************************************************************************
*	関数名：GetCtrlRect															*
*	用　途：親ウィンドウに対しての相対座標取得									*
*	引き数：ウインドウ、座標格納場所											*
*	戻り値：取得成功でＴＲＵＥ、失敗でＦＡＬＳＥ								*
*	備　考：																	*
********************************************************************************/
BOOL GetCtrlRect(CWnd* pWnd , PRECT tpRect)
{ 
	CWnd	*pParent;
	CRect	rect;

	if (pWnd == 0 || tpRect == 0)
	{
		return FALSE;
	}

	pParent = pWnd->GetParent();
	if (pParent == 0)
	{
		return FALSE;
	}

	pWnd->GetWindowRect(tpRect);
	pParent->ScreenToClient(tpRect);

	return TRUE;
}
