It's not so simple giving an example but here' s a start
Look at - GetScrollInfo, SetScrollInfo, SCROLLINFO
Here's a routine that uses this stuff.
int DoScrollHorz(HWND hWnd, WPARAM wParam, int val)
{
int xInc;
RECT rc;
THISFILE * f = (THISFILE*) GetWindowLong(hWnd, 0);
// Get scrollinfo Horz Type
SCROLLINFO si;
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_POS | SIF_RANGE | SIF_PAGE;
GetScrollInfo(hWnd, SB_HORZ, &si);
switch LOWORD(wParam){
case VK_HOME:
f->CaretPosX = 0;
f->CaretChar = 0;
si.fMask = SIF_POS;
si.nPos = 0;
SetScrollInfo(hWnd, SB_HORZ, &si, TRUE);
SetRect(&rc, 10, 0, rc.right, rc.bottom);
SetCaretPos(f->CaretPosX * f->Fw + 10, f->CaretPosY * f->Fh);
if (f->horzOff != 10) InvalidateRect(hWnd, &rc, TRUE);
f->horzOff = 10;
return 0;
case VK_END:
DoLineEnd(hWnd, f->startline[f->CaretPosY]);
return 0;
case VK_USER:
f->CaretPosX -= val;
xInc = val;
break;
case VK_DOWN:
case SB_LINEDOWN:
xInc = 1;
break;
case VK_UP:
case SB_LINEUP:
xInc = -1;
break;
case VK_LEFT:
xInc = -1;
break;
case VK_RIGHT:
xInc = 1;
break;
case VK_PRIOR:
case SB_PAGEUP:
xInc = -(int)si.nPage+1;
break;
case VK_NEXT:
case SB_PAGEDOWN:
xInc = (int)si.nPage-1;
break;
case SB_THUMBTRACK:
// special case for 32bit position
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_TRACKPOS;
GetScrollInfo(hWnd, SB_HORZ, &si);
xInc = si.nTrackPos - si.nPos;
break;
default:
return 0;
}
// This will return the correct +ve or -ve value when
// scrollbar is in range and '0' when out of range.
int j = (si.nMax - si.nPage + 1);
xInc = max(-si.nPos, min(xInc, j - si.nPos));
if (xInc){
GetClientRect(hWnd, &rc);
// SW_INVALIDATE | SW_ERASE
SetRect(&rc, 10, 0, rc.right, rc.bottom);
ScrollWindowEx(hWnd, -xInc * f->Fw, 0, NULL, &rc, NULL, NULL, SW_ERASE | SW_INVALIDATE);
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_POS;
si.nPos += xInc;
// Set new pos
f->horzOff -= xInc * f->Fw;
UpdateWindow(hWnd);
SetScrollInfo(hWnd, SB_HORZ, &si, TRUE);
}
return 0;
}
Hope it helps.
John