滚动条窗口

#include<Windows.h>
#include<strsafe.h>

HINSTANCE hinst;
HWND hwndMain;

#define LINES 28

LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	HDC hdc;
	PAINTSTRUCT ps;
	TEXTMETRIC tm;
	SCROLLINFO si;
	
	static int xClient;
	static int yClient;
	static int xClientMax;

	static int xChar;
	static int yChar;
	static int xUpper;

	static int xPos;
	static int yPos;

	int i;
	int x, y;

	int FirstLine;
	int LastLine;
	HRESULT hr;
	size_t abcLength;

	static TCHAR *abc[] = {
		TEXT("anteater"),  TEXT("bear"),      TEXT("cougar"),
		TEXT("dingo"),     TEXT("elephant"),  TEXT("falcon"),
		TEXT("gazelle"),   TEXT("hyena"),     TEXT("iguana"),
		TEXT("jackal"),    TEXT("kangaroo"),  TEXT("llama"),
		TEXT("moose"),     TEXT("newt"),      TEXT("octopus"),
		TEXT("penguin"),   TEXT("quail"),     TEXT("rat"),
		TEXT("squid"),     TEXT("tortoise"),  TEXT("urus"),
		TEXT("vole"),      TEXT("walrus"),    TEXT("xylophone"),
		TEXT("yak"),       TEXT("zebra"),
		TEXT("This line contains words, but no character. Go figure."),
		TEXT("")
	};

	switch (uMsg)
	{
	case WM_CREATE:
		hdc = GetDC(hwnd);

		GetTextMetrics(hdc, &tm);
		xChar = tm.tmAveCharWidth;
		xUpper = (tm.tmPitchAndFamily & 1 ? 3 : 2) * xChar / 2;
		yChar = tm.tmHeight + tm.tmExternalLeading;

		ReleaseDC(hwnd, hdc);

		xClientMax = 48 * xChar + 12 * xUpper;
		break;

	case WM_SIZE:
		yClient = HIWORD(lParam);
		xClient = LOWORD(lParam);
		
		si.cbSize = sizeof(si);
		si.fMask = SIF_RANGE | SIF_PAGE;
		si.nMin = 0;
		si.nMax = LINES - 1;
		si.nPage = yClient / yChar;
		SetScrollInfo(hwnd, SB_VERT, &si, TRUE);

		si.cbSize = sizeof(si);
		si.fMask = SIF_RANGE | SIF_PAGE;
		si.nMin = 0;
		si.nMax = 2 + xClientMax / xChar;
		si.nPage = xClient / xChar;
		SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
		break;

	case WM_HSCROLL:
		si.cbSize = sizeof(si);
		si.fMask = SIF_ALL;

		GetScrollInfo(hwnd, SB_HORZ, &si);
		xPos = si.nPos;
		switch (LOWORD(wParam))
		{
		case SB_LINELEFT:
			si.nPos -= 1;
			break;

		case SB_LINERIGHT:
			si.nPos += 1;
			break;

		case SB_PAGELEFT:
			si.nPos -= si.nPage;
			break;

		case SB_PAGERIGHT:
			si.nPos += si.nPage;
			break;

		case SB_THUMBTRACK:
			si.nPos = si.nTrackPos;
			break;

		default:
			break;
		}

		si.fMask = SIF_POS;
		SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
		GetScrollInfo(hwnd, SB_HORZ, &si);

		if (si.nPos != xPos) 
		{
			ScrollWindow(hwnd, xChar * (xPos - si.nPos), 0, NULL, NULL);
		}
		break;

	case WM_VSCROLL:
		si.cbSize = sizeof(si);
		si.fMask = SIF_ALL;
		GetScrollInfo(hwnd, SB_VERT, &si);

		yPos = si.nPos;
		switch (LOWORD(wParam))
		{
		case SB_TOP:
			si.nPos = si.nMin;
			break;

		case SB_BOTTOM:
			si.nPos = si.nMax;
			break;

		case SB_LINEUP:
			si.nPos -= 1;
			break;

		case SB_LINEDOWN:
			si.nPos += 1;
			break;

		case SB_PAGEUP:
			si.nPos -= si.nPage;
			break;

		case SB_PAGEDOWN:
			si.nPos += si.nPage;
			break;

		case SB_THUMBTRACK:
			si.nPos = si.nTrackPos;
			break;

		default:
			break;
		}

		si.fMask = SIF_POS;
		SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
		GetScrollInfo(hwnd, SB_VERT, &si);

		if (si.nPos != yPos)
		{
			ScrollWindow(hwnd, 0, yChar * (yPos - si.nPos), NULL, NULL);
			UpdateWindow(hwnd);
		}
		break;

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

		si.cbSize = sizeof(si);
		si.fMask = SIF_POS;
		GetScrollInfo(hwnd, SB_VERT, &si);
		yPos = si.nPos;

		GetScrollInfo(hwnd, SB_HORZ, &si);
		xPos = si.nPos;

		FirstLine = max(0, yPos + ps.rcPaint.top / yChar);
		LastLine = min(LINES - 1, yPos + ps.rcPaint.bottom / yChar);

		

		x = xChar * (1 - xPos);
		y = yChar * (1 - yPos);
		
		for (i = FirstLine; i <= LastLine; i++)
		{
			//y = yChar * (i - yPos);
			;
			hr = StringCchLength(abc[i], 64, &abcLength);
			if ((FAILED(hr)) | (abcLength == NULL))
			{
				//Error
			}

			TextOut(hdc, x, y + (i - 1) * yChar, abc[i], abcLength);
		}

		EndPaint(hwnd, &ps);
		break;

	case WM_DESTROY:
		PostQuitMessage(0);
		break;

	default:
		return DefWindowProc(hwnd, uMsg, wParam, lParam);
	}

	return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpszCmdLine, int nCmdShow)
{
	MSG msg;
	BOOL bRet;
	WNDCLASS wc;
	UNREFERENCED_PARAMETER(lpszCmdLine);

	static TCHAR lpszAppName[] = TEXT("MyWindows");

	if (!hPrevInstance)
	{
		wc.style = CS_HREDRAW | CS_VREDRAW;
		wc.lpfnWndProc = WndProc;
		wc.cbClsExtra = 0;
		wc.cbWndExtra = 0;
		wc.hInstance = hInstance;
		wc.hIcon = LoadIcon((HINSTANCE)NULL, IDI_APPLICATION);
		wc.hCursor = LoadCursor((HINSTANCE)NULL, IDC_ARROW);
		wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
		wc.lpszMenuName = NULL;
		wc.lpszClassName = lpszAppName;

		if (!RegisterClass(&wc))
			return FALSE;
	}
	
	hinst = hInstance;

	hwndMain = CreateWindow(
		lpszAppName,
		"MainWindow",
		WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		(HWND)NULL,
		(HMENU)NULL,
		hinst,
		(LPVOID)NULL,);

	if (!hwndMain)
		return FALSE;

	ShowWindow(hwndMain, nCmdShow);
	UpdateWindow(hwndMain);

	while ( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
	{
		if (bRet == -1)
		{
			//Error
		}
		else
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	return msg.wParam;
}

  

原文地址:https://www.cnblogs.com/eternalmoonbeam/p/10827792.html