INT_PTR ErrorPrompt(HWND hWnd, CTSTRING &tsSrcFile, CTSTRING &tsDestFile,
                    bool bContinue, bool bCopy)
{

  INT_PTR r            = -1;
  PVOID pErrFromSystem = NULL;

  FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
                NULL,
                GetLastError(),
                0x0409,
                reinterpret_cast<TCHAR *>(&pErrFromSystem),
                256,
                NULL);

  if (NULL != pErrFromSystem) {

    PVOID pText       = LocalLock(pErrFromSystem);
    TCHAR *szQuestion = NULL;
    UINT_PTR uFlags   = 0U;

    if (bContinue) {
      szQuestion = _T("\nWould you like extFileCopy to")
                   _T(" continue with the next file?");
      uFlags     = MB_YESNO | MB_ICONSTOP;
    } else {
      szQuestion = _T("");
      uFlags     = MB_OK | MB_ICONSTOP;
    }

    r = PrintMsgBox(hWnd, _T("extFileCopy : ERROR"), uFlags,
                    _T("While attempting to %s:\n\n%s\n\nto\n\n%s\n\nThe following")
                    _T(" error occurred:\n\n%s%s"), bCopy ? _T("copy") : _T("move"),
                    tsSrcFile.c_str(), tsDestFile.c_str(), reinterpret_cast<TCHAR *>(pText),
                    szQuestion);

    LocalFree(pErrFromSystem);
  }

  return -1;
}
unsigned __stdcall _OpFileMoveThread(void *pVoid) {

  OPERATIONSTRUCT os  = *reinterpret_cast<POPERATIONSTRUCT>(pVoid);
  OPCALLBACKDATA ocd;
  TSTRINGLISTIT it    = os.Files.begin();
  UINT uiCurFile      = 1U;
  bool bAskOverwrite  = true;
  BOOL bCancelOp      = FALSE;
  TSTRING tsTemp;

 /*
  * If the destination directory is invalid,
  * it's probably been moved, or renamed
  * since its association with the application.
  * Prompt the user to see if they'd like to 
  * create it, or abort.
  */
  if (FALSE == PathIsDirectory(os.tsDest.c_str())) {

    INT_PTR iChoice = PrintMsgBox(os.hWnd, _T("extFileCopy")
                                  _T(" : Directory not found"),
                                  MB_YESNO | MB_ICONWARNING,
                                  _T("The destination directory:\n\n")
                                  _T("%s\n\nhas either been moved")
                                  _T(" or renamed since its association")
                                  _T(" with extFileCopy. Would you like")
                                  _T(" to create it?"),
                                  os.tsDest.c_str());
            
    switch (iChoice) {

      case IDYES:
      {
       /*
        * Attempt to create the directory.
        */
        if (FALSE == CreateDirectory(os.tsDest.c_str(), NULL)) {

         /*
          * We've failed miserably.
          * Can't copy any files to a non-existant
          * directory; done.
          */
          PrintMsgBox(os.hWnd, _T("extFileCopy : ERROR"),
                      MB_OK | MB_ICONSTOP,
                      _T("An error occurred while attempting")
                      _T(" to create the directory:\n\n%s.\n\n")
                      _T("The directory will be disassociated with")
                      _T("extFileCopy.\n\n")
                      _T("Win32 error: %d"),
                      os.tsDest.c_str(),
                      GetLastError());

          RegUtil_RemAssociatedDirectory(ExtensionFromList(os.Files), os.tsDest);

          goto mtFinish;
        }

      }
      break;

      case IDNO:
      {
       /*
        * User doesn't want to bother creating
        * the directory; We have to remove
        * the association in the registry.
        */
        PrintMsgBox(os.hWnd, _T("extFileCopy : Removing association"),
                    MB_OK | MB_ICONWARNING,
                    _T("The inaccessible directory:\n\n%s\n\nwill now")
                    _T(" be disassociated with extFileCopy."),
                    os.tsDest.c_str());

        RegUtil_RemAssociatedDirectory(ExtensionFromList(os.Files), os.tsDest);

        goto mtFinish;
      }
      break;

    }

  }

  os.pDlg->SetCancelPtr(&bCancelOp);

 /*
  * Set up the dialog UI
  */
  if (os.bCopy) {

    os.pDlg->SetWindowText(_T("Copying ..."));

  } else {

    os.pDlg->SetWindowText(_T("Moving ..."));

  }

  os.pDlg->SetElapsedTime(0);

  for(; it != os.Files.end(); it++) {

   /*
    * Check if the operation was cancelled
    * by the user
    */
    os.pMutex->Lock();

    if (TRUE == bCancelOp) {

      os.pMutex->Unlock();
      goto mtFinish;
    }

    os.pMutex->Unlock();

   /*
    * Update overall progress
    */
    INT64 iOverallPct = ((uiCurFile * 100) / os.Files.size());

    sprintf(tsTemp, _T("Overall Progress (file %d of %d) : %I64d%%"),
            uiCurFile++, os.Files.size(), iOverallPct);

    os.pDlg->SetOverallProgress(iOverallPct, tsTemp);

   /*
    * Update current file name
    */
    TSTRING tsShortFile = GetFileFromPath((*it));
    TSTRING tsDisplay   = tsShortFile;

   /*
    * Truncate file name if necessary
    */
    tsDisplay = FileGetCompactName(tsDisplay, PD_MAXCURFILE);
    
    sprintf(tsTemp, _T("Current file '%s' : %I64d%%"),
            tsDisplay.c_str(), 0LL);

    os.pDlg->SetCurrentProgress(0, tsTemp);

   /*
    * Reset transfer rate
    */
    os.pDlg->SetTransferRate(_T("Transfer Rate: calculating..."));
            
   /* 
    * If the resulting destination path is > MAX_PATH,
    * we've got to skip this file and tell the user.
    */
    TSTRING tsDest = PathConcatFile(os.tsDest, tsShortFile);

    if (MAX_PATH < tsDest.size()) {

      PrintMsgBox(os.hWnd, _T("extFileCopy : Can't copy file"),
                  MB_OK | MB_ICONWARNING,
                  _T("The following destination path:\n\n")
                  _T("%s\n\nis longer than MAX_PATH characters, and")
                  _T(" cannot be created."), tsDest.c_str());

      continue;

    }

   /*
    * Make sure the file doesn't exist; if it does,
    * we've got to prompt the user to overwrite.
    */
    if (-1 != GetFileAttributes(tsDest.c_str())) {

     /*
      * Yeah, the file exists.
      */
      if (bAskOverwrite) {

        OverwriteDlg dlg((*it), tsDest, 1 < os.Files.size());

        if (!dlg.DoModal(static_cast<HINSTANCE>(g_hModule),
                         MAKEINTRESOURCE(IDD_OVERWRITE),
                         os.pDlg->m_hWnd))
        {
          
          MessageBox(os.pDlg->m_hWnd, _T("A fatal internal error has occurred. Cannot continue.\n"),
                     _T("extFileCopy : ERROR"), MB_OK | MB_ICONSTOP);

          os.pDlg->CleanUp();
          _endthreadex(1);

        }

       /*
        * Find out what the user chose
        */
        switch (dlg.Result()) {

          case YES:
           /*
            * Ok to overwrite, but don't touch
            * bAskOverwrite.
            */            
          break;

          case YESTOALL:
           /*
            * Ok to overwrite ALL files.
            */
            bAskOverwrite = false;
          break;

          case NO:
           /*
            * Don't overwrite this file;
            * instead skip to the next.
            */
            continue;
          break;

          case CANCEL:
           /*
            * Forget it. We're outta here.
            */
            os.pMutex->Lock();
            bCancelOp = TRUE;
            os.pMutex->Unlock();
            goto mtFinish;
          break;

        }

      }

    }

   /*
    * File doesn't exist, or we don't
    * really care.  Continue normally
    */
    TSTRING tsCurFile = FileGetCompactName(tsShortFile.c_str(), PD_MAXCURFILE);

    ocd.pbCancel    = &bCancelOp;
    ocd.dwStartTime = (2 == uiCurFile) ? GetTickCount() : ocd.dwStartTime;
    ocd.dwLastTime  = (2 == uiCurFile) ? ocd.dwStartTime : ocd.dwLastTime;
    ocd.dwLastRate  = GetTickCount();
    ocd.iLastPct    = 0LL;
    ocd.iThroughput = 0LL;
    ocd.pDlg        = os.pDlg;
    ocd.pMutex      = os.pMutex;
    ocd.szCurFile   = tsCurFile.c_str();

    if (os.bCopy) {

     /*
      * This is a copy operation
      */
      if (0 == CopyFileEx((*it).c_str(), tsDest.c_str(), _Callback,
                           &ocd, &bCancelOp, 0UL))
      {

       /*
        * The copy operation has failed!
        * Let's tell the user, and then
        * if there's more than one file
        * being copied, ask the user if
        * they'd like to continue with
        * the next file. (If the error
        * didn't result from user abortion)
        */
        if (ERROR_REQUEST_ABORTED != GetLastError()) {

          INT_PTR iUser = ErrorPrompt(os.pDlg->m_hWnd, (*it), tsDest, 
                                    (1 < os.Files.size()) ? true : false, os.bCopy);

          if (1 < os.Files.size()) {

            if (IDYES == iUser) {

            /*
              * User wishes to try the next file.
              */
              continue;

            } else if (IDNO == iUser) {

              break;

            }

          } else {

            continue;

          }

        }

      }

    } else {

     /*
      * This is a move operation
      */
      if (0 == MoveFileWithProgress((*it).c_str(), tsDest.c_str(), _Callback,
                                    &ocd, MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING
                                    | MOVEFILE_WRITE_THROUGH))
      {

       /*
        * The move operation has failed!
        * Let's tell the user, and then
        * if there's more than one file
        * being copied, ask the user if
        * they'd like to continue with
        * the next file. (If the error
        * didn't result from user abortion)
        */
        if (ERROR_REQUEST_ABORTED != GetLastError()) {

          INT_PTR iUser = ErrorPrompt(os.pDlg->m_hWnd, (*it), tsDest,
                                      (1 < os.Files.size()) ? true : false, os.bCopy);

          if (1 < os.Files.size()) {

            if (IDYES == iUser) {

            /*
              * User wishes to try the next file.
              */
              continue;

            } else if (IDNO == iUser) {

              break;

            }

          } else {

            continue;

          }

        }

      }

    }

  }

mtFinish:

  os.pDlg->CleanUp();
  _endthreadex(0U);
  return 0U;
}
Exemple #3
0
//==============================================================================
// Brief  : コンストラクタ
// Return :								: なし
// Arg    : HWND hWnd						: アプリケーションのウィンドウハンドル
// Arg    : unsigned int widthScreen		: スクリーン幅
// Arg    : unsigned int heightScreen		: スクリーン高さ
// Arg    : bool isWindow					: ウィンドウモード
// Arg    : bool useSkinning				: ウィンドウモード
//==============================================================================
CExecutorDraw::CExecutorDraw( HWND hWnd, unsigned int widthScreen, unsigned int heightScreen, bool isWindow, bool useSkinning )
{
	// メンバ変数の初期化
	m_idCurrent = 0;
	m_pItemTop = nullptr;
	m_pD3DDevice = nullptr;
	m_pGraphicDevice = nullptr;
	m_isEnable = true;
	ZeroMemory( &m_criticalSection, sizeof( CRITICAL_SECTION ) );
	m_pTextureDepth = nullptr;
	m_pSurfaceTextureDepth = nullptr;
	m_pSurfaceDepth = nullptr;

	// Direct3Dの初期化
	LPDIRECT3D9				pD3D;
	D3DPRESENT_PARAMETERS	d3dpp;
	D3DDISPLAYMODE			d3ddm;
	int						nNumDisplayMode = 0;		// ディスプレイモードの最大数

	// Direct3Dオブジェクトの生成
	pD3D = Direct3DCreate9( D3D_SDK_VERSION );
	if( pD3D == nullptr )
	{
		PrintMsgBox( _T( "Direct3Dオブジェクトの生成に失敗しました。" ) );
		ThrowExceptionFunction();
	}

	// フルスクリーンの確認
	if( !isWindow )
	{	// ウィンドウモードの指定がされていないとき
		if( MessageBox( NULL, _T( "フルスクリーンで起動しますか?\n" ), _T( "フルスクリーンの確認" ), MB_YESNO ) == IDYES )
		{
			m_isWindowMode = false;
		}
		else
		{
			m_isWindowMode = true;
		}
	}
	else
	{
		m_isWindowMode = true;
	}

	// ディスプレイモードの列挙
	if( !m_isWindowMode )
	{	// ウィンドウモードの指定がされていないとき
		isWindow = true;
		nNumDisplayMode = pD3D->GetAdapterModeCount( D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8 );
		for( int nCntDisp = 0; nCntDisp < nNumDisplayMode; ++nCntDisp )
		{
			// ディスプレイモードの取得
			if( FAILED( pD3D->EnumAdapterModes( D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8, nCntDisp, &d3ddm ) ) )
			{
				PrintMsgBox( _T( "ディスプレイモードの取得に失敗しました。" ), _T( "エラー" ) );
				ThrowExceptionFunction();
			}

			// ディスプレイモードの決定
			if( d3ddm.Width == widthScreen && d3ddm.Height == heightScreen )
			{
				isWindow = false;
				break;
			}
		}
	}

	// デバイスのプレゼンテーションパラメータの設定
	ZeroMemory( &d3dpp, sizeof( d3dpp ) );						// ワークをゼロクリア
	d3dpp.BackBufferCount			= 1;						// バックバッファの数
	d3dpp.BackBufferWidth			= widthScreen;				// ゲーム画面サイズ(幅)
	d3dpp.BackBufferHeight			= heightScreen;				// ゲーム画面サイズ(高さ)
	d3dpp.BackBufferFormat			= D3DFMT_UNKNOWN;			// バックバッファのフォーマットは現在設定されているものを使う
	d3dpp.SwapEffect				= D3DSWAPEFFECT_DISCARD;	// 映像信号に同期してフリップする
	d3dpp.Windowed					= m_isWindowMode;			// ウィンドウモード
	d3dpp.EnableAutoDepthStencil	= TRUE;						// デプスバッファ(Zバッファ)とステンシルバッファを作成
	d3dpp.AutoDepthStencilFormat	= D3DFMT_D24S8;				// デプスバッファとして16bitを使う( 対応しているか確認した方がよい ) D3DFMT_D24S8 が良い
	d3dpp.hDeviceWindow				= hWnd;

	if( m_isWindowMode )
	{	// ウィンドウモード
		d3dpp.BackBufferFormat				= D3DFMT_UNKNOWN;					// バックバッファ
		d3dpp.FullScreen_RefreshRateInHz	= 0;								// リフレッシュレート
		d3dpp.PresentationInterval			= D3DPRESENT_INTERVAL_IMMEDIATE;	// インターバル( ティアリングが起きる )
	}
	else
	{	// フルスクリーンモード
		d3dpp.BackBufferFormat				= D3DFMT_R5G6B5;					// バックバッファ
		d3dpp.FullScreen_RefreshRateInHz	= D3DPRESENT_RATE_DEFAULT;			// リフレッシュレート
		d3dpp.PresentationInterval			= D3DPRESENT_INTERVAL_DEFAULT;		// インターバル
	}

	// デバイスオブジェクトの生成
	if( useSkinning )
	{
		// [デバイス作成制御]<描画>と<頂点処理>をハードウェアとCPUで切り替えて行う
		if( FAILED( pD3D->CreateDevice(	D3DADAPTER_DEFAULT,						// ディスプレイアダプタ
										D3DDEVTYPE_HAL,							// ディスプレイタイプ
										hWnd,									// フォーカスするウインドウへのハンドル
										D3DCREATE_MIXED_VERTEXPROCESSING,		// デバイス作成制御の組み合わせ
										&d3dpp,									// デバイスのプレゼンテーションパラメータ
										&m_pD3DDevice ) ) )						// デバイスインターフェースへのポインタ
		{
			// 初期化失敗
			PrintMsgBox( _T( "デバイスオブジェクトの初期化に失敗しました。" ) );
			ThrowExceptionFunction();
		}
	}
	else
	{
		// [デバイス作成制御]<描画>と<頂点処理>をハードウェアで行なう
		if( FAILED( pD3D->CreateDevice(	D3DADAPTER_DEFAULT,						// ディスプレイアダプタ
										D3DDEVTYPE_HAL,							// ディスプレイタイプ
										hWnd,									// フォーカスするウインドウへのハンドル
										D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED,	// デバイス作成制御の組み合わせ
										&d3dpp,									// デバイスのプレゼンテーションパラメータ
										&m_pD3DDevice ) ) )						// デバイスインターフェースへのポインタ
		{
			// [デバイス作成制御]<描画>と<頂点処理>をハードウェアで行なう
			d3dpp.AutoDepthStencilFormat	= D3DFMT_D16;
			if( FAILED( pD3D->CreateDevice(	D3DADAPTER_DEFAULT,						// ディスプレイアダプタ
				D3DDEVTYPE_HAL,							// ディスプレイタイプ
				hWnd,									// フォーカスするウインドウへのハンドル
				D3DCREATE_HARDWARE_VERTEXPROCESSING,	// デバイス作成制御の組み合わせ
				&d3dpp,									// デバイスのプレゼンテーションパラメータ
				&m_pD3DDevice ) ) )						// デバイスインターフェースへのポインタ
			{
				MessageBox( NULL, _T( "低画質モードで起動します。" ), _T( "確認" ), MB_OK );
				// 上記の設定が失敗したら
				// [デバイス作成制御]<描画>をハードウェアで行い、<頂点処理>はCPUで行なう
				if( FAILED( pD3D->CreateDevice(	D3DADAPTER_DEFAULT, 
					D3DDEVTYPE_HAL, 
					hWnd, 
					D3DCREATE_SOFTWARE_VERTEXPROCESSING, 
					&d3dpp,
					&m_pD3DDevice ) ) )
				{
					// 上記の設定が失敗したら
					// [デバイス作成制御]<描画>と<頂点処理>をCPUで行なう
					if( FAILED( pD3D->CreateDevice(	D3DADAPTER_DEFAULT, 
						D3DDEVTYPE_REF,
						hWnd, 
						D3DCREATE_SOFTWARE_VERTEXPROCESSING, 
						&d3dpp,
						&m_pD3DDevice ) ) )
					{
						// 初期化失敗
						PrintMsgBox( _T( "デバイスオブジェクトの初期化に失敗しました。" ) );
						ThrowExceptionFunction();
					}
				}
			}
		}
	}

	// フルスクリーン時のダイアログ設定
	if( !m_isWindowMode )
	{
		m_pD3DDevice->SetDialogBoxMode( TRUE );
	}

	// Direct3Dオブジェクトの開放
	pD3D->Release();
	pD3D = nullptr;

	// 描画デバイス受渡し用クラスの初期化
	m_pGraphicDevice = new CGraphicDevice( m_pD3DDevice );
	if( m_pGraphicDevice == nullptr )
	{
		ThrowExceptionBadAllocation();
	}

	// クリティカルセクションの初期化
	InitializeCriticalSectionEx( &m_criticalSection, 0, 0 );

	// 深度手描画用テクスチャの生成
	IDirect3DSurface9*	pSurfaceCurrentDepth = nullptr;		// 現在のレンダーターゲット
	D3DSURFACE_DESC		descSurfaceDepth;					// サーフェイス情報
	unsigned int		widthSurface;						// サーフェイスの幅
	unsigned int		heightSurface;						// サーフェイスの高さ
	m_pD3DDevice->GetRenderTarget( 0, &pSurfaceCurrentDepth );
	pSurfaceCurrentDepth->GetDesc( &descSurfaceDepth );
	widthSurface = descSurfaceDepth.Width;
	heightSurface = descSurfaceDepth.Height;
	pSurfaceCurrentDepth->Release();
	pSurfaceCurrentDepth = nullptr;
	if( FAILED( D3DXCreateTexture( m_pD3DDevice, widthSurface, heightSurface, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_pTextureDepth ) ) )
	{
		ThrowExceptionBadAllocation();
	}

	// 深度手描画用バッファの生成
	D3DSURFACE_DESC		descSurfaceTexture;					// サーフェイス情報
	unsigned int		widthTexture;						// サーフェイスの幅
	unsigned int		heightTexture;						// サーフェイスの高さ
	m_pTextureDepth->GetSurfaceLevel( 0, &m_pSurfaceTextureDepth );
	m_pSurfaceTextureDepth->GetDesc( &descSurfaceTexture );
	widthTexture = descSurfaceTexture.Width;
	heightTexture = descSurfaceTexture.Height;
	if( FAILED( m_pD3DDevice->CreateDepthStencilSurface( widthTexture, heightTexture, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, FALSE, &m_pSurfaceDepth, nullptr ) ) )
	{
		ThrowExceptionBadAllocation();
	}

#ifdef _DEBUG
	// デバッグ表示の初期化
	CDebugProc::Init( m_pGraphicDevice );
#endif
}