⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hexview.c

📁 直接IRP操作文件的实现问题
💻 C
📖 第 1 页 / 共 3 页
字号:
			bHighLight = FALSE;

			if (selEnd != -1)
			{
				if (j + startAddr < selStart)
				{
					k = MIN((DWORD)k, selStart - (j + startAddr));
					bHighLight = FALSE;
				}
				else if ((DWORD)j + startAddr == selStart)
				{
					k = MIN((DWORD)k, selEnd - (j + startAddr) + 1);
					bHighLight = TRUE;
				}
				else if ((DWORD)j + startAddr <= selEnd)
				{
					k = MIN((DWORD)k, selEnd - (j + startAddr) + 1);
					bHighLight = TRUE;
				}
			}

			hv_pfmt = (PHV_PRINTFMT)buf;				//输出十六进制
			hv_pfmt->x = (1 + 8 + 1 + j * 3);
			hv_pfmt->y = i;
			hv_pfmt->color = bModify ? HV_COLOR_MODIFY : HV_COLOR_HEX;
			hv_pfmt->highlight = bHighLight ? 1 : 0;
			hv_pfmt->len = k * 3;
			buf += sizeof(HV_PRINTFMT);

			for (l = 0; l < k; l++)
			{
				*buf++ = "0123456789ABCDEF"[(text[i * lineWidth + j + l] >> 4) & 15];
				*buf++ = "0123456789ABCDEF"[(text[i * lineWidth + j + l] >> 0) & 15];
				*buf++ = ' ';
			}

			if (j + k >= lineWidth - 1 || (bHighLight && j + startAddr + k == selEnd + 1))
			{
				hv_pfmt->len -= 1;
				buf--;
			}

			hv_pfmt = (PHV_PRINTFMT)buf;				//输出文本
			hv_pfmt->x = (1 + 8 + lineWidth * 3 + 4 + j);
			hv_pfmt->y = i;
			hv_pfmt->color = bModify ? HV_COLOR_MODIFY : HV_COLOR_TEXT;
			hv_pfmt->highlight = bHighLight ? 1 : 0;
			hv_pfmt->len = k;
			buf += sizeof(HV_PRINTFMT) + hv_pfmt->len;

			for (l = 0; l < k; l++)
				hv_pfmt->data[l] = text[i * lineWidth + j + l] < 0x20 ? '.' : text[i * lineWidth + j + l];
		}

		startAddr += lineWidth;
	}

	hv_pfmt = (PHV_PRINTFMT)buf;				//输出结束
	hv_pfmt->x = 0;
	hv_pfmt->y = 0;
	hv_pfmt->color = 0;
	hv_pfmt->len = 0;
}

