reactos/subsys/system/regedit
diff -u -r1.5 -r1.6
--- hexedit.c 20 Jun 2004 19:26:59 -0000 1.5
+++ hexedit.c 20 Jun 2004 22:52:39 -0000 1.6
@@ -35,16 +35,29 @@
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 @@
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 @@
/*** 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 @@
PBYTE buf, current, end, line;
UINT bufsize;
TCHAR hex[3], addr[17];
+ RECT rct;
if(hed->hBuffer)
{
@@ -157,24 +194,35 @@
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 @@
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 @@
else
{
hed->hBuffer = LocalFree(hed->hBuffer);
+ hed->Position = 0;
HEXEDIT_Update(hed);
return 0;
@@ -244,11 +391,13 @@
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 @@
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 @@
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 @@
DWORD nLines, nFirst;
HFONT hOldFont;
HDC hTempDC;
+ DWORD height;
if(GetUpdateRect(hed->hWndSelf, &rc, FALSE) && (hed->LineHeight > 0))
{
@@ -479,7 +629,12 @@
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 @@
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 @@
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));