[다국어 프로그래밍] ⑤ 닷넷으로 하면 쉽다!

일반입력 :2008/09/18 08:41

하정희 (마이크로소프트웨어 필자)

시간은 화살 같다는 말이 부쩍 실감나는 요즘입니다. 다들 연초에 세웠던 계획은 잘 지키고 있는지 모르겠네요. 다시 한번 숨을 돌리고 뒤를 돌아보며 앞으로 나갈 힘을 비축해야 할 때입니다.

이번에는 그동안 비주얼 스튜디오 6.0의 이런저런 테크닉을 이용해 어렵게 처리해야 했던 다국어 프로그래밍의 문제가 닷넷에서는 얼마나 쉽고 편하게 바뀌었는지 알아보도록 하겠습니다.

닷넷이 제공해 주는 여러 가지 이점

닷넷 프레임워크는 리소스와 관련된 여러 클래스와 도구들을 가지고 있습니다. 본격적으로 예제를 통해 다국어 프로그래밍을 연습해 보기 전에 우선 기본적인 지식을 쌓아보기로 할까요? 그 첫 번째로 다음에 소개하는 내용은 리소스 관련 클래스들입니다.

◆ 리소스 관련 클래스들

1. ResourceManager 클래스 : ResourceManager는 실행시 적절한 리소스에 접근할 수 있도록 해주는 클래스입니다. 지역화된 리소스가 존재하지 않을 경우에 대비해 언어 중립적인 리소스에 접근할 수 있도록 해주는 역할을 하며, CreateFileBasedResourceManager 라는 메쏘드를 이용하면 어셈블리 내부에 포함되어 있지 않은 리소스에 대한 접근도 가능하게 해줍니다.

2. ResourceWriter 클래스 : ResourceWriter 클래스는 시스템의 기본 형식에 맞추어 리소스를 파일이나 스트림의 형태로 작성할 수 있게 해줍니다. AddResource라는 메쏘드를 이용해 이름-값의 짝의 형태로 관리할 수 있습니다.

3. ResourceReader 클래스 : ResourceReader 리소스 파일, 스트림 등을 읽어들일 수 있습니다.

4. ResourceSet 클래스 : ResourceSet 클래스는 특정 문화에 맞춰 지역화된 모든 종류의 리소스를 저장할 수 있습니다. ResourceManager와는 달리 지역화된 리소스가 없을 경우의 대비책은 제공해 주지 않습니다.

5. CultureInfo 클래스 : CultureInfo 클래스는 사용자의 주언어, 보조언어, 국가/지역, 문화 특성에 따른 사용자의 선호도에 따른 정보를 포함하고 있습니다. 이 클래스를 이용해 날짜 형식이나 시간 형식, 숫자 형식, 문자열의 정렬 등을 정의할 수 있습니다.

6. RegionInfo 클래스 : RegionInfo 클래스는 측정의 단위를 결정하고 지역 코드를 이름으로 변환하는 기준을 제공합니다.

또한 리소스 관련 도구들에는 어떤 것들이 있을까요?

◆ 리소스 관련 도구들

1. Resgen.exe(리소스 파일 생성 유틸리티) : 텍스트 파일과 .resx 파일을 .resources 파일로 변환시켜주는 유틸리티입니다. 또한 .resources 파일을 다시 .resx 파일로 변화시킬 수도 있습니다. 이 유틸리티에 사용되는 텍스트 파일은 ASCII, UTF-8, UTF-16 등의 형식이면 됩니다.

2. Al.exe(어셈블리 링커) : .resources 파일을 dll 파일로 변화시킬 수 있습니다.

이렇게만 말씀드리니 대체 무슨 말을 하는지 모르겠다구요? 앞에서 간략히 설명한 클래스들과 도구들은 실제 예제를 통해 그 사용법을 배워보기로 하겠습니다.

첫 번째 예제 - 다국어 폼 만들기

비주얼 스튜디오 닷넷을 시작해 LocalizationDemo1이라는 이름의 솔루션을 윈도우 응용 프로그램 형태로 만듭시다. 이후 Form1.cs를 <화면 1>과 같이 구성해 프로젝트에 새로운 폼 Form2.cs를 추가해 봅시다.

