Windows Program-文本查看器

实现滚动显示

#include <windows.h>

#define ID_LIST 1
#define ID_TEXT 2
#define MAXREAD 8192
#define DIRATTR (DDL_READWRITE|DDL_READONLY|DDL_HIDDEN|DDL_SYSTEM|\
				DDL_DIRECTORY|DDL_ARCHIVE|DDL_DRIVES)
#define DTFLAGS (DT_WORDBREAK|DT_EXPANDTABS|DT_NOCLIP|DT_NOPREFIX)

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

WNDPROC OldList;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
	PSTR szCmdLine, int iCmdShow)
{
	static TCHAR szAppName[] = TEXT("head");
	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)(COLOR_BTNFACE + 1);
	wndclass.lpszMenuName = NULL;
	wndclass.lpszClassName = szAppName;

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

	hwnd = CreateWindow(szAppName, TEXT("head"),
		WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN|ES_AUTOVSCROLL|WS_VSCROLL,
		CW_USEDEFAULT, CW_USEDEFAULT,
		CW_USEDEFAULT, CW_USEDEFAULT,
		NULL, NULL, hInstance, NULL);

	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)
{
	static BOOL bValidFile;
	static BYTE buffer[MAXREAD];
	static HWND hwndList, hwndText;
	static RECT rect;
	static TCHAR szFile[MAX_PATH + 1];
	static int readSize;
	static bool isRollText;
	static int vScrollRange, hScrollRange;
	static int c_lineOfPage, c_widthOfPage;
	static int cxChar, cyChar;
	static int iVscrollPos, iHscrollPos;
	
	HANDLE hFile;
	HDC hdc;
	int i;
	PAINTSTRUCT ps;
	TCHAR szBuffer[MAX_PATH + 1];

	switch (message)
	{
	case WM_CREATE:
		cxChar = LOWORD(GetDialogBaseUnits());
		cyChar = HIWORD(GetDialogBaseUnits());
		rect.left = 20 * cxChar;
		rect.top = 3 * cyChar;

		hwndList = CreateWindow(TEXT("listbox"), NULL, WS_CHILDWINDOW|WS_VISIBLE|LBS_STANDARD, cxChar, cyChar * 3,
			cxChar * 13 + GetSystemMetrics(SM_CXVSCROLL), cyChar * 10, hwnd, (HMENU)ID_LIST, (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL);
		GetCurrentDirectory(MAX_PATH + 1, szBuffer);
		
		hwndText = CreateWindow(TEXT("static"), szBuffer, WS_CHILDWINDOW | WS_VISIBLE | SS_LEFT, cxChar, cyChar, cxChar*MAX_PATH, cyChar, hwnd, (HMENU)ID_TEXT, (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL);
		
		OldList = (WNDPROC)SetWindowLong(hwndList, GWL_WNDPROC, (LPARAM)ListProc);

		SendMessage(hwndList, LB_DIR, DIRATTR, (LPARAM)TEXT("*.*"));
		return 0;
	case WM_SIZE:
		rect.right = LOWORD(lParam)/*-GetSystemMetrics(SM_CXVSCROLL)*/;
		rect.bottom = HIWORD(lParam)/*-GetSystemMetrics(SM_CYHSCROLL)*/;
		c_lineOfPage = rect.bottom / cyChar - 3;
		c_widthOfPage = rect.right / cxChar - 20;
		return 0;
	case WM_SETFOCUS:
	//	SetFocus(hwndList);
		return 0;
	case WM_COMMAND:
		if (LOWORD(wParam) == ID_LIST&&HIWORD(wParam) == LBN_DBLCLK)
		{
			if (LB_ERR == (i = SendMessage(hwndList, LB_GETCURSEL, 0, 0)))
			{
				break;
			}
			SendMessage(hwndList, LB_GETTEXT, i, (LPARAM)szBuffer);
			if (INVALID_HANDLE_VALUE != (hFile = CreateFile(szBuffer, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)))
			{
				CloseHandle(hFile);
				bValidFile = TRUE;
				lstrcpy(szFile, szBuffer);
				GetCurrentDirectory(MAX_PATH + 1, szBuffer);
				if (szBuffer[lstrlen(szBuffer) - 1] != '\\')
				{
					lstrcat(szBuffer, TEXT("\\"));
					SetWindowText(hwndText, lstrcat(szBuffer, szFile));
				}
			}
			else
			{
				bValidFile = false;
				szBuffer[lstrlen(szBuffer) - 1] = '\0';
				if (!SetCurrentDirectory(szBuffer + 1))
				{
					szBuffer[3] = ':';
					szBuffer[4] = '\0';
					SetCurrentDirectory(szBuffer + 2);
				}

				GetCurrentDirectory(MAX_PATH + 1, szBuffer);
				SetWindowText(hwndText, szBuffer);
				SendMessage(hwndList, LB_RESETCONTENT, 0, 0);
				SendMessage(hwndList, LB_DIR, DIRATTR, (LPARAM)TEXT("*.*"));
			}
			InvalidateRect(hwnd, NULL, TRUE);
		}
		return 0;
	case WM_PAINT:
		if (!bValidFile)
			break;
		if (INVALID_HANDLE_VALUE == (hFile = CreateFile(szFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)))
		{
			bValidFile = FALSE;
			break;
		}
		hdc = BeginPaint(hwnd, &ps);
		if (isRollText)
		{
			SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
			SetTextColor(hdc, GetSysColor(COLOR_BTNTEXT));
			SetBkColor(hdc, GetSysColor(COLOR_BTNFACE));
			RECT myWirte;
			myWirte.left =( 20-iHscrollPos) * cxChar;//超过画面的方式实现滚动
			myWirte.top = (3 - iVscrollPos)*cyChar;//超过画面的方式实现滚动
			myWirte.right = rect.right;
			myWirte.bottom = rect.bottom;
			DrawTextA(hdc, (LPCSTR)buffer, -1, &myWirte, DT_EXPANDTABS | DT_NOCLIP | DT_NOPREFIX);//第三个参数填负-1
					//TextOutA(hdc, 20 * cxChar, (3 + (j - iVscrollPos))*cyChar, (LPCSTR)(dataLine[j].c_str() + iHscrollPos), dataLine[j].size());
					//DrawTextA(hdc, (LPCSTR)buffer, readSize, &rect, (DT_EXPANDTABS | DT_NOCLIP | DT_NOPREFIX));
					//DrawTextA(hdc, (LPCSTR)buffer, readSize, &rect, DTFLAGS);
					//DrawTextA(hdc, NULL, 0, &myWirte, (DT_EXPANDTABS | DT_NOCLIP | DT_NOPREFIX));
			isRollText = false;
		}
		else
		{
			memset(buffer,0, sizeof(buffer));
			ReadFile(hFile, buffer, MAXREAD, (LPDWORD)&readSize, NULL);
			if (readSize == MAXREAD)
			{
				buffer[readSize - 1] = '\0';
				if (buffer[readSize - 2] == '\r')
				{
					buffer[readSize - 2] = '\0';
				}
			}
			else
			{
				buffer[readSize] = '\0';
			}
			CloseHandle(hFile);
			SetScrollPos(hwnd, SB_VERT, 0, TRUE);
			SetScrollPos(hwnd, SB_HORZ, 0, TRUE);
			SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
			SetTextColor(hdc, GetSysColor(COLOR_BTNTEXT));
			SetBkColor(hdc, GetSysColor(COLOR_BTNFACE));
			DrawTextA(hdc, (LPCSTR)buffer, readSize, &rect, /*DTFLAGS*/DT_EXPANDTABS | DT_NOCLIP | DT_NOPREFIX);
			hScrollRange = 0;
			int cur = 0;
			int line = 0;
			int countOfline = 0;
			while (cur < readSize)
			{
				if (buffer[cur] == '\r')
				{
					if ((cur + 1 < readSize) && buffer[cur + 1] == '\n')
					{
						line++;
						hScrollRange = max(hScrollRange, countOfline);
						cur += 2;
						countOfline = 0;
						continue;
					}
				}
				if (buffer[cur] == '\t')
				{
					countOfline += 8;//'\t'占8个字符
				}
				else
				{
					countOfline++;
				}
				cur++;
			}
			line++;
			hScrollRange = max(hScrollRange, countOfline);

			vScrollRange = max(0, line - c_lineOfPage);
			hScrollRange = max(0, hScrollRange - c_widthOfPage);
			SetScrollRange(hwnd, SB_VERT, 0, vScrollRange, true);
			SetScrollRange(hwnd, SB_HORZ, 0, hScrollRange, true);
		}
		EndPaint(hwnd, &ps);
		return 0;
	case WM_VSCROLL:
		switch (LOWORD(wParam))
		{
		case SB_LINEUP:
			iVscrollPos -= 1;
			break;
		case SB_LINEDOWN:
			iVscrollPos += 1;
			break;
		case SB_PAGEUP:
			iVscrollPos -= c_lineOfPage;
			break;
		case SB_PAGEDOWN:
			iVscrollPos += c_lineOfPage;
			break;
		case SB_THUMBPOSITION:
			iVscrollPos = HIWORD(wParam);
			break;
		default:
			break;
		}
		iVscrollPos = max(0, min(iVscrollPos, vScrollRange));
		if (iVscrollPos != GetScrollPos(hwnd, SB_VERT))
		{
			SetScrollPos(hwnd, SB_VERT, iVscrollPos, TRUE);
			isRollText = true;
			InvalidateRect(hwnd, &rect, TRUE);//不全部重绘,只重绘文字部分
		}
		return 0;
	case WM_HSCROLL:
		switch (LOWORD(wParam))
		{
		case SB_LINELEFT:
			iHscrollPos -= 1;
			break;
		case SB_LINERIGHT:
			iHscrollPos += 1;
			break;
		case SB_PAGELEFT:
			iHscrollPos -= c_widthOfPage;
			break;
		case SB_PAGERIGHT:
			iHscrollPos += c_widthOfPage;
			break;
		case SB_THUMBPOSITION:
			iHscrollPos = HIWORD(wParam);
			break;
		default:
			break;
		}
		iHscrollPos = max(0, min(iHscrollPos, hScrollRange));
		if (iHscrollPos != GetScrollPos(hwnd, SB_HORZ))
		{
			SetScrollPos(hwnd, SB_HORZ, iHscrollPos, TRUE);
			isRollText = true;
			InvalidateRect(hwnd, &rect, TRUE);//不全部重绘,只重绘文字部分
		}
		return 0;
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return DefWindowProc(hwnd, message, wParam, lParam);
}

LRESULT CALLBACK ListProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	if (message == WM_KEYDOWN&&wParam == VK_RETURN)
	{
		SendMessage(GetParent(hwnd), WM_COMMAND, MAKELONG(1, LBN_DBLCLK), (LPARAM)hwnd);
	}
	return CallWindowProc(OldList, hwnd, message, wParam, lParam);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值