Character code and keyboards under windows
Basically, windows uses the ANSI character set and not the 8-bits ASCII char set. The ANSI char set contains 255 chars. To enter a char, the user hit a key or a combination of keys (shift, ctrl, ...). He (she) can also use the Alt+0nnn command, where nnn represents the ANSI code of the char set. To use this command, keep the Alt key down and enter the char code from the numeric pad, NumLock being on. Examples: In order to get the char a, I can hit the a key on my keyboard or I can enter the command Alt+097.
To obtain an e acute, one can use the Alt+0233 command; for a n tilde, I use Alt+241; for an angstroem, Alt+0229. Alt+0nnn is working for every kbd (US or not US).
The european chars are in the range 128..255 of the ANSI char set.
Every language has its own keyboard. The system provides a keyboard/language "driver" for every language. Roughly speaking, when the user hit a key or a combination of keys, the keyboard/language driver translates the 'pressed keys' into an Alt+0nnn char code.
Some more examples coming from my swiss french keyboard: In order to get an 'a' , I hit the a key or I may enter the Alt+097 command. To get the A, I press Shift+a or I enter the command Alt+065. To get the a # char (comment char in python), I should press Ctrl+Alt+3. A } is obtained by Ctrl+Alt+$ or by the command Alt+0125.
Pressing simultaneously three keys is not very pratical. That the reason why on european keyboards we have a key called AltGr. AltGr is nothing else than Ctrl and Alt used simultaneoulsy. So in my example, if I want to get the # char, I can press Ctrl+Alt+3, AltGr+3 or enter the command Alt+035. AltGr can be see as a 'super Shift' or as 'one another shift' key.
On a US keyboard, you can not type directly an e acute, you have to enter the command Alt+0233. (Yes, I installed a us kbd and tested it under windows, this can be done in 2 minutes)
Things can be even a litte bit more complicated with the so called dead keys. What is a dead key? When you press a dead key, the caret will not move. It will move only after a secong key has been pressed. Example: On my swiss french keyboard, I can not enter directly an e circumflex. I have to use the circumflex key which is a dead key. In order to obtain an e cicumflex, I hit the circumflex key, the carret is not moving, then I hit the e key and the e circumlflex appears on my screen. An alternative way is to use the Alt+0234 command.
Python coding using wxPython
What can go wrong within (wx)Python? I see two problems.
1. It seems that some wxPython (wxWindows?) ctrls are using only the first
- half of the ANSI char set. That means only a 7 bits char code. (The first half of the ANSI char set is identical to the 7-bits ASCII char set).
2. We have seen that AltGr = Ctrl + Alt. So if your application needs to
- check the Ctrl key status (up/down), do not forget to check the Alt key
status too. Ctrl can be seen down, just because the AltGr key is pressed. By not doing this, an european may not use a AltGr key correclty.
Below an example showing how pressed key(s) are handled correcly. From shell.py, PyCrust, available in the demo. I deleted some lines.
def OnKeyDown(self, event): """Key down event handler. ... key = event.KeyCode() controlDown = event.ControlDown() altDown = event.AltDown() shiftDown = event.ShiftDown() currpos = self.GetCurrentPos() endpos = self.GetTextLength() # Return (Enter) is used to submit a command to the interpreter. if not controlDown and key == WXK_RETURN: ... self.processLine() # If the auto-complete window is up let it do its thing. elif self.AutoCompActive(): ... event.Skip() # Let Ctrl-Alt-* get handled normally. elif controlDown and altDown: event.Skip() ... ... # Cut to the clipboard. elif (controlDown and key in (ord('X'), ord('x'))) \ or (shiftDown and key == WXK_DELETE): self.Cut() ... ... # Insert the next command from the history buffer. else: event.Skip()
The two lines of code
elif controlDown and altDown: event.Skip()
let european people use smoothly their AltGr keys.
char codes and key codes
Char codes and key codes are two different things. The method event.KeyCode() returns a key code, not a char code. The left arrow has a key code but no char code.
The char issue: Python, wxPython or UNICODE problem?
I don't know. Using pyCrust under windows, you can test the following code:
>>> for i in range(32, 255): ... print i, chr(i)
You will see, that you obtain (correcly) all the ANSI chars. Note: if you try the same test using IDLE, you don't get the same result. This is normal, chr() will return a char based on the 8-bits ASCII char set (DOS).
Are my fonts updated?
This may sound stupid, but the TTF font files have changed. Try the following key combination Ctrl+Alt+e or AltGr+e or Alt+0128. You should obtain the euro char, the new currency unit symbol used in Europe. If not, update your ttf files (free).
The developers using an US kbd can easily test their code with some non english chars just by using a few Alt+0nnn commands. Preferably, test some chars with an ANSI code > 127, just to see what's happen. A serious developer must do this.
If you don't know what to type, try to enter correctly the word: attaché-case (attache[acute]-case)
Regards to all. Jean-Michel Fauth, Switzerland.