‘닫기’ 버튼의 이름을 btnCloseForm으로 정하고, 클릭하면 폼이 닫히도록 다음의 코드를 추가해 둡시다.

this.Hide();

지역화를 지원할 수 있도록 Form2.cs의 속성 창에서 Localizable 속성을 True로 바꾸고, Language 특성을 기본 값에서 영어로 변경해 봅시다.

Lanuage를 영어로 바꾸는 순간, 리소스가 추가된다는 메시지 박스가 나타나서 이제 두 언어의 디자인 환경이 각각 다르게 관리된다는 사실을 알려주게 됩니다. 이제 다시 Form1의 디자인 환경으로 돌아가 봅시다. 프로그램 시작 버튼을 더블 클릭해서 다음의 코드를 추가합니다.

private void button1_Click(object sender, System.EventArgs e)

{

if( this.radioButton1.Checked )

{

//Get the Default installed culture

System.Threading.Thread.CurrentThread.CurrentUICulture =

System.Globalization.CultureInfo.InstalledUICulture ;

}

else if( this.radioButton2.Checked )

{

//Get the English culture

System.Threading.Thread.CurrentThread.CurrentUICulture =

new System.Globalization.CultureInfo(en) ;

}

Form2 f2 = new Form2();

f2.Show();

}

첫 번째 라디오 버튼이 선택될 경우 실행되고 있는 환경의 기본 로케일을 따라 리소스를 선택해 폼을 로드하는 것이고, 두 번째 라디오 버튼이 선택되면 영어 환경에 맞춰진 리소스를 선택해 폼를 로드하는 코드입니다. 앞의 코드에서는 앞서 말씀드린 CultureInfo 클래스가 사용되었으며, 현재 실행 중인 쓰레드의 UI를 결정하기 위해 System.Threading.Thread.CurrentThread.CurrentUICulture라는 값을 이용하고 있습니다.

여기까지만 살펴보아도 닷넷이 기본적으로 제공해주는 지역화 도구가 상당히 편리해졌음을 알 수 있습니다. 예전 같으면 기본적인 리소스 편집기로는 사실 다국어 프로그래밍에 필요한 리소스를 편집하는 것이 불가능했습니다. 두 가지 언어의 리소스를 같이 입력하는 것 자체가 불가능했기 때문입니다. 하지만 닷넷은 폼의 Language 프로퍼티를 바꾸는 것만으로 간단하게 각각의 Culture에 대한 리소스를 디자인 환경에서 편집할 수 있는 강력함을 보여주고 있습니다. 또한 소스코드 자체도 유니코드로 관리되는 편리함도 제공합니다.

두 번째 예제 - 문자열 지역화하기

이제 두 번째 예제를 만들어 봅시다. 프로젝트의 이름을 LocalizationDemo2라고 하고, Form1을 <화면 5>과 같이 구성해 봅시다.

디자인 환경에서 컨트롤을 추가할 때 자동으로 생성된 코드가 <리스트 1>처럼 나타납니다. 이중에서 윈도우 폼 디자이너에서 생성한 코드 부분을 열어 코드를 구경해 보면 여러분이 디자인 환경에서 한 작업이 어떻게 코드로 표시되었는지 확인할 수 있을 것입니다.

이제 프로젝트에 새 항목을 추가해 보겠습니다. 솔루션 탐색기의 프로젝트 명에서 오른쪽 마우스 버튼을 클릭해 추가 메뉴에서 새 항목 추가를 클릭해 봅시다. 이 중 ‘어셈블리 리소스 파일’을 선택해 새로 생성합니다(resource1.resx). 그리고 <화면 6>, <화면 7>처럼 resource1.resx에 값을 추가해 봅시다.

프로젝트에 resource1.en-US.resx라는 이름의 어셈블리 리소스 파일을 추가해 <화면 8>과 같이 편집합니다.

이제 Form1.cs의 소스를 편집해 봅시다. 우선 다음의 네임스페이스들을 추가합니다.

using System.Resources;

using System.Globalization;

using System.Threading;

또한 컨트롤들이 선언된 아래에 다음의 코드를 추가합니다. ResourceManger 클래스를 이용해 닷넷에서 제공하는 기본적인 리소스 형식인 .resx를 로드할 수 있게 해주는 코드입니다.

