본문 바로가기

Dev/[MFC]

[MFC] 멀티바이트 환경에서 유니코드 문자 set하기

반응형

안녕하세요.

 

멀티바이트 환경으로 만들어진 MFC 프로젝트에서 유니코드 문자열을 사용하는 방법입니다.

 

멀티바이트와 유니코드를 번갈아 사용하는 가장 좋은 방법은

애초에 프로젝트를 설계할 때 아래와 같이 #define UNICODE 를 선언하고 안하고에 따라 

진입점을 다르게하고, 개발 과정에서도 이를 고려하여 작성하면 됩니다.

 

typedef wchar_t WCHAR;
typedef char CHAR;

#ifdef UNICODE
typedef WCHAR TCHAR;
#else
typedef char TCHAR;
#endif



그러나 이미 멀티바이트로 제작된지 오래 된 프로젝트에 위 방식을 적용하기란

쉽지 않은 작업입니다.

 

아래 방법은 약간 편법입니다만,

API기반의 라이브러리인 MFC 에서 SetwindowText 라는 API를 조작하는 방법입니다.

 

우선 Setwindowtext 는 컨트롤의 Text를 Set 하는 함수입니다.

docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowtexta

 

SetWindowTextA function (winuser.h) - Win32 apps

Changes the text of the specified window's title bar (if it has one). If the specified window is a control, the text of the control is changed. However, SetWindowText cannot change the text of a control in another application.

docs.microsoft.com

docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowtextw

 

SetWindowTextW function (winuser.h) - Win32 apps

Changes the text of the specified window's title bar (if it has one). If the specified window is a control, the text of the control is changed. However, SetWindowText cannot change the text of a control in another application.

docs.microsoft.com

여기서 우리는 SetWindowTextW 와 SetWindowTextA 를 볼 수 있습니다.

이 구조가 정의된 곳을 가보면,

 

WINAPI
SetWindowTextA(
    _In_ HWND hWnd,
    _In_opt_ LPCSTR lpString);
WINUSERAPI
BOOL
WINAPI
SetWindowTextW(
    _In_ HWND hWnd,
    _In_opt_ LPCWSTR lpString);
#ifdef UNICODE
#define SetWindowText  SetWindowTextW
#else
#define SetWindowText  SetWindowTextA
#endif // !UNICODE

이런식으로 되어있습니다.

따라서 UNICODE라는 놈이 선언되어있지 않다면, SetWindowTextA를 사용하고,

선언되어있다면 SetWindowTextW 를 사용하는 것입니다.

 

우리는 지금 멀티바이트 환경이므로 SetWindowTextA를 사용할것이고,

_T(L"✈✌❦♫") 와 같은 문자를 출력할 수 없습니다.

 

이를 사용할 때, 3가지를 먼저 이해하면 좋습니다.

(급하시면 걍 복붙하시고..)

 

1. 우선 멀티바이트(ANSI)와 유니코드가 무엇인지 부터 이해하면 좋겠습니다.

 

2. MFC라는 놈이 WIN API기반이고, SetWindowText와 같은 함수들이 WIN API에서 어떻게 구현되는지도

이해하면 좋겠습니다.

 

3. MFC의 서브클래싱에 대해 이해하면 좋겠습니다.

 

// 컨트롤의 핸들을 얻어온다.
HWND h = ::GetDlgItem(GetSafeHwnd(), IDC_BUTTON_RESTART);

// 기존 윈도우 프로시저를 저장해놓음
LONG_PTR originalWndProc = GetWindowLongPtrW(h, GWLP_WNDPROC);

// 기존 윈도우에 전달되는 메시지는 이제 서브클래싱한 윈도우로 전달됨
SetWindowLongPtrW(h, GWLP_WNDPROC, (LONG_PTR)DefWindowProcW);

// 컨트롤에 Text Set
SetWindowTextW(h, L"✈✌❦♫");

// 다시 원래의 윈도우 프로시저로 복원
SetWindowLongPtrW(h, GWLP_WNDPROC, originalWndProc);

이상입니다.

 

 

출처는 StackOverflow:

stackoverflow.com/questions/9410681/setwindowtextw-in-an-ansi-project

반응형