#include <windows.h>

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

char array[] = {'T', 'e', 's', 't', 'A', 'r', 'r', 'a', 'y', 'C', 'S', '3', '5', '1', 
			'T', 'e', 's', 't', 'A', 'r', 'r', 'a', 'y', 'C', 'S', '3', '5', '1', 
			'T', 'e', 's', 't', 'A', 'r', 'r', 'a', 'y', 'C', 'S', '3', '\0'};

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
					PSTR szCmdLine, int iCmdShow)
{
	static TCHAR szAppName[] = TEXT ("Array") ;
	HWND         hwnd ;
	MSG          msg ;
	WNDCLASS     wndclass ;

	wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
	wndclass.lpfnWndProc   = WndProc ;
	wndclass.cbClsExtra    = 0 ;
	wndclass.cbWndExtra    = 0 ;
	wndclass.hInstance     = hInstance ;
	wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
	wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
	wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
	wndclass.lpszMenuName  = NULL ;
	wndclass.lpszClassName = szAppName ;

	if (!RegisterClass (&wndclass))
	{
		MessageBox (NULL, TEXT ("This program requires Windows NT!"), 
			szAppName, MB_ICONERROR) ;
		return 0 ;
	}

	hwnd = CreateWindow (szAppName,                  // window class name
		TEXT ("Output Array - Horizontal Scroll"), // window caption
		WS_OVERLAPPEDWINDOW | WS_HSCROLL,        // window style
		CW_USEDEFAULT,              // initial x position
		CW_USEDEFAULT,              // initial y position
		CW_USEDEFAULT,              // initial x size
		CW_USEDEFAULT,              // initial y size
		NULL,                       // parent window handle
		NULL,                       // window menu handle
		hInstance,                  // program instance handle
		NULL) ;                     // creation parameters

	ShowWindow (hwnd, iCmdShow) ;
	UpdateWindow (hwnd) ;

	while (GetMessage (&msg, NULL, 0, 0))
	{
		TranslateMessage (&msg) ;
		DispatchMessage (&msg) ;
	}
	return msg.wParam ;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	HDC         hdc ;
	PAINTSTRUCT ps ;
	RECT        rect ;
	TCHAR		szText[1024];
	int			szLen;
	TEXTMETRIC  tm;
	
	int i, j;

	static int cxChar, cyChar;
	static int cxClient, cyClient;
	static int iHScrollPos;

	switch (message)
	{
	case WM_CREATE:
		hdc = GetDC (hwnd);
		
		GetTextMetrics (hdc, &tm);
		cxChar = tm.tmAveCharWidth;
		cyChar = tm.tmHeight + tm.tmExternalLeading;

		ReleaseDC (hwnd, hdc);
	
		SetScrollRange (hwnd, SB_HORZ, 0, 39, FALSE);
		SetScrollPos   (hwnd, SB_HORZ, iHScrollPos, TRUE);
		
		return 0 ;
	
	case WM_HSCROLL:
		switch (LOWORD (wParam))
		{
		case SB_LINEUP:
			iHScrollPos--;
			break;

		case SB_LINEDOWN:
			iHScrollPos++;
			break;

		case SB_PAGEUP:
			iHScrollPos -= cxClient / cxChar;
			break;

		case SB_PAGEDOWN:
			iHScrollPos += cxClient / cxChar;
			break;

		case SB_THUMBPOSITION:
			iHScrollPos = HIWORD (wParam);
			break;

		default:
			break;
		}

		iHScrollPos = max (0, min (iHScrollPos, 39));

		if (iHScrollPos != GetScrollPos (hwnd, SB_HORZ))
		{
			SetScrollPos (hwnd, SB_HORZ, iHScrollPos, TRUE);
			InvalidateRect (hwnd, NULL, TRUE);
		}

		return 0;

	case WM_SIZE:
		cxClient = LOWORD(lParam);
		cyClient = HIWORD(lParam);
		return 0;

	case WM_PAINT:
		hdc = BeginPaint (hwnd, &ps) ;

		GetClientRect (hwnd, &rect) ;


		i = iHScrollPos;
		j = 0;
		while ((i < 40) && (i < (iHScrollPos + cxClient/cxChar)))
		{
			szLen = wsprintf (szText, TEXT ("%c"), array[i]);
			TextOut (hdc, j * 3 * cxChar, cyClient / 2, szText, szLen);

			i++;
			j++;
		}

		EndPaint (hwnd, &ps) ;
		return 0 ;

	case WM_DESTROY:
		PostQuitMessage (0) ;
		return 0 ;
	}
	return DefWindowProc (hwnd, message, wParam, lParam) ;
}