private ResourceManager m_ResourceManager = new ResourceManager(LocalizationDemo2.resource1,

System.Reflection.Assembly.GetExecutingAssembly());

private CultureInfo m_EnglishCulture = new CultureInfo(en-US);

private CultureInfo m_KoreanCulture = new CultureInfo(ko-KR);

다음 함수를 코드에 추가해 주고, Form1의 생성자에서 이를 호출합니다. UpdateUI 함수를 호출하면 resx 파일로부터 리소스를 읽어들여 각 컨트롤의 리소스를 변경하게 됩니다.

public Form1()

{

//

// 윈도우 폼 디자이너 지원에 필요합니다.

//

InitializeComponent();

UpdateUI();

//

// TODO: InitializeComponent를 호출한 다음 생성자 코드를 추가합니다.

//

}

:

:

private void UpdateUI()

{

lblName.Text = m_ResourceManager.GetString(lblName);

btnHello.Text = m_ResourceManager.GetString(btnHello);

optKorean.Text = m_ResourceManager.GetString(optKorean);

optEnglish.Text = m_ResourceManager.GetString(optEnglish);

}

마지막으로 다음의 이벤트 핸들러들을 코드에 추가해 라디오 버튼을 클릭했을 때 해당 언어의 인사말과 메뉴가 나오도록 수정합니다.

private void optKorean_CheckedChanged(object sender, System.EventArgs e)

{

Thread.CurrentThread.CurrentUICulture = m_KoreanCulture;

UpdateUI();

}

private void optEnglish_CheckedChanged(object sender, System.EventArgs e)

{

Thread.CurrentThread.CurrentUICulture = m_EnglishCulture;

UpdateUI();

}

private void btnHello_Click(object sender, System.EventArgs e)

{

string message = String.Format(m_ResourceManager.GetString(greetingMessage), txtName.Text);

MessageBox.Show(this, message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);

}

완성된 프로그램을 실행하면 <화면 9>, <화면 10>처럼 한국어 옵션을 선택했을 때는 한국어 인사말이, 영어 옵션을 선택했을 때는 영어 인사말이 나옴을 확인할 수 있습니다.

닷넷이 가진 다국어 프로그래밍의 힘

지금까지 살펴본 방법은 윈도우 환경 내에서 리소스를 편집하고 이를 불러오는 방법입니다. 이외에도 resgen.exe를 이용해 기존의 .resx 파일을 .resource 파일로 변경해 새로운 리소스 파일을 만들어낸 후 이를 Al.exe를 이용해 애플리케이션과 별개의 리소스 dll로 리소스를 관리하기도 합니다. 또한 텍스트 파일에 리소스를 저장하고 이를 불러오는 방법에 대비한 클래스들도 준비되어 있습니다.

앞서 말씀드린 것처럼 닷넷은 기존의 비주얼 스튜디오 6.0이 불완전하게 지원하던 다국어 프로그래밍을 설계 단계에서부터 완벽하게 지원할 수 있도록 되어 있습니다. 누군가 제게 다국어 프로그램을 하나 짜야한다고 말한다면 저는 주저없이 닷넷을 개발도구로 택할 것 같습니다. 그 편리함을 한 번 맛보고 나면 다시는 예전으로 돌아갈 수 없어서 말이죠.

지금까지 다섯번에 걸쳐 비주얼 베이직 6.0, 비주얼 C++ 6.0, 비주얼 스튜디오 닷넷을 이용해 다국어 프로그래밍을 하는 방법에 대해 간략하게 살펴보았습니다. 사실 연재에서 다뤄진 부분보다 훨씬 더 많은 것을 고려해야만 제대로 된 다국어 프로그램을 하나 만들어낼 수 있겠지만, 이번 글로 독자 여러분들께서 다국어 프로그래밍에 대한 기본적인 이해와 지식을 가져갔으면 하는 것이 필자의 작은 소망입니다. 그동안 읽어주셔서 감사합니다. 독자 여러분들 매일매일 행복한 날 되시고, 여러분의 프로그래밍 실력이 부쩍부쩍 늘어나길 기원해 봅니다. @