Until user has explicitly chosen a language, on launch see if there

are any installed and prefer one of them to English.  Somebody wanting
other than English shouldn't have to dig through menus to enable his
language after installing the .dll.
This commit is contained in:
ehouse 2010-01-11 03:36:12 +00:00
parent 8d3c951c81
commit 1b8e4223c1
4 changed files with 139 additions and 53 deletions

View file

@ -934,7 +934,7 @@ ceInitAndStartBoard( CEAppGlobals* globals, XP_Bool newGame,
} }
XP_ASSERT( !!globals->game.board ); XP_ASSERT( !!globals->game.board );
ceSizeIfFullscreen( globals, globals->hWnd ); (void)ceSizeIfFullscreen( globals, globals->hWnd );
(void)cePositionBoard( globals ); (void)cePositionBoard( globals );
board_invalAll( globals->game.board ); board_invalAll( globals->game.board );
@ -1092,7 +1092,7 @@ ceLoadPrefs( CEAppGlobals* globals )
XP_U32 bytesRead; XP_U32 bytesRead;
if ( ReadFile( fileH, &tmpPrefs, sizeof(tmpPrefs), if ( ReadFile( fileH, &tmpPrefs, sizeof(tmpPrefs),
&bytesRead, NULL ) ) { &bytesRead, NULL ) ) {
XP_ASSERT( tmpPrefs.versionFlags == CUR_CE_PREFS_FLAGS ); XP_ASSERT( tmpPrefs.versionFlags==CUR_CE_PREFS_FLAGS );
result = XP_TRUE; result = XP_TRUE;
} }
} }
@ -1455,17 +1455,30 @@ InitInstance(HINSTANCE hInstance, int nCmdShow
replaceStringIfDifferent( globals->mpool, &globals->langFileName, dll ); replaceStringIfDifferent( globals->mpool, &globals->langFileName, dll );
} }
#endif #endif
HINSTANCE inst = NULL;
if ( !!globals->langFileName && !globals->locInst ) { if ( !!globals->langFileName && !globals->locInst ) {
HINSTANCE inst = ceLoadResFile( globals->langFileName ); inst = ceLoadResFile( globals->langFileName );
if ( !!inst ) { if ( !inst ) { /* load didn't work */
globals->locInst = inst;
} else {
XP_FREE( globals->mpool, globals->langFileName ); XP_FREE( globals->mpool, globals->langFileName );
globals->langFileName = NULL; globals->langFileName = NULL;
} }
} }
if ( !globals->locInst ) {
/* Failed to load, or user hadn't chosen one */
if ( !inst && !globals->appPrefs.resChosen ) {
XP_UCHAR buf[MAX_PATH];
if ( ceGetOneResFile( buf, VSIZE(buf) ) ) {
inst = ceLoadResFile( buf );
if ( !!inst ) {
replaceStringIfDifferent( globals->mpool,
&globals->langFileName, buf );
}
}
}
if ( !!inst ) {
globals->locInst = inst;
} else {
globals->locInst = globals->hInst; globals->locInst = globals->hInst;
} }
@ -1829,6 +1842,7 @@ ceDoNewGame( CEAppGlobals* globals, GIShow showWhat )
if ( results.langChanged ) { if ( results.langChanged ) {
ceWarnLangChange( globals ); ceWarnLangChange( globals );
globals->appPrefs.resChosen = XP_TRUE;
} }
#if defined XWFEATURE_RELAY || defined XWFEATURE_BLUETOOTH #if defined XWFEATURE_RELAY || defined XWFEATURE_BLUETOOTH
@ -1951,6 +1965,7 @@ ceDoPrefsDlg( CEAppGlobals* globals )
if ( langChanged ) { if ( langChanged ) {
ceWarnLangChange( globals ); ceWarnLangChange( globals );
globals->appPrefs.resChosen = XP_TRUE;
} }
/* need to reflect vars set in state into globals, and update/inval /* need to reflect vars set in state into globals, and update/inval
@ -2433,7 +2448,7 @@ ceToggleFullScreen( CEAppGlobals* globals )
{ {
globals->appPrefs.fullScreen = !globals->appPrefs.fullScreen; globals->appPrefs.fullScreen = !globals->appPrefs.fullScreen;
ceSizeIfFullscreen( globals, globals->hWnd ); (void)ceSizeIfFullscreen( globals, globals->hWnd );
(void)cePositionBoard( globals ); (void)cePositionBoard( globals );
} /* ceToggleFullScreen */ } /* ceToggleFullScreen */

View file

