Я скомпилировал следующий полный код C как WinMain.c
на 64-разрядной платформе Windows 7 с TDM GCC 5.1.0 (64-разрядная версия).
#include <windows.h>
#include <commctrl.h>
#define szAppWndClassName L"MyApp"
HINSTANCE g_hInstance;
HWND createTabCtrlW (HWND hwndParent, LPRECT lprectPlace, PWCHAR* pszLabels)
{
TCITEMW ti = {0};
HWND tab_ctrl = CreateWindowW(WC_TABCONTROLW, L"", WS_CHILD | WS_VISIBLE,
lprectPlace->left,
lprectPlace->top,
(lprectPlace->right) - (lprectPlace->left),
(lprectPlace->bottom) - (lprectPlace->top),
hwndParent, NULL, g_hInstance, NULL);
if (tab_ctrl != NULL)
{
ti.mask = TCIF_TEXT;
ti.iImage = -1;
/* Test code begin*/
ti.pszText = L"Mon";
SendMessageW(tab_ctrl, TCM_SETUNICODEFORMAT, TRUE, 0); /* This seems can
get the tab ctrl
to support Unicode,
but in fact it won't do */
SendMessageW(tab_ctrl, TCM_INSERTITEM, 1, (LPARAM)&ti); /* Insert tabs */
/* Test code end */
}
return tab_ctrl;
}
static void createControls(HWND hwndParent)
{
PWCHAR labels[]={L"Mon", L"Tue", L"Wed", NULL};
RECT position, client_area;
GetClientRect(hwndParent, &client_area);
position.left = client_area.left;
position.top = client_area.top;
position.right = client_area.right;
position.bottom = position.top + 200;
INITCOMMONCONTROLSEX icc={sizeof(INITCOMMONCONTROLSEX), ICC_TAB_CLASSES};
InitCommonControlsEx(&icc);
HWND hTab=createTabCtrlW(hwndParent, &position, labels);
}
LRESULT CALLBACK MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CREATE:
createControls(hWnd);
return 0;
case WM_DESTROY:
PostQuitMessage (0);
return 0;
}
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpszCmdln, int nShowState)
{
WNDCLASSW wc;
HWND hMainFrame;
MSG msg;
WINBOOL msgResult;
g_hInstance = hInst;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst;
wc.hIcon = LoadIconW(NULL, (LPCWSTR)IDI_APPLICATION);
wc.hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW);
wc.hbrBackground = CreateSolidBrush(GetSysColor(COLOR_MENU));
wc.lpszMenuName = NULL;
wc.lpszClassName = szAppWndClassName;
if (!RegisterClassW(& wc))
{
MessageBoxW(NULL, L"WinMain: RegisterClass() failed", L"Error", MB_OK);
return 1;
}
hMainFrame = CreateWindowW (szAppWndClassName,
L"Window Title",
WS_OVERLAPPEDWINDOW,
544,375,800,600,
NULL, NULL, hInst,
NULL) ;
if (NULL == hMainFrame)
{
MessageBoxW(NULL, L"WinMain: CreateWindow() returns NULL", L"Error", MB_OK);
return 1;
}
ShowWindow(hMainFrame, nShowState);
while (TRUE)
{
msgResult = GetMessageW(&msg, NULL, 0, 0);
if (0 == msgResult)
{
break;
}
else if (-1 == msgResult)
{
MessageBoxW(NULL, L"WinMain: GetMessage() error", L"Error", MB_OK);
return 1;
}
else
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
}
return msg.wParam;
}
Компиляция командной строки:
gcc -mwindows -o WinMain WinMain.c -lcomctl32
В разделе тестового кода предполагается создать вкладку с меткой «Mon», но на самом деле метка отображает только одну букву «M».
Внешний вид окна
Некоторые попытки отладки показывают, что проблема возникает из-за нулевого байта, следующего за каждой буквой в представлении Unicode (например, L"Mon" -> 0x4D 0x00 0x6F 0x00 0x6E 0x00
). Нулевой байт был обработан как терминатор строки ANSI где-то внутри Windows, так что результат.
Но это не то поведение, которое предполагается приложением Юникода.
Даже если «Установка элемента управления вкладкой в Юникод» с помощью SendMessageW(tab_ctrl, TCM_SETUNICODEFORMAT, TRUE, 0)
не помогла.
Как правильно получить Unicode с поддержкой Tab Control, не могу ли я использовать что-то вроде WideCharToMultiByte
?