Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4304193

Dead keys don't work due to failure to account for a Windows API design flaw.

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P1 P1
    • 1.3.0
    • 1.1.8, 1.2.2, 1.3.0
    • client-libs
    • rc2
    • x86
    • windows_2000



      Name: skT88420 Date: 01/12/2000


      java version "1.3beta"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.3beta-O)
      Java(TM) HotSpot Client VM (build 1.3beta-O, mixed mode)

      This is a duplicate of bug 4157080, which is incorrectly marked as fixed. This
      is an extremely serious problem still occurring in JDK 1.3, and the fix is easy.

      (Note: As long as this bug goes unfixed, it seriously hampers Java's usefulness
      in certain markets such as German, French, and Spanish.)


      Dead keys do not function as expected in Java applications. This is happening
      because of a call to either ::ToAscii() or ::ToUnicode() somewhere in the
      keyboard handling code (probably when handling the WM_KEYUP message).


        To reproduce the problem:

      1. Go to the keyboard settings under the Control Panel, and select the US
      International keyboard.

      2. Run any Java application with a TextField or JTextField.

      3. Try to use a dead key combination, such as <apostrophe><a> (which should
      generate 'á').

      Step 3 might sometimes seem to work if the second key is pressed before the
      first is released; but if you release the first key before pressing the second
      key, it will not work reliably.


      This is probably happening because of a call to either ::ToAscii()
      or ::ToUnicode() while handling the WM_KEYUP message. These are low-level
      keyboard layout driver APIs which, as a side effect of their implementation,
      invert the active status of dead key codes. This is old behavior from way back
      in the Windows 3.x days, that could not be corrected without breaking existing
      applications.


        To fix this problem, always make calls to ::ToAscii() or ::ToUnicode() in
      pairs. That way, any flag that gets inverted on the first call will be
      inverted back on the second one. This is Microsoft's recommendation in
      knowledge base article Q99337:

      http://support.microsoft.com/support/kb/articles/Q99/3/37.ASP


      The remainder of this message describes how to reproduce the exact behavior
      occurring in Java, but in a small MFC-based Windows application. This may help
      your developers to understand what is happening and determine how to best deal
      with it.

      1. Use Visual C++ 6's AppWizard to create a dialog-based application.

      2. Put an edit control on the dialog.

      3. In the dialog class, override PreTranslateMessage, and give it the
      following implementation:

      BOOL CDeadKeyDlg::PreTranslateMessage(MSG* pMsg)
      {
      // This problem can be reproduced just as easily
      using ::ToUnicode().
      // I use ::ToAscii() here because it's slightly simpler and
      doesn't require NT.
      if (pMsg->message == WM_KEYUP)
      {
      BYTE state[256];
      WORD ch;

      ::GetKeyboardState(state);
      ::ToAscii(pMsg->wParam, LOBYTE(HIWORD(pMsg->lParam)),
      state, &ch, 0);
      }
      return CDialog::PreTranslateMessage(pMsg);
      }

      4. Now compile and run the application. Note that in the dialog's edit box,
      dead keys now behave exactly as they do in all Java applications.

      5. Now, change the above function so that it makes two calls to ::ToAscii(),
      like this:

      BOOL CDeadKeyDlg::PreTranslateMessage(MSG* pMsg)
      {
      if (pMsg->message == WM_KEYUP)
      {
      BYTE state[256];
      WORD ch;

      ::GetKeyboardState(state);
      // Note: ::ToAscii() is intentionally called twice.
      ::ToAscii(pMsg->wParam, LOBYTE(HIWORD(pMsg->lParam)),
      state, &ch, 0);
      ::ToAscii(pMsg->wParam, LOBYTE(HIWORD(pMsg->lParam)),
      state, &ch, 0);
      }
      return CDialog::PreTranslateMessage(pMsg);
      }

      6. Compile and run the application, and note that the dead keys now work fine.
      (Review ID: 99850)
      ======================================================================

            ehawkessunw Eric Hawkes (Inactive)
            skonchad Sandeep Konchady
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: