// StringCchTest.cpp : This file contains the 'main' function. Program execution begins and ends there. // #include #include #include int main() { WCHAR szTestFileName1252[ ] = L"123 123456789012345678901234567.txt"; WCHAR szTestFileName[ ] = L"\u672a\u66f4\u65b0 123456789012345678901234567.txt"; CHAR szANSIFileName[ MAX_PATH ] = ""; BOOL bUsedDefaultChar = FALSE; int iResult; HRESULT hr; // Testing with WideCharToMultiByte, to confirm that "bUsedDefaultChar = TRUE" occurs in situations // where the characters are not available in the current ANSI code page, but a successful string // with the "?" character substituted for each unsupported character is returned. szANSIFileName[ 0 ] = '\0'; szANSIFileName[ ARRAYSIZE( szANSIFileName ) - 1 ] = '\0'; iResult = WideCharToMultiByte( CP_ACP, 0, szTestFileName, -1, szANSIFileName, ARRAYSIZE( szANSIFileName ), NULL, &bUsedDefaultChar ); printf( "WideCharToMultiByte ARRAYSIZE( szTestFileName ) = %u, ARRAYSIZE( szANSIFileName ) = %u, iResult = %d, last error = %u, bUsedDefaultChar = %s.\n", ARRAYSIZE( szTestFileName ), ARRAYSIZE( szANSIFileName ), iResult, GetLastError( ), bUsedDefaultChar ? "TRUE" : "FALSE" ); if ( ( 36 == iResult ) || ( 39 == iResult ) ) printf( "Resulting ANSI string is: \"%s\".\n", szANSIFileName ); else if ( !szANSIFileName[ 0 ] ) printf( "Resulting ANSI string is: Still NULL terminated at start.\n" ); else if ( !szANSIFileName[ ARRAYSIZE( szANSIFileName ) - 1 ] ) printf( "Resulting ANSI string is: Still NULL terminated at end.\n" ); else printf( "Resulting ANSI string is: No longer NULL terminated.\n" ); bUsedDefaultChar = FALSE; szANSIFileName[ 0 ] = '\0'; szANSIFileName[ ARRAYSIZE( szANSIFileName ) - 1 ] = '\0'; iResult = WideCharToMultiByte( CP_ACP, 0, szTestFileName1252, -1, szANSIFileName, ARRAYSIZE( szANSIFileName ), NULL, &bUsedDefaultChar ); printf( "WideCharToMultiByte ARRAYSIZE( szTestFileName1252 ) = %u, ARRAYSIZE( szANSIFileName ) = %u, iResult = %d, last error = %u, bUsedDefaultChar = %s.\n", ARRAYSIZE( szTestFileName1252 ), ARRAYSIZE( szANSIFileName ), iResult, GetLastError( ), bUsedDefaultChar ? "TRUE" : "FALSE" ); if ( ( 36 == iResult ) || ( 39 == iResult ) ) printf( "Resulting ANSI string is: \"%s\".\n", szANSIFileName ); else if ( !szANSIFileName[ 0 ] ) printf( "Resulting ANSI string is: Still NULL terminated at start.\n" ); else if ( !szANSIFileName[ ARRAYSIZE( szANSIFileName ) - 1 ] ) printf( "Resulting ANSI string is: Still NULL terminated at end.\n" ); else printf( "Resulting ANSI string is: No longer NULL terminated.\n" ); // Testing with StringCchPrintfA, which is in the family of strsafe.h APIs // we actually intend to use in NCNetProvider's DbgPrintMessage. szANSIFileName[ 0 ] = '\0'; szANSIFileName[ ARRAYSIZE( szANSIFileName ) - 1 ] = '\0'; hr = StringCchPrintfA( szANSIFileName, ARRAYSIZE( szANSIFileName ), "%ls", szTestFileName ); printf( "StringCchPrintfA ARRAYSIZE( szTestFileName ) = %u, ARRAYSIZE( szANSIFileName ) = %u, HRESULT = 0x%08X, last error = %u.\n", ARRAYSIZE( szTestFileName ), ARRAYSIZE( szANSIFileName ), hr, GetLastError( ) ); if ( SUCCEEDED( hr ) ) printf( "Resulting ANSI string is: \"%s\".\n", szANSIFileName ); else if ( !szANSIFileName[ 0 ] ) printf( "Resulting ANSI string is: Still NULL terminated at start.\n" ); else if ( !szANSIFileName[ ARRAYSIZE( szANSIFileName ) - 1 ] ) printf( "Resulting ANSI string is: Still NULL terminated at end.\n" ); else printf( "Resulting ANSI string is: No longer NULL terminated.\n" ); szANSIFileName[ 0 ] = '\0'; szANSIFileName[ ARRAYSIZE( szANSIFileName ) - 1 ] = '\0'; hr = StringCchPrintfA( szANSIFileName, ARRAYSIZE( szANSIFileName ), "%ls", szTestFileName1252 ); printf( "StringCchPrintfA ARRAYSIZE( szTestFileName1252 ) = %u, ARRAYSIZE( szANSIFileName ) = %u, HRESULT = 0x%08X, last error = %u.\n", ARRAYSIZE( szTestFileName1252 ), ARRAYSIZE( szANSIFileName ), hr, GetLastError( ) ); if ( SUCCEEDED( hr ) ) printf( "Resulting ANSI string is: \"%s\".\n", szANSIFileName ); else if ( !szANSIFileName[ 0 ] ) printf( "Resulting ANSI string is: Still NULL terminated at start.\n" ); else if ( !szANSIFileName[ ARRAYSIZE( szANSIFileName ) - 1 ] ) printf( "Resulting ANSI string is: Still NULL terminated at end.\n" ); else printf( "Resulting ANSI string is: No longer NULL terminated.\n" ); // Testing with _snprintf_s_l, which is in the same family of CRT calls // that StringCchPrintfA uses internally to implement the actual printing. // So here we are calling it directly, instead of through StringCchPrintfA. szANSIFileName[ 0 ] = '\0'; szANSIFileName[ ARRAYSIZE( szANSIFileName ) - 1 ] = '\0'; _locale_t locale = _get_current_locale( ); iResult = _snprintf_s_l( szANSIFileName, ARRAYSIZE( szANSIFileName ), ARRAYSIZE( szANSIFileName ), "%ls", locale, szTestFileName ); printf( "_snprintf_s_l ARRAYSIZE( szTestFileName ) = %u, ARRAYSIZE( szANSIFileName ) = %u, iResult = %d, last error = %u.\n", ARRAYSIZE( szTestFileName ), ARRAYSIZE( szANSIFileName ), iResult, GetLastError( ) ); if ( ( 35 == iResult ) || ( 36 == iResult ) || ( 38 == iResult ) || ( 39 == iResult ) ) printf( "Resulting ANSI string is: \"%s\".\n", szANSIFileName ); else if ( !szANSIFileName[ 0 ] ) printf( "Resulting ANSI string is: Still NULL terminated at start.\n" ); else if ( !szANSIFileName[ ARRAYSIZE( szANSIFileName ) - 1 ] ) printf( "Resulting ANSI string is: Still NULL terminated at end.\n" ); else printf( "Resulting ANSI string is: No longer NULL terminated.\n" ); _free_locale( locale ); szANSIFileName[ 0 ] = '\0'; szANSIFileName[ ARRAYSIZE( szANSIFileName ) - 1 ] = '\0'; iResult = _snprintf_s( szANSIFileName, ARRAYSIZE( szANSIFileName ), ARRAYSIZE( szANSIFileName ), "%ls", szTestFileName ); printf( "_snprintf_s ARRAYSIZE( szTestFileName ) = %u, ARRAYSIZE( szANSIFileName ) = %u, iResult = %d, last error = %u.\n", ARRAYSIZE( szTestFileName ), ARRAYSIZE( szANSIFileName ), iResult, GetLastError( ) ); if ( ( 35 == iResult ) || ( 36 == iResult ) || ( 38 == iResult ) || ( 39 == iResult ) ) printf( "Resulting ANSI string is: \"%s\".\n", szANSIFileName ); else if ( !szANSIFileName[ 0 ] ) printf( "Resulting ANSI string is: Still NULL terminated at start.\n" ); else if ( !szANSIFileName[ ARRAYSIZE( szANSIFileName ) - 1 ] ) printf( "Resulting ANSI string is: Still NULL terminated at end.\n" ); else printf( "Resulting ANSI string is: No longer NULL terminated.\n" ); // Test with the Windows platform wsprintfA instead of a CRT function. szANSIFileName[ 0 ] = '\0'; szANSIFileName[ ARRAYSIZE( szANSIFileName ) - 1 ] = '\0'; iResult = wsprintfA( szANSIFileName, "%ls", szTestFileName ); printf( "wsprintfA ARRAYSIZE( szTestFileName ) = %u, ARRAYSIZE( szANSIFileName ) = %u, iResult = %d, last error = %u.\n", ARRAYSIZE( szTestFileName ), ARRAYSIZE( szANSIFileName ), iResult, GetLastError( ) ); if ( ( 35 == iResult ) || ( 36 == iResult ) || ( 38 == iResult ) || ( 39 == iResult ) ) printf( "Resulting ANSI string is: \"%s\".\n", szANSIFileName ); else if ( !szANSIFileName[ 0 ] ) printf( "Resulting ANSI string is: Still NULL terminated at start.\n" ); else if ( !szANSIFileName[ ARRAYSIZE( szANSIFileName ) - 1 ] ) printf( "Resulting ANSI string is: Still NULL terminated at end.\n" ); else printf( "Resulting ANSI string is: No longer NULL terminated.\n" ); return 0; } // Run program: Ctrl + F5 or Debug > Start Without Debugging menu // Debug program: F5 or Debug > Start Debugging menu // Tips for Getting Started: // 1. Use the Solution Explorer window to add/manage files // 2. Use the Team Explorer window to connect to source control // 3. Use the Output window to see build output and other messages // 4. Use the Error List window to view errors // 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project // 6. In the future, to open this project again, go to File > Open > Project and select the .sln file