6.8 Add a Keyboard and Mouse Interface

This section explains the tenth step in writing Phone Book: add message-handler functions for the keyboard and the mouse.

·To add the keyboard and mouse message-handlers:

1.Add the following OnUp message-handler member function to the CMainWindow section of your VIEW.CPP file below the OnHScroll member function:

// CMainWindow::OnUp

// Uses Accelerator tables to link the up arrow key to this

// routine. Decrements the select line with checking for scrolling

// and wrapping off the top of the list.

//

//

void CMainWindow::OnUp()

{

InvalidateLine();

if ( m_nSelectLine <= 0 )

{

m_nSelectLine = m_people.GetCount() - 1;

m_nVscrollPos = max( 0, m_nSelectLine + 1 - ( m_cyClient /

m_cyChar ) );

Invalidate( TRUE );

}

else

{

m_nSelectLine--;

if ( m_nSelectLine - m_nVscrollPos < 0 )

OnVScroll( SB_LINEUP, 0, NULL );

// Selection is off the screen

if ( m_nSelectLine - m_nVscrollPos > ( m_cyClient / m_cyChar ) )

{

m_nVscrollPos = m_nSelectLine + 1 - ( m_cyClient /

m_cyChar );

SetScrollPos( SB_VERT, m_nVscrollPos, TRUE );

Invalidate( TRUE );

}

if ( m_nSelectLine - m_nVscrollPos < 0 )

{

m_nVscrollPos = m_nSelectLine;

SetScrollPos( SB_VERT, m_nVscrollPos, TRUE );

Invalidate( TRUE );

}

}

InvalidateLine();

}

OnUp responds to the UP ARROW key. It moves the selection in the window upward one line. At the top of the database list, the selection wraps around to the bottom of the list. The database record that was formerly selected is unhighlighted and the newly selected line is inverted to highlight it. OnUp calls the InvalidateLine utility member function to change a line's highlighting. You'll add InvalidateLine later.

2.Add the following OnDown message-handler member function to the CMainWindow section of your VIEW.CPP file below the OnUp member function:

// CMainWindow::OnDown

// Uses Accelerator tables to link the down arrow key to this

// routine. Inc the select line with checking for scrolling

// and wrapping off the bottom of the list.

//

void CMainWindow::OnDown()

{

InvalidateLine();

if ( m_nSelectLine == (int)( m_people.GetCount() - 1 )

|| m_nSelectLine == -1 )

{

m_nSelectLine = 0;

m_nVscrollPos = 0;

Invalidate( TRUE );

}

else

{

m_nSelectLine++;

if ( ( m_nSelectLine - m_nVscrollPos + 1 ) > ( m_cyClient /

m_cyChar ) )

OnVScroll( SB_LINEDOWN, 0, NULL );

// Selection is off the screen

if ( ( m_nSelectLine - m_nVscrollPos ) > ( m_cyClient /

m_cyChar ) )

{

m_nVscrollPos = m_nSelectLine + 1 - ( m_cyClient /

m_cyChar );

SetScrollPos( SB_VERT, m_nVscrollPos, TRUE );

Invalidate( TRUE );

}

if ( ( m_nSelectLine - m_nVscrollPos ) < 0 )

{

m_nVscrollPos = m_nSelectLine;

SetScrollPos( SB_VERT, m_nVscrollPos, TRUE );

Invalidate( TRUE );

}

}

InvalidateLine();

}

OnDown moves the selection down one line or, if it reaches the last line of the database information, wraps the selection around to the top.

3.Add the following OnLButtonDown message-handler member function to the CMainWindow section of your VIEW.CPP file below the OnDown member function:

// CMainWindow::OnLButtonDown

// Turns the location of the mouse pointer into a line number

// and stores that information in m_nSelectLine. Uses

// InvalidateLine to cause OnPaint to change the screen.

//

void CMainWindow::OnLButtonDown( UINT, CPoint location )

{

InvalidateLine();

int pos = m_nVscrollPos + location.y / m_cyChar;

if ( ( m_nSelectLine != pos ) && ( pos <

(int)m_people.GetCount() ) )

{

m_nSelectLine = pos;

InvalidateLine();

}

else

m_nSelectLine = -1;

}

OnLButtonDown responds to a mouse click in the client area of the window. It checks the location of the click and calculates the line number that was clicked. Then it changes the selection to that line. If there is no selection, the member variable m_nSelectLine is set to -1 to indicate that status.

4.Add the following OnLButtonDblClk message-handler member function to VIEW.CPP below OnLButtonDown:

// CMainWindow::OnLButtonDblClk

// Translates mouse left button double click into edit person.

//

void CMainWindow::OnLButtonDblClk( UINT wParam, CPoint location )

{

if ( m_nSelectLine == -1 )

OnLButtonDown( wParam, location );

OnEdit();

}

OnLButtonDblClk responds to a double-click in the window's client area. A double-click on a line of the display calls the OnEdit member function to allow the user to edit data for the selected person.

5.Add the following OnKeyDown message-handler member function to VIEW.CPP below OnLButtonDblClk:

// CMainWindow::OnKeyDown

// Translates keyboard input into scroll messages

//

void CMainWindow::OnKeyDown( UINT wParam, UINT, UINT )

{

switch ( wParam )

{

case VK_HOME:

OnVScroll( SB_TOP, 0, NULL );

break;

case VK_END:

OnVScroll( SB_BOTTOM, 0, NULL );

break;

case VK_PRIOR:

OnVScroll( SB_PAGEUP, 0, NULL );

break;

case VK_NEXT:

OnVScroll( SB_PAGEDOWN, 0, NULL );

break;

case VK_LEFT:

OnHScroll( SB_PAGEUP, 0, NULL );

break;

case VK_RIGHT:

OnHScroll( SB_PAGEDOWN, 0, NULL );

break;

}

}

OnKeyDown implements keyboard commands for scrolling. Hence it's closely related to the scrolling member functions presented in the previous section. It's presented here as part of the keyboard interface.

To continue the tutorial, see “Add a Member Function to Handle the WM_PAINT Message” on page 235. For more information on the handlers you just added, see the discussion in the next section.