@ -107,6 +107,7 @@ typedef struct CEAppPrefs {
COLORREF colors[CE_NUM_COLORS]; COLORREF colors[CE_NUM_COLORS];
XP_Bool showColors; XP_Bool showColors;
XP_Bool fullScreen; XP_Bool fullScreen;
XP_Bool resChosen;
} CEAppPrefs; } CEAppPrefs;
enum { OWNED_RECT_LEFT enum { OWNED_RECT_LEFT

View file

@ -199,12 +199,12 @@ typedef struct _DllSelState {
} DllSelState; } DllSelState;
static void static void
copyWideStr( CEAppGlobals* XP_UNUSED_DBG(globals), const wchar_t* str, copyWideStr( CEAppGlobals* XP_UNUSED_DBG(globals),
wchar_t** loc ) wchar_t** dest, const wchar_t* src )
{ {
XP_U16 len = 1 + wcslen( str ); XP_U16 len = 1 + wcslen( src );
*loc = XP_MALLOC( globals->mpool, len * sizeof(**loc) ); *dest = XP_MALLOC( globals->mpool, len * sizeof(**dest) );
wcscpy( *loc, str ); wcscpy( *dest, src );
} }
static XP_U16 static XP_U16
@ -221,30 +221,21 @@ getDLLVersion( HINSTANCE hinst )
return version; return version;
} }
/* Iterate through .dll files listing the name of any that has one. Pair with typedef XP_Bool (*DllCbk)( const WIN32_FIND_DATA* data, const wchar_t* name,
* file from which it came since that's what we'll return. void* closure );
*/
static void
listDlls( DllSelState* state )
{
HANDLE fileH;
HWND hDlg = state->dlgHdr.hDlg;
WIN32_FIND_DATA data;
CEAppGlobals* globals = state->dlgHdr.globals;
XP_U16 nItems = 0;
XP_S16 selIndex = 0; /* default to built-in */
wchar_t name[64];
LoadString( globals->hInst, IDS_LANGUAGE_NAME, name, VSIZE(name) ); static void
copyWideStr( globals, name, &state->names[nItems++] ); for_each_dll( DllCbk cbk, void* closure )
(void)SendDlgItemMessage( hDlg, state->dllListID, ADDSTRING(globals), {
0, (LPARAM)name ); wchar_t name[64];
HANDLE fileH;
WIN32_FIND_DATA data;
XP_MEMSET( &data, 0, sizeof(data) );
wchar_t path[MAX_PATH]; wchar_t path[MAX_PATH];
ceGetExeDir( path, VSIZE(path) ); ceGetExeDir( path, VSIZE(path) );
wcscat( path, L"\\xwords4*.dll" ); wcscat( path, L"\\xwords4*.dll" );
XP_MEMSET( &data, 0, sizeof(data) );
fileH = FindFirstFile( path, &data ); fileH = FindFirstFile( path, &data );
while ( fileH != INVALID_HANDLE_VALUE ) { while ( fileH != INVALID_HANDLE_VALUE ) {
@ -253,20 +244,10 @@ listDlls( DllSelState* state )
if ( CUR_DLL_VERSION != getDLLVersion( hinst ) ) { if ( CUR_DLL_VERSION != getDLLVersion( hinst ) ) {
/* do nothing; wrong version (or just not our .dll) */ /* do nothing; wrong version (or just not our .dll) */
} else if ( LoadString( hinst, IDS_LANGUAGE_NAME, } else if ( LoadString( hinst, IDS_LANGUAGE_NAME,
name, VSIZE(name) ) ) { name, VSIZE(name) ) ) {
(void)SendDlgItemMessage( hDlg, state->dllListID, if ( !(*cbk)( &data, name, closure ) ) {
ADDSTRING(globals), break;
0, (LPARAM)name );
copyWideStr( globals, name, &state->names[nItems] );
copyWideStr( globals, data.cFileName, &state->files[nItems] );
if ( !!state->curFile ) {
if ( !wcscmp( data.cFileName, state->curFile ) ) {
selIndex = nItems;
}
} }
++nItems;
} else { } else {
XP_LOGF( "IDS_LANGUAGE_NAME not found in %ls", XP_LOGF( "IDS_LANGUAGE_NAME not found in %ls",
data.cFileName ); data.cFileName );
@ -277,18 +258,72 @@ listDlls( DllSelState* state )
XP_LOGF( "Unable to open" ); XP_LOGF( "Unable to open" );
} }
if ( nItems >= VSIZE(state->names) ) { if ( !FindNextFile( fileH, &data ) ) {
break;
} else if ( !FindNextFile( fileH, &data ) ) {
XP_ASSERT( GetLastError() == ERROR_NO_MORE_FILES ); XP_ASSERT( GetLastError() == ERROR_NO_MORE_FILES );
break; break;
} }
} }
SendDlgItemMessage( hDlg, state->dllListID, SETCURSEL(globals), } /* for_each_dll */
selIndex, 0L );
state->nItems = nItems; typedef struct _ListingData {
state->initialSel = selIndex; DllSelState* state;
CEAppGlobals* globals;
XP_U16 nItems;
XP_S16 selIndex;
} ListingData;
static XP_Bool
addToListCB( const WIN32_FIND_DATA* data, const wchar_t* name, void* closure )
{
ListingData* ld = (ListingData*)closure;
(void)SendDlgItemMessage( ld->state->dlgHdr.hDlg, ld->state->dllListID,
ADDSTRING(ld->globals), 0, (LPARAM)name );
copyWideStr( ld->globals, &ld->state->names[ld->nItems], name );
copyWideStr( ld->globals, &ld->state->files[ld->nItems], data->cFileName );
if ( !!ld->state->curFile ) {
if ( !wcscmp( data->cFileName, ld->state->curFile ) ) {
ld->selIndex = ld->nItems;
}
}
++ld->nItems;
XP_Bool cont = ld->nItems < VSIZE(ld->state->names);
return cont;
}
/* Iterate through .dll files listing the name of any that has one. Pair with
* file from which it came since that's what we'll return.
*/
static void
listDlls( DllSelState* state )
{
HWND hDlg = state->dlgHdr.hDlg;
CEAppGlobals* globals = state->dlgHdr.globals;
wchar_t name[64];
ListingData ld = {
.globals = globals,
.state = state,
.nItems = 0,
.selIndex = 0
};
LoadString( globals->hInst, IDS_LANGUAGE_NAME, name, VSIZE(name) );
copyWideStr( globals, &state->names[ld.nItems++], name );
(void)SendDlgItemMessage( hDlg, state->dllListID, ADDSTRING(globals),
0, (LPARAM)name );
for_each_dll( addToListCB, &ld );
SendDlgItemMessage( hDlg, state->dllListID, SETCURSEL(globals),
ld.selIndex, 0L );
state->nItems = ld.nItems;
state->initialSel = ld.selIndex;
} /* listDlls */ } /* listDlls */
static void static void
@ -374,6 +409,39 @@ DllSelDlg( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
return result; return result;
} /* DllSelDlg */ } /* DllSelDlg */
typedef struct _FindOneData {
XP_UCHAR* buf;
XP_U16 bufLen;
XP_Bool called;
} FindOneData;
static XP_Bool
findFirstCB( const WIN32_FIND_DATA* data, const wchar_t* XP_UNUSED(name),
void* closure )
{
FindOneData* fd = (FindOneData*)closure;
(void)WideCharToMultiByte( CP_ACP, 0, data->cFileName, -1,
fd->buf, fd->bufLen, NULL, NULL );
fd->called = XP_TRUE;
return XP_FALSE; /* don't continue */
}
/* Pick the first .dll found, if any */
XP_Bool
ceGetOneResFile( XP_UCHAR* buf, XP_U16 bufLen )
{
FindOneData fod = {
.buf = buf,
.bufLen = bufLen,
.called = XP_FALSE,
};
for_each_dll( findFirstCB, &fod );
return fod.called;
}
/* ceChooseResFile: List all the available .rc files and return if user /* ceChooseResFile: List all the available .rc files and return if user
* chooses one different from the one passed in. * chooses one different from the one passed in.
*/ */
@ -404,4 +472,4 @@ ceChooseResFile( HWND hwnd, CEAppGlobals* globals, const XP_UCHAR* curFileName,
LOG_RETURNF( "%s", buf ); LOG_RETURNF( "%s", buf );
return !state.cancelled; return !state.cancelled;
} } /* ceChooseResFile */

View file

@ -27,6 +27,8 @@ void ceCloseResFile( HINSTANCE inst );
XP_Bool ceChooseResFile( HWND hwnd, CEAppGlobals* globals, XP_Bool ceChooseResFile( HWND hwnd, CEAppGlobals* globals,
const XP_UCHAR* curFileName, const XP_UCHAR* curFileName,
XP_UCHAR* buf, XP_U16 bufLen ); XP_UCHAR* buf, XP_U16 bufLen );
/* pick some random file, assuming there's only one */
XP_Bool ceGetOneResFile( XP_UCHAR* buf, XP_U16 bufLen );
const XP_UCHAR* ceGetResString( CEAppGlobals* globals, XP_U16 resID ); const XP_UCHAR* ceGetResString( CEAppGlobals* globals, XP_U16 resID );
const wchar_t* ceGetResStringL( CEAppGlobals* globals, XP_U16 resID ); const wchar_t* ceGetResStringL( CEAppGlobals* globals, XP_U16 resID );