Adding WM_KEYDOWN Logic

One obvious way to create a keyboard interface is to add some WM_KEYDOWN logic to the window procedure that parallels the WM_VSCROLL and WM_HSCROLL logic:

case WM_KEYDOWN :

nVscrollInc = nHscrollInc = 0 ;

switch (wParam)

{

case VK_HOME : // same as WM_VSCROLL, SB_TOP

nVscrollInc = -nVscrollPos ;

break ;

case VK_END : // same as WM_VSCROLL, SB_BOTTOM

nVscrollInc = nVscrollMax - nVscrollPos ;

break ;

case VK_UP : // same as WM_VSCROLL, SB_LINEUP

nVscrollInc = -1 ;

break ;

case VK_DOWN : // same as WM_VSCROLL, SB_LINEDOWN

nVscrollInc = 1 ;

break ;

case VK_PRIOR : // same as WM_VSCROLL, SB_PAGEUP

nVscrollInc = min (-1, -cyClient / cyChar) ;

break ;

case VK_NEXT : // same as WM_VSCROLL, SB_PAGEDOWN

nVscrollInc = max (1, cyClient / cyChar) ;

break ;

case VK_LEFT : // same as WM_HSCROLL, SB_PAGEUP

nHscrollInc = -8 ;

break ;

case VK_RIGHT : // same as WM_HSCROLL, SB_PAGEDOWN

nHscrollInc = 8 ;

break ;

default :

break ;

}

if (nVscrollInc = max (-nVscrollPos,

min (nVscrollInc, nVscrollMax - nVscrollPos)))

{

nVscrollPos += nVscrollInc ;

ScrollWindow (hwnd, 0, -cyChar * nVscrollInc, NULL, NULL) ;

SetScrollPos (hwnd, SB_VERT, nVscrollPos, TRUE) ;

UpdateWindow (hwnd) ;

}

if (nHscrollInc = max (-nHscrollPos,

min (nHscrollInc, nHscrollMax - nHscrollPos)))

{

nHscrollPos += nHscrollInc ;

ScrollWindow (hwnd, -cxChar * nHscrollInc, 0, NULL, NULL) ;

SetScrollPos (hwnd, SB_HORZ, nHscrollPos, TRUE) ;

}

return 0 ;

Do you dislike this code as much as I do? Simply duplicating all the scroll bar code is unwise, because if we ever wanted to change the scroll bar logic, we'd have to make parallel changes in WM_KEYDOWN. There has to be a better way. And there is.