본문 바로가기
C#
2014.08.25 13:21

언어팩 방법론 (c#기준)

다물칸 주소복사
조회 수 465 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
Extra Form
구분 팁&트릭
출처 내가작성

언어팩을 고려할때 언어팩으로 표현 시 코딩하는 부분은 같으나 다음과 같은 부분을 먼저 생각해야 한다.  


1. 언어팩은 사용자가 쉽게 고치지 못하도록 해야 한다.

2. 언어팩을 손쉽게 사용자가 고쳐서 활용할 수 있다. 


1번의 경우 DLL, DB, Resource 형태등으로 만들어 쓰면 된다. 

2번의 경우 사용자가 쉽게 접근하고 쉽게 수정해서 표시가 되야 하므로 외부 텍스트 형태의 파일로 고려되어야 한다. 


1. 중복 언어일 때 코드를 따로 뽑을 것인가? 중복언어를 체크해서 재활용 할 것인가? 


이 고려사안은 일장일단이 있다. 중복언어일 경우 당연히 재활용하는 것이 좋긴하다. 하지만 프로젝트가 크고 개발인원이 많은 경우

관리 하기가 쉽지 않다. 

이를 테면 설정화면이 10개인데 여기에 저장버튼이 있다고 했을 때, 저장 버튼의 캡션을 10개의 코드로 뽑을 것인가? 1개의 코드로 사용할 것인가이다. 


필자의 경우 언어팩도 만들고 영문게임을 한글화하는 작업을 여럿해봤는데 요즘 게임의 경우 코드를 화면별로 뽑는 추세인 것 같다. 중복언어가 많다는 이야기.


개인적으로 전전에 다녔던 회사가 해외지사가 많은 관계로 기본적으로 개발할 때 영문이 기본인 회사를 오래다녀서 모르겠지만 기본언어는 영문을 기준으로 개발한다. 여기에 한글이 필요하면 클라이언트 프로그램(사용자 UI)일 경우에만 언어팩을 만들어 한글화하는 방식을 취한다. 

여기에 사용된 방식을 소개한다. 


우선 언어팩 포맷형태

Ex) 단순 Text와 Comma로 처리하는 방식 (저장형태 UTF-8)

영문팩

Code,Original English,Localization

LANG_COLUMN_STUDYDATE,StudyDate,StudyDate

LANG_COLUMN_PATIENTID,Pat.ID,Pat.ID

LANG_COLUMN_PATIENTNAME,Pat.Name,Pat.Name

LANG_COLUMN_PATIENTSEX,Pat.Sex,Pat.Sex

LANG_COLUMN_PATIENTBIRTH,Pat.DOB,Pat.DOB

한글팩

Code,Original English,Localization

LANG_COLUMN_STUDYDATE,StudyDate,검사일자

LANG_COLUMN_PATIENTID,Pat.ID,번호

LANG_COLUMN_PATIENTNAME,Pat.Name,이름

LANG_COLUMN_PATIENTSEX,Pat.Sex,성별

LANG_COLUMN_PATIENTBIRTH,Pat.DOB,생년월일


위 예를 든 포맷을 보면 공통적으로 원본영문이 포함된다. 이는 영문팩을 기준으로 다른언어로 변역할 때 참조하라고 일부러 넣어놓았다. 

UTF-8로 저장하는 이유는 어떤 언어의 OS라도 저렇게 저장하면 읽을 때 적어도 깨지지 않는다. 물론 중문OS에서 한글팩을 설치하지 않았다면 

당연히 깨진다. 


프로그램에서는 기본적으로 코드를 상수화하고 원본 영문을 상수에 넣어 처리한다. 

이는 언어팩을 만들어 배포를 한 후, 만약 실수로 혹은 누군가가 고의로 언어팩을 모두 삭제할 경우에 대한 예외처리를 하기 위함이다. 

아래 방식은 전체 파일을 한꺼번에 읽어서 코드상수에 넣어서 처리하는 방식으로 큰 프로그램의 경우 언어팩 크기가 하나의 파일로 하기에 커질 경우 언어팩 팩을 분할하여 관리하는 방식을 취할 수 있다. 

  1.         public static string LANG_MESSAGE_STORAGECHECK_TITLE = "Storage usage check";
  2.         public static string LANG_MESSAGE_STORAGECHECK = "{0}% of the storage is exceeded. Please replace the storage.\n\r(Usage: {1}/ Total: {2})";
  3.  
  4.         public static string LANG_MESSAGE_ISEXITPROGRAM_TITLE = "Exit Program";
  5.         public static string LANG_MESSAGE_ISEXITPROGRAM = "Is exit program?";


이 함수는 전체 언어팩에서 특정코드의 값을 가져오는 함

  1.        private static string ProcGetLang(string[] aTot, string Code)
  2.         {
  3.             for (int i = 0; i < aTot.Count(); i++)
  4.             {
  5.                 string[] aLang = aTot[i].Split(',');
  6.  
  7.                 aLang[0] = aLang[0].Replace("\n""");
  8.  
  9.                 if (aLang[0] == Code)
  10.                 {
  11.  
  12.                     if (aLang[2] == "")
  13.                     {
  14.                         // Localization이 NULL이면 Original값을 던진다.
  15.                         return aLang[1];
  16.                     }
  17.                     else
  18.                     {
  19.                         // Localization값을 던진다.
  20.                         return aLang[2];
  21.                     }
  22.                 }
  23.             }
  24.  
  25.             return "";
  26.         }

?이 함수는 언어팩을 가져와서 각 코드 상수에 설정된 언어팩값으로 가져오는 함수

  1.         public static void ProcRefreshLang()
  2.         {
  3.             string LangFile = Path.Combine(gMain.LanguagePath, gMain.pInfo.Language + ".loc");
  4.             string sTmp = "";
  5.             string sTotLang = EMCommon.FileLoad(LangFile, Encoding.UTF8);
  6.             string[] aTotLang = sTotLang.Split('\r');
  7.  
  8.             // Message
  9.             sTmp = ProcGetLang(aTotLang, "LANG_MESSAGE_ISDELETESTUDY_TITLE");
  10.             if (sTmp != "") { gLang_Message.LANG_MESSAGE_ISDELETESTUDY_TITLE = sTmp; }
  11.  
  12.             sTmp = ProcGetLang(aTotLang, "LANG_MESSAGE_ISDELETESTUDY");
  13.             if (sTmp != "") { gLang_Message.LANG_MESSAGE_ISDELETESTUDY = sTmp; }
  14.         }