📄 hexedvw.cpp
字号:
// hexedvw.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "editcmd.h"
#include "hexedvw.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
TCHAR hextable[16] = {_T ('0'), _T ('1'), _T ('2'), _T ('3'), _T ('4'), _T ('5'), _T ('6'), _T ('7'),
_T ('8'), _T ('9'), _T ('A'), _T ('B'), _T ('C'), _T ('D'), _T ('E'), _T ('F')};
#define TOHEX(a, b) {*b++ = hextable[a >> 4];*b++ = hextable[a&0xf];}
/////////////////////////////////////////////////////////////////////////////
// CHexEditView
#define DEMO
IMPLEMENT_DYNCREATE(CHexEditView, CView)
static LPBYTE s_pData = NULL; // pointer to data
static int s_length = 0; // length of data
CHexEditView::CHexEditView()
{
m_pData = &s_pData;
m_length = &s_length;
m_topindex = 0;
m_bpr = 16; // byte per row
m_lpp = 1;
m_dwFlags = (HVW_SHOW_ADDRESS|HVW_SHOW_ASCII|HVW_SHOW_HEX|HVW_WIDE_ADDRESS);
m_offAddress = 0;
m_offHex = 0;
m_offAscii = 0;
m_dwFlags |= HVW_UPDATE; // update font info
m_currentMode = EDIT_NONE;
m_editPos.x = m_editPos.y = 0;
m_currentAddress = 0;
m_dwFlags |= HVW_HALF_PAGE;
m_selStart = 0xffffffff;
m_selEnd = 0xffffffff;
m_Font.CreateFont(-12, 0,0,0,0,0,0,0,0,0,0,0,0, _T ("Courier New"));
}
CHexEditView::~CHexEditView()
{
}
BEGIN_MESSAGE_MAP(CHexEditView, CView)
ON_WM_CONTEXTMENU()
//{{AFX_MSG_MAP(CHexEditView)
ON_WM_CHAR()
ON_WM_KILLFOCUS()
ON_WM_PAINT()
ON_WM_SETFOCUS()
ON_WM_SIZE()
ON_WM_VSCROLL()
ON_WM_HSCROLL()
ON_WM_GETDLGCODE()
ON_WM_ERASEBKGND()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONDBLCLK()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
ON_WM_KEYDOWN()
ON_COMMAND(ID_EDIT_CLEAR, OnEditClear)
ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
ON_COMMAND(ID_EDIT_CUT, OnEditCut)
ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
ON_COMMAND(ID_EDIT_SELECT_ALL, OnEditSelectAll)
ON_COMMAND(ID_EDIT_UNDO, OnEditUndo)
ON_COMMAND (ID_READ_ONLY, OnReadOnly)
ON_UPDATE_COMMAND_UI (ID_READ_ONLY, OnReadOnly)
ON_COMMAND (ID_FORMAT_SHOW_ADDRESS, OnFormatShowAddress)
ON_UPDATE_COMMAND_UI (ID_FORMAT_SHOW_ADDRESS, OnUpdateFormatShowAddress)
ON_COMMAND (ID_FORMAT_SHOW_ASCII, OnFormatShowAscii)
ON_UPDATE_COMMAND_UI (ID_FORMAT_SHOW_ASCII, OnUpdateFormatShowAscii)
ON_COMMAND (ID_FORMAT_SHOW_HEX, OnFormatShowHex)
ON_UPDATE_COMMAND_UI (ID_FORMAT_SHOW_HEX, OnUpdateFormatShowHex)
ON_COMMAND (ID_FORMAT_WIDE_ADDRESS, OnFormatWideAddress)
ON_UPDATE_COMMAND_UI (ID_FORMAT_WIDE_ADDRESS, OnUpdateFormatWideAddress)
ON_COMMAND_RANGE (ID_FORMAT_BPR_FIRST, ID_FORMAT_BPR_LAST, OnBpr)
ON_UPDATE_COMMAND_UI_RANGE (ID_FORMAT_BPR_FIRST, ID_FORMAT_BPR_LAST, OnUpdateBpr)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CHexEditView message handlers
void CHexEditView::OnDraw(CDC* pDC)
{
CDocument* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
}
void CHexEditView::OnPaint()
{
CPaintDC pdc(this); // device context for painting
CRect rc;
GetClientRect(rc);
CDC dc;
dc.CreateCompatibleDC(CDC::FromHandle(pdc.m_ps.hdc));
CBitmap bm;
bm.CreateCompatibleBitmap(CDC::FromHandle(pdc.m_ps.hdc), rc.Width(), rc.Height());
dc.SelectObject(bm);
CBrush b;
b.CreateSolidBrush(RGB(0xff,0xff,0xff));
dc.FillRect(rc, &b);
ASSERT(m_currentAddress >= 0);
ASSERT(m_topindex >= 0);
dc.SelectObject(m_Font);
int height = 0;
int x,y;
TCHAR buf[256];
x = rc.TopLeft().x;
y = rc.TopLeft().y;
dc.SetBoundsRect(&rc, DCB_DISABLE);
if(m_pData && *m_pData)
{
//
// get char dimensions
//
if(m_dwFlags & HVW_UPDATE)
{
dc.GetCharWidth(_T ('0'), _T ('0'), &m_nullWidth);
CSize sz = dc.GetTextExtent(_T ("0"), 1);
m_lineHeight = sz.cy;
m_offHex = m_dwFlags & HVW_SHOW_ADDRESS ? (m_dwFlags & HVW_WIDE_ADDRESS ? m_nullWidth * 9 : m_nullWidth * 5) : 0;
m_offAscii = m_dwFlags & HVW_SHOW_ADDRESS ? (m_dwFlags & HVW_WIDE_ADDRESS ? m_nullWidth * 9 : m_nullWidth * 5) : 0;
m_offAscii += m_dwFlags & HVW_SHOW_HEX ? (m_bpr * 3 * m_nullWidth) : 0;
m_lpp = rc.Height() / m_lineHeight;
m_dwFlags &= ~HVW_HALF_PAGE;
if(m_lpp * m_bpr > *m_length)
{
m_lpp = (*m_length + (m_bpr/2)) / m_bpr ;
if(*m_length % m_bpr != 0)
{
m_dwFlags |= HVW_HALF_PAGE;
m_lpp++;
}
}
m_dwFlags &= ~HVW_UPDATE;
UpdateScrollbars();
}
TRACE(_T ("%i %i\n"), m_topindex, m_selStart);
height = rc.Height() / m_lineHeight;
height *= m_lineHeight;
if(m_dwFlags & HVW_SHOW_ADDRESS)
{
TCHAR fmt[8] = {_T ('%'), _T ('0'), _T ('8'), _T ('l'), _T ('X')};
fmt[2] = m_dwFlags & HVW_WIDE_ADDRESS ? _T ('8') : _T ('4');
int w = m_dwFlags & HVW_WIDE_ADDRESS ? 8 : 4;
y = 0;
CRect rcd = rc;
rcd.TopLeft().x = m_offAddress;
for(int i = m_topindex; (i < *m_length) && (rcd.TopLeft().y < height); i+= m_bpr)
{
_stprintf(buf, fmt, i);
dc.DrawText(buf, w, rcd, DT_LEFT|DT_TOP|DT_SINGLELINE|DT_NOPREFIX);
rcd.TopLeft().y += m_lineHeight;
}
}
if(m_dwFlags & HVW_SHOW_HEX)
{
y = 0;
CRect rcd = rc;
rcd.TopLeft().x = x = m_offHex;
if(m_selStart != 0xffffffff && (m_currentMode == EDIT_HIGH || m_currentMode == EDIT_LOW))
{
int i;
int n = 0;
int selStart = m_selStart, selEnd = m_selEnd;
if(selStart > selEnd)
selStart ^= selEnd ^= selStart ^= selEnd;
for(i = m_topindex; (i < selStart) && (y < height); i++)
{
LPTSTR p = buf;
TOHEX((*m_pData)[i], p);
*p++ = _T (' ');
dc.TextOut(x, y, buf, 3);
x += m_nullWidth * 3;
n++;
if(n == m_bpr)
{
n = 0;
x = m_offHex;
y += m_lineHeight;
}
}
dc.SetTextColor(GetSysColor(COLOR_HIGHLIGHTTEXT));
dc.SetBkColor(GetSysColor(COLOR_HIGHLIGHT));
for(; (i < selEnd) && (i < *m_length) && (y < height); i++)
{
LPTSTR p = buf;
TOHEX((*m_pData)[i], p);
*p++ = _T (' ');
dc.TextOut(x, y, buf, 3);
x += m_nullWidth * 3;
n++;
if(n == m_bpr)
{
n = 0;
x = m_offHex;
y += m_lineHeight;
}
}
dc.SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
dc.SetBkColor(GetSysColor(COLOR_WINDOW));
for(; (i < *m_length) && (y < height); i++)
{
LPTSTR p = buf;
TOHEX((*m_pData)[i], p);
*p++ = _T (' ');
dc.TextOut(x, y, buf, 3);
x += m_nullWidth * 3;
n++;
if(n == m_bpr)
{
n = 0;
x = m_offHex;
y += m_lineHeight;
}
}
}
else
{
for(int i = m_topindex; (i < *m_length) && (rcd.TopLeft().y < height);)
{
LPTSTR p = buf;
for(int n = 0; (n < m_bpr) && (i < *m_length); n++)
{
TOHEX((*m_pData)[i], p);
*p++ = _T (' ');
i++;
}
while(n < m_bpr)
{
*p++ = _T (' '); *p++ = _T (' '); *p++ = _T (' ');
n++;
}
dc.DrawText(buf, m_bpr*3, rcd, DT_LEFT|DT_TOP|DT_SINGLELINE|DT_NOPREFIX);
rcd.TopLeft().y += m_lineHeight;
}
}
}
if(m_dwFlags & HVW_SHOW_ASCII)
{
y = 0;
CRect rcd = rc;
rcd.TopLeft().x = x = m_offAscii;
if(m_selStart != 0xffffffff && m_currentMode == EDIT_ASCII)
{
int i;
int n = 0;
int selStart = m_selStart, selEnd = m_selEnd;
if(selStart > selEnd)
selStart ^= selEnd ^= selStart ^= selEnd;
for(i = m_topindex; (i < selStart) && (y < height); i++)
{
buf[0] = isprint((*m_pData)[i]) ? (*m_pData)[i] : _T ('.');
dc.TextOut(x, y, buf, 1);
x += m_nullWidth;
n++;
if(n == m_bpr)
{
n = 0;
x = m_offAscii;
y += m_lineHeight;
}
}
dc.SetTextColor(GetSysColor(COLOR_HIGHLIGHTTEXT));
dc.SetBkColor(GetSysColor(COLOR_HIGHLIGHT));
for(; (i < selEnd) && (y < height); i++)
{
buf[0] = isprint((*m_pData)[i]) ? (*m_pData)[i] : _T ('.');
dc.TextOut(x, y, buf, 1);
x += m_nullWidth;
n++;
if(n == m_bpr)
{
n = 0;
x = m_offAscii;
y += m_lineHeight;
}
}
dc.SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
dc.SetBkColor(GetSysColor(COLOR_WINDOW));
for(; (i < *m_length) && y < height; i++)
{
buf[0] = isprint((*m_pData)[i]) ? (*m_pData)[i] : _T ('.');
dc.TextOut(x, y, buf, 1);
x += m_nullWidth;
n++;
if(n == m_bpr)
{
n = 0;
x = m_offAscii;
y += m_lineHeight;
}
}
}
else
{
for(int i = m_topindex; (i < *m_length) && (rcd.TopLeft().y < height);)
{
LPTSTR p = buf;
for(int n = 0; (n < m_bpr) && (i < *m_length); n++)
{
*p++ = isprint((*m_pData)[i]) ? (*m_pData)[i] : _T ('.');
i++;
}
dc.DrawText(buf, n, rcd, DT_LEFT|DT_TOP|DT_SINGLELINE|DT_NOPREFIX);
rcd.TopLeft().y += m_lineHeight;
}
}
}
}
pdc.BitBlt(0, 0, rc.Width(), rc.Height(), &dc, 0, 0, SRCCOPY);
}
void CHexEditView::OnSetFocus(CWnd* pOldWnd)
{
if(m_pData && *m_pData && !IsSelected())
{
if(m_editPos.x == 0 && (m_dwFlags & HVW_SHOW_ADDRESS))
CreateAddressCaret();
else
CreateEditCaret();
SetCaretPos(m_editPos);
ShowCaret();
}
CWnd::OnSetFocus(pOldWnd);
}
void CHexEditView::OnKillFocus(CWnd* pNewWnd)
{
DestroyCaret();
CWnd::OnKillFocus(pNewWnd);
}
void CHexEditView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
}
void CHexEditView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
pScrollBar;
if(!m_pData || !*m_pData)
return;
int oa = m_topindex;
switch(nSBCode)
{
case SB_LINEDOWN:
if(m_topindex < *m_length - m_lpp*m_bpr)
{
//ScrollWindow(0, -m_lineHeight, rc);
m_topindex += m_bpr;
RedrawWindow();
}
break;
case SB_LINEUP:
if(m_topindex > 0)
{
//ScrollWindow(0, m_lineHeight, rc);
m_topindex -= m_bpr;
RedrawWindow();
}
break;
case SB_PAGEDOWN:
if(m_topindex < *m_length - m_lpp*m_bpr)
{
m_topindex += m_bpr * m_lpp;
if(m_topindex > *m_length - m_lpp*m_bpr)
m_topindex = *m_length - m_lpp*m_bpr;
RedrawWindow();
}
break;
case SB_PAGEUP:
if(m_topindex > 0)
{
m_topindex -= m_bpr * m_lpp;
if(m_topindex < 0)
m_topindex = 0;
RedrawWindow();
}
break;
case SB_THUMBTRACK:
m_topindex = nPos * m_bpr;
RedrawWindow();
break;
}
::SetScrollPos(this->m_hWnd, SB_VERT, m_topindex / m_bpr, TRUE);
if(!(m_dwFlags & HVW_NO_ADDRESS_CHANGE))
m_currentAddress += (m_topindex - oa);
RepositionCaret(m_currentAddress);
}
void CHexEditView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
nSBCode;nPos; pScrollBar;
}
UINT CHexEditView::OnGetDlgCode()
{
return DLGC_WANTALLKEYS;
}
BOOL CHexEditView::PreCreateWindow(CREATESTRUCT& cs)
{
// cs.style |= WS_HSCROLL|WS_VSCROLL;
// cs.style &= ~(WS_HSCROLL|WS_VSCROLL);
return CView::PreCreateWindow(cs);
}
BOOL CHexEditView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
{
// dwStyle |= WS_HSCROLL|WS_VSCROLL;
dwStyle &= ~(WS_HSCROLL|WS_VSCROLL);
BOOL bRet = CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);
if(bRet)
SetFont(&m_Font);
return bRet;
}
BOOL CHexEditView::OnEraseBkgnd(CDC* pDC)
{
pDC;
return TRUE;
}
void CHexEditView::GetOptions(BOOL &a, BOOL &h, BOOL &c, BOOL &w, BOOL &r)
{
a = (m_dwFlags & HVW_SHOW_ADDRESS) != 0;
h = (m_dwFlags & HVW_SHOW_HEX) != 0;
c = (m_dwFlags & HVW_SHOW_ASCII) != 0;
w = (m_dwFlags & HVW_WIDE_ADDRESS) != 0;
r = (m_dwFlags & HVW_READ_ONLY) != 0;
}
void CHexEditView::SetOptions(BOOL a, BOOL h, BOOL c, BOOL w, BOOL r)
{
if (a)
m_dwFlags |= HVW_SHOW_ADDRESS;
else
m_dwFlags &= ~HVW_SHOW_ADDRESS;
if (h)
m_dwFlags |= HVW_SHOW_HEX;
else
m_dwFlags &= ~HVW_SHOW_HEX;
if (c)
m_dwFlags |= HVW_SHOW_ASCII;
else
m_dwFlags &= ~HVW_SHOW_ASCII;
if (w)
m_dwFlags |= HVW_WIDE_ADDRESS;
else
m_dwFlags &= ~HVW_WIDE_ADDRESS;
if (r)
m_dwFlags |= HVW_READ_ONLY;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -