670 lines
23 KiB
C++
670 lines
23 KiB
C++
/*
|
|
** Command & Conquer Generals Zero Hour(tm)
|
|
** Copyright 2025 Electronic Arts Inc.
|
|
**
|
|
** This program is free software: you can redistribute it and/or modify
|
|
** it under the terms of the GNU General Public License as published by
|
|
** the Free Software Foundation, either version 3 of the License, or
|
|
** (at your option) any later version.
|
|
**
|
|
** This program is distributed in the hope that it will be useful,
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
** GNU General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/****************************************************************************
|
|
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
|
****************************************************************************
|
|
* *
|
|
* Project Name : Setup *
|
|
* *
|
|
* File Name : UTILS.C *
|
|
* *
|
|
* Programmers: Maria del Mar McCready Legg *
|
|
* *
|
|
* Start Date : December 12, 1992 *
|
|
* *
|
|
* Last Update : March 16, 1998 [MML] *
|
|
* *
|
|
*--------------------------------------------------------------------------*
|
|
* Functions: *
|
|
* *
|
|
* Clip_Line_To_Rect -- Clips a line (two points) against a *
|
|
* rectangle, using CS algorithm. *
|
|
* Compute_Code -- computes line clipping bit code for *
|
|
* point & rectangle. *
|
|
* Copy_File -- Copies a file from one dir to another. *
|
|
* Convert_Hex_To_Version -- Converts a hex num obtained from the *
|
|
* Registry, into a string *
|
|
* representation of a version *
|
|
* number ( XX.XX ). *
|
|
* Convert_Version_To_Hex -- Converts a string to an unsigned long. *
|
|
* Convert_To_Version_Format -- Converts version string's "," to "."s *
|
|
* Dialog_Box -- draws a dialog background box *
|
|
* Draw_Box -- Displays a highlighted box. *
|
|
* Fatal -- General purpose fatal error handler. *
|
|
* Get_Version -- Retrieves a version string from a file. *
|
|
* Get_String -- Returns a pointer to the undipped text. *
|
|
* Is_File_Available -- Use both FindFirst to check that CD is *
|
|
* in drive & if File_Exists() to *
|
|
* determine if file is really there. *
|
|
* Pad_With_Zeros -- Adds zeros to the beginning of string. *
|
|
* String_Width -- Calculate with of the string. *
|
|
* Strip_Newlines -- Remove '\r' from string passed in. *
|
|
* TextPtr -- Returns a pointer to the undipped text. *
|
|
* Path_Name_Valid -- Validate that the path has the correct *
|
|
* number of chars between '\' in the *
|
|
* path. *
|
|
* Path_Get_Next_Directory -- Return the next dir path from string. *
|
|
* Path_Add_Back_Slash -- Add a "\\" to the end of the string. *
|
|
* Path_Remove_Back_Slash -- Remove a '\\' at the end of the string. *
|
|
* Path_Trim_Blanks -- Trim lead/trail white spaces off string *
|
|
* Pad_With_Zeros -- Adds zeros to the beginning of string. *
|
|
* Remove_Ending_Spaces -- Remove any blank spaces at end of string*
|
|
* Remove_Spaces -- Remove spaces from string passed in. *
|
|
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
|
|
|
|
#include <io.h>
|
|
#include "args.h"
|
|
#include "assert.h"
|
|
#include "locale_api.h"
|
|
#include "resource.h"
|
|
#include "utils.h"
|
|
#include "winfix.h"
|
|
#include "wnd_file.h"
|
|
#include <winver.h>
|
|
#include <shlwapi.h>
|
|
//#include "resources.h"
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: Fix_Single_Ampersands()
|
|
//
|
|
// Purpose: To replace each "&" with "&&" for display in a dialog.
|
|
// Some dialogs mistake a single "&" for an accelerator key.
|
|
//
|
|
// Input: pszString - any NULL terminated string.
|
|
//
|
|
// Returns: VOID (returns nothing)
|
|
//
|
|
// Comments: Modifies the characters in pszString.
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
|
|
void Fix_Single_Ampersands ( LPSTR pszString, bool upper_case )
|
|
{
|
|
char pszTemp[ MAX_PATH ]; // variable to hold the string passed
|
|
char pszOld[ MAX_PATH ]; // variable to hold the string passed
|
|
char * letter;
|
|
int i = 0;
|
|
|
|
lstrcpy((LPSTR)pszOld, (LPSTR)pszString );
|
|
letter = pszOld;
|
|
memset ( pszTemp, '\0', MAX_PATH );
|
|
|
|
//----------------------------------------------------------------------
|
|
// While our ptr has not passed the end of the string...
|
|
//----------------------------------------------------------------------
|
|
while (*letter != '\0') {
|
|
|
|
if (*letter == '&') {
|
|
|
|
pszTemp[i++] = '&';
|
|
pszTemp[i++] = '&';
|
|
letter++;
|
|
|
|
} else {
|
|
|
|
if ( upper_case ) {
|
|
pszTemp[i++] = (char) toupper( *( letter++ ));
|
|
} else {
|
|
pszTemp[i++] = *(letter++);
|
|
}
|
|
}
|
|
}
|
|
strcpy((LPSTR)pszString, (LPSTR)pszTemp );
|
|
}
|
|
|
|
void Fix_Single_Ampersands ( wchar_t *pszString, bool upper_case )
|
|
{
|
|
wchar_t pszTemp[ MAX_PATH ]; // variable to hold the string passed
|
|
wchar_t pszOld[ MAX_PATH ]; // variable to hold the string passed
|
|
wchar_t *letter;
|
|
int i = 0;
|
|
|
|
wcscpy( pszOld, pszString );
|
|
letter = pszOld;
|
|
memset ( pszTemp, '\0', MAX_PATH );
|
|
|
|
//----------------------------------------------------------------------
|
|
// While our ptr has not passed the end of the string...
|
|
//----------------------------------------------------------------------
|
|
while (*letter != '\0') {
|
|
|
|
if (*letter == '&') {
|
|
|
|
pszTemp[i++] = '&';
|
|
pszTemp[i++] = '&';
|
|
letter++;
|
|
|
|
} else {
|
|
|
|
if ( upper_case ) {
|
|
pszTemp[i++] = (char) toupper( *( letter++ ));
|
|
} else {
|
|
pszTemp[i++] = *(letter++);
|
|
}
|
|
}
|
|
}
|
|
wcscpy( pszString, pszTemp );
|
|
}
|
|
|
|
////////////////UnicodeString Fix_Single_Ampersands( UnicodeString string, bool upper_case)
|
|
////////////////{
|
|
//////////////// UnicodeString retval;
|
|
////////////////
|
|
//////////////// Int i = 0;
|
|
//////////////// while (i < string.getLength()) {
|
|
//////////////// if (upper_case) {
|
|
//////////////// retval.concat(toupper(string.getCharAt(i)));
|
|
//////////////// } else {
|
|
//////////////// retval.concat(string.getCharAt(i));
|
|
//////////////// }
|
|
//////////////// if (string.getCharAt(i) == L'&') {
|
|
//////////////// retval.concat(string.getCharAt(i));
|
|
//////////////// }
|
|
//////////////// ++i;
|
|
//////////////// }
|
|
////////////////
|
|
//////////////// return retval;
|
|
////////////////}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Function: Fix_Double_Ampersands()
|
|
//
|
|
// Purpose: To replace each "&&" with "&" for display in a dialog.
|
|
// Some dialogs mistake a single "&" for an accelerator key.
|
|
//
|
|
// Input: pszString - any NULL terminated string.
|
|
//
|
|
// Returns: VOID (returns nothing)
|
|
//
|
|
// Comments: Modifies the characters in pszString.
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
|
|
void Fix_Double_Ampersands ( LPSTR pszString, bool upper_case )
|
|
{
|
|
char pszTemp[ MAX_PATH ]; // variable to hold the string passed
|
|
char pszOld[ MAX_PATH ]; // variable to hold the string passed
|
|
char *letter;
|
|
int i = 0;
|
|
|
|
lstrcpy( (LPSTR)pszOld, (LPSTR)pszString );
|
|
letter = pszOld;
|
|
memset ( pszTemp, '\0', MAX_PATH );
|
|
|
|
//----------------------------------------------------------------------
|
|
// While our ptr has not passed the end of the string...
|
|
//----------------------------------------------------------------------
|
|
while (*letter != '\0') {
|
|
|
|
if ((*letter == '&') && (*( letter+1 ) == '&')) {
|
|
|
|
pszTemp[i++] = '&';
|
|
letter = letter + 2;
|
|
|
|
} else {
|
|
|
|
if ( upper_case ) {
|
|
pszTemp[i++] = (char) toupper( *( letter++ ));
|
|
} else {
|
|
pszTemp[i++] = *(letter++);
|
|
}
|
|
}
|
|
}
|
|
strcpy((LPSTR)pszString, (LPSTR)pszTemp );
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
* Load_Alloc_Data -- Allocates a buffer and loads the file into it. *
|
|
* *
|
|
* This is the C++ replacement for the Load_Alloc_Data function. It will *
|
|
* allocate the memory big enough to hold the file & read the file into it. *
|
|
* *
|
|
* INPUT: file -- The file to read. *
|
|
* mem -- The memory system to use for allocation. *
|
|
* *
|
|
* OUTPUT: Returns with a pointer to the allocated and filled memory block. *
|
|
* *
|
|
* WARNINGS: none *
|
|
* *
|
|
* HISTORY: *
|
|
* 10/17/1994 JLB : Created. *
|
|
*============================================================================*/
|
|
|
|
void * Load_Alloc_Data( char *filename, long *filesize )
|
|
{
|
|
int size, bytes_read;
|
|
void *ptr = NULL;
|
|
StandardFileClass file;
|
|
|
|
//-------------------------------------------------------------------------
|
|
// Open file in READ ONLY mode. If fails, exit.
|
|
//-------------------------------------------------------------------------
|
|
file.Open( filename, MODE_READ_ONLY );
|
|
if ( !file.Query_Open()) {
|
|
return( NULL );
|
|
}
|
|
|
|
//-------------------------------------------------------------------------
|
|
// Get filesize and create a buffer.
|
|
//-------------------------------------------------------------------------
|
|
size = file.Query_Size();
|
|
ptr = (void*)malloc(size + 1);
|
|
if ( !ptr ) {
|
|
return( NULL );
|
|
}
|
|
|
|
//-------------------------------------------------------------------------
|
|
// Read data into the buffer, close the file.
|
|
//-------------------------------------------------------------------------
|
|
memset( ptr, '\0', size + 1 );
|
|
bytes_read = file.Read( ptr, size );
|
|
file.Close();
|
|
|
|
//-------------------------------------------------------------------------
|
|
// Check return bytes. It should match the file size.
|
|
//-------------------------------------------------------------------------
|
|
assert( bytes_read == size );
|
|
if ( bytes_read != size ) {
|
|
free(ptr);
|
|
return( NULL );
|
|
}
|
|
|
|
if ( filesize != NULL ) {
|
|
*filesize = (long)size;
|
|
}
|
|
return( ptr );
|
|
}
|
|
|
|
/****************************************************************************
|
|
* MIXFILECLASS::LOAD_FILE -- Returns a buffer loaded with file desired. *
|
|
* *
|
|
* INPUT: none. * *
|
|
* *
|
|
* OUTPUT: none. *
|
|
* *
|
|
* WARNINGS: Searches MixFile first, then local directory. *
|
|
* Use free() to release buffer. * *
|
|
* *
|
|
* HISTORY: *
|
|
* 04/13/1998 ML/MG : Created. *
|
|
*==========================================================================*/
|
|
|
|
void *Load_File ( char *filename, long *filesize )
|
|
{
|
|
void *ptr = NULL;
|
|
|
|
if ( filename == NULL || filename[0] == '\0' ) {
|
|
return( NULL );
|
|
}
|
|
|
|
//-------------------------------------------------------------------------
|
|
// Try loading from local directory.
|
|
//-------------------------------------------------------------------------
|
|
ptr = Load_Alloc_Data( filename, filesize );
|
|
|
|
return( ptr );
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
* MAKE_CURRENT_PATH_TO -- Returns a buffer to path desired. *
|
|
* *
|
|
* INPUT: none. * *
|
|
* *
|
|
* OUTPUT: none. *
|
|
* *
|
|
* WARNINGS: * *
|
|
* *
|
|
* HISTORY: *
|
|
* 10/08/2001 MML : Created. *
|
|
*==========================================================================*/
|
|
|
|
char *Make_Current_Path_To ( char *filename, char *path )
|
|
{
|
|
char szPath [ _MAX_PATH ];
|
|
char drive [ _MAX_DRIVE];
|
|
char dir [ _MAX_DIR ];
|
|
|
|
strcpy( szPath, Args->Get_argv(0));
|
|
_splitpath( szPath, drive, dir, NULL, NULL );
|
|
_makepath( szPath, drive, dir, NULL, NULL );
|
|
Path_Add_Back_Slash( szPath );
|
|
strcat( szPath, filename );
|
|
|
|
if( path != NULL ) {
|
|
strcpy( path, szPath );
|
|
}
|
|
return( path );
|
|
}
|
|
|
|
wchar_t *Make_Current_Path_To ( wchar_t *filename, wchar_t *path )
|
|
{
|
|
wchar_t szPath [ _MAX_PATH ];
|
|
wchar_t drive [ _MAX_DRIVE];
|
|
wchar_t dir [ _MAX_DIR ];
|
|
|
|
wcscpy( szPath, (wchar_t *)Args->Get_argv(0));
|
|
_wsplitpath( szPath, drive, dir, NULL, NULL );
|
|
_wmakepath( szPath, drive, dir, NULL, NULL );
|
|
Path_Add_Back_Slash( szPath );
|
|
wcscat( szPath, filename );
|
|
|
|
if( path != NULL ) {
|
|
wcscpy( path, szPath );
|
|
}
|
|
return( path );
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
* Path_Add_Back_Slash -- Add a '\\' to the end of the path.
|
|
*
|
|
* INPUT: char * path -- Pointer to the string to be modified.
|
|
*
|
|
* OUTPUT: char * path
|
|
*
|
|
* WARNINGS: none
|
|
*
|
|
* HISTORY:
|
|
* 08/14/1998 MML : Created.
|
|
*============================================================================*/
|
|
|
|
char *Path_Add_Back_Slash ( char *path )
|
|
{
|
|
if ( path != NULL && *path != '\0' ) {
|
|
if ( path[ strlen( path )-1 ] != '\\' ) {
|
|
strcat( path, "\\" );
|
|
}
|
|
}
|
|
return( path );
|
|
}
|
|
|
|
wchar_t *Path_Add_Back_Slash ( wchar_t *path )
|
|
{
|
|
if ( path != NULL && *path != '\0' ) {
|
|
if ( path[ wcslen( path )-1 ] != '\\' ) {
|
|
wcscat( path, L"\\" );
|
|
}
|
|
}
|
|
return( path );
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
* Path_Remove_Back_Slash -- Remove a '\\' from the end of the path.
|
|
*
|
|
* INPUT: char * path -- Pointer to the string to be modified.
|
|
*
|
|
* OUTPUT: char * path
|
|
*
|
|
* WARNINGS: none
|
|
*
|
|
* HISTORY:
|
|
* 08/14/1998 MML : Created.
|
|
*============================================================================*/
|
|
|
|
char *Path_Remove_Back_Slash ( char *path )
|
|
{
|
|
if ( path != NULL && *path != '\0' ) {
|
|
if ( path[ strlen( path )-1 ] == '\\' ) {
|
|
path[ strlen( path )-1 ] = '\0';
|
|
}
|
|
}
|
|
return( path );
|
|
}
|
|
|
|
wchar_t *Path_Remove_Back_Slash ( wchar_t *path )
|
|
{
|
|
if ( path != NULL && *path != '\0' ) {
|
|
if ( path[ wcslen( path )-1 ] == L'\\' ) {
|
|
path[ wcslen( path )-1 ] = L'\0';
|
|
}
|
|
}
|
|
return( path );
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
/* Function: PlugInProductName */
|
|
/* */
|
|
/* Descrip: The function plugs the product name defined in */
|
|
/* SdProductName() into %P found in the static message. */
|
|
/* It will search for the first nMax controls only. */
|
|
/* Misc: */
|
|
/* */
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
void PlugInProductName ( char *szString, char *szName )
|
|
{
|
|
int nCount, nMsgLength;
|
|
char szTextBuf[ MAX_PATH ];
|
|
char szOut[ MAX_PATH ];
|
|
char szProduct[ MAX_PATH ];
|
|
char * temp = NULL;
|
|
char * next = NULL;
|
|
|
|
if ( szName == NULL || szName[0] == '\0' ) {
|
|
return;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// Find the first appearance of "%P".
|
|
//--------------------------------------------------------------------------
|
|
strcpy( szProduct, szName );
|
|
strcpy( szTextBuf, szString );
|
|
nMsgLength = strlen( szTextBuf );
|
|
nCount = 0;
|
|
temp = strstr( szTextBuf, "%s" );
|
|
|
|
//-------------------------------------------------------------
|
|
// Substitute each "%P" with "%s". nStrReturn is the index
|
|
// into the buffer where "%P" was found.
|
|
//-------------------------------------------------------------
|
|
while ( temp != NULL && nCount < 6) {
|
|
next = temp+1;
|
|
nCount = nCount + 1;
|
|
temp = strstr( next, "%s" );
|
|
}
|
|
|
|
//-------------------------------------------------------------
|
|
// Only support up to 5 product name per message.
|
|
// Do the substitution of the product name and store in szOut.
|
|
//-------------------------------------------------------------
|
|
switch( nCount ) {
|
|
case 1:
|
|
sprintf( szOut, szTextBuf, szProduct );
|
|
break;
|
|
case 2:
|
|
sprintf( szOut, szTextBuf, szProduct, szProduct );
|
|
break;
|
|
case 3:
|
|
sprintf( szOut, szTextBuf, szProduct, szProduct, szProduct );
|
|
break;
|
|
case 4:
|
|
sprintf( szOut, szTextBuf, szProduct, szProduct, szProduct, szProduct );
|
|
break;
|
|
case 5:
|
|
sprintf( szOut, szTextBuf, szProduct, szProduct, szProduct, szProduct, szProduct, szProduct );
|
|
break;
|
|
}
|
|
|
|
//-------------------------------------------------------------
|
|
// Replace szTextBuf with szOut.
|
|
//-------------------------------------------------------------
|
|
if ( nCount >= 1 ) {
|
|
strcpy( szString, szOut );
|
|
}
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
/* Function: PlugInProductName */
|
|
/* */
|
|
/* Descrip: The function plugs the product name defined in */
|
|
/* SdProductName() into %P found in the static message. */
|
|
/* It will search for the first nMax controls only. */
|
|
/* Misc: */
|
|
/* */
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
void PlugInProductName( char *szString, int nName )
|
|
{
|
|
/*
|
|
int nCount, nMsgLength;
|
|
char szTextBuf[ MAX_PATH ];
|
|
char szOut[ MAX_PATH ];
|
|
char szProduct[ MAX_PATH ];
|
|
char * temp = NULL;
|
|
char * next = NULL;
|
|
|
|
if ( nName <= STRNONE ) {
|
|
nName = STRNONE;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// Find the first appearance of "%P".
|
|
//-------------------------------------------------------------
|
|
// LoadString( Main::hInstance, nName, szProduct, MAX_PATH );
|
|
Locale_GetString( nName, szProduct );
|
|
|
|
strcpy( szTextBuf, szString );
|
|
nMsgLength = strlen( szTextBuf );
|
|
nCount = 0;
|
|
temp = strstr( szTextBuf, "%s" );
|
|
|
|
//-------------------------------------------------------------
|
|
// Substitute each "%P" with "%s". nStrReturn is the index
|
|
// into the buffer where "%P" was found.
|
|
//-------------------------------------------------------------
|
|
while ( temp != NULL && nCount < 6) {
|
|
next = temp+1;
|
|
nCount = nCount + 1;
|
|
temp = strstr( next, "%s" );
|
|
}
|
|
|
|
//-------------------------------------------------------------
|
|
// Only support up to 5 product name per message.
|
|
// Do the substitution of the product name and store in szOut.
|
|
//-------------------------------------------------------------
|
|
switch( nCount ) {
|
|
case 1:
|
|
sprintf( szOut, szTextBuf, szProduct );
|
|
break;
|
|
case 2:
|
|
sprintf( szOut, szTextBuf, szProduct, szProduct );
|
|
break;
|
|
case 3:
|
|
sprintf( szOut, szTextBuf, szProduct, szProduct, szProduct );
|
|
break;
|
|
case 4:
|
|
sprintf( szOut, szTextBuf, szProduct, szProduct, szProduct, szProduct );
|
|
break;
|
|
case 5:
|
|
sprintf( szOut, szTextBuf, szProduct, szProduct, szProduct, szProduct, szProduct, szProduct );
|
|
break;
|
|
}
|
|
|
|
//-------------------------------------------------------------
|
|
// Replace szTextBuf with szOut.
|
|
//-------------------------------------------------------------
|
|
if ( nCount >= 1 ) {
|
|
strcpy( szString, szOut );
|
|
}
|
|
*/
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
/* Function: PlugInProductName */
|
|
/* */
|
|
/* Descrip: The function plugs the product name defined in */
|
|
/* SdProductName() into %P found in the static message. */
|
|
/* It will search for the first nMax controls only. */
|
|
/* Misc: */
|
|
/* */
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
void PlugInProductName ( wchar_t *szString, const wchar_t *szName )
|
|
{
|
|
int nCount, nMsgLength;
|
|
wchar_t szTextBuf[ MAX_PATH ];
|
|
wchar_t szOut[ MAX_PATH ];
|
|
wchar_t szProduct[ MAX_PATH ];
|
|
wchar_t *temp = NULL;
|
|
wchar_t *next = NULL;
|
|
|
|
if ( szName == NULL || szName[0] == '\0' ) {
|
|
return;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// Find the first appearance of "%P".
|
|
//--------------------------------------------------------------------------
|
|
wcscpy( szProduct, szName );
|
|
wcscpy( szTextBuf, szString );
|
|
nMsgLength = wcslen( szTextBuf );
|
|
nCount = 0;
|
|
temp = wcsstr( szTextBuf, L"%s" );
|
|
|
|
//-------------------------------------------------------------
|
|
// Substitute each "%P" with "%s". nStrReturn is the index
|
|
// into the buffer where "%P" was found.
|
|
//-------------------------------------------------------------
|
|
while ( temp != NULL && nCount < 6) {
|
|
next = temp+1;
|
|
nCount = nCount + 1;
|
|
temp = wcsstr( next, L"%s" );
|
|
}
|
|
|
|
//-------------------------------------------------------------
|
|
// Only support up to 5 product name per message.
|
|
// Do the substitution of the product name and store in szOut.
|
|
//-------------------------------------------------------------
|
|
switch( nCount ) {
|
|
case 1:
|
|
swprintf( szOut, szTextBuf, szProduct );
|
|
break;
|
|
case 2:
|
|
swprintf( szOut, szTextBuf, szProduct, szProduct );
|
|
break;
|
|
case 3:
|
|
swprintf( szOut, szTextBuf, szProduct, szProduct, szProduct );
|
|
break;
|
|
case 4:
|
|
swprintf( szOut, szTextBuf, szProduct, szProduct, szProduct, szProduct );
|
|
break;
|
|
case 5:
|
|
swprintf( szOut, szTextBuf, szProduct, szProduct, szProduct, szProduct, szProduct, szProduct );
|
|
break;
|
|
}
|
|
|
|
//-------------------------------------------------------------
|
|
// Replace szTextBuf with szOut.
|
|
//-------------------------------------------------------------
|
|
if ( nCount >= 1 ) {
|
|
wcscpy( szString, szOut );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|