VOID HV_PrintHexView(HDC hDC, PHEXVIEW pHex, DWORD nWidth, DWORD nHeight)
{
	TCHAR HexTitle[] = " OFFSET   0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F ";
	HFONT hFont, hOldFont;
	HBRUSH hbr;
	PHV_PRINTFMT hv_pfmt;
	DWORD lastBgColor = -1, lastColor = -1;
	UINT nCharWidth, nCharHeight;
	PVOID fmt;
	RECT rc;
	LONG SelStart, SelEnd;

	hFont = CreateFont(-12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Courier New");
	hOldFont = SelectObject(hDC, hFont);

	nCharWidth = pHex->CharWidth;
	nCharHeight = pHex->CharHeight;

	rc.top = 0;
	rc.left = 0;
	rc.bottom = nHeight;
	rc.right = nWidth;

	hbr = CreateSolidBrush(pHex->color[HV_COLOR_BG0]);
	FillRect(hDC, &rc, hbr);
	DeleteObject(hbr);

	SetBkColor(hDC, RGB(0, 255, 255));
	TextOut(hDC, nCharWidth, 0, HexTitle, 9 + pHex->LineWidth * 3);

	fmt = VirtualAlloc(NULL, 0x5000, MEM_COMMIT, PAGE_READWRITE);

	if (fmt == NULL) 
		return;

	SelStart = MIN(pHex->SelStart, pHex->SelEnd);
	SelEnd = MAX(pHex->SelStart, pHex->SelEnd);

	HV_FormatForPrint(	pHex->LineWidth,
						nHeight / nCharHeight - 1,
						pHex->PageOffset,
						&pHex->hv_modl,
						pHex->Buffer,
						SelStart,
						SelEnd,
						fmt);

	do
	{
		hv_pfmt = (PHV_PRINTFMT)fmt;
		(PBYTE)fmt += sizeof(HV_PRINTFMT) + hv_pfmt->len;

		if (hv_pfmt->len == 0)
			break;

		if (pHex->color[hv_pfmt->color] != lastColor)
		{
			SetTextColor(hDC, pHex->color[hv_pfmt->color]);
			lastColor = pHex->color[hv_pfmt->color];
		}

		if (pHex->color[hv_pfmt->highlight] != lastBgColor)
		{
			SetBkColor(hDC, pHex->color[hv_pfmt->highlight]);
			lastBgColor = pHex->color[hv_pfmt->highlight];
		}

		TextOut(	hDC,
					hv_pfmt->x * nCharWidth,
					hv_pfmt->y * nCharHeight + nCharHeight,
					hv_pfmt->data,
					hv_pfmt->len);
	} while (1);

	VirtualFree(fmt, 0, MEM_RELEASE);
	SelectObject(hDC, hOldFont);
	DeleteObject(hFont);
}

ULONG HV_GetCurrentCursor(PHEXVIEW pHex, short x, short y, PDWORD pEditMode)
{
	UINT nCharWidth, nCharHeight;
	int lenHex, lenAscii;
	int bx, by, mx, my, middle;
	DWORD dwEditMode;

	nCharWidth = pHex->CharWidth;
	nCharHeight = pHex->CharHeight;

	bx = x / (int)nCharWidth;
	by = y / (int)nCharHeight - 1;
	bx -= pHex->AddressWidth * 2 + 2;

	middle = pHex->LineWidth * 3 + 1;
	lenHex = pHex->LineWidth * 3 - 1;
	lenAscii = pHex->LineWidth;

	mx = pHex->PageLength % pHex->LineWidth;
	my = pHex->PageLength / pHex->LineWidth;
	mx = pHex->LineWidth - mx;

	if (by < 0)
		by = 0;

	if (by > my)
		by = my;

	if (mx != 0 && by == my)
	{
		lenHex -= mx * 3;
		lenAscii -= mx;
	}

	if (bx >= middle)
	{
		bx -= middle + 2;

		if (bx < 0)
		{
			bx = 0;
		}
		else if (bx >= lenAscii)
		{
			bx = lenAscii - 1;
		}

		dwEditMode = EM_TEXT;
	}
	else
	{
		if (bx < 0)
		{
			bx = 0;
		}

		if ((bx + 1) % 3 == 0)
		{
			if (x % nCharWidth < nCharWidth / 2)
			{
				bx--;
			}
			else
			{
				bx++;
			}
		}

		if (bx >= lenHex)
		{
			bx = lenHex - 1;
		}

		if ((bx + 1) % 3 == 1)
			dwEditMode = EM_HEX_HIGH;
		else
			dwEditMode = EM_HEX_LOW;

		bx = (bx + 1) / 3;
	}

	if (pEditMode != NULL)
		*pEditMode = dwEditMode;

	return bx + by * pHex->LineWidth + pHex->PageOffset;
}

VOID HV_OnPaint(HWND hWnd)
{
	UINT nWndWidth, nWndHeight;
	HDC hDC, hMemDC;
	HBITMAP hBitmap;
	RECT rect;
	PAINTSTRUCT ps;

	GetClientRect(hWnd, &rect);
	nWndWidth = rect.right - rect.left;
	nWndHeight = rect.bottom - rect.top;

	hDC = BeginPaint(hWnd, &ps);
	hMemDC = CreateCompatibleDC(hDC);
	hBitmap = CreateCompatibleBitmap(hDC, nWndWidth, nWndHeight);
	SelectObject(hMemDC, hBitmap);

	HV_PrintHexView(	hMemDC,
						(PHEXVIEW)GetWindowLong(hWnd, GWL_HEXINFO),
						nWndWidth,
						nWndHeight);

	BitBlt(hDC, 0, 0, nWndWidth, nWndHeight, hMemDC, 0, 0, SRCCOPY);

	DeleteDC(hMemDC);
	DeleteObject(hBitmap);
	EndPaint(hWnd, &ps);
}

int HV_MoveCursor(PHEXVIEW pHex, int lx, int ly)
{
	if (lx != 0)
	{
		switch (pHex->EditMode)
		{
		case EM_TEXT:
			pHex->Cursor += lx;
			break;

		case EM_HEX_HIGH:
			if (lx > 0)
			{
				pHex->EditMode = lx & 1 ? EM_HEX_LOW : EM_HEX_HIGH;
				pHex->Cursor += lx / 2;
			}
			else
			{
				pHex->EditMode = lx & 1 ? EM_HEX_LOW : EM_HEX_HIGH;
				pHex->Cursor += (lx - 1) / 2;
			}
			break;

		case EM_HEX_LOW:
			if (lx > 0)
			{
				pHex->EditMode = lx & 1 ? EM_HEX_HIGH : EM_HEX_LOW;
				pHex->Cursor += (lx + 1) / 2;
			}
			else
			{
				pHex->EditMode = lx & 1 ? EM_HEX_HIGH : EM_HEX_LOW;
				pHex->Cursor += lx / 2;
			}
			break;
		}
	}

	pHex->Cursor += ly * pHex->LineWidth;

	if (pHex->Cursor >= (int)(pHex->Length))
	{
		pHex->Cursor = pHex->Length - 1;
		pHex->EditMode = pHex->EditMode == EM_TEXT ? EM_TEXT : EM_HEX_LOW;
	}
	else if (pHex->Cursor < 0)
	{
		pHex->Cursor = 0;
		pHex->EditMode = pHex->EditMode == EM_TEXT ? EM_TEXT : EM_HEX_HIGH;
	}

	if (pHex->Cursor >= (int)(pHex->PageOffset + pHex->PageLength))
	{
		int n = pHex->Cursor / pHex->LineWidth;
		n -= pHex->PageMaxLength / pHex->LineWidth - 1;
		pHex->PageOffset = n * pHex->LineWidth;
		pHex->PageLength = MIN(pHex->PageMaxLength, pHex->Length - pHex->PageOffset);
		return n;
	}
	else if (pHex->Cursor < (int)pHex->PageOffset)
	{
		int n = pHex->Cursor / pHex->LineWidth;
		pHex->PageOffset = n * pHex->LineWidth;
		pHex->PageLength = MIN(pHex->PageMaxLength, pHex->Length - pHex->PageOffset);
		return n;
	}

	return -1;
}

VOID HV_UpdatePage(HWND hWnd, int n)
{
	SCROLLINFO si;

	if (n != -1)
	{
		si.cbSize = sizeof(SCROLLINFO);
		si.fMask = SIF_POS;
		SetScrollPos(hWnd, SB_VERT, n, TRUE);
	}

	RedrawWindow(hWnd, NULL, 0, RDW_INVALIDATE);
}

VOID HV_OnChar(HWND hWnd, WPARAM wParam)
{
	char ch = (char)wParam, ch1;
	PHEXVIEW pHex = (PHEXVIEW)GetWindowLong(hWnd, GWL_HEXINFO);
	DWORD off = pHex->Cursor;
	int i;
	NMHDR n;

	if (pHex->EditMode == EM_TEXT)
	{
		HV_AddModifyLog(&pHex->hv_modl, off, 1, &ch);
		i = HV_MoveCursor(pHex, 1, 0);
		HV_UpdatePage(hWnd, i);
	}
	else
	{
		switch (ch = toupper(ch))
		{
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
			ch -= '0';
			break;
		case 'A':
		case 'B':
		case 'C':
		case 'D':
		case 'E':
		case 'F':
			ch -= 'A' - 0x0a;
			break;
		default:
			return;
		}

		HV_GetModifyData(&pHex->hv_modl, off, &ch1, 1);

		if (pHex->EditMode != EM_HEX_HIGH)
		{
			if (ch != (ch1 & 0x0f))
			{
				ch |= ch1 & 0xf0;
				HV_AddModifyLog(&pHex->hv_modl, off, 1, &ch);
			}
		}
		else
		{
			ch <<= 4;
			if (ch != (ch1 & 0xf0))
			{
				ch |= ch1 & 0x0f;
				HV_AddModifyLog(&pHex->hv_modl, off, 1, &ch);
			}
		}

		i = HV_MoveCursor(pHex, 1, 0);
		HV_UpdatePage(hWnd, i);
	}
	RedrawWindow(hWnd, NULL, 0, RDW_INVALIDATE);

	n.code = HV_EN_CHANGE;
	n.idFrom = GetDlgCtrlID(hWnd);
	n.hwndFrom = hWnd;
	SendMessage(GetParent(hWnd), WM_NOTIFY, GetDlgCtrlID(hWnd), (LPARAM)&n);
}

VOID CALLBACK HV_TimerProc(HWND hWnd, UINT uMsg, UINT idEvent, DWORD dwTime)
{
	int t, x, y, w, h;
	HDC hDC;
	PHEXVIEW pHex;

	pHex = (PHEXVIEW)GetWindowLong(hWnd, GWL_HEXINFO);

	w = pHex->CharWidth;
	h = pHex->CharHeight;

	if (pHex->NoCursor == TRUE)
		return;

	t = pHex->Cursor - pHex->PageOffset;

	if (t < 0 || t >= (int)pHex->PageLength)
		return;

	switch (pHex->EditMode)
	{
	case EM_TEXT:
		x = t % pHex->LineWidth;
		x += pHex->AddressWidth * 2 + pHex->LineWidth * 3 + 3 + 2;
		break;

	case EM_HEX_HIGH:
		x = t % pHex->LineWidth * 3;
		x += pHex->AddressWidth * 2 + 2;
		break;

	case EM_HEX_LOW:
		x = t % pHex->LineWidth * 3 + 1;
		x += pHex->AddressWidth * 2 + 2;
		break;
	}

	x *= pHex->CharWidth;
	y = (t / pHex->LineWidth + 1) * pHex->CharHeight;

	hDC = GetDC(hWnd);
	BitBlt(hDC, x, y, w, h, NULL, 0, 0, DSTINVERT);
	ReleaseDC(hWnd, hDC);
}

VOID HV_LButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
	PHEXVIEW pHex;
	ULONG i;
	NMHDR n;

	pHex = (PHEXVIEW)GetWindowLong(hWnd, GWL_HEXINFO);
	i = HV_GetCurrentCursor(pHex, LOWORD(lParam), HIWORD(lParam), &pHex->EditMode);

	pHex->SelStart = i;
	pHex->SelEnd = -1;
	pHex->Cursor = i;
	RedrawWindow(hWnd, NULL, 0, RDW_INVALIDATE);

	n.code = HV_EN_SELCHANGE;
	n.idFrom = GetDlgCtrlID(hWnd);
	n.hwndFrom = hWnd;
	SendMessage(GetParent(hWnd), WM_NOTIFY, GetDlgCtrlID(hWnd), (LPARAM)&n);
}

