Ajout de la prise en charge Region-Change à une application
[La fonctionnalité associée à cette page, DirectShow, est une fonctionnalité héritée. Il a été remplacé par MediaPlayer, IMFMediaEngine et Audio/Video Capture dans Media Foundation. Ces fonctionnalités ont été optimisées pour Windows 10 et Windows 11. Microsoft recommande vivement au nouveau code d’utiliser MediaPlayer, IMFMediaEngine et La capture audio/vidéo dans Media Foundation au lieu de DirectShow, lorsque cela est possible. Microsoft suggère que le code existant qui utilise les API héritées soit réécrit pour utiliser les nouvelles API si possible.]
Les fonctions suivantes sont fournies aux développeurs qui souhaitent intégrer la prise en charge du changement de région dans leurs décodeurs ou applications DVD.
// Forward declares, constants, typedefs.
const short MAX_DRIVE_NAME = 4;
struct DriveName
{
TCHAR name[MAX_DRIVE_NAME];
};
BOOL DoesFileExist(LPTSTR pszFile);
BOOL GetDriveLetter(IDvdInfo2 *pDvd, DriveName& szDrive);
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
/////////////////////////////////////////////////////////////////////
// ChangeDVDRegion : Function to change the DVD drive region.
// Parameters:
// hWnd - Handle to the application window.
// Returns TRUE if the change is successful, or FALSE otherwise.
// (Failure usually means there was no drive with a valid DVD-V disc.)
/////////////////////////////////////////////////////////////////////
BOOL ChangeDVDRegion(HWND hWnd, IDvdInfo2 *pDvd)
{
typedef BOOL (APIENTRY *DVDPPLAUNCHER) (HWND hWnd, CHAR DriveLetter);
// First find out which drive is a DVD drive with a valid DVD-V disc.
DriveName szDVDDrive;
if (! GetDriveLetter(pDvd, szDVDDrive) )
{
MessageBox(hWnd, TEXT("No DVD drive was found with DVD-V disc."),
TEXT("Error"), MB_OK | MB_ICONERROR) ;
return FALSE;
}
// Detect the version.
OSVERSIONINFO ver;
ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&ver);
if (VER_PLATFORM_WIN32_NT == ver.dwPlatformId)
{
HINSTANCE hInstDLL;
DVDPPLAUNCHER dvdPPLauncher;
CHAR szDVDDriveA[MAX_DRIVE_NAME];
const TCHAR szDllName[] = TEXT("\\storprop.dll");
// Allocate a large enough string to hold the path + the name.
TCHAR szCmdLine[MAX_PATH + (sizeof(szDllName)/sizeof(TCHAR)) + 1];
#ifdef UNICODE
WideCharToMultiByte(CP_ACP, 0, szDVDDrive.name, -1,
szDVDDriveA, sizeof(szDVDDriveA), NULL, NULL );
#else
StringCchCopy(szDVDDriveA, MAX_DRIVE_NAME, szDVDDrive.name);
#endif
UINT cb = GetSystemDirectory(szCmdLine, MAX_PATH + 1);
if (cb == 0 || cb > MAX_PATH + 1)
{
return FALSE;
}
StringCchCat(szCmdLine, ARRAY_SIZE(szCmdLine), szDllName);
hInstDLL = LoadLibrary (szCmdLine);
if (hInstDLL)
{
BOOL bResult = FALSE;
dvdPPLauncher = (DVDPPLAUNCHER) GetProcAddress(hInstDLL,
"DvdLauncher");
if (dvdPPLauncher)
{
bResult = dvdPPLauncher(hWnd, szDVDDriveA[0]);
}
FreeLibrary(hInstDLL);
return bResult;
}
}
else
{
return FALSE;
}
return FALSE;
}
/////////////////////////////////////////////////////////////////////
// GetDriveLetter: Returns the drive letter of the active DVD drive.
// Parameters:
// pDvdC - IDvdControl2 interface of the DVD Navigator filter.
// pszDrive - Receives the first DVD drive with a valid DVD-V disc.
// Returns TRUE if there is a DVD drive with a valid disc.
/////////////////////////////////////////////////////////////////////
BOOL GetDriveLetter(IDvdInfo2 *pDvd, DriveName& pszDrive)
{
WCHAR szPathW[MAX_PATH];
TCHAR szPath[MAX_PATH];
ULONG ulActualSize = 0;
pszDrive.name[0] = pszDrive.name[MAX_DRIVE_NAME - 1] = 0;
// Get the current root directory
HRESULT hr = pDvd->GetDVDDirectory(szPathW, MAX_PATH, &ulActualSize);
if (SUCCEEDED(hr))
{
#ifdef UNICODE
StringCchCopy(pszDrive.name, MAX_DRIVE_NAME, szPathW);
#else
WideCharToMultiByte(CP_ACP, 0, szPathW, ulActualSize, szPath, MAX_PATH, 0, 0);
StringCchCopy(pszDrive.name, MAX_DRIVE_NAME, szPath);
#endif
if (DRIVE_CDROM == GetDriveType(pszDrive.name)) // could be a DVD drive
return TRUE;
}
// Now loop through all the valid drives to detect which one
// is a DVD drive with a valid DVD-V disc in it.
// Get all valid drives
DWORD dwLen = GetLogicalDriveStrings(MAX_PATH, szPath);
if (dwLen > MAX_PATH)
{
// The function returns a larger value if the buffer is too small.
return FALSE;
}
// Try all drives one by one
for (size_t dw = 0; dw < dwLen; )
{
TCHAR *szTmp = szPath + dw;
// Look only for CD-ROM drives that has a disc with required (.ifo) files
if (DRIVE_CDROM == GetDriveType(szTmp))
{
TCHAR szDVDPath1[MAX_PATH + 1];
TCHAR szDVDPath2[MAX_PATH + 1];
StringCchCopy(szDVDPath1, MAX_DRIVE_NAME, szTmp);
StringCchCopy(szDVDPath2, MAX_DRIVE_NAME, szTmp);
StringCchCat(szDVDPath1, ARRAY_SIZE(szDVDPath1), TEXT("Video_ts\\Video_ts.ifo"));
StringCchCat(szDVDPath2, ARRAY_SIZE(szDVDPath2), TEXT("Video_ts\\Vts_01_0.ifo"));
// If the .ifo files exist on this drive then it has a valid DVD-V disc
if (DoesFileExist(szDVDPath1) && DoesFileExist(szDVDPath2))
{
StringCchCopy(pszDrive.name, MAX_DRIVE_NAME, szTmp);
return TRUE; // return the first drive that has a valid DVD-V disc
}
}
size_t len = 0;
StringCchLength(szTmp, STRSAFE_MAX_CCH, &len);
dw += len + 1;
}
return FALSE ; // didn't find any DVD drive with DVD-V content
}
/////////////////////////////////////////////////////////////////////
// DoesFileExist : Determines whether a specified file exists
// Parameters:
// pszFile - File name to check.
// Returns TRUE if the specified file is found, or FALSE otherwise.
/////////////////////////////////////////////////////////////////////
BOOL DoesFileExist(LPTSTR pszFile)
{
if (pszFile == NULL)
{
return FALSE;
}
size_t len = 0;
if (FAILED(StringCchLength(pszFile, STRSAFE_MAX_CCH, &len)))
{
return FALSE;
}
if (len > MAX_PATH)
{
return FALSE;
}
// We don't want any error message box to pop up when we try to test
// if the required file is available to open for read --apcb.
UINT uErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
HANDLE hFile = CreateFile(pszFile, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
SetErrorMode(uErrorMode); // restore error mode
if (INVALID_HANDLE_VALUE == hFile)
{
return FALSE;
}
CloseHandle(hFile);
return TRUE;
}
Rubriques connexes