딱지_CEGUI
1 IME #
참고 사이트;
1.1 IME란 무엇인가? #
IME란 Input Method Editor로 극동 아시아 언어인 한국어, 중국어, 일본어등 DBCS(Double Byte Character Sets) / MDCS(Multi Byte Character Sets)을 입력 받는 에디터를 말한다.
참고자료 >>
http://www.dexgame.com/zbxe/?mid=download&search_target=title&search_keyword=ime&document_srl=5879
다국어 IME 구현 재료 (ANSI 모드 사용)
IME_Test.zip (2006.12.08)...
이권일 안녕하세요. 매크로 없는 메비~랍니다.
다국어 IME 구현 자료입니다. 옛날 자료실에 있었는데 이쪽으로 약간 수정한 새 버젼을 올립니다. 기본적으로 ANSI 버젼에서 작동하는 코드이며 다국어 입/출력 관련 코드가 들어 있습니다. Composite 와 Candidate 는 GDI에 직접 그려주고 있으니 뜯어서 게임에 보여주시면 되고 폰트 출력부분을 Unicode 로 하고 있으나 ANSI 로 변환해서 찍어주셔도 됩니다.
변경사항; Vietnam Charset/Codepage 처리 추가 (switch문)
1.2 일반적인 IME의 동작 #
일반적인
CWnd를 상속받아서 만든 윈도우는 영문자를 입력 받으로 WM_KEYDOWN 다음에 WM_CHAR메세지가 발생하게 되지만 한글일 경우에는 WM_KEYDOWN 다음에 WM_IME_COMPOSITION이 발생하고 한글이 완성이 되면 WM_CHAR이 두번 발생되게 된다. 왜 두번이냐면 한글은 2byte이므로 한번에 전달할 수 없기 때문이다.
이럴때의 문제점은 한글처리가 자음이나 모음단위로 처리할 수 없고 글자단위로 처리해야 한다는 것이다.
이런 문제를 해결하기 위해서 기본 IME에서 발생되는 메세지에 대한 처리를 프로그래머가 직접해야 하는 것이다.
시스템에서는 IME 윈도우의 변화/조립 문자열의 변화 등 IME의 모든 상태 변화에 대해 WM_IME 로 시작되는 IME 메시지를 포커스 윈도우에 보낸다. 이 메시지들을 처리하지 않고
DefWindowProc() 으로 보낼 경우 프로그램은 완성된 문자에 대해서만 WM_CHAR 메시지를 받게 된다.
1.2.1 IME에 관련된 함수들 #
함수 | 설명 |
ImmAssociateContext | 특정윈도우와 IME를 매핑시킨다. Default IME를 사용할 수 있지만 새로운 IME를 생성해서 내 윈도우 특성에 맞게 사용할수 있다. |
ImmCreateContext | 새로운 IME를 생성한다. 나중에 반드시 ImmDestroyContext를 호출해야 한다. |
ImmDestroyContext | IME를 반환한다. |
ImmGetDefault | IMEWnd Default IME 핸들의 얻는다. 나중에 반드시 ImmReleaseContext 를 호출해야 한다. |
ImmReleaseContext | Default IME 핸들을 OS에 반환한다. |
ImmGetConversionStatus | IME의 상태를 취득한다. |
ImmSimulateHotKey | 한/영, 전각/반각, 한자등의 키를 Simulation 해 준다. |
ImmGetCompositionString | 현재 IME에 입력되어 있는 한글코드의 크기 및 내용을 취득한다. |
IsDBCSLeadByte | 한글 두 Byte중에서 첫번째 Byte인지 검사해 주는 함수이지만 조합형 한글은 첫번째 Byte에 올수 있는 코드와 두번째 Byte에 올 수 있는 코드의 범위가 같아서 이 함수로 검사할 수 없다. 따라서 이 함수를 사용하지 말고 직접 만들어서 사용하는 것이 바람직하다. |
1.3 한글 입력 관련 윈도우 메세지 #
메세지 | 상 수 값 | 상수의 의미 |
WM_KEYDOWN | &H100 | 키가 눌릴 때 발생 |
| 한글 입력 중에는 wParam에 229(콘트롤의 "KeyDown"이벤트와 같음)를, lParam에 키코드와 다른 정보를 함께 반환한다. lParam값을 API함수인 "MapVirtualKey"를 사용하여 한글 입력 중에 눌린 키를 알아낼 수 있다. 한글이 아닐 경우에는 wParam에 콘트롤의 "KeyDown"이벤트에서 반환하는 "KeyCode와 같은 값을 반환한다.(이 때도 lParam에 같은 값이 반환됨) |
WM_KEYUP | &H101 | 콘트롤의 "KeyUp"이벤트와 같다 |
WM_CHAR | &H102 | 콘트롤의 "KeyPress"이벤트와 같지만 한글의 경우에는 한글의 첫바이트만 반환한다 |
WM_IME_STARTCOMPOSITION | &H10D | 한글을 처음 입력할 때 발생(IME가 조립 문자열을 만들기 직전에 보낸다) |
| -.영문 입력 후 또는 수자 입력 후 한글 키를 누르면 단 한번만 발생한다.예) "123"을 입력하다가 "ㄱ"을 누르면 발생(WM_IME_ENDCOMPOSITION 발생후 한글 입력시 발생) |
| -.조립을 시작한다는 통지이므로 wParam, lParam 으로 전달되는 인자가 없으며 리턴 값도 의미가 없다. 디폴트 윈도우에서는 이 메시지를 받았을 때 조립 윈도우를 보여준다. |
WM_IME_COMPOSITION | &H10F | 한글 입력 중에 발생(한글을 합성중인라는 의미 임) |
| -.WM_IME_STARTCOMPOSITION가 발생한 후 한글 키를 누를 때 마다 발생하며 wParam과 lParam에 부가적인 정보가 반환 된다. |
| -.한글의 경우 한 음소가 입력될 때마다 메시지가 발생하므로 조립중인 문자를 보여주고 싶은 경우 이 메시지를 처리한다(WM_IME_COMPOSITION 메시지는 조합이 끝나면 WM_IME_CHAR 메시지를 추가로 발생 시킨다) |
| wParam | 합성 중인 한글에 대한 ASCII Code가 반환된다(조립중인 문자의 코드가 전달되며 2바이트의 DBCS 문자로 조립중인 중간 문자 코드이다) |
| lParam | 반환된 wParam가 합성중인 글자 인지 완성된 글자인지를 반환한다(조립 상태가 어떻게 변경되었는지, 이 문자를 어떻게 처리해야 하는지 나타내는 플래그의 집합이다) |
| lParam 값 의미 | |
| &H6018(GCS_COMPSTR) | 반환된 wParam가 합성중인 글자임(아직 한 음절이 완성되지 않았다) |
| &H800(GCS_RESULTSTR) | 반환된 wParam가 완성된 글자임 |
WM_IME_ENDCOMPOSITION | &H10E | 한글 입력을 종료할 때 발생/ 한글입력도중 한글이외의 문자가 입력되었을때 발생(조립이 끝났다는 통지 메시지 |
| -.한글 입력 중 한글키가 아닌 키를 누를 때(숫자키, Enter키, 한영 변환키, 방향키 등), 마우스로 클릭하거나, 포거스를 잃을 때 발생한다.(즉 한글 입력 중에는 검정 상자가 생기는 데 그 검정 상자가 없어질 때) |
| -.인수와 리턴 값이 없다. |
WM_IME_SETCONTEXT | &H281 | 윈도우가 활성화 될때 기본 IME의 초기화를 위해서 발생(응용 프로그램이 활성/비활성화 될 때 보내진다) |
| 커스텀 윈도우의 경우 이 메시지를 받았을 때 ImmIsUIMessage() 함수를 호출하여 조립 윈도우와 후보 윈도우를 보이도록 해야한다. |
| wParam | 활성화 되면 TRUE, 비활성화 되면 FALSE가 전달된다. |
WM_IME_NOTIFY | &H282 | IME 윈도우가 변경되었다는 통지 메시지이다. |
| IME_OPENSTATUSWINDOW 통지 메시지는 시스템 설정에서 'IME 상태표시' 옵션이 선택되어있지 않으면 전달되지 않는다. |
| wParam | 변경의 종류. 후보 윈도우가 열렸다거나 목록이 변경됨, 한글, 영문 입력 모드가 변경되었음을 통지한다 |
|
WM_IME_CONTROL | &H283 | |
WM_IME_COMPOSITIONFULL | &H284 | |
WM_IME_SELECT | &H285 | |
WM_IME_CHAR | &H286 | 완성된 한글에 대한 ASCII값을 반환(문자 하나가 완성되었을 때 보내진다) |
| WM_IME_COMPOSITION 발생 후(lParam 값이 &H800일 때) 발생한다. 위에서 설명한 바와 같이 한글의 경우 WM_CHAR가 한글의 첫바이트만 반환하기 때문에 완성된 한글만을 알아내기 위해서는 이 메세지를 사용해야 한다.(실제로는 WM_IME_COMPOSITION 메세지를 사용하기 때문에 별로 사용하지 않음) |
| 완성된 문자를 직접 처리하려면 이 메시지를 처리한다. 이 메시지를 무시하면 한글 한 문자에 대해 WM_CHAR 메시지를 두 번 받게 된다. WM_IME_CHAR 메시지는 WM_CHAR메시지를 추가로 발생 시킨다. |
| wParam | 완성된 문자의 코드가 전달된다. 이 코드는 DBCS 일 수 있다. 단, 유니 코드의 경우 WM_CHAR와 WM_IME_CHAR는 동일한 바이트를 처리한다. |
WM_IME_KEYDOWN | &H290 | 한글 입력중 한글키가 아닌 키를 누를 경우 그 키값을 반환 |
| WM_IME_ENDCOMPOSITION메세지 발생 후에(한글 입력을 종료하고)발생한다. |
WM_IME_KEYUP | &H291 | |
WM_IME_REPORT | &H0280 | |
WM_IME_REQUEST | &H0288 | |
1.3.1 WM_IME_COMPOSITION의 발생과 취득 한글 코드 #
이 부분은 한글을 입력 했을때, 즉 WM_IME_COMPOSITION 메세지가 발생했을때 IME 버퍼의 내용을 표로 만들어 놓은 것이다.
WM_IME_COMPOSITION 메세지는 한글모드에서 한글이 입력되면 완성이든 미완성이든 이 메세지를 발생하게 되는데 lParam의 값으로 검사해서 완성된 글자인지 미 완성된 글자인지 알수 있다. 그리고 IME가 저장하고 있는 문자열을 Composition 문자열이라고 한다.
입력순서 | lParam의 내용 | 버퍼의 내용 | | 입력순서 | lParam의 내용 | 버퍼의 내용 |
ㄱ | GCS_COMPSTR | ㄱ | | ㄱ | GCS_COMPSTR | ㄱ |
ㅏ | GCS_COMPSTR | 가 | | ㅏ | GCS_COMPSTR | 가 |
ㄴ | GCS_COMPSTR | 간 | | Back Space | GCS_COMPSTR | ㄱ |
ㅏ | GCS_RESULTSTR | 가 | | Back Space | GCS_COMPSTR | NULL (길이 0) |
| GCS_COMPSTR | 나 |
ㄷ | GCS_COMPSTR | 낟 |
ㅏ | GCS_RESULTSTR | 나 |
| GCS_COMPSTR | 다 |
3 | GCS_RESULTSTR | 다3 |
'CEGUI-SDK-0.5.0b-vc8\datafiles\'폴드에 저장된 다양한 파일을 로딩해서 사용하며
기본적인 구조로 schemes, looknfeel, imagesets, layouts로 구성된다.
<
xml version="1.0" ?> // xml 버전
<
GUIScheme Name="
WindowsLookSkin"> //
GUIScheme 이름
<Imageset Name="
WindowsLook" Filename="
WindowsLook.imageset" /> // 연동될 Image Set
<
LookNFeel Filename="
WindowsLook.looknfeel" /> // 연동될
LookNFeel
<
WindowSet Filename="
CEGUIFalagardWRBase" /> // 연동될
WindowSet
<
FalagardMapping
WindowType="
WindowsLook/Button" // 윈도우 타입
TargetType="CEGUI
/PushButton" // 타겟 타입
Renderer="Falagard/Button" // 렌더러 타입
LookNFeel="
WindowsLook/Button" /> //
LookNFeel
Falagard 스킨을 구성하는 부분으로 기본적인 구조는 다음과 같다.
<
xml version="1.0" ?>
<Falagard>
<
WidgetLook name="
WindowsLook/Button">
<
PropertyDefinition name="
NormalTextColour" initialValue="
FF000000" redrawOnWrite="true" /> // 속성을 정의
</
WidgetLook>
</ Falagard>
이미지셋은 이미지/텍스처 상의 정의된 영역의 집합으로
CEImagesetEditor를 통해서 작성할 수 있다.
<
xml version="1.0" ?>
<Imageset Name="
WindowsLook" Imagefile="
WindowsLook.tga"
NativeHorzRes="800"
NativeVertRes="600"
AutoScaled="true">
<Image Name="Background"
XPos="9"
YPos="9" Width="2" Height="2" />
...
</Imageset>
정의된 영영들은 시스템 내부에서 단일한 이름의 Image로 사용한다.
CELayoutEditor를 사용해서 레이아웃을 작성할 수 있다.
<
xml version="1.0" ?>
<
GUILayout>
<Window Type="Vanilla/Button" Name="Vanilla/Console/Submit">
<Property Name="ID" Value="1" />
</Window>
...
<
/GUILayout>
출처;
http://blog.naver.com/dekaf?Redirect=Log&logNo=40041234507
1.CEGUI 0.5.0부터는 몇 가지 등록을 통해서 한글을 출력한다.은 순서로 등록해 준다.
1-1.한글 폰트 등록
-.사용할 폰트를 datafiles\fonts에 넣어준다.
-.한글.font 파일을 작성
<
xml version="1.0" ?>
<Font Name="Han-12" Filename="
H2GTRE.TTF" Type="
FreeType" Size="10"
NativeHorzRes="800"
NativeVertRes="600"
AutoScaled="true"/>
-.한글 폰트로서 Filename="
H2GTRE.TTF"를 사용하며, 위치가 다를 경우 폴드 경로를 설정
1-2.프로그램에서 폰트 로딩
-.FontManager:
:getSingleton().createFont("한글.font");
1-3.출력할 한글을 UTF-8로 변환
1) 소스코드 자체를 UTF-8로 저장; Visual Studio에서 소스코드를 저장할 때, UTF-8로 저장하면 별 문제없이 한글이 출력
Visual Studio 6.0에서 저장형식을 설정할 수 없음
VS 2005에서는 고급옵션에서 UTF-8로 저장 가능(제대로 되지 않는다고 함)
VS 2003에서는 잘 된다고 함
2) 정적으로 출력할 문자들을 UTF-8로 인코드 해서 File로 저장시켜두고 거기서 읽어서 출력
VS 2005에서 UTF-8로 인코딩된 파일을 읽어서 찍으면 한글이 잘 나옴
3) MBC 문자열을 UTF-8로 만들어서 CEGUI 모듈로 보내기(변환은 MBC -> Unicode -> UTF-8 순서로)
참고 파일(in orge3d 스터디 카페)
strconv-dekaf.h
#include "strconv.h"
#define CONV_UTF8_MBCS(a) convUni2Mbcs(convUtf82Uni(a)).c_str()
#define CONV_MBCS_
UTF8(a) convUni2Utf8(convMbcs2Uni(a)).c_str()
사용시, (utf8*)CONV_MBCS_
UTF8(txt)로 사용
예) history->
SetText((utf8*)CONV_MBCS_
UTF8("한글출력"));
출처;
http://www.gpgstudy.com/forum/viewtopic.php?topic=15388
WM_IME_COMPOSITION 메세지 처리시에는 return값으로 true를 줘서 ime입력 메세지가 더이상 다른 곳으로 전달되지 않게 막는다.
#pragma comment(lib, "imm32.lib")
#include <imm.h>
void processImeInput(LPARAM lParam, CEGUI:
:System *pC
EGUISystem)
{
// 활성화된 CEGUI윈도우가 Editbox타입이 아니라면 IME 입력처리 안합
Window* myRoot = CEGUI:
:System::getSingleton().getG
UISheet();
CEGUI:
:Editbox *pEditWindow =(CEGUI:
:Editbox*)myRoot->getActiveChild();
if(pEditWindow == NULL)
return;
// IME 핸들얻기. 실패하면 IME 입력처리 안함
HIMC hImc =
ImmGetContext(
GetWindowReference());
if(hImc == NULL)
return;
// 변수 설정
int nLength = 0;
wchar_t wszComp[4] = {0,};
// IME 문자 조합이 완료되었다면
if(lParam == GCS_RESULTSTR)
{
nLength =
ImmGetCompositionStringW(hImc, GCS_RESULTSTR, NULL, 0);
if(nLength > 0)
{
ImmGetCompositionStringW(hImc, GCS_RESULTSTR, wszComp, nLength);
for(int i = 0; i < nLength; i++)
{
if(wszComp[i] != 0)
pC
EGUISystem->injectChar(wszComp[i]);
}
// 문자 조합이 완료되었으면 조합중인 문자 선택해제
size_t caretIndex = pEditWindow->getCaratIndex();
pEditWindow->setSelection(caretIndex, caretIndex);
}
}
// IME 문자 조합중이라면
else
{
nLength =
ImmGetCompositionStringW(hImc, GCS_COMPSTR, NULL, 0);
if(nLength > 0)
{
ImmGetCompositionStringW(hImc, GCS_COMPSTR, wszComp, nLength);
for(int i = 0; i < nLength; i++)
{
if(wszComp[i] != 0)
{
pC
EGUISystem->injectChar(wszComp[i]);
}
}
// 에디트 입력창을 위해 조합중인 문자가 선택되도록 함
size_t caretIndex = pEditWindow->getCaratIndex();
pEditWindow->setSelection(caretIndex - 1, caretIndex);
}
}
// IME 핸들 해제
ImmReleaseContext(
GetWindowReference(), hImc);
}
문제점; 스페이스바를 눌러줘서 조합을 끝내면 그제서야 보이는 문제가 있음
다음은 WM_CHAR 메시에서 처리하는 방법으로 입력된 글자가 넘어왔을 때 2바이트 문자인지 1바이트문자인지 체크해서
1바이트 문자라면 입력 받는 즉시 넘기고, 2바이트 문자라면 누적시키고 2바이트 누적이 다되면 UTF-8로 컨버트 해서 넘긴다.
#include < ctype.h >
inline int __cdecl isLeadByte(int _C) {return ((unsigned char)(_C) & 0x80); }
switch(pEventRecord->uiMsg)
{
case WM_CHAR:
{
static char
MultiByte[2] = {0};
static bool isHaveMultiByte = false;
if(isHaveMultiByte)
{
isHaveMultiByte = false;
MultiByte[1] = (unsigned char)pEventRecord->wParam;
int iLengthUnicode = 0;
wchar_t szUnicode;
MultiByteToWideChar(CP_ACP, 0, (char*)
MultiByte, 2, &szUnicode, 1);
CEGUI:
:System::getSingleton().injectChar((CEGUI:
:utf32)szUnicode);
break;
}
else
{
if( isLeadByte(pEventRecord->wParam) )
{
isHaveMultiByte = true;
MultiByte[0] = (unsigned char)pEventRecord->wParam;
return true;
}
else
{
CEGUI:
:System::getSingleton().injectChar((CEGUI:
:utf32)pEventRecord->wParam);
break;
}
}
}
break;
}
3 공개 GUI 라이브러리 링크 모음 #
GPG에 pacman님이 2004.04.13 정리해 주신 내용 (
http://www.gpgstudy.com/forum/viewtopic.php?topic=5016 )
이름 | 링크 | 내용 |
FLTK | http://www.fltk.org/index.php | 멀티 플랫폼/ UI 툴 제공, 포럼/ Article, FAQ, Developer Document |
GTK+ | http://www.gtk.org/ | 멀티 플랫폼/ 수많은 GNU 응용 프로그램에 사용됨/ 메일링 리스트/ FAQ, Tutorial, API Reference |
wxWidgets | http://www.wxwidgets.org/ | 멀티 플랫폼/ 메일링 리스트, 게시판, 위키 등/ FAQ, Book, Reference, Presentations, Tutorials, Courses, Sample Code |
NGL | http://home.gna.org/ngl/about.html | 멀티 플랫폼/ OpenGL 응용 프로그램을 위한 C++ GUI 프레임웍/ UI 툴(RADtool) 제공/ XML, 테마 기능 제공/ 포럼 미흡/ Reference Manual, FAQ |
XML User Interface Language (XUL) | http://www.mozilla.org/projects/xul/ | 멀티 플랫폼/ Mozilla Project에 사용/ XUL Planet (www.xulplanet.com - Tutorial, Developer Guide, References, Forum)/ Specification, Tutorial, Reference Manual |
Crazy Eddie's GUI System | http://www.cegui.org.uk/modules/news/ | 티 플랫폼/ 툴 제공/ 포럼, 메일링 리스트, 위키/ API Reference, Tutorials, FAQ |
Para GUI | http://www.bms-aust...ts/paragui/index.php | 멀티 플랫폼/ SDL (Simple DirectMedia Layer) 기반/ 포럼, 메일링 리스트/ FAQ, API Reference, Source Code Documentation |
gameswf | http://www.tulrich....ekstuff/gameswf.html | 플래쉬 swf파일을 게임 상에서 보여주는 GUI 라이브러리/ 메일링 리스트/ 문서화(FAQ) 미흡 |
3DControls | http://3dcontrols.free.fr/ | 3차원 공간상에서 입체적인 인터페이스를 보여줌/ 데모 프로그램 내장/ 포럼(불어, 영어) |