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; }
//============================================================================== // 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 }