- Notepad2-mod 한글 IME 패치
- 컴퓨터야그/notepad2
- 2012. 1. 15. 22:00
2010/03/04 - [컴퓨터야그/notepad2] - notepad2 컴파일 삽질기 8 : 한글 IME 패치
Notepad2-mod에서 한글을 정상적으로 입력하려면 (아는 분들은 다 아시다시피) IME 처리부분을 수정해야 한다.
그런데, 기존에 공개한 패치는 최신 버전의 WDK에서는 정상적으로 컴파일되지 않는다.
사실 크게 수정된 것은 아니지만, 다소 포스팅을 정리할 필요가 있어 다시 포스팅한다.
코드 자체는 크게 바뀐 게 없고, 명확성을 기하기 위한 타입캐스팅이 추가되었다.
수정 대상은 scintilla\win32\ScintillaWin.cxx 하나다.
1. 수정#1: WndProc()
우선 sptr_t ScintillaWin::WndProc()를 찾는다.
이 함수는 하나의 switch-case로 되어있는데, 여기서 case WM_IME_STARTCOMPOSITION:를 찾는다.
이 부분을 아래와 같이 수정한다. 지난 패치와 완전히 동일하다.
이 함수는 하나의 switch-case로 되어있는데, 여기서 case WM_IME_STARTCOMPOSITION:를 찾는다.
이 부분을 아래와 같이 수정한다. 지난 패치와 완전히 동일하다.
case WM_IME_STARTCOMPOSITION: // dbcs
ImeStartComposition();
// added from here-------------------------------------------------
if (LOWORD(GetKeyboardLayout(0))==MAKELANGID(LANG_KOREAN, SUBLANG_KOREAN)) {
// if the current IME is the Korean IME, do not show the default IME window
return 0;
}
// added to here-------------------------------------------------
return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam);
2. 수정#2: sptr_t ScintillaWin::HandleComposition()
다음으로, sptr_t ScintillaWin::HandleComposition()를 찾아 아래 내용으로 대체한다.
지난 패치에 비해 아주 깨알같이 달라졌다.
지난 패치에 비해 아주 깨알같이 달라졌다.
sptr_t ScintillaWin::HandleComposition(uptr_t wParam, sptr_t lParam) {
#ifdef __DMC__
// Digital Mars compiler does not include Imm library
return 0;
#else
static int cs = -1;
static int undo = -1;
static bool comp = false;
static bool bEndOfLine, bOverstrike;
static bool wasSelection = false;
bool bKoreanIME = LOWORD(GetKeyboardLayout(0))==MAKELANGID(LANG_KOREAN, SUBLANG_KOREAN);
if (bKoreanIME && (lParam & GCS_COMPSTR)) {
HIMC hIMC = ::ImmGetContext(MainHWND());
if (hIMC) {
const int maxLenInputIME = 200;
wchar_t wcs[maxLenInputIME];
LONG bytes = ::ImmGetCompositionStringW(hIMC, GCS_COMPSTR, wcs, (maxLenInputIME-1)*2);
int wides = bytes / 2;
int lastitem = (int)(sel.Count()-1);
int selBegin = (int)(sel.Range(lastitem).End().Position());
int selEnd = selBegin;
if (bytes) {
//comp==false 이면 최초 진입
//undo를 마비시키기 전에 삭제할 글자/블럭 삭제
if (!comp)
{
FilterSelections();
{
UndoGroup ug(pdoc, (sel.Count() > 1) || !sel.Empty() || inOverstrike);
for (size_t r=0; r<sel.Count(); r++) {
if (!RangeContainsProtected(sel.Range(r).Start().Position(),
sel.Range(r).End().Position())) {
selBegin = sel.Range(r).Start().Position();
if (!sel.Range(r).Empty()) {
if (sel.Range(r).Length()) {
pdoc->DeleteChars(selBegin, sel.Range(r).Length());
sel.Range(r).ClearVirtualSpace();
} else {
// Range is all virtual so collapse to start of virtual space
sel.Range(r).MinimizeVirtualSpace();
}
} else if (inOverstrike) {
if (selBegin < pdoc->Length()) {
if (!IsEOLChar(pdoc->CharAt(selBegin))) {
pdoc->DelChar(selBegin);
sel.Range(r).ClearVirtualSpace();
}
}
}
selBegin = InsertSpace(selBegin, sel.Range(r).caret.VirtualSpace());
sel.Range(r).ClearVirtualSpace();
// If in wrap mode rewrap current line so EnsureCaretVisible has accurate information
if (wrapState != eWrapNone) {
AutoSurface surface(this);
if (surface) {
WrapOneLine(surface, pdoc->LineFromPosition(selBegin));
}
}
}
}
}
bOverstrike = inOverstrike;
}
if (cs < 0 && !bOverstrike) {
cs = vs.caretStyle;
vs.caretStyle = CARETSTYLE_BLOCK;
}
if (undo < 0) {
undo = pdoc->IsCollectingUndo()?1:0;
pdoc->SetUndoCollection(false);
}
if (!comp) {
comp = true;
} else {
DelChar();
}
} else {
//조합 중 조합중인 글자를 다 지운 경우
if (cs >= 0) {
vs.caretStyle = cs;
cs = -1;
}
if (comp) {
comp = false;
DelChar();
}
if (undo >= 0) {
pdoc->SetUndoCollection(undo==1);
undo = -1;
}
}
MovePositionTo(selBegin);
inOverstrike = false;
if (IsUnicodeMode()) {
char utfval[maxLenInputIME * 3];
unsigned int len = UTF8Length(wcs, wides);
UTF8FromUTF16(wcs, wides, utfval, len);
utfval[len] = '\0';
AddCharUTF(utfval, len);
} else {
char dbcsval[maxLenInputIME * 2];
int size = ::WideCharToMultiByte(InputCodePage(),
0, wcs, wides, dbcsval, sizeof(dbcsval) - 1, 0, 0);
for (int i=0; i<size; i++) {
AddChar(dbcsval[i]);
}
}
inOverstrike = bOverstrike;
MovePositionTo(selBegin);
}
}
if (lParam & GCS_RESULTSTR) {
//앞의 if문 6개는 모두 한글 입력기에서만 동작
//다른 언어 IME에서는 패스
if (comp) {
comp = false;
DelChar();
}
if (cs >= 0) {
vs.caretStyle = cs;
cs = -1;
}
if (undo >= 0){
pdoc->SetUndoCollection(undo==1);
undo = -1;
}
//덮어쓰기에서 한글 조합 중 마지막에 숫자나 기호를 붙인 경우 한 글자 더 삭제(가9)
bool bKoreanPlusOneMore = false;
if (bKoreanIME && bOverstrike)
{
HIMC hIMC = ::ImmGetContext(MainHWND());
if (hIMC) {
const int maxLenInputIME = 200;
wchar_t wcs[maxLenInputIME];
LONG bytes = ::ImmGetCompositionStringW(hIMC,
GCS_RESULTSTR, wcs, (maxLenInputIME-1)*2);
int wides = bytes / 2;
char dbcsval[maxLenInputIME * 2];
int size = ::WideCharToMultiByte(InputCodePage(),
0, wcs, wides, dbcsval, sizeof(dbcsval) - 1, 0, 0);
bKoreanPlusOneMore = (size==3);
::ImmReleaseContext(MainHWND(), hIMC);
}
}
if (bKoreanPlusOneMore) DelChar();
if (bKoreanIME) inOverstrike = false;
HIMC hIMC = ::ImmGetContext(MainHWND());
if (hIMC) {
const int maxLenInputIME = 200;
wchar_t wcs[maxLenInputIME];
LONG bytes = ::ImmGetCompositionStringW(hIMC,
GCS_RESULTSTR, wcs, (maxLenInputIME-1)*2);
int wides = bytes / 2;
if (IsUnicodeMode()) {
char utfval[maxLenInputIME * 3];
unsigned int len = UTF8Length(wcs, wides);
UTF8FromUTF16(wcs, wides, utfval, len);
utfval[len] = '\0';
AddCharUTF(utfval, len);
} else {
char dbcsval[maxLenInputIME * 2];
int size = ::WideCharToMultiByte(InputCodePage(),
0, wcs, wides, dbcsval, sizeof(dbcsval) - 1, 0, 0);
for (int i=0; i<size; i++)
AddChar(dbcsval[i]);
}
// Set new position after converted
Point pos = LocationFromPosition(sel.Range(0).End().Position());
COMPOSITIONFORM CompForm;
CompForm.dwStyle = CFS_POINT;
CompForm.ptCurrentPos.x = pos.x;
CompForm.ptCurrentPos.y = pos.y;
::ImmSetCompositionWindow(hIMC, &CompForm);
::ImmReleaseContext(MainHWND(), hIMC);
}
if (bKoreanIME) inOverstrike = bOverstrike;
return 0;
}
return ::DefWindowProc(MainHWND(), WM_IME_COMPOSITION, wParam, lParam);
#endif
}
이렇게 수정하면 아래와 같이 정상적으로 한글을 입력할 수 있다.
'컴퓨터야그 > notepad2' 카테고리의 다른 글
Notepad2-mod r698 한글화 버전 공개 (2) | 2012.01.15 |
---|---|
Notepad2-mod 패치 모음 (0) | 2012.01.15 |
Notepad2 한글화는 Notepad2-mod를 기준으로 진행 (4) | 2012.01.10 |
Notepad2 4.2.25zk 정식버전 공개 (수정) (38) | 2011.06.08 |
Notepad2 4.2.25 정식버전 패치 컬렉션 (4) | 2011.05.09 |
Recent comment