resourceTest
リソース・ファイルのコンパイル
memo
- リソースを各言語のファイルをtxtファイルで用意。
- txt から resource生成
- デフォルトの string.resources は 直接exeにリンク
- ほかの言語はal.exe で dll 作成後各DIRへ
リソースへのアクセス
- ResourceManager クラス (MSDN2)
- CultureInfo クラス (MSDN2
,ref)
でシステム側のデフォルトカルチャ入手
- もしくは強制
- 各言語対応の文字列入手
cat resourceTest.cpp
// resourceTest.cpp
#using <mscorlib.dll>
using namespace System;
using namespace System::Resources;
using namespace System::Reflection;
using namespace System::Globalization;
#include "myApp.h"
[STAThreadAttribute]
int main(array<System::String ^> ^args)
{
myApp^ ma = gcnew myApp;
// show the base cultures for which the app was designed to handle...
Console::WriteLine( "1. New Zealand English" );
Console::WriteLine( "2. US English" );
Console::WriteLine( "3. German (Germany)" );
Console::WriteLine( "4. Japanese" );
ma->ShowPrompt( "promptCulture", 1, 4 );
Console::WriteLine( "\r\n" );
//set the current culture to the choice made!
switch ( ma->culture )
{
case 1: // New Zealand
ma->ci = gcnew CultureInfo( "en-NZ" );
break;
case 3: // German
ma->ci = gcnew CultureInfo( "de-DE" );
break;
case 4: // Japanese
ma->ci = gcnew CultureInfo( "ja-JP" );
break;
default: // use the default...
ma->ci = gcnew CultureInfo( "en" );
break;
}
ma->ShowName();
ma->ShowAge( 15, 120 );
ma->ShowDegrees();
ma->ShowDistance();
ma->PrintOutputs();
return 0;
}
cat myApp.h
// myApp.h
public ref class myApp {
public:
// an assembly aware constructor...
static ResourceManager^ rm ;
Int32 age;
Int32 culture;
Int32 degrees;
Int32 distToWork;
String^ name;
CultureInfo^ ci;
// Default constructor
myApp() ;
void ShowName() ;
void ShowDegrees() ;
void ShowAge( Int32 lb, Int32 ub ) ;
void ShowPrompt( String^ RetrieveString, Int32 lb, Int32 ub ) ;
void ShowDistance() ;
void PrintOutputs() ;
};
cat myApp.cpp
#using <mscorlib.dll>
using namespace System;
using namespace System::Resources;
using namespace System::Reflection;
using namespace System::Globalization;
#include "myApp.h"
// Default constructor
myApp::myApp() {
rm = gcnew ResourceManager( "strings", Assembly::GetExecutingAssembly());
Int32 age = 0;
Int32 culture = 0;
Int32 degrees = 0;
Int32 distToWork = 0;
String^ name = "";
CultureInfo^
ci = gcnew CultureInfo( CultureInfo::CurrentUICulture->Name );
}
void myApp::ShowName() {
Console::WriteLine();
// show the inital prompt until a valid entry is made...
while (true) {
Console::Write( String::Concat( rm->GetString( "promptName",ci), " " ) );
name = Console::ReadLine();
if ( !name->Equals( "" ) )
return;
Console::WriteLine();
Console::WriteLine( rm->GetString( "promptMissing", ci ) );
}
}
void myApp::ShowDegrees() {
Console::WriteLine();
// show the inital prompt until a valid entry is made...
while (true) {
Console::Write( String::Concat( rm->GetString( "promptDegrees",ci ), " ", rm->GetString( "degree1", ci ), " " ) );
try {
degrees = Convert::ToInt32( Console::ReadLine() );
}
catch( Exception^ ) {}
if ( degrees >= Convert::ToInt32( rm->GetString( "degree2", ci ) ) &&
degrees <= Convert::ToInt32( rm->GetString( "degree3", ci ) ) )
return;
Console::WriteLine();
Console::WriteLine( rm->GetString( "promptValidDeg", ci ) );
}
}
void myApp::ShowAge( Int32 lb, Int32 ub ) {
Console::WriteLine();
// show the inital prompt until a valid entry is made...
while (true) {
Console::Write( String::Concat( rm->GetString( "promptAge", ci ), " " ) );
try {
age = Convert::ToInt32( Console::ReadLine() );
}
catch( Exception^ ) {}
if ( age >= lb && age <= ub )
return;
Console::WriteLine();
Console::WriteLine( rm->GetString( "promptValidAge", ci ) );
}
}
void myApp::ShowPrompt( String^ RetrieveString, Int32 lb, Int32 ub ) {
Console::WriteLine();
// show the inital prompt until a valid entry is made...
while (true) {
Console::Write( String::Concat( rm->GetString( RetrieveString, ci ), " " ) );
try {
culture = Convert::ToInt32(Console::ReadLine());
}
catch( Exception^ ) {}
if ( culture >= lb && culture <= ub )
break;
Console::WriteLine();
Console::WriteLine( rm->GetString( "promptMissing", ci ) );
}
}
void myApp::ShowDistance() {
Console::WriteLine();
// show the inital prompt until a valid entry is made...
while (true) {
Console::Write( String::Concat( rm->GetString( "promptDist",ci), " ", rm->GetString( "dist1", ci ), " " ) );
try {
distToWork = Convert::ToInt32( Console::ReadLine() );
}
catch( Exception^ ) {}
if ( distToWork > 0 && distToWork <= 2000 )
break;
Console::WriteLine();
Console::WriteLine( rm->GetString( "promptValidDist", ci ) );
}
}
void myApp::PrintOutputs() {
Console::WriteLine();
Console::Write( rm->GetString( "promptEntries", ci ) );
Console::WriteLine();
Console::WriteLine( "{0,-20}{1}", rm->GetString( "outputName", ci ),name);
Console::WriteLine( "{0,-20}{1}", rm->GetString( "outputAge", ci ), age);
Console::WriteLine( "{0,-20}{1}", rm->GetString( "outputDegrees", ci),degrees );
Console::WriteLine( "{0,-20}{1}", rm->GetString( "outputDist", ci ),distToWork );
}
cat strings.txt
;prompts
promptCulture = Please select the culture you wish to view this example in ==>
;
promptName = Please enter your name ==>
promptAge = Please enter your age ==>
promptDegrees = Please enter the current temperature,
promptMissing = Please ensure you enter a valid value.
promptValidAge = Please enter a valid age for an adult (15 and up)
promptDist = Please tell us how far you travel to work
promptValidDist = Please enter a valid distance (greater than zero).
promptValidDeg = Please enter a viable outside temperature (-100 to 140).
promptEntries = You entered the following information:
;ditances
dist1 = (in Miles) ==>
;degree measurements
degree1 = in Fahrenheit:
degree2 = -100
degree3 = 140
;outputs
outputName = Name:
outputAge = Age:
outputDegrees = Temperature:
outputDist = Distance To Work:
cat strings.ja.txt | nkf -s
;prompts
promptCulture = このサンプルであなたが見たいカルチャーを選択してください。==>
promptName = 名前を入力してください。==>
promptAge = 年齢を入力してください。==>
promptDegrees = 現在の気温を入力してください、
promptMissing = 正しい値を入力したか確認してください。
promptValidAge = 正しい年齢を入力してください。(15以上)
promptDist = 職場までの距離を教えてください。
promptValidDist = 正しい距離を入力してください。(0以上).
promptValidDeg = 正しい屋外の気温を入力してください。(-100 to 140).
promptEntries = あなたの入力した情報は以下のとおりです:
;ditances
dist1 = (キロメートル) ==>
;degree measurements
degree1 = 摂氏:
degree2 = -100
degree3 = 140
;outputs
outputName = 名前:
outputAge = 年齢:
outputDegrees = 気温:
outputDist = 職場までの距離:
cat makefile
.PHONY: all test mmm clean
.SUFFIXES: .obj .txt .resources .dll
TARGET=resourceTest
CULTUREDIRS=ja en-NZ de
DLLS:= $(shell for x in $(CULTUREDIRS); do echo $$x/$(TARGET).resources.dll; done )
all: $(TARGET).exe $(DLLS)
TEXTFILES:=strings.txt $(shell for x in $(CULTUREDIRS); do echo strings.$$x.txt; done )
RESOURCES=$(TEXTFILES:%.txt=%.resources)
$(RESOURCES): $(TEXTFILES)
LOPT=
OBJS=$(TARGET).obj myApp.obj
$(TARGET).obj: $(TARGET).cpp myApp.h
myApp.obj: myApp.cpp myApp.h
$(TARGET).exe: $(OBJS) $(RESOURCES)
link $(LOPT) $(OBJS) /assemblyResource:strings.resources
.cpp.obj:
cl -c -Wall -Od -clr $<
.txt.resources:
resgen $*.txt $*.resources
$(DLLS): $(RESOURCS)
@(for x in $(CULTUREDIRS); do \
if [ ! -d $$x ] ; then mkdir $$x; fi ;\
al /t:lib /culture:$$x /embed:strings.$$x.resources /out:$$x\\$(TARGET).resources.dll ;\
done;)
test: $(TARGET).exe
./$(TARGET).exe
clean:
-rm $(TARGET).exe *.obj *~ $(TARGET).exe.manifest *.resources
-rm -fr $(CULTUREDIRS)
mmm:
cat $(TARGET).cpp
cat myApp.h
cat myApp.cpp
cat strings.txt
cat strings.ja.txt | nkf -s
@echo
cat makefile
html:
cat /dev/clipboard | code2html.exe | unix2dos
dd:
echo $(CULTUREDIRS)
echo $(RESOURCES)
echo $(TEXTFILES)