none
WM_UNICHAR

Answers

  • Thanks. If you used the "Send comments about this topic to Microsoft" link then that is the best way to report doc issues. The connect site Mike mentioned is for Visual Studio, not for the SDK docs (it would probably get forwarded, but that's not automatic). I've also filed this internally just to make sure.

    To summarize: this is a documentation error. WM_UNICHAR is not generated by Windows. As you inferred, it was intended for use by 3rd party applications. The paragraph about it being posted by TranslateMessage has never been true in any version of Windows.

    --Rob

    Friday, April 13, 2012 6:59 PM

All replies

  • The docs for WM_UNICHAR state that it is "Posted to the window with the keyboard focus when aWM_KEYDOWN <http://msdn.microsoft.com/en-us/library/windows/desktop/ms646280(v=vs.85).aspx> message is translated by the TranslateMessage <http://msdn.microsoft.com/en-us/library/windows/desktop/ms644955(v=vs.85).aspx> function":

    http://msdn.microsoft.com/en-us/library/windows/desktop/ms646288(v=vs.85).aspx

    Is that actually true in any current version of Windows?

    Does it depend on whether the application is ANSI perhaps?

    Dave

    Wednesday, April 11, 2012 1:11 PM
  • Does it depend on whether the application is ANSI perhaps?

    WM_UNICHAR is specifically intended for ANSI applications, so that's how I'm testing it: "It is designed to send or post Unicode characters to ANSI windows":

    http://msdn.microsoft.com/en-us/library/windows/desktop/ms646288(v=vs.85).aspx

    However as far as I'm aware it is never generated by Windows, irrespective of whether the application is ANSI or Unicode.  I've found comments to this effect going back to 2003, but I'm puzzled that the docs still appear to be incorrect.

    Wednesday, April 11, 2012 1:41 PM
  • Does it depend on whether the application is ANSI perhaps?

    WM_UNICHAR is specifically intended for ANSI applications, so that's how I'm testing it: "It is designed to send or post Unicode characters to ANSI windows":

    OK.

    Have you seen this:
    http://blog.tavultesoft.com/2011/06/accepting-unicode-input-in-your-windows-application.html

    that notes:

    "The WM_UNICHAR message is first sent to a window, with UNICODE_NOCHAR
    (0xFFFF) in order to determine if the window supports it. If not
    handled, DefWindowProc will return 0 (on all versions of Windows),
    indicating that WM_UNICHAR is not supported. You must return 1 from
    your window procedure in order to receive input via WM_UNICHAR. After
    returning 1, subsequent characters will be posted in, by Keyman, via
    WM_UNICHAR instead of by WM_CHAR. Note that WM_UNICHAR uses UTF-32
    instead of UTF-16 which most Windows applications use."

    Dave

    Wednesday, April 11, 2012 1:58 PM
  • > "The WM_UNICHAR message is first sent to a window, with UNICODE_NOCHAR
    > (0xFFFF) in order to determine if the window supports it.

    Indeed, and that is what my code does.  I've tested it with Keyman (it's their site you quoted from) and it works perfectly, so my code for receiving WM_UNICHAR appears to be fine.

    Richard.

    Wednesday, April 11, 2012 2:18 PM
  • "The WM_UNICHAR message is first sent to a window, with UNICODE_NOCHAR
    (0xFFFF) in order to determine if the window supports it.

    Indeed, and that is what my code does.  I've tested it with Keyman (it's their site you quoted from) and it works perfectly, so my code for receiving WM_UNICHAR appears to be fine.

    Richard,

    Having now tried something myself, I'd have to conclude the same as
    you - it doesn't appear to occur.

    Dave

    Wednesday, April 11, 2012 7:49 PM
  • Having now tried something myself, I'd have to conclude the same as
    you - it doesn't appear to occur.

    So, why are the docs still so misleading, when this has apparently been known for years?  Not even any 'Community Additions' for clarification (perhaps I should add something myself).

    Richard.

    Thursday, April 12, 2012 10:07 PM
  • >So, why are the docs still so misleading, when this has apparently been known for years?  Not even any 'Community Additions' for clarification (perhaps I should add something myself).

    Please do add something - and click the 'Did you find this helpful?'
    (no option) and provide feedback.

    Dave

    Thursday, April 12, 2012 11:43 PM
  • I think Joel's this reply will give us some helpful information about understanding this Message: http://stackoverflow.com/questions/378296/why-is-my-wm-unichar-handler-never-called

    The documentation is far from clear on when, exactly, a WM_UNICHAR message gets generated, but from what I can gather in very limited poking around on Google Groups and on the Internet it looks like it gets sent by 3rd party apps and not by Windows itself, unless the Window is an ANSI window (CreateWindowA and all that). Have you tried manually sending a WM_UNICHAR message to your window to see what happens? If you get the message then there's nothing wrong with your message dispatch code and there's just nothing happening that would cause WM_UNICHAR. You can also check with Spy++ and see whether you're getting that message, though I suspect it's just not being sent.

    And the post from James Brown: http://us.generation-nt.com/answer/wm-unichar-wm-char-help-25920442.html

    WM_CHAR is sent as ANSI to ANSI Windows, and as UTF-16 to Unicode Windows.
    WM_UNICHAR is not sent to a window as a normal part of character-input. It is usually encounted when a 3rd party app directs character input to another window, such as IMEs etc.

    I think you can use the MS Connect web site to submit your feedback about this document, and the same time I will also try to use some internal channel submit the WM_UNICHAR document feedback.

    Best wishes,


    Mike Zhang[MSFT]
    MSDN Community Support | Feedback to us

    Friday, April 13, 2012 10:00 AM
  • Please do add something - and click the 'Did you find this helpful?'
    (no option) and provide feedback.

    I've added a comment and provided feedback.  What I find interesting is that the docs describe an entirely sensible and consistent way that the message might work.  They say it is posted to the window with the keyboard focus when a WM_KEYDOWN message is translated by the TranslateMessage function, and that DefWindowProc then posts a WM_CHAR (appropriate to whether it's a Unicode or ANSI window).

    The detailed (but apparently entirely false) description makes me wonder whether this scheme actually was implemented at some point, but was later abandoned for some reason.

    Friday, April 13, 2012 11:25 AM
  • Thanks. If you used the "Send comments about this topic to Microsoft" link then that is the best way to report doc issues. The connect site Mike mentioned is for Visual Studio, not for the SDK docs (it would probably get forwarded, but that's not automatic). I've also filed this internally just to make sure.

    To summarize: this is a documentation error. WM_UNICHAR is not generated by Windows. As you inferred, it was intended for use by 3rd party applications. The paragraph about it being posted by TranslateMessage has never been true in any version of Windows.

    --Rob

    Friday, April 13, 2012 6:59 PM
  • To summarize: this is a documentation error. WM_UNICHAR is not generated by Windows. As you inferred, it was intended for use by 3rd party applications. The paragraph about it being posted by TranslateMessage has never been true in any version of Windows.

    Having confirmed that WM_UNICHAR is "not generated by Windows" can you say whether it is generated by Microsoft IMEs?  It would seem rather strange if not!

    I guess it ought to be possible for my (ANSI) application to add a custom 'TranslateMessage' in its message loop which emulates the currently-documented WM_UNICHAR behavior, but I don't know how tricky that would be.  The obvious API would seem to be ToUnicode but the docs warn about its use in conjunction with TranslateMessage.

    Richard.

    Saturday, April 14, 2012 9:27 AM
  • As far as I know, no Microsoft IMEs generate WM_UNICHAR.  WM_UNICHAR is a stopgap for legacy applications and while Keyman has generated it for years (it was initially introduced to the Windows API as the result of discussions between myself, Microsoft and some SIL language support people), it is not a great solution.

    Most of the newer Windows keyboards (e.g. Lao) are Unicode-only, and they will not work with ANSI applications.  As I write in my blog post at http://blog.tavultesoft.com/2011/06/accepting-unicode-input-in-your-windows-application.html, you should look at using Unicode windows for text fields at the very least, especially now that Windows 9x really is irrelevant.

    We have helped quite a number of application developers update their applications to support Unicode windows and would be happy to assist -- if you are interested you can get in touch via our website or @MarcDurdin on Twitter.

    Thursday, April 19, 2012 12:32 AM
  • you should look at using Unicode windows for text fields at the very least, especially now that Windows 9x really is irrelevant.

    You may consider Win9x to be "irrelevant" but my customers do not!  I know that many of them are still running it.  So my challenge is to improve support for foreign-language input and display whilst preserving binary compatibility with Win9x.  WM_UNICHAR is a good solution for me.

    I am aware of the blog post to which you linked.  I cannot adopt that approach directly because my (custom) edit window is still an ANSI window, despite using Unicode internally.

    Richard.

    Thursday, April 19, 2012 9:06 AM
  • You may consider Win9x to be "irrelevant" but my customers do not!  I know that many of them are still running it.  So my challenge is to improve support for foreign-language input and display whilst preserving binary compatibility with Win9x.  WM_UNICHAR is a good solution for me.

    Just FYI: to my knowledge the only (widely used) application that generates WM_UNICHAR for input is our tool, Keyman -- and we stopped supporting Windows 9x when we released version 7.1, about 4 years ago.  Version 6.0 and 7.0 of Keyman do work on Windows 9x (as long as you can find the necessary redistributables) -- but these versions are no longer available for sale.

    Friday, May 04, 2012 5:51 AM
  • Just FYI: to my knowledge the only (widely used) application that generates WM_UNICHAR for input is our tool, Keyman -- and we stopped supporting Windows 9x when we released version 7.1, about 4 years ago.

    I am happy with the workaround I have adopted, which is that in my main message loop I convert WM_CHAR messages into WM_UNICHAR messages.  That means my (ANSI) custom editor window can successfully receive Unicode input without sacrificing Win9x compatibility.  Here is the code I am using (calls to IsDialogMessage and TranslateAccelerator omitted for clarity):

    while (TRUE)
      {
        while (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE))
          {
            if ((msg.hwnd == hwndEdit) && (msg.message == WM_CHAR) &&
                PeekMessageW (&msg, NULL, 0, 0, PM_REMOVE))
              msg.message = WM_UNICHAR ;
            else
              PeekMessageA (&msg, NULL, 0, 0, PM_REMOVE) ;
            if (msg.message == WM_QUIT)
              break ;
            TranslateMessage (&msg) ;
            DispatchMessage (&msg) ;
          }
        if (msg.message == WM_QUIT)
          break ;
        WaitMessage () ;
      }
    Richard.
    Friday, May 04, 2012 8:26 AM
  • That looks fine (I'm guessing you are using MSLU to avoid dynamic link issues with PeekMessageW?), although I'd make two comments:

    1. WM_UNICHAR uses UTF-32, as opposed to the more usual UTF-16 that WM_CHAR uses.  So if you are passing that WM_UNICHAR to your own window, you do need to remember to handle both cases in your window procedure.  If you are passing WM_UNICHAR to a system window, then you'll need to do that UTF-16 to UTF-32 conversion in your message loop, which is kinda messy.
    2. If you have your own window procedure, you don't really need to use WM_UNICHAR at all; you could just as well use WM_USER[+xx], and then you don't have to worry about generating messages according to the WM_UNICHAR definition in the documentation.
    Sunday, May 06, 2012 10:04 PM
  •  I'm guessing you are using MSLU to avoid dynamic link issues with PeekMessageW?

    It's interesting that you should ask that.  I had indeed expected to need MSLU, but PeekMessageW is exported by the user32.dll shipped with Windows 95 OSR2 (dated 08-24-96 11:11a).  It may be a non-functional stub, but my application links and runs OK without unicows.dll being present.

    > WM_UNICHAR uses UTF-32

    Yes, but in any case my application supports only the Basic Multilingual Plane so I ignore the 32-bit issues.

    > you don't really need to use WM_UNICHAR at all; you could just as well use WM_USER[+xx]

    I was hoping (although this is untested) that by using WM_UNICHAR I would be able to receive Unicode input from a suitable version of Keyman under Win9x.  If I use WM_USER+nn I can't receive any kind of Unicode keyboard input under Win9x, without MSLU.

    Richard.

    Monday, May 07, 2012 9:34 AM
  • I was hoping (although this is untested) that by using WM_UNICHAR I would be able to receive Unicode input from a suitable version of Keyman under Win9x.  If I use WM_USER+nn I can't receive any kind of Unicode keyboard input under Win9x, without MSLU.
    If you return TRUE when you are sent WM_UNICHAR with wParam=UNICODE_NOCHAR, as per the message spec, Keyman (versions 5.0 onwards) will recognise that your window accepts WM_UNICHAR and post subsequent character messages as WM_UNICHAR to your window.
    Monday, May 07, 2012 12:22 PM