Transcript Programming Windows with MFC
Programming Windows with MFC
Chapter 3 The Mouse and the Keyboard
Getting Input from the Mouse
•
Client-area
mouse messages • Nonclient-area mouse messages • Event – The
press
or
release
of a mouse button – The
double click
of a mouse button – The
movement
of the mouse
Client-Area Mouse Messages
Message WM_LBUTTONDOWN WM_LBUTTONUP WM_LBUTTONDBLCLK WM_MBUTTONDOWN WM_MBUTTONUP WM_MBUTTONDBLCLK WM_RBUTTONDOWN WM_RBUTTONUP WM_RBUTTONDBLCLK WM_MOUSEMOVE Sent When
The
left
mouse button is
pressed
.
The
left
mouse button is
released
.
The
left
mouse button is
double-clicked
.
The
middle
mouse button is
pressed
.
The
middle
mouse button is
released
.
The
middle
mouse button is
double-clicked
.
The
right
mouse button is
pressed
.
The
right
mouse button is
released
.
The
right
mouse button is
double-clicked
.
The cursor is
moved
area.
over the window's client
Number of Mouse Buttons
Int nButtonCount = ::GetSystemMetrics(SM_CMOUSEBUTTONS);
• 0 – No mouse installed
Message-Map Macros and Message Handlers for Client-Area Mouse Messages
Message WM_LBUTTONDOWN WM_LBUTTONUP WM_LBUTTONDBLCLK WM_MBUTTONDOWN WM_MBUTTONUP WM_MBUTTONDBLCLK WM_RBUTTONDOWN WM_RBUTTONUP WM_RBUTTONDBLCLK WM_MOUSEMOVE Message-map Macro
ON_WM_LBUTTONDOWN ON_WM_LBUTTONUP ON_WM_LBUTTONDBLCLK ON_WM_MBUTTONDOWN ON_WM_MBUTTONUP ON_WM_MBUTTONDBLCLK ON_WM_RBUTTONDOWN ON_WM_RBUTTONUP ON_WM_RBUTTONDBLCLK ON_WM_MOUSEMOVE
Handling Function
OnLButtonDown OnLButtonUp OnLButtonDblClk OnMButtonDown OnMButtonUp OnMButtonDblClk OnRButtonDown OnRButtonUp OnRButtonDblClk OnMouseMove
Mouse Message Handlers Prototype
afx_msg void OnMsgName (UINT nFlags , CPoint point )
The
nFlags
Parameter
Mask Meaning If Set MK_LBUTTON MK_MBUTTON MK_RBUTTON
The left mouse button is pressed.
The middle mouse button is pressed.
The right mouse button is pressed.
MK_CONTROL
The Ctrl key is pressed.
MK_SHIFT
The Shift key is pressed.
The TicTac Application
CWnd::MessageBox
int MessageBox (LPCTSTR lpszText , LPCTSTR lpszCaption UINT nType = MB_OK) = NULL,
•
lpszText
•
the text in the body
of the message box •
lpszCaption
• the
caption
for the message box's title bar •
nType
• one or more bit flags defining the message box's
style
Message Box Types
MB_YESNO
Type
MB_OKCANCEL MB_RETRYCANCEL MB_YESNOCANCEL
OK Yes Buttons
MB_ABORTRETRYIGNORE
Abort
, Retry, Ignore MB_OK
OK
, Cancel
Retry
, Cancel , No
Yes
, No, Cancel
Possible Return Codes
IDABORT, IDRETRY, IDIGNORE IDOK IDOK, IDCANCEL IDRETRY, IDCANCEL IDYES, IDNO IDYES, IDNO, IDCANCEL
Nonclient-Area Mouse Messages
Message WM_NCLBUTTONDOWN WM_NCLBUTTONUP WM_NCLBUTTONDBLCLK WM_NCMBUTTONDOWN WM_NCMBUTTONUP WM_NCMBUTTONDBLCLK WM_NCRBUTTONDOWN WM_NCRBUTTONUP WM_NCRBUTTONDBLCLK WM_NCMOUSEMOVE Sent When
The left mouse button is pressed.
The left mouse button is released.
The left mouse button is double-clicked.
The middle mouse button is pressed.
The middle mouse button is released.
The middle mouse button is double-clicked.
The right mouse button is pressed.
The right mouse button is released.
The right mouse button is double-clicked.
The cursor is moved over the window's nonclient area.
Message-Map Macros and Message Handlers for Nonclient-Area Mouse Messages
Message Message-Map Macro WM_NCLBUTTONDOWN WM_NCLBUTTONUP WM_NCLBUTTONDBLCLK WM_NCMBUTTONDOWN ON_WM_NCLBUTTONDOWN ON_WM_NCLBUTTONUP ON_WM_NCLBUTTONDBLCLK ON_WM_NCMBUTTONDOWN WM_NCMBUTTONUP ON_WM_NCMBUTTONUP WM_NCMBUTTONDBLCLK ON_WM_NCMBUTTONDBLCLK WM_NCRBUTTONDOWN WM_NCRBUTTONUP ON_WM_NCRBUTTONDOWN ON_WM_NCRBUTTONUP WM_NCRBUTTONDBLCLK ON_WM_NCRBUTTONDBLCLK WM_NCMOUSEMOVE ON_WM_NCMOUSEMOVE Handling Function OnNcLButtonDown OnNcLButtonUp OnNcLButtonDblClk OnNcMButtonDown OnNcMButtonUp OnNcMButtonDblClk OnNcRButtonDown OnNcRButtonUp OnNcRButtonDblClk OnNcMouseMove
Message Handlers for Nonclient-area Messages
afx_msg void OnMsgName (UINT nHitTest , CPoint point )
–
point .x, point .y
•
screen coordination
•
nHitTest
– where the event occurred in the window’s nonclient area
Commonly Used Hit-Test Codes
Value HTCAPTION HTCLOSE HTGROWBOX HTHSCROLL HTMENU HTREDUCE HTSIZE HTSYSMENU HTVSCROLL HTZOOM Corresponding Location
The title bar The close button The restore button (same as
HTSIZE
) The window's horizontal scroll bar The menu bar The minimize button The restore button (same as
HTGROWBOX
) The system menu box The window's vertical scroll bar The maximize button
The
WM_NCHITTEST
Message
•
Before a window receives
a client area or nonclient-area mouse message • The cursor’s screen coordinates
The
WM_MOUSELEAVE
and
WM_MOUSEOVER
Messages
• •
WM_MOUSELEAVE
– The cursor leaves a window
WM_MOUSEOVER
– The cursor hovers over a window
::TrackMouseEvent
• To determine when the mouse cursor leaves or hovers • Accept a pointer parameter • TRACKMOUSEEVENT structure – Winuser.h
The Mouse Wheel
• Message –
WM_MOUSEWHEEL
• Message-Map Macro –
ON_WM_MOUSEWHEEL
• Handling Function –
OnMouseWheel BOOL OnMouseWheel (UINT nFlags, short zDelta , CPoint point)
•
zDelta
•
the distance the wheel was rotated
Capturing the Mouse
•
CWnd::SetCapture
•
::ReleaseCapture
// In CMainWindow's message map ON_WM_LBUTTONDOWN () ON_WM_LBUTTONUP () …… void CMainWindow::OnLButtonDown (UINT nFlags, CPoint point) {
SetCapture ();
} void CMainWindow::OnLButtonUp (UINT nFlags, CPoint point) {
::ReleaseCapture ();
}
Mouse Capturing in Action
Getting Input from the Keyboard
•
WM_KEYDOWN
•
WM_KEYUP
•
WM_CHAR
The Input Focus
• Keyboard messages – Directed to the window with the “
input focus
” •
No more than one window has the input focus
•
WM_SETFOCUS
/
WM_KILLFOCUS
Keystorke Messages
• •
WM_KEYDOWN WM_KEYUP
• •
WM_SYSKEYDOWN WM_SYSKEYUP
– Alt and F10 key
Keystorke Message Handlers
afx_msg void OnMsgName (UINT
nChar
, UINT
nRepCnt
, UINT
nflags
) • • •
nChar
• the virtual key code of the key that was pressed or released.
nRepCnt
• the repeat count—the number of keystrokes encoded in the message
nFlags
• the key's scan code and zero or more of the bit flags
Virtual Key Codes
• Windows identifies keys with the virtual key codes •
Winuser.h
– the letters and the numerals : ANSI codes
WM_CHAR
messages : better way
Shift States and Toggles
::GetKeyState(
VK_SHIFT
) -returns a negative value if the Shift key ::GetKeyState(
VK_CONTROL
) -return a negative value if the Ctrl key is held down • Ctrl-Left if ((nChar==VK_LEFT) && ::GetKeyState(VK_CONTROL) <0)) {……}
Character Messages
ON_WM_CHAR ()
…… void CMainWindow::
OnChar
nRepCnt, UINT nFlags) { (UINT nChar, UINT if
( ((nChar>=_T(‘A’))&&(nChar<=_T(‘Z’)))
||
((nChar>=_T(‘a’))&&(nChar<=_T (‘z’))) )
{ // Display the character } else if (
nChar == VK_RETURN
) { // Process the Enter key } } ……
The Caret
• The point where the next character will be inserted • Per-thread resource
CWnd Caret Handling Functions
Function
CreateCaret CreateSolidCaret CreateGrayCaret GetCaretPos SetCaretPos ShowCaret HideCaret
Description
Creates a caret from a bitmap Creates a solid line caret or a block caret Creates a gray line caret or a block caret Retrieves the current caret position Sets the caret position Displays the caret Hides the caret
Simple Rules
• Create and destroy – CreateCaret, CreateSolidCaret, CreateGrayCaret –
::DestroyCaret
• Show and hide – ShowCaret – HideCaret • Outside an OnPaint handler – Should hide the caret to avoid corrupting • Moving – SetCaretPos – GetCaretPos
The Caret
void CMainWindow::
OnSetFocus
{ } (CWnd* pWnd)
CreateSolidCaret SetCaretPos
(2, m_cyChar); (m_ptCaretPos);
ShowCaret
(); void CMainWindow::
OnKillFocus
{ }
HideCaret
(); m_ptCaretPos =
GetCaretPos ::DestroyCaret
(); (CWnd* pWnd) ();
The VisualKB Application
VisualKB.cpp
CMainWindow::CMainWindow () { // Load the arrow cursor // and the I-beam cursor // and save their handles.
m_hCursorArrow = AfxGetApp()->
LoadStandardCursor
(
IDC_ARROW
); m_hCursorIBeam = AfxGetApp ()->
LoadStandardCursor
(
IDC_IBEAM
); }
{
VisualKB.cpp
void CMainWindow::OnSetFocus (CWnd* pWnd) // Show the caret when the VisualKB // window receives the input focus.
CreateSolidCaret
m_cyChar);
SetCaretPos
(max (2, ::GetSystemMetrics (SM_CXBORDER)), (m_ptCaretPos);
ShowCaret
(); } void CMainWindow::OnKillFocus (CWnd* pWnd) { // Hide the caret when the VisualKB // window loses the input focus.
HideCaret
(); m_ptCaretPos =
GetCaretPos
(); }
::DestroyCaret
();
VisualKB.cpp
void CMainWindow::
OnKeyDown
nFlags) { (UINT nChar, UINT nRepCnt, UINT switch (nChar) { case VK_LEFT: m_nTextPos--; PositionCaret (); break; case VK_RIGHT: m_nTextPos++; PositionCaret (); break; case VK_HOME: m_nTextPos = 0; PositionCaret (); break; case VK_END: m_nTextPos = m_strInputText.GetLength (); PositionCaret (); break; } }
VisualKB.cpp
void CMainWindow::
OnChar
{ (UINT nChar, UINT nRepCnt, UINT nFlags) ShowMessage (_T ("WM_CHAR"), nChar, nRepCnt, nFlags); CClientDC dc (this); switch (nChar) { case VK_ESCAPE: case VK_RETURN: case VK_BACK: default: if ((nChar >= 0) && (nChar <= 31)) return; if (m_nTextPos == m_strInputText.GetLength ()) {
m_strInputText += nChar
;
m_nTextPos++;
} else m_strInputText.SetAt (m_nTextPos++, nChar); …… } // Update the contents of the text box.
HideCaret
();
DrawInputText PositionCaret ShowCaret
(); (&dc); (&dc); }