From 77ea00dd5067c4d368481b21896779a7635d8a29 Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Sun, 20 Jun 2004 22:52:39 +0000 Subject: [PATCH] some little fixes svn path=/trunk/; revision=9778 --- reactos/subsys/system/regedit/hexedit.c | 271 ++++++++++++++++++++++-- 1 file changed, 256 insertions(+), 15 deletions(-) diff --git a/reactos/subsys/system/regedit/hexedit.c b/reactos/subsys/system/regedit/hexedit.c index 1f079c99413..7138a704c03 100644 --- a/reactos/subsys/system/regedit/hexedit.c +++ b/reactos/subsys/system/regedit/hexedit.c @@ -35,16 +35,29 @@ typedef struct DWORD ColumnsPerLine; DWORD nLines; DWORD nVisibleLines; + INT Position; INT LineHeight; INT CharWidth; HFONT hFont; INT LeftMargin; - INT TopMargin; INT AddressSpacing; INT SplitSpacing; + + BOOL EditingField; + INT CaretCol; + INT CaretLine; } HEXEDIT_DATA, *PHEXEDIT_DATA; +/* hit test codes */ +#define HEHT_LEFTMARGIN (0x1) +#define HEHT_ADDRESS (0x2) +#define HEHT_ADDRESSSPACING (0x3) +#define HEHT_HEXDUMP (0x4) +#define HEHT_HEXDUMPSPACING (0x5) +#define HEHT_ASCIIDUMP (0x6) +#define HEHT_RIGHTMARGIN (0x7) + LRESULT WINAPI HexEditWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); ATOM @@ -55,7 +68,7 @@ RegisterHexEditorClass(HINSTANCE hInstance) ZeroMemory(&WndClass, sizeof(WNDCLASSEX)); WndClass.cbSize = sizeof(WNDCLASSEX); - WndClass.style = CS_DBLCLKS;// | CS_PARENTDC; + WndClass.style = CS_DBLCLKS; WndClass.lpfnWndProc = (WNDPROC)HexEditWndProc; WndClass.cbWndExtra = sizeof(PHEXEDIT_DATA); WndClass.hInstance = hInstance; @@ -76,10 +89,33 @@ UnregisterHexEditorClass(HINSTANCE hInstance) /*** Helper functions *********************************************************/ static VOID -HEXEDIT_MoveCaret(PHEXEDIT_DATA hed, INT Col, INT Line) +HEXEDIT_MoveCaret(PHEXEDIT_DATA hed, INT Line, INT Column, BOOL HexDump) { - /* FIXME - include the scroll position */ - SetCaretPos(hed->LeftMargin + (Col * hed->CharWidth), hed->TopMargin + (Line * hed->LineHeight)); + SCROLLINFO si; + + si.cbSize = sizeof(SCROLLINFO); + si.fMask = SIF_POS; + GetScrollInfo(hed->hWndSelf, SB_VERT, &si); + + if(si.nPos > Line) + { + si.nPos = Line; + SetScrollInfo(hed->hWndSelf, SB_VERT, &si, TRUE); + GetScrollInfo(hed->hWndSelf, SB_VERT, &si); + InvalidateRect(hed->hWndSelf, NULL, TRUE); + } + else if((Line - si.nPos) > hed->nVisibleLines) + { + si.nPos += (Line - si.nPos); + SetScrollInfo(hed->hWndSelf, SB_VERT, &si, TRUE); + GetScrollInfo(hed->hWndSelf, SB_VERT, &si); + InvalidateRect(hed->hWndSelf, NULL, TRUE); + } + + if(HexDump) + SetCaretPos(hed->LeftMargin + ((4 + hed->AddressSpacing) * hed->CharWidth) - 2, (Line - si.nPos) * hed->LineHeight); + else + SetCaretPos(hed->LeftMargin + ((4 + hed->AddressSpacing + hed->SplitSpacing + (3 * hed->ColumnsPerLine)) * hed->CharWidth) - 2, (Line - si.nPos) * hed->LineHeight); } static VOID @@ -136,6 +172,7 @@ HEXEDIT_PaintLines(PHEXEDIT_DATA hed, HDC hDC, DWORD ScrollPos, DWORD First, DWO PBYTE buf, current, end, line; UINT bufsize; TCHAR hex[3], addr[17]; + RECT rct; if(hed->hBuffer) { @@ -157,24 +194,35 @@ HEXEDIT_PaintLines(PHEXEDIT_DATA hed, HDC hDC, DWORD ScrollPos, DWORD First, DWO current = buf + linestart; Last = min(hed->nLines - ScrollPos, Last); - for(; First <= Last && current < end; First++) + while(First <= Last && current < end) { - int slen; + DWORD dh; dx = hed->LeftMargin; /* draw address */ _stprintf(addr, _T("%04X"), linestart); TextOut(hDC, dx, dy, addr, 4); - dx += (4 + hed->AddressSpacing) * hed->CharWidth; + + dx += ((4 + hed->AddressSpacing) * hed->CharWidth); + dh = (3 * hed->CharWidth); + + rct.left = dx; + rct.top = dy; + rct.right = rct.left + dh; + rct.bottom = dy + hed->LineHeight; /* draw hex map */ + dx += (hed->CharWidth / 2); line = current; for(x = 0; x < hed->ColumnsPerLine && current < end; x++) { + rct.left += dh; + rct.right += dh; + _stprintf(hex, _T("%02X"), *(current++)); - TextOut(hDC, dx, dy, hex, 2); - dx += (3 * hed->CharWidth); + ExtTextOut(hDC, dx, dy, ETO_OPAQUE, &rct, hex, 2, NULL); + dx += dh; } /* draw ascii map */ @@ -183,19 +231,117 @@ HEXEDIT_PaintLines(PHEXEDIT_DATA hed, HDC hDC, DWORD ScrollPos, DWORD First, DWO for(x = 0; x < hed->ColumnsPerLine && current < end; x++) { _stprintf(hex, _T("%C"), *(current++)); - hex[0] = ((hex[0] & _T('\x007f')) > _T(' ') ? hex[0] : _T('.')); + hex[0] = ((hex[0] & _T('\x007f')) >= _T(' ') ? hex[0] : _T('.')); TextOut(hDC, dx, dy, hex, 1); dx += hed->CharWidth; } dy += hed->LineHeight; linestart += hed->ColumnsPerLine; + First++; } } LocalUnlock(hed->hBuffer); } +static DWORD +HEXEDIT_HitRegionTest(PHEXEDIT_DATA hed, POINTS pt, POINTS *ptClient) +{ + WINDOWINFO wi; + int d, x; + + wi.cbSize = sizeof(WINDOWINFO); + GetWindowInfo(hed->hWndSelf, &wi); + + x = pt.x - wi.rcClient.left; + if(ptClient) + { + ptClient->x = x; + ptClient->y = pt.y - wi.rcClient.top; + } + + if(x <= hed->LeftMargin) + { + return HEHT_LEFTMARGIN; + } + + x -= hed->LeftMargin; + d = (4 * hed->CharWidth); + if(x <= d) + { + return HEHT_ADDRESS; + } + + x -= d; + d = (hed->AddressSpacing * hed->CharWidth); + if(x <= d) + { + return HEHT_ADDRESSSPACING; + } + + x -= d; + d = (3 * hed->ColumnsPerLine * hed->CharWidth); + if(x <= d) + { + return HEHT_HEXDUMP; + } + + x -= d; + d = (hed->SplitSpacing * hed->CharWidth); + if(x <= d) + { + return HEHT_HEXDUMPSPACING; + } + + x -= d; + d = (hed->ColumnsPerLine * hed->CharWidth); + if(x <= d) + { + return HEHT_ASCIIDUMP; + } + + return HEHT_RIGHTMARGIN; +} + +static DWORD +HEXEDIT_PositionFromPoint(PHEXEDIT_DATA hed, POINTS pt, DWORD *Hit) +{ + SCROLLINFO si; + POINTS ptClient; + DWORD Line; + + *Hit = HEXEDIT_HitRegionTest(hed, pt, &ptClient); + + si.cbSize = sizeof(SCROLLINFO); + si.fMask = SIF_POS; + GetScrollInfo(hed->hWndSelf, SB_VERT, &si); + + if(hed->LineHeight > 0) + { + Line = min(si.nPos + (ptClient.y / hed->LineHeight), hed->nLines); + } + else + return 0; + + switch(*Hit) + { + case HEHT_LEFTMARGIN: + case HEHT_ADDRESS: + case HEHT_ADDRESSSPACING: + return Line * hed->ColumnsPerLine; + + case HEHT_HEXDUMP: + return 0; + + case HEHT_ASCIIDUMP: + return 0; + + case HEHT_RIGHTMARGIN: + return (Line + 1) * hed->ColumnsPerLine; + } +} + /*** Control specific messages ************************************************/ static LRESULT @@ -222,6 +368,7 @@ HEXEDIT_HEM_LOADBUFFER(PHEXEDIT_DATA hed, PVOID Buffer, DWORD Size) else { hed->hBuffer = LocalFree(hed->hBuffer); + hed->Position = 0; HEXEDIT_Update(hed); return 0; @@ -244,11 +391,13 @@ HEXEDIT_HEM_LOADBUFFER(PHEXEDIT_DATA hed, PVOID Buffer, DWORD Size) LocalUnlock(hed->hBuffer); } + hed->Position = 0; HEXEDIT_Update(hed); return Size; } else if(hed->hBuffer) { + hed->Position = 0; hed->hBuffer = LocalFree(hed->hBuffer); HEXEDIT_Update(hed); } @@ -318,9 +467,9 @@ HEXEDIT_WM_NCCREATE(HWND hWnd, CREATESTRUCT *cs) hed->ColumnsPerLine = 8; hed->LeftMargin = 2; - hed->TopMargin = 2; hed->AddressSpacing = 2; hed->SplitSpacing = 2; + hed->EditingField = TRUE; /* in hexdump field */ SetWindowLong(hWnd, 0, (LONG)hed); @@ -351,8 +500,8 @@ HEXEDIT_WM_CREATE(PHEXEDIT_DATA hed) static LRESULT HEXEDIT_WM_SETFOCUS(PHEXEDIT_DATA hed) { - CreateCaret(hed->hWndSelf, 0, 2, hed->LineHeight); - HEXEDIT_MoveCaret(hed, 0, 0); + CreateCaret(hed->hWndSelf, 0, 1, hed->LineHeight); + HEXEDIT_MoveCaret(hed, hed->CaretLine, hed->CaretCol, hed->EditingField); ShowCaret(hed->hWndSelf); return 0; } @@ -471,6 +620,7 @@ HEXEDIT_WM_PAINT(PHEXEDIT_DATA hed) DWORD nLines, nFirst; HFONT hOldFont; HDC hTempDC; + DWORD height; if(GetUpdateRect(hed->hWndSelf, &rc, FALSE) && (hed->LineHeight > 0)) { @@ -479,7 +629,12 @@ HEXEDIT_WM_PAINT(PHEXEDIT_DATA hed) si.fMask = SIF_POS; GetScrollInfo(hed->hWndSelf, SB_VERT, &si); - nLines = (rc.bottom - rc.top) / hed->LineHeight; + height = (rc.bottom - rc.top); + nLines = height / hed->LineHeight; + if((height % hed->LineHeight) > 0) + { + nLines++; + } if(nLines > hed->nLines - si.nPos) { nLines = hed->nLines - si.nPos; @@ -543,6 +698,86 @@ HEXEDIT_WM_MOUSEWHEEL(PHEXEDIT_DATA hed, int cyMoveLines, WORD ButtonsDown, LPPO return 0; } +static LRESULT +HEXEDIT_WM_SETCURSOR(PHEXEDIT_DATA hed) +{ + POINTS pt; + DWORD Hit, Pos; + + Pos = GetMessagePos(); + pt = MAKEPOINTS(Pos); + Hit = HEXEDIT_HitRegionTest(hed, pt, NULL); + + switch(Hit) + { + case HEHT_HEXDUMP: + case HEHT_HEXDUMPSPACING: + case HEHT_ASCIIDUMP: + SetCursor(LoadCursor(0, MAKEINTRESOURCE(IDC_IBEAM))); + break; + + default: + SetCursor(LoadCursor(0, MAKEINTRESOURCE(IDC_ARROW))); + break; + } + return TRUE; +} + +static BOOL +HEXEDIT_WM_KEYDOWN(PHEXEDIT_DATA hed, INT VkCode) +{ + DWORD bufsize; + BOOL shift, control, handled; + + if(GetKeyState(VK_MENU) & 0x8000) + { + return FALSE; + } + + shift = GetKeyState(VK_SHIFT) & 0x8000; + control = GetKeyState(VK_CONTROL) & 0x8000; + + bufsize = (hed->hBuffer ? LocalSize(hed->hBuffer) : 0); + handled = FALSE; + + switch(VkCode) + { + case VK_LEFT:MessageBox(0, L"", L"", 0); + if(hed->Position > 0) + { + if(--hed->CaretCol < 0) + { + hed->CaretLine--; + hed->CaretCol = hed->ColumnsPerLine; + } + else + hed->Position--; + + HEXEDIT_MoveCaret(hed, hed->CaretLine, hed->CaretCol, hed->EditingField); + } + handled = TRUE; + break; + + case VK_RIGHT: + if(hed->Position < bufsize) + { + if(++hed->CaretCol > hed->ColumnsPerLine) + { + hed->CaretLine = 0; + hed->CaretLine++; + } + else + hed->Position++; + + HEXEDIT_MoveCaret(hed, hed->CaretLine, hed->CaretCol, hed->EditingField); + } + handled = TRUE; + break; + } + + return FALSE; +} + LRESULT WINAPI HexEditWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) @@ -558,6 +793,12 @@ HexEditWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case WM_PAINT: return HEXEDIT_WM_PAINT(hed); + case WM_SETCURSOR: + return HEXEDIT_WM_SETCURSOR(hed); + + case WM_KEYDOWN: + return HEXEDIT_WM_KEYDOWN(hed, (INT)wParam); + case WM_VSCROLL: return HEXEDIT_WM_VSCROLL(hed, HIWORD(wParam), LOWORD(wParam));