📄 hexedit.c
字号:
/*** Message Proc *************************************************************/
static LRESULT
HEXEDIT_WM_NCCREATE(HWND hWnd, CREATESTRUCT *cs)
{
PHEXEDIT_DATA hed;
if(!(hed = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(HEXEDIT_DATA))))
{
return FALSE;
}
hed->hWndSelf = hWnd;
hed->hWndParent = cs->hwndParent;
hed->style = cs->style;
hed->ColumnsPerLine = 8;
hed->LeftMargin = 2;
hed->AddressSpacing = 2;
hed->SplitSpacing = 2;
hed->EditingField = TRUE; /* in hexdump field */
SetWindowLongPtr(hWnd, 0, (DWORD_PTR)hed);
HEXEDIT_Update(hed);
return TRUE;
}
static LRESULT
HEXEDIT_WM_NCDESTROY(PHEXEDIT_DATA hed)
{
if(hed->hBuffer)
{
//while(LocalUnlock(hed->hBuffer));
LocalFree(hed->hBuffer);
}
if(hed->hFont)
{
DeleteObject(hed->hFont);
}
SetWindowLongPtr(hed->hWndSelf, 0, (DWORD_PTR)0);
HeapFree(GetProcessHeap(), 0, hed);
return 0;
}
static LRESULT
HEXEDIT_WM_CREATE(PHEXEDIT_DATA hed)
{
UNREFERENCED_PARAMETER(hed);
return 1;
}
static LRESULT
HEXEDIT_WM_SETFOCUS(PHEXEDIT_DATA hed)
{
CreateCaret(hed->hWndSelf, 0, 1, hed->LineHeight);
HEXEDIT_MoveCaret(hed, FALSE);
ShowCaret(hed->hWndSelf);
return 0;
}
static LRESULT
HEXEDIT_WM_KILLFOCUS(PHEXEDIT_DATA hed)
{
UNREFERENCED_PARAMETER(hed);
DestroyCaret();
return 0;
}
static LRESULT
HEXEDIT_WM_VSCROLL(PHEXEDIT_DATA hed, WORD ThumbPosition, WORD SbCmd)
{
int ScrollY;
SCROLLINFO si;
UNREFERENCED_PARAMETER(ThumbPosition);
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)
{
HDC hDC;
TEXTMETRIC tm;
HFONT hOldFont = 0;
if(hFont == 0)
{
hFont = HEXEDIT_GetFixedFont();
}
hed->hFont = hFont;
hDC = GetDC(hed->hWndSelf);
if(hFont)
{
hOldFont = SelectObject(hDC, hFont);
}
GetTextMetrics(hDC, &tm);
hed->LineHeight = tm.tmHeight;
hed->CharWidth = tm.tmAveCharWidth;
if(hOldFont)
{
SelectObject(hDC, hOldFont);
}
ReleaseDC(hed->hWndSelf, hDC);
if(bRedraw)
{
InvalidateRect(hed->hWndSelf, NULL, TRUE);
}
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;
INT nLines, nFirst;
HFONT hOldFont;
HDC hTempDC;
DWORD height;
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);
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;
}
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;
UNREFERENCED_PARAMETER(ButtonsDown);
UNREFERENCED_PARAMETER(MousePos);
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;
}
static LRESULT
HEXEDIT_WM_GETDLGCODE(LPMSG Msg)
{
UNREFERENCED_PARAMETER(Msg);
return DLGC_WANTARROWS | DLGC_WANTCHARS;
}
static LRESULT
HEXEDIT_WM_LBUTTONDOWN(PHEXEDIT_DATA hed, INT Buttons, POINTS Pt)
{
BOOL NewField;
POINT EditPos;
DWORD Hit = HEXEDIT_HitRegionTest(hed, Pt);
UNREFERENCED_PARAMETER(Buttons);
SetFocus(hed->hWndSelf);
hed->Position = HEXEDIT_PositionFromPoint(hed, Pt, Hit, &EditPos, &NewField);
hed->EditingField = NewField;
hed->CaretCol = EditPos.x;
hed->CaretLine = EditPos.y;
HEXEDIT_MoveCaret(hed, TRUE);
return 0;
}
static BOOL
HEXEDIT_WM_KEYDOWN(PHEXEDIT_DATA hed, INT VkCode)
{
size_t bufsize;
BOOL shift, control;
if(GetKeyState(VK_MENU) & 0x8000)
{
return FALSE;
}
shift = GetKeyState(VK_SHIFT) & 0x8000;
control = GetKeyState(VK_CONTROL) & 0x8000;
bufsize = (hed->hBuffer ? LocalSize(hed->hBuffer) : 0);
switch(VkCode)
{
case VK_LEFT:
if(hed->Position > 0)
{
if(--hed->CaretCol < 0)
{
hed->CaretLine--;
hed->CaretCol = hed->ColumnsPerLine;
}
else
hed->Position--;
}
HEXEDIT_MoveCaret(hed, TRUE);
break;
case VK_RIGHT:
if(hed->Position < (INT)bufsize)
{
if(++hed->CaretCol > hed->ColumnsPerLine)
{
hed->CaretCol = 0;
hed->CaretLine++;
}
else
hed->Position++;
}
HEXEDIT_MoveCaret(hed, TRUE);
break;
case VK_UP:
if(hed->Position > 0)
{
if(hed->CaretLine <= 0)
{
hed->CaretCol = 0;
hed->Position = 0;
}
else
{
hed->CaretLine--;
hed->Position -= hed->ColumnsPerLine;
}
}
HEXEDIT_MoveCaret(hed, TRUE);
break;
case VK_DOWN:
if(hed->Position <= (INT)bufsize)
{
if(hed->CaretLine < hed->nLines - 1)
{
hed->Position += hed->ColumnsPerLine;
hed->CaretLine++;
if(hed->Position > (INT)bufsize)
{
hed->Position = (INT) bufsize;
hed->CaretLine = (hed->nLines > 0 ? hed->nLines - 1 : 0);
hed->CaretCol = (INT) bufsize % hed->ColumnsPerLine;
}
}
else
{
INT tmp = (INT) bufsize % hed->ColumnsPerLine;
hed->Position = (INT) bufsize;
hed->CaretCol = (tmp == 0 ? hed->ColumnsPerLine : tmp);
}
}
HEXEDIT_MoveCaret(hed, TRUE);
break;
}
return FALSE;
}
static LRESULT
HEXEDIT_WM_SIZE(PHEXEDIT_DATA hed, DWORD sType, WORD NewWidth, WORD NewHeight)
{
UNREFERENCED_PARAMETER(sType);
UNREFERENCED_PARAMETER(NewHeight);
UNREFERENCED_PARAMETER(NewWidth);
HEXEDIT_Update(hed);
return 0;
}
INT_PTR CALLBACK
HexEditWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
PHEXEDIT_DATA hed;
hed = (PHEXEDIT_DATA)(LONG_PTR)GetWindowLongPtr(hWnd, (DWORD_PTR)0);
switch(uMsg)
{
case WM_ERASEBKGND:
return TRUE;
case WM_PAINT:
return HEXEDIT_WM_PAINT(hed);
case WM_KEYDOWN:
return HEXEDIT_WM_KEYDOWN(hed, (INT)wParam);
case WM_VSCROLL:
return HEXEDIT_WM_VSCROLL(hed, HIWORD(wParam), LOWORD(wParam));
case WM_SIZE:
return HEXEDIT_WM_SIZE(hed, (DWORD)wParam, LOWORD(lParam), HIWORD(lParam));
case WM_LBUTTONDOWN:
return HEXEDIT_WM_LBUTTONDOWN(hed, (INT)wParam, MAKEPOINTS(lParam));
case WM_MOUSEWHEEL:
{
UINT nScrollLines = 3;
int delta = 0;
SystemParametersInfoW(SPI_GETWHEELSCROLLLINES, 0, &nScrollLines, 0);
delta -= (SHORT)HIWORD(wParam);
if(abs(delta) >= WHEEL_DELTA && nScrollLines != 0)
{
return HEXEDIT_WM_MOUSEWHEEL(hed, nScrollLines * (delta / WHEEL_DELTA), LOWORD(wParam), &MAKEPOINTS(lParam));
}
break;
}
case HEM_LOADBUFFER:
return HEXEDIT_HEM_LOADBUFFER(hed, (PVOID)wParam, (DWORD)lParam);
case HEM_COPYBUFFER:
return HEXEDIT_HEM_COPYBUFFER(hed, (PVOID)wParam, (DWORD)lParam);
case HEM_SETMAXBUFFERSIZE:
return HEXEDIT_HEM_SETMAXBUFFERSIZE(hed, (DWORD)lParam);
case WM_SETFOCUS:
return HEXEDIT_WM_SETFOCUS(hed);
case WM_KILLFOCUS:
return HEXEDIT_WM_KILLFOCUS(hed);
case WM_GETDLGCODE:
return HEXEDIT_WM_GETDLGCODE((LPMSG)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);
case WM_NCCREATE:
if(!hed)
{
return HEXEDIT_WM_NCCREATE(hWnd, (CREATESTRUCT*)lParam);
}
break;
case WM_NCDESTROY:
if(hed)
{
return HEXEDIT_WM_NCDESTROY(hed);
}
break;
}
return CallWindowProc(DefWindowProc, hWnd, uMsg, wParam, lParam);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -