How can I set a column label in listview using unicode strings (non-english to be precise)?
Following code fails. Although MessageBoxW displays the string correctly.


class_list dw L(<SysListView32>\0)

unic db 18h, 04h, 3Ch ,04h, 4Fh, 04h, 0,0 ; cyrillic


        invoke  CreateWindowExW, WS_EX_RIGHTSCROLLBAR, ADDR class_list, 0, WS_BORDER or LVS_REPORT or LVS_SHOWSELALWAYS or WS_CHILD or WS_VISIBLE, 3, 57, 785, 482, , 0, , 0
        mov , eax

        mov    lvc.fmt,LVCFMT_LEFT
        mov    lvc.imask,LVCF_WIDTH
        mov    lvc.lx,20
        mov    lvc.iSubItem,0
        invoke SendMessageW, , LVM_INSERTCOLUMN, 0, ADDR lvc
        mov    lvc.imask, LVCF_TEXT or LVCF_WIDTH

        invoke MessageBoxW,0,ADDR unic,0,0

        mov    lvc.pszText, offset unic
        mov    lvc.lx,342
        inc    lvc.iSubItem
        invoke SendMessageW, , LVM_INSERTCOLUMN, 1, ADDR lvc
Posted on 2006-07-14 21:31:30 by arafel
Ah, never mind. The problem has been solved. LVM_INSERTCOLUMNW...
Posted on 2006-07-14 23:31:37 by arafel
Arghh... curse whoever did the unicode support in windows.  :mad:
Now I am unable to set window title using unicode string:


app_class dw L(<test_class>\0)
apptitle  dw L(<test>\0)

        mov    wndcls.cbSize, sizeof WNDCLASSEX
        mov    wndcls.lpfnWndProc, offset WndProc
        mov    wndcls.cbClsExtra, 0
        mov    wndcls.cbWndExtra, 0
        mov    eax,
        mov    wndcls.hInstance, eax
        mov    wndcls.hbrBackground, COLOR_BTNFACE+1
        mov    wndcls.lpszMenuName, 0
        mov    wndcls.lpszClassName, offset app_class
        mov    eax,
        mov    wndcls.hIcon, eax
        invoke  LoadCursor, 0, IDC_ARROW
        mov    wndcls.hCursor, eax
        mov    eax,
        mov    wndcls.hIconSm, eax

        invoke  RegisterClassExW, ADDR wndcls
        test    eax, eax
        je      exit
        invoke  CreateWindowExW, 0, ADDR app_class, ADDR apptitle, WS_SIZEBOX or WS_CAPTION or \
WS_SYSMENU or WS_MINIMIZEBOX or WS_MAXIMIZEBOX or WS_CLIPCHILDREN, 10, 10, 500, 300, 0, 0, , 0       

any ideas?
Posted on 2006-07-15 15:21:27 by arafel
CreateWindowExW and/or SetWindowtextW is enough to set any given window's text to a unicode string. Therefore I don't see anything wrong in your code, assuming that "L(<test>\0)" properly creates a unicode string (double-null-terminated). You don't even have to use RegisterClassW (you need it only when you want your class to be named using a unicode string, but it's faster to use class-atoms, anyways).
Posted on 2006-07-16 11:06:15 by ti_mo_n

You don't even have to use RegisterClassW (you need it only when you want your class to be named using a unicode string, but it's faster to use class-atoms, anyways).

I am not one hundred percent sure, but I think you are mistaken. If RegisterClassEx is used, then all window messages are passed as ANSI strings and messages such as WM_SETTEXT unable to pass unicode strings (WM_SETTEXT works fine in other parts of the code by the way, it's just this window title I am failing to set).

IsWindowUnicode returns non zero value for the window and L MACRO creates UTF-16LE strings correctly (taken from masm32\com\include).

Also at first I thought that the problem might be in using non unicode versions of GetMessage, DispatchMessage, etc. But it seems to not make any difference.

It's beyond me why the unicode string in title is failing.
Posted on 2006-07-16 12:00:14 by arafel
Hi arafel

You dont need to use RegisterClassExW or CreateWindowExW (unless class and caption is unicode).
What is really important is DefWindowProcW.

Posted on 2006-07-16 16:47:00 by KetilO
Ok, DefWindowProcW has fixed the problem.

ti_mo_n you were right after all, I just tested WM_SETTEXT (among other) with unicode strings and it worked just as fine with window belonging to a class registered with ansi version of RegisterClassEx. Sorry..

Thanks for the help guys.
Posted on 2006-07-16 17:11:14 by arafel
Those API functions which use strings have their "W" versions, so you can pass/get a unicode string as an argument/return value. You can register a class using an ANSI string (you call RegisterClassA, then), create an instance of this class using a unicode name (you call CreateWindowExW, then), and then you can send both the ANSI and unicode text to it (using 'A' and 'W' functions' versions, respectively). The only reason there are 2 versions of those functions is that so they can tell what string you give to it or what string you expect to get. There could be as well only 1 version of each, but then every one of them would need an additional parameter telling whether you give/expect an ANSI or unicode string. Or there could be a global variable "unicode application" and an API for it "SetStringMode". But that would be very discomfortable.
Posted on 2006-07-16 21:06:27 by ti_mo_n
Yes, yes, I figured that out.

This is what got me confused initially:

If you register the window class by using RegisterClassExA, the application tells the system that the windows of the created class expect messages with text or character parameters to use the ANSI character set; if you register it by using RegisterClassExW, the application requests that the system pass text parameters of messages as Unicode.

I thought it implied that all messages for a window and child windows of a given class will expect unicode strings and fail otherwise. Basically that unicode version of RegisterClassEx determined whenever the application can use unicode or not. Apparently this is not the case.
Posted on 2006-07-16 22:16:11 by arafel