Download presentation
Presentation is loading. Please wait.
1
Summer 2001 James Amyot Robert Gowans
Advance Windows Programming Chapter 3 - Mouse and Keyboard (Keyboard Input) Summer 2001 James Amyot Robert Gowans
2
Keyboard Input - Overview
Input Focus Keystroke Messages Virtual Key Codes Shift States and Toggles Character Messages Dead-key Messages The Caret VisualKB Application (example)
3
Keyboard Input Key inputs are handled through windows messages:
WM_KEYDOWN WM_KEYUP WM_CHAR The way the application uses the keyboard input will dictate which of these three inputs will be used Using only WM_CHAR can enable Windows to factor in other events or keystrokes such as Ctrl or Shift keys being pressed
4
Input Focus The keyboard is globally shared by all applications
Focus must be set appropriately Mouse works with whatever window is directly under it Alternately, the keyboard input is received by whichever window has focus Only one window can have focus at a time Child windows or controls may have input focus within the window To set or remove focus, the following are used ON_WM_SETFOCUS ( ) ON_WM_KILLFOCUS ( ) ON_WM_SETFOCUS is used to notify a window that it is about to receive the input focus. ON_WM_KILLFOCUS is used to notify a window that it is about to lose the input focus.
5
Keystroke Messages Keystroke messages come in the form of
WM_KEYDOWN WM_KEYUP WM_SYSKEYDOWN WM_SYSKEYUP All keys produce WM_KEYDOWN and WM_KEYUP messages, except Alt and F10 Alt and F10 are “system” keys which have special meaning to Windows.
6
Keystroke Messages cont.
Keystroke message handlers are prototyped as follows afx_msg void OnMsgName (UINT nChar, UINT nRepCnt, UINT nFlags) nChar is the virtual key code of the pressed key nRepCnt is the repeat count nFlags contains the key’s scan code and (zero, or a flag) nRepCnt, or the repeat count always counts WM_KEYUP and WM_SYSKEYUP as single counts, while WM_KEYDOWN and WM_SYSKEYDOWN can have higher than 1. Most programs treat combined WM_KEYDOWN messages as a single message.
7
Keystroke Messages – nFlag bits
Bit(s) Meaning Description 0-7 OEM scan code 8-bit OEM scan code 8 Extended key flag 1 if extended, 0 otherwise 9-12 Reserved N/A 13 Context code 1 if Alt is pressed, 0 otherwise 14 Previous key state 1 if key was previously pressed, 0 if it was up 15 Transition state 0 if the key is being pressed, 1 if it is being released OEM represent original keys (mapped to the bios) Eighth bit allows system to differentiate between the duplicate keys that appear on keyboards (number keys, etc.)
8
Keystroke Messages cont.
OEM – identifies the key to the keyboard BIOS Extended key flag – allows application to recognize duplicate keys. For these, the value is 1 Ctrl and Alt keys on right side of keyboard Home, End, Insert, Delete, Page Up, Page Down Number and arrow keys Enter and forward slash (/) Transition state, previous key state, and context code are generally disregarded
9
Key Handling Notes WM_SYSKEYDOWN and WM_SYSKEYUP should not be processed in most cases by your code These must eventually get to ::DefWindowProc, system keyboard commands such as Alt-Tab and Alt-Esc will stop working Failure to pass these messages to the system can result in unusual and unreliable behavior
10
Virtual Key Codes Virtual Key Codes represent keys
nChar identifies the key that was pressed Virtual Key Codes represent keys These representations avoid depending on hard-coded values or OEM scan codes A to Z, a to z, and 0 to 9 are not in the virtual key table These use ANSI codes and are identified by these by HEX notation A better way than relying on key-up and key-down messages is WM_CHAR messages
11
Shift States and Toggles
Code may require that you know the state of the Shift, Alt, or Ctrl keys before you proceed Given any virtual key code, ::GetKeyState ( ) will report whether the key in question is held down ::GetKeyState (VK_SHIFT) reports back a negative value if the shift key is presently held down Similarly, entering VK_CONTROL or VK_MENU will return negative if the Ctrl or Alt keys are held down, respectively
12
Shift States and Toggles cont.
::GetKeyState ( ) indicates the state of the key at the time the keyboard message was generated (not at time function is called) Do not call ::GetKeyState ( ) outside a keyboard message handler: the information it returns is only valid after a keyboard message has been retrieved by the message queue
13
Character Messages It can get complicated to depend on key-down and key-up messages to determine characters Interpretation of a letter (such as ‘A’ – Hex 0x41), would require Knowing the keyboard key pressed Whether the shift key was depressed Whether caps lock is on Handling possible inconsistencies between keyboards internationally Windows provides ::TranslateMessge to translate keystroke messages into WM_CHAR messages
14
Character Message – WM_CHAR
::TranslateMessage ( ) directly maps each WM_CHAR message into a symbol in the ANSI character set in Windows 98 Unicode character set in Windows 2000 ANSI codes are 8-bits wide, for a total of 256 possible characters Unicode codes are 16-bits wide, for a possible character count of 65,536 The first 256 characters map directly to ANSI chars
15
Character Messages – WM_CHAR
A message map which includes ON_WM_CHAR routes the WM_CHAR messages to the member function OnChar Afx_msg void OnChar (UINT nChar, UINT nRepCnt, UINT nFlags) nRepCnt and nFlags mean the same as in keystroke messages nChar holds either ANSI (Win98) or Unicode (NT) character code
16
Dead-Key Messages By pressing the Dead Key, then the desired character, users of many international keyboards can enter an accented character ::TranslateMessage translates WM_KEYUP messages of dead-keys into WM_DEADCHAR messages WM_SYSKEYUP messages of dead-keys into WM_SYSDEADCHAR messages Usually, these keyboard messages are passed on for default handling using ::DefWindowProc
17
The Caret Visible as a flashing vertical bar ( | )
The caret marks where the next character will be entered in a set of text Carets are a per-thread shared resource among all resources running on the same thread
18
The Caret cont. CWnd Caret Handling Functions:
CreateCaret CreateSolidCaret CreateGrayCaret GetCaretPos SetCaretPos ShowCaret HideCaret ::DestroyCaret destroys the caret
19
The Caret cont. A window that uses a caret should create it when it receives focus, destroy it afterwards After created, ShowCaret must be used to make it visible Each instance of HideCaret requires a ShowCaret to restore If drawing outside the OnPaint handler, you should hide the caret to avoid corrupting the display, then re-show it SetCaretPos is called to move the caret. Windows doesn’t move it, so you must handle it in your code
20
VisualKB – Header file protected:
virtual void PostNcDestroy (); - destroys window afx_msg int OnCreate (LPCREATESTRUCT lpCreateStruct); afx_msg void OnPaint (); afx_msg void OnSetFocus (CWnd* pWnd); afx_msg void OnKillFocus (CWnd* pWnd); afx_msg BOOL OnSetCursor (CWnd* pWnd, UINT nHitTest, UINT message); afx_msg void OnLButtonDown (UINT nFlags, CPoint point);
21
VisualKB – Header cont. All of the following are of the same form:
afx_msg void OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags); OnKeyUp OnSysKeyDown OnSysKeyUp OnChar OnSysChar
22
VisualKB – Message Map BEGIN_MESSAGE_MAP (CMainWindow, CWnd)
ON_WM_CREATE () ON_WM_PAINT () ON_WM_SETFOCUS () ON_WM_KILLFOCUS () ON_WM_SETCURSOR () ON_WM_LBUTTONDOWN () ON_WM_KEYDOWN () ON_WM_KEYUP () ON_WM_SYSKEYDOWN () ON_WM_SYSKEYUP () ON_WM_CHAR () ON_WM_SYSCHAR () END_MESSAGE_MAP ()
23
VisualKB – Handling the Caret
void CMainWindow::OnSetFocus (CWnd* pWnd) { CreateSolidCaret (max (2, ::GetSystemMetrics (SM_CXBORDER)), m_cyChar); SetCaretPos (m_ptCaretPos); ShowCaret (); - must show caret after creating } Shows the caret when the VisualKB window receives the input focus.
24
VisualKB – Handling the Caret cont.
void CMainWindow::OnKillFocus (CWnd* pWnd) { HideCaret (); m_ptCaretPos = GetCaretPos (); ::DestroyCaret (); } Hides the caret when the VisualKB window loses the input focus.
25
VisualKB – Positioning Caret
switch (nChar) { case VK_LEFT: if (m_nTextPos != 0) { m_nTextPos--; - nTextPos is where next char entered PositionCaret (); - defined function } break; (Moves the caret when the left key is pressed)
26
VisualKB – Positioning Caret
The caret is positioned at the end of the line using m_nTextPos = m_strInputText.GetLength (); PositionCaret (); Whenever a new character is added to the line, the position gets updated m_strInputText += nChar;
27
VisualKB – Mouse Positioning Caret
void CMainWindow::OnLButtonDown (UINT nFlags, CPoint point) { if (m_rcTextBox.PtInRect (point)) m_nTextPos = GetNearestPos (point); PositionCaret (); } Moves the caret if the text box is clicked with the left mouse button.
28
VisualKB – Entering, Editing Text
void CMainWindow::OnChar (UINT nChar, UINT nRepCnt, UINT nFlags) { ShowMessage (_T ("WM_CHAR"), nChar, nRepCnt, nFlags); CClientDC dc (this); switch (nChar) { - Determine which character was just input case VK_ESCAPE: case VK_RETURN: m_strInputText.Empty (); m_nTextPos = 0; break;
29
VisualKB – Entering, Editing Text cont.
case VK_BACK: - virtual key if (m_nTextPos != 0) { m_strInputText = m_strInputText.Left (m_nTextPos - 1) + m_strInputText.Right (m_strInputText.GetLength () - m_nTextPos); m_nTextPos--; } break; default: if ((nChar >= 0) && (nChar <= 31)) return;
30
VisualKB – Entering, Editing Text
If text position is at end, add the text to the end if (m_nTextPos == m_strInputText.GetLength ()) { m_strInputText += nChar; m_nTextPos++; } else m_strInputText.SetAt (m_nTextPos++, nChar); Otherwise, add it to the position it’s at and add to the position
31
VisualKB – Entering, Editing Text
CSize size = dc.GetTextExtent (m_strInputText, m_strInputText.GetLength ()); if ((m_ptTextOrigin.x + size.cx) > m_nTextLimit) { m_strInputText = nChar; m_nTextPos = 1; } break;
32
VisualKB – Entering, Editing Text
Update the contents of the text box. HideCaret (); DrawInputText (&dc); PositionCaret (&dc); ShowCaret (); }
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.