// HexEdit.cpp : implementation file
//
#include "stdafx.h"
//#include "CommWizard.h"
#include "HexEdit.h"
#include <ctype.h>
#include <afxole.h>
#include <afxdisp.h>
#include "resource.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
char hextable[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
#define TOHEX(a, b) {*b++ = hextable[a >> 4];*b++ = hextable[a&0xf];}
/////////////////////////////////////////////////////////////////////////////
// CHexEdit
CHexEdit::CHexEdit()
{
#if !defined(DEMO)
m_pData = NULL; // pointer to data
m_length = 0; // length of data
#else
m_pData = (LPBYTE)malloc(0x40);
for(int i = 0; i < 0x40; i++)
m_pData[i] = i;
m_length = 0x40;
#endif
m_topindex = 0;
m_bpr = 8; // byte per row
m_lpp = 1;
m_bShowHex = TRUE;
m_bShowAscii = TRUE;
m_bShowAddress = TRUE;
m_bAddressIsWide= TRUE; // 4/8 byte address
m_offAddress = 0;
m_offHex = 0;
m_offAscii = 0;
m_bUpdate = TRUE; // update font info
m_bNoAddressChange = FALSE;
m_currentMode = EDIT_NONE;
m_editPos.x = m_editPos.y = 0;
m_currentAddress = 0;
m_bHalfPage = TRUE;
m_selStart = 0xffffffff;
m_selEnd = 0xffffffff;
m_Font.CreateFont(-12, 0,0,0,0,0,0,0,0,0,0,0,0, "Courier New");
AfxOleInit();
}
CHexEdit::~CHexEdit()
{
}
BEGIN_MESSAGE_MAP(CHexEdit, CEdit)
ON_WM_CONTEXTMENU()
//{{AFX_MSG_MAP(CHexEdit)
ON_WM_CHAR()
ON_WM_KILLFOCUS()
ON_WM_PAINT()
ON_WM_SETFOCUS()
ON_WM_VSCROLL()
ON_WM_LBUTTONDOWN()
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_WM_ERASEBKGND()
ON_WM_LBUTTONDBLCLK()
ON_WM_HSCROLL()
ON_WM_CONTEXTMENU()
ON_WM_SIZE()
ON_WM_GETDLGCODE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CHexEdit message handlers
void CHexEdit::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;
char buf[256];
x = rc.TopLeft().x;
y = rc.TopLeft().y;
dc.SetBoundsRect(&rc, DCB_DISABLE);
if(m_pData)
{
//
// get char dimensions
//
if(m_bUpdate)
{
dc.GetCharWidth('0', '0', &m_nullWidth);
CSize sz = dc.GetTextExtent("0", 1);
m_lineHeight = sz.cy;
m_offHex = m_bShowAddress ? (m_bAddressIsWide ? m_nullWidth * 9 : m_nullWidth * 5) : 0;
m_offAscii = m_bShowAddress ? (m_bAddressIsWide ? m_nullWidth * 9 : m_nullWidth * 5) : 0;
m_offAscii += m_bShowHex ? (m_bpr * 3 * m_nullWidth) : 0;
m_lpp = rc.Height() / m_lineHeight;
m_bHalfPage = FALSE;
if(m_lpp * m_bpr > m_length)
{
m_lpp = (m_length + (m_bpr/2)) / m_bpr ;
if(m_length % m_bpr != 0)
{
m_bHalfPage = TRUE;
m_lpp++;
}
}
m_bUpdate = FALSE;
UpdateScrollbars();
}
TRACE("%i %i\n", m_topindex, m_selStart);
height = rc.Height() / m_lineHeight;
height *= m_lineHeight;
if(m_bShowAddress)
{
char fmt[8] = {'%','0','8','l','X'};
fmt[2] = m_bAddressIsWide ? '8' : '4';
int w = m_bAddressIsWide ? 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)
{
sprintf(buf, fmt, i);
dc.DrawText(buf, w, rcd, DT_LEFT|DT_TOP|DT_SINGLELINE|DT_NOPREFIX);
rcd.TopLeft().y += m_lineHeight;
}
}
if(m_bShowHex)
{
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++)
{
char* p = &buf[0];
TOHEX(m_pData[i], p);
*p++ = ' ';
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++)
{
char* p = &buf[0];
TOHEX(m_pData[i], p);
*p++ = ' ';
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++)
{
char* p = &buf[0];
TOHEX(m_pData[i], p);
*p++ = ' ';
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);)
{
char* p = &buf[0];
int n;
for(n = 0; (n < m_bpr) && (i < m_length); n++)
{
TOHEX(m_pData[i], p);
*p++ = ' ';
i++;
}
while( n< m_bpr)
{
*p++ = ' '; *p++ = ' '; *p++ = ' ';
n++;
}
dc.DrawText(buf, m_bpr*3, rcd, DT_LEFT|DT_TOP|DT_SINGLELINE|DT_NOPREFIX);
rcd.TopLeft().y += m_lineHeight;
}
}
}
if(m_bShowAscii)
{
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] : '.';
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] : '.';
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] : '.';
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);)
{
char* p = &buf[0];
int n;
for(n = 0; (n < m_bpr) && (i < m_length); n++)
{
*p++ = isprint(m_pData[i]) ? m_pData[i] : '.';
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(),