VOID HV_OnVscroll(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
	PHEXVIEW pHex;
	int i;
	SCROLLINFO si;

	si.cbSize = sizeof(SCROLLINFO);
	si.fMask = SIF_ALL;
	GetScrollInfo(hWnd, SB_VERT, &si);

	pHex = (PHEXVIEW)GetWindowLong(hWnd, GWL_HEXINFO);

	switch (LOWORD(wParam))
	{
	case SB_LINEUP:
		i = si.nPos - 1;
		break;
	case SB_LINEDOWN:
		i = si.nPos + 1;
		break;
	case SB_PAGEUP:
		i = si.nPos - si.nPage;
		break;
	case SB_PAGEDOWN:
		i = si.nPos + si.nPage;
		break;
	case SB_THUMBPOSITION:
	case SB_THUMBTRACK:
		i = HIWORD(wParam);
		break;
	default:
		return;
	}

	i = MAX(i, si.nMin);
	i = MIN(i, MAX(0, (int)(si.nMax - si.nPage + 1)));

	pHex->PageOffset = pHex->LineWidth * i;
	pHex->PageLength = MIN(pHex->Length - pHex->PageOffset, pHex->PageMaxLength);
	SetScrollPos(hWnd, SB_VERT, i, TRUE);
	RedrawWindow(hWnd, NULL, 0, RDW_INVALIDATE);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -