diff --git a/reactos/subsys/system/regedit/hexedit.c b/reactos/subsys/system/regedit/hexedit.c index 35160374206..92a7a36e1db 100644 --- a/reactos/subsys/system/regedit/hexedit.c +++ b/reactos/subsys/system/regedit/hexedit.c @@ -32,13 +32,14 @@ typedef struct HLOCAL hBuffer; DWORD style; DWORD MaxBuffer; + DWORD ColumnsPerLine; + DWORD nLines; + DWORD nVisibleLines; INT LineHeight; INT CharWidth; HFONT hFont; INT LeftMargin; INT TopMargin; - INT CaretX; - INT CaretY; } HEXEDIT_DATA, *PHEXEDIT_DATA; LRESULT WINAPI HexEditWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); @@ -51,7 +52,7 @@ RegisterHexEditorClass(HINSTANCE hInstance) ZeroMemory(&WndClass, sizeof(WNDCLASSEX)); WndClass.cbSize = sizeof(WNDCLASSEX); - WndClass.style = CS_DBLCLKS | CS_PARENTDC; + WndClass.style = CS_DBLCLKS;// | CS_PARENTDC; WndClass.lpfnWndProc = (WNDPROC)HexEditWndProc; WndClass.cbWndExtra = sizeof(PHEXEDIT_DATA); WndClass.hInstance = hInstance; @@ -78,6 +79,110 @@ HEXEDIT_MoveCaret(PHEXEDIT_DATA hed, INT Col, INT Line) SetCaretPos(hed->LeftMargin + (Col * hed->CharWidth), hed->TopMargin + (Line * hed->LineHeight)); } +static VOID +HEXEDIT_Update(PHEXEDIT_DATA hed) +{ + SCROLLINFO si; + RECT rcClient; + + GetClientRect(hed->hWndSelf, &rcClient); + hed->style = GetWindowLong(hed->hWndSelf, GWL_STYLE); + + hed->nLines = max((hed->hBuffer ? LocalSize(hed->hBuffer) / hed->ColumnsPerLine : 1), 1); + + if(hed->LineHeight > 0) + { + hed->nVisibleLines = rcClient.bottom / hed->LineHeight; + if(rcClient.bottom % hed->LineHeight) + { + hed->nVisibleLines++; + } + } + else + hed->nVisibleLines = 0; + + /* update scrollbar */ + si.cbSize = sizeof(SCROLLINFO); + si.fMask = SIF_RANGE | SIF_PAGE; + si.nMin = 0; + si.nMax = hed->nLines; + if(hed->LineHeight > 0) + si.nPage = rcClient.bottom / hed->LineHeight; + else + si.nPage = 0; + SetScrollInfo(hed->hWndSelf, SB_VERT, &si, TRUE); + + if(hed->style & WS_VISIBLE) + { + InvalidateRect(hed->hWndSelf, NULL, TRUE); + } +} + +static HFONT +HEXEDIT_GetFixedFont(PHEXEDIT_DATA hed) +{ + LOGFONT lf; + GetObject(GetStockObject(ANSI_FIXED_FONT), sizeof(LOGFONT), &lf); + lf.lfWeight = FW_BOLD; + return CreateFontIndirect(&lf); +} + +static VOID +HEXEDIT_PaintLines(PHEXEDIT_DATA hed, HDC hDC, DWORD ScrollPos, DWORD First, DWORD Last, RECT *rc) +{ + DWORD x, dx, dy, linestart; + PBYTE buf, current, end; + UINT bufsize; + TCHAR hex[3], addr[17]; + + if(hed->hBuffer) + { + bufsize = LocalSize(hed->hBuffer); + buf = LocalLock(hed->hBuffer); + } + else + { + buf = NULL; + bufsize = 0; + } + + FillRect(hDC, rc, (HBRUSH)(COLOR_WINDOW + 1)); + if(buf) + { + end = buf + bufsize; + dy = First * hed->LineHeight; + linestart = (ScrollPos + First) * hed->ColumnsPerLine; + current = buf + linestart; + Last = min(hed->nLines - ScrollPos, Last); + + for(; First <= Last && current < end; First++) + { + int strlen; + + dx = hed->LeftMargin; + /* draw address */ + _stprintf(addr, _T("%04X"), linestart); + strlen = _tcslen(addr); + TextOut(hDC, dx, dy, addr, strlen); + dx += (strlen + 2) * hed->CharWidth; + + /* draw byte map */ + for(x = 0; x < 8 && current < end; x++) + { + _stprintf(hex, _T("%02X"), *(current++)); + strlen = _tcslen(hex); + TextOut(hDC, dx, dy, hex, strlen); + dx += ((strlen + 1) * hed->CharWidth); + } + + dy += hed->LineHeight; + linestart += hed->ColumnsPerLine; + } + } + + LocalUnlock(hed->hBuffer); +} + /*** Control specific messages ************************************************/ static LRESULT @@ -104,6 +209,7 @@ HEXEDIT_HEM_LOADBUFFER(PHEXEDIT_DATA hed, PVOID Buffer, DWORD Size) else { hed->hBuffer = LocalFree(hed->hBuffer); + HEXEDIT_Update(hed); return 0; } @@ -125,11 +231,13 @@ HEXEDIT_HEM_LOADBUFFER(PHEXEDIT_DATA hed, PVOID Buffer, DWORD Size) LocalUnlock(hed->hBuffer); } + HEXEDIT_Update(hed); return Size; } else if(hed->hBuffer) { hed->hBuffer = LocalFree(hed->hBuffer); + HEXEDIT_Update(hed); } return 0; @@ -175,6 +283,7 @@ HEXEDIT_HEM_SETMAXBUFFERSIZE(PHEXEDIT_DATA hed, DWORD nMaxSize) { /* truncate the buffer */ hed->hBuffer = LocalReAlloc(hed->hBuffer, hed->MaxBuffer, LMEM_MOVEABLE); + HEXEDIT_Update(hed); } } @@ -194,8 +303,14 @@ HEXEDIT_WM_NCCREATE(HWND hWnd, CREATESTRUCT *cs) hed->hWndParent = cs->hwndParent; hed->style = cs->style; + hed->ColumnsPerLine = 8; + hed->LeftMargin = 2; + hed->TopMargin = 2; + SetWindowLong(hWnd, 0, (LONG)hed); + hed->hFont = HEXEDIT_GetFixedFont(hed); + return TRUE; } @@ -217,8 +332,6 @@ HEXEDIT_WM_NCDESTROY(PHEXEDIT_DATA hed) static LRESULT HEXEDIT_WM_CREATE(PHEXEDIT_DATA hed) { - hed->LeftMargin = 2; - hed->TopMargin = 2; return 1; } @@ -238,6 +351,62 @@ HEXEDIT_WM_KILLFOCUS(PHEXEDIT_DATA hed) return 0; } +static LRESULT +HEXEDIT_WM_VSCROLL(PHEXEDIT_DATA hed, WORD ThumbPosition, WORD SbCmd) +{ + int ScrollY; + SCROLLINFO si; + + ZeroMemory(&si, sizeof(SCROLLINFO)); + si.cbSize = sizeof(SCROLLINFO); + si.fMask = SIF_ALL; + GetScrollInfo(hed->hWndSelf, SB_VERT, &si); + + ScrollY = si.nPos; + switch(SbCmd) + { + case SB_TOP: + si.nPos = si.nMin; + break; + + case SB_BOTTOM: + si.nPos = si.nMax; + break; + + case SB_LINEUP: + si.nPos--; + break; + + case SB_LINEDOWN: + si.nPos++; + 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; + } + + si.fMask = SIF_POS; + SetScrollInfo(hed->hWndSelf, SB_VERT, &si, TRUE); + GetScrollInfo(hed->hWndSelf, SB_VERT, &si); + + if(si.nPos != ScrollY) + { + ScrollWindow(hed->hWndSelf, 0, (ScrollY - si.nPos) * hed->LineHeight, NULL, NULL); + UpdateWindow(hed->hWndSelf); + } + + return 0; +} + static LRESULT HEXEDIT_WM_SETFONT(PHEXEDIT_DATA hed, HFONT hFont, BOOL bRedraw) { @@ -268,6 +437,94 @@ HEXEDIT_WM_SETFONT(PHEXEDIT_DATA hed, HFONT hFont, BOOL bRedraw) return 0; } +static LRESULT +HEXEDIT_WM_GETFONT(PHEXEDIT_DATA hed) +{ + return (LRESULT)hed->hFont; +} + +static LRESULT +HEXEDIT_WM_PAINT(PHEXEDIT_DATA hed) +{ + PAINTSTRUCT ps; + SCROLLINFO si; + RECT rc; + HBITMAP hbmp, hbmpold; + DWORD nLines, nFirst; + HFONT hOldFont; + HDC hTempDC; + + if(GetUpdateRect(hed->hWndSelf, &rc, FALSE) && (hed->LineHeight > 0)) + { + ZeroMemory(&si, sizeof(SCROLLINFO)); + si.cbSize = sizeof(SCROLLINFO); + si.fMask = SIF_POS; + GetScrollInfo(hed->hWndSelf, SB_VERT, &si); + + nLines = (rc.bottom - rc.top) / hed->LineHeight; + if(nLines > hed->nLines - si.nPos) + { + nLines = hed->nLines - si.nPos; + } + nFirst = rc.top / hed->LineHeight; + + BeginPaint(hed->hWndSelf, &ps); + if(!(hTempDC = CreateCompatibleDC(ps.hdc))) + { + FillRect(ps.hdc, &rc, (HBRUSH)(COLOR_WINDOW + 1)); + goto epaint; + } + if(!(hbmp = CreateCompatibleBitmap(hTempDC, ps.rcPaint.right, ps.rcPaint.bottom))) + { + FillRect(ps.hdc, &rc, (HBRUSH)(COLOR_WINDOW + 1)); + DeleteDC(hTempDC); + goto epaint; + } + hbmpold = SelectObject(hTempDC, hbmp); + hOldFont = SelectObject(hTempDC, hed->hFont); + HEXEDIT_PaintLines(hed, hTempDC, si.nPos, nFirst, nFirst + nLines, &ps.rcPaint); + BitBlt(ps.hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, hTempDC, rc.left, rc.top, SRCCOPY); + SelectObject(hTempDC, hOldFont); + SelectObject(hTempDC, hbmpold); + + DeleteObject(hbmp); + DeleteDC(hTempDC); + + epaint: + EndPaint(hed->hWndSelf, &ps); + } + + return 0; +} + +static LRESULT +HEXEDIT_WM_MOUSEWHEEL(PHEXEDIT_DATA hed, int cyMoveLines, WORD ButtonsDown, LPPOINTS MousePos) +{ + SCROLLINFO si; + int ScrollY; + + SetFocus(hed->hWndSelf); + + si.cbSize = sizeof(SCROLLINFO); + si.fMask = SIF_ALL; + GetScrollInfo(hed->hWndSelf, SB_VERT, &si); + + ScrollY = si.nPos; + + si.fMask = SIF_POS; + si.nPos += cyMoveLines; + SetScrollInfo(hed->hWndSelf, SB_VERT, &si, TRUE); + + GetScrollInfo(hed->hWndSelf, SB_VERT, &si); + if(si.nPos != ScrollY) + { + ScrollWindow(hed->hWndSelf, 0, (ScrollY - si.nPos) * hed->LineHeight, NULL, NULL); + UpdateWindow(hed->hWndSelf); + } + + return 0; +} + LRESULT WINAPI HexEditWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) @@ -277,6 +534,18 @@ HexEditWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) hed = (PHEXEDIT_DATA)GetWindowLong(hWnd, 0); switch(uMsg) { + case WM_ERASEBKGND: + return 0; + + case WM_PAINT: + return HEXEDIT_WM_PAINT(hed); + + case WM_VSCROLL: + return HEXEDIT_WM_VSCROLL(hed, HIWORD(wParam), LOWORD(wParam)); + + case WM_MOUSEWHEEL: + return HEXEDIT_WM_MOUSEWHEEL(hed, ((SHORT)(wParam >> 16) < 0 ? 3 : -3), LOWORD(wParam), &MAKEPOINTS(lParam)); + case HEM_LOADBUFFER: return HEXEDIT_HEM_LOADBUFFER(hed, (PVOID)wParam, (DWORD)lParam); @@ -295,6 +564,9 @@ HexEditWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case WM_SETFONT: return HEXEDIT_WM_SETFONT(hed, (HFONT)wParam, (BOOL)LOWORD(lParam)); + case WM_GETFONT: + return HEXEDIT_WM_GETFONT(hed); + case WM_CREATE: return HEXEDIT_WM_CREATE(hed); @@ -315,3 +587,4 @@ HexEditWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return CallWindowProc(DefWindowProc, hWnd, uMsg, wParam, lParam); } +