4

I have a problem with unicode filenames appearing as question marks in my edit boxes.

When I paste unicode characters in an edit box, for example Arabic or Thai, they show correctly, but after I run this code, they become question marks. How come?

WCHAR buf[100];
GetWindowTextW(hWndEditBox, buf, 100);
SetWindowTextW(hWndEditBox, buf);

Another thing - the project is ANSI (we have code that can't be ported so the entire project stays ANSI), i.e. _UNICODE macro is undefined, but I explicitly use the Unicode versions of the filenames.

sashoalm
  • 75,001
  • 122
  • 434
  • 781

2 Answers2

2

The GetWindowText function actually sends a WM_GETTEXT message to the window (hWndEditBox). Since you're using the *A functions rather than the *W function (specifically CreateWindowExA in this case, I think) your message loop will be converting from wide characters to multi-byte characters using some locale.

Your only solution here seems to be changing the entire window setup - if your code that requires ANSI is not related to UI this should be possible. Alternatively, you may be able to replace the edit box with rich edit boxes, that provide extra messages (such as streaming, for example).

You may want to check whether it is the GetWindowTextW call or the SetWindowTextW call that is doing the bad conversion - if GetWindowTextW works correctly you may be able to convert to multibyte using the correct locale before you set it.

Finally, you can try adjusting the thread's code page before reading the text, though this may cause all sorts of other issues. The usual advice is to use Unicode.

Sources: GetWindowText and this comment from Raymond Chen on his blog.

Zooba
  • 11,221
  • 3
  • 37
  • 40
  • In addition, you should use `IsWindowUnicode()` to decide whether to call *A or *W functions on any particular HWND. – Remy Lebeau Feb 14 '11 at 22:46
  • @Remy Lebeau - TeamB Only if it becomes an issue, as it did here. The whole point of the window manager handling the marshalling for you is so there's no need to test in advance - as long as you're using the *W functions you won't get invalid results. – Zooba Feb 14 '11 at 23:17
  • In fact, for long enough now that it doesn't matter, Windows does everything internally with wide-characters. So if you ever use the *A functions, you're paying the price of allocation/deallocation/`MultiByteToWideChar` calls. 16-bit wide characters are native to Windows, so they should always be your default position (unless portability is more important than performance and, as we've seen, correctness). – Zooba Feb 14 '11 at 23:20
0

A useful answer to address SetWindowTextW()is given in https://stackoverflow.com/a/11515400/1190077 : intercept the resulting WM_SETTEXT message and re-route it to DefWindowProcW() instead of DefWindowProc().

Community
  • 1
  • 1
Hugues
  • 2,865
  • 1
  • 27
  • 39