display hex dump of the binary data

svn path=/trunk/; revision=9769
This commit is contained in:
Thomas Bluemel
2004-06-20 18:36:31 +00:00
parent 8350c577cb
commit c86604cbe4
+278 -5
View File
@@ -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);
}