⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hexeditbase.cpp

📁 EZ-USB 开发板完整资料
💻 CPP
📖 第 1 页 / 共 5 页
字号:
///////////////////////////////////////////////////////////////////////////
// Implementation
//-------------------------------------------------------------------------
// file........................hexeditbase.cpp
//-------------------------------------------------------------------------
// for more information check the definition file hexeditbase.h
///////////////////////////////////////////////////////////////////////////
// history:
//
// date	     | signature | descritpion of modification
//-----------+-----------+-------------------------------------------------
// 11.01.01  | kuendig   | version 0.0.0.1 
//           |           | - first test version
//-----------+-----------+-------------------------------------------------
// 13.01.01  | kuendig   | version 0.0.0.2 
//           |           | - context menue 
//           |           |   use OnExtendContextMenu to extend the 
//           |           |   context menue in a derived class
//           |           | - paste methode
//           |           | - Windows-Class registering
//           |           |   - CHexEditBase: for use with DDX / Edit-Control
//           |           |   - CHexEditBase_SC: when not using DDX
//           |           | - several small changes
//-----------+-----------+-------------------------------------------------
// 19.01.01  | kuendig   | version 0.0.0.3
//           |           | - bug in CreateHighlightingPolygons
//           |           |   (when scrolling highlighting out of window on 
//           |           |   top, sometimes the address got overpainted
//           |           |   by some parts of the highlighting section)
//-----------+-----------+-------------------------------------------------
// 04.02.01  | kuendig   | version 1.0.0.0 (official release)
//           |           | - MakeVisible is now smarter
//           |           | - SetFont, GetFont WM_SETFONT, WM_GETFONT works now
//-----------+-----------+-------------------------------------------------
// 24.05.01  | kuendig   | version 1.1.0.0
//           |           | - Fixed the 16Bit Scrollrange limitation when
//           |           |   thumbtracking (see OnVScroll)
//           |           | - Modified SetFont to only accept fixed-pitched
//           |           |   fonts
//           |           | - Replaced some GetSafeHwnd() with 
//           |           |   ::IsWindow(m_hWnd), since it's rather what's
//           |           |   beeing checked. (Even when GetSafeHwnd worked
//           |           |   in most of the cases)
//           |           | - Call DestroyWnd from the Destructor, to get
//           |           |   rid of the TRACE from "CWnd::~CWnd ..."
//-----------+-----------+-------------------------------------------------
// --.--.--  |           | 
//-----------+-----------+-------------------------------------------------
// --.--.--  |           | 
//-----------+-----------+-------------------------------------------------
// --.--.--  |           | 
//-----------+-----------+-------------------------------------------------
// --.--.--  |           | 
//-----------+-----------+-------------------------------------------------
// --.--.--  |           | 
//-----------+-----------+-------------------------------------------------
// --.--.--  |           | 
//-----------+-----------+-------------------------------------------------
///////////////////////////////////////////////////////////////////////////
//
///////////////////////////////////////////////////////////////////////////



/////////////////////////////////////////////////////////////////////////////
// includes
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <memory>
#include <afxole.h>
#include "HexEditBase.h"


/////////////////////////////////////////////////////////////////////////////
// defines
/////////////////////////////////////////////////////////////////////////////
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

// control-layout customization (low-level)
#define ADR_DATA_SPACE				5
#define DATA_ASCII_SPACE			5
#define CONTROL_BORDER_SPACE		5

// boundaries and special values
#define MAX_HIGHLIGHT_POLYPOINTS	8
#define UM_SETSCROLRANGE			(WM_USER + 0x5000)
#define MOUSEREP_TIMER_TID			0x400
#define MOUSEREP_TIMER_ELAPSE		0x5

// clipboard format
#define CF_BINDATA_HEXCTRL			_T("BinaryData")

// windows-class-name
#define HEXEDITBASECTRL_CLASSNAME	_T("CHexEditBase")
#define HEXEDITBASECTRL_CLSNAME_SC	_T("CHexEditBase_SC") //self creating

// macros
#define NORMALIZE_SELECTION(beg, end) if(beg>end){UINT tmp = end; end=beg; beg=tmp; }



/////////////////////////////////////////////////////////////////////////////
// global data
/////////////////////////////////////////////////////////////////////////////
const char tabHexCharacters[16] = {
	'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' }; 




	
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// class CHexEditBase
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
	
IMPLEMENT_DYNCREATE(CHexEditBase, CWnd)

BEGIN_MESSAGE_MAP(CHexEditBase, CWnd)
	//{{AFX_MSG_MAP(CHexEditBase)
	ON_MESSAGE(UM_SETSCROLRANGE, OnUmSetScrollRange)
	ON_MESSAGE(WM_CHAR, OnWMChar)
	ON_MESSAGE(WM_SETFONT, OnWMSetFont)
	ON_MESSAGE(WM_GETFONT, OnWMGetFont)
	ON_WM_DESTROY()
	ON_WM_TIMER()
	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_WM_MOUSEWHEEL()
	ON_WM_CONTEXTMENU()
	ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
	ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
	ON_COMMAND(ID_EDIT_SELECT_ALL, OnEditSelectAll)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


CHexEditBase::CHexEditBase() :
	m_bSelfCleanup(false),
	m_bDeleteData(true),
	m_pData(NULL), 
	m_nLength(0), 
	m_nAdrSize(8), 
	m_nBytesPerRow(16), 
	m_nCurCaretWidth(0),
	m_nCurCaretHeight(0), 
	m_bHasCaret(false), 
	m_bHighBits(true),
	m_bReadOnly(false), 
	m_nHighlightedBegin(NOSECTION_VAL), 
	m_nHighlightedEnd(NOSECTION_VAL),
	m_nSelectingBeg(NOSECTION_VAL),
	m_nSelectingEnd(NOSECTION_VAL),
	m_nSelectionBegin(NOSECTION_VAL),
	m_nSelectionEnd(NOSECTION_VAL), 
	m_tAdrBkgCol(RGB(90,0,0)), 
	m_tAdrTxtCol(RGB(255,0,0)), 
	m_tAsciiBkgCol(RGB(0,20,0)), 
	m_tAsciiTxtCol(RGB(0,255,0)),
	m_tHighlightBkgCol(RGB(0,90,210)), 
	m_tHighlightTxtCol(RGB(0,200,0)), 
	m_tHighlightFrameCol(RGB(0,255,255)),
	m_tHexTxtCol(RGB(0,0,255)), 
	m_tHexBkgCol(RGB(180,210,190)), 
	m_tNotUsedBkCol(RGB(210,210,210)),
	m_nCurrentAddress(0),
	m_bAutoBytesPerRow(false), 
	m_bRecalc(true),
	m_nScrollPostionX(0), 
	m_nScrollRangeX(0), 
	m_nScrollPostionY(0), 
	m_nScrollRangeY(0),
	m_bShowAscii(false), 
	m_bInputAscii(false), 
	m_bShowAddress(false), 
	m_bShowCategory(false),
	m_nMouseRepSpeed(0),
	m_iMouseRepDelta(0),
	m_nMouseRepCounter(0),
	m_bIsMouseRepActive(false),
	m_cDragRect(0,0,0,0),
	m_cContextCopy("Copy"),
	m_cContextPaste("Paste")

{
	memset(&m_tPaintDetails, 0, sizeof(PAINTINGDETAILS));
	m_tSelectedNoFocusTxtCol = GetSysColor(COLOR_WINDOWTEXT);
	m_tSelectedNoFocusBkgCol = GetSysColor(COLOR_BTNFACE);
	m_tSelectedFousTxtCol = GetSysColor(COLOR_HIGHLIGHTTEXT);
	m_tSelectedFousBkgCol = GetSysColor(COLOR_HIGHLIGHT);
	if(!m_cFont.CreateStockObject(ANSI_FIXED_FONT)) {
		AfxThrowResourceException();
	}
	
	// register clipboard format
	m_nBinDataClipboardFormat = RegisterClipboardFormat(CF_BINDATA_HEXCTRL);
	ASSERT(m_nBinDataClipboardFormat != 0);

	// try to load strings from the resources
#ifdef IDS_CONTROL_COPY
	if(!m_cContextCopy.LoadString(IDS_CONTROL_COPY)) {
		cString = _T("Copy");
	}
#endif
#ifdef IDS_CONTROL_PASTE
	if(!m_cContextPaste.LoadString(IDS_CONTROL_PASTE)) {
		cString = _T("Paste");
	}
#endif

	// register windows-class
	RegisterClass();
}

CHexEditBase::~CHexEditBase()
{
	if(m_bDeleteData) {
		delete []m_pData;
	}
    if(m_cFont.m_hObject != NULL) {
		m_cFont.DeleteObject();
	}
	if(::IsWindow(m_hWnd)) {
		DestroyWindow();
	}
}

BOOL CHexEditBase::Create(LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
{
	return CWnd::Create(HEXEDITBASECTRL_CLASSNAME, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);
}

BOOL CHexEditBase::CreateEx(DWORD dwExStyle, LPCTSTR lpszWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hwndParent, HMENU nIDorHMenu, LPVOID lpParam)
{
	return CWnd::CreateEx(dwExStyle, HEXEDITBASECTRL_CLASSNAME, lpszWindowName, dwStyle, x, y, nWidth, nHeight, hwndParent, nIDorHMenu, lpParam);
}

BOOL CHexEditBase::CreateEx(DWORD dwExStyle, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, LPVOID lpParam)
{
	return CWnd::CreateEx(dwExStyle, HEXEDITBASECTRL_CLASSNAME, lpszWindowName, dwStyle, rect, pParentWnd, nID, lpParam);
}

void CHexEditBase::RegisterClass()
{
	// register windowsclass
	WNDCLASS tWndClass;
	if(!::GetClassInfo(AfxGetInstanceHandle(), HEXEDITBASECTRL_CLASSNAME, &tWndClass))
	{
		memset(&tWndClass, 0, sizeof(WNDCLASS));
        tWndClass.style = CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW;
		tWndClass.lpfnWndProc = ::DefWindowProc;
		tWndClass.hInstance = AfxGetInstanceHandle();
		tWndClass.hCursor = ::LoadCursor(NULL, IDC_IBEAM);
		tWndClass.lpszClassName = HEXEDITBASECTRL_CLASSNAME;

		if(!AfxRegisterClass(&tWndClass)) {
			AfxThrowResourceException();
		}
	}
	if(!::GetClassInfo(AfxGetInstanceHandle(), HEXEDITBASECTRL_CLSNAME_SC, &tWndClass))
	{
		memset(&tWndClass, 0, sizeof(WNDCLASS));
        tWndClass.style = CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW;
		tWndClass.lpfnWndProc = CHexEditBase::WndProc;
		tWndClass.hInstance = AfxGetInstanceHandle();
		tWndClass.hCursor = ::LoadCursor(NULL, IDC_IBEAM);
		tWndClass.lpszClassName = HEXEDITBASECTRL_CLSNAME_SC;

		if(!AfxRegisterClass(&tWndClass)) {
			AfxThrowResourceException();
		}
	}	
}

LRESULT CALLBACK CHexEditBase::WndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
	if(nMsg == WM_NCCREATE) {		
		ASSERT(FromHandlePermanent(hWnd) == NULL );
		CHexEditBase* pControl = NULL;
		try {
			pControl = new CHexEditBase();
			pControl->m_bSelfCleanup = true;
		} catch(...) { 
			return FALSE;
		}
		if(pControl == NULL) {
			return FALSE;
		}
		if(!pControl->SubclassWindow(hWnd)) { 
			TRACE("CHexEditBase::WndProc: ERROR: couldn't subclass window (WM_NCCREATE)\n");
			delete pControl;
			return FALSE;
		}
		return TRUE;
	}
	return ::DefWindowProc(hWnd, nMsg, wParam, lParam);
}

void CHexEditBase::NotifyParent(WORD wNBotifictionCode)
{
	CWnd *pWnd = GetParent();
	if(pWnd != NULL) {
		pWnd->SendMessage(WM_COMMAND, MAKEWPARAM((WORD)GetDlgCtrlID(), wNBotifictionCode), (LPARAM)m_hWnd);
	}
}

void CHexEditBase::PostNcDestroy() 
{
	if(m_bSelfCleanup) {
		m_bSelfCleanup = false;
		delete this;
	}
}

void CHexEditBase::OnDestroy() 
{
	CWnd::OnDestroy();
}

void CHexEditBase::CalculatePaintingDetails(CDC& cDC)
{
	ASSERT(m_nScrollPostionY >= 0);

	CFont *pOldFont;
	m_bRecalc = false;

	// Get size information
	int iWidth;
	pOldFont = cDC.SelectObject(&m_cFont);
	cDC.GetCharWidth('0', '0', &iWidth);
	ASSERT(iWidth > 0);
	m_tPaintDetails.nCharacterWidth = iWidth;
	CSize cSize = cDC.GetTextExtent("0", 1);
	ASSERT(cSize.cy > 0);
	m_tPaintDetails.nLineHeight = cSize.cy;

	// count of visible lines
	GetClientRect(m_tPaintDetails.cPaintingRect);
	if(GetStyle() & ES_MULTILINE) {
		m_tPaintDetails.cPaintingRect.InflateRect(-CONTROL_BORDER_SPACE, -CONTROL_BORDER_SPACE, 
			-CONTROL_BORDER_SPACE, -CONTROL_BORDER_SPACE);
		if(m_tPaintDetails.cPaintingRect.right < m_tPaintDetails.cPaintingRect.left) {
			m_tPaintDetails.cPaintingRect.right = m_tPaintDetails.cPaintingRect.left;
		}
		if(m_tPaintDetails.cPaintingRect.bottom < m_tPaintDetails.cPaintingRect.top) {
			m_tPaintDetails.cPaintingRect.bottom = m_tPaintDetails.cPaintingRect.top;
		}
	}
	m_tPaintDetails.nVisibleLines = m_tPaintDetails.cPaintingRect.Height() / m_tPaintDetails.nLineHeight;
	m_tPaintDetails.nLastLineHeight = m_tPaintDetails.cPaintingRect.Height() % m_tPaintDetails.nLineHeight;
	if(m_tPaintDetails.nLastLineHeight > 0) {
		m_tPaintDetails.nFullVisibleLines = m_tPaintDetails.nVisibleLines;
		m_tPaintDetails.nVisibleLines++;
	} else {
		m_tPaintDetails.nFullVisibleLines = m_tPaintDetails.nVisibleLines;
		m_tPaintDetails.nLastLineHeight = m_tPaintDetails.nLineHeight;
	}
	
	// position & size of the address
	if(m_bShowAddress) {
		m_tPaintDetails.nAddressPos = 0;
		m_tPaintDetails.nAddressLen = ADR_DATA_SPACE + m_tPaintDetails.nCharacterWidth*m_nAdrSize;
	} else {
		m_tPaintDetails.nAddressPos = 0;
		m_tPaintDetails.nAddressLen = 0;
	}

	// Calculate how many bytes per line we can display, when this is automatically calculated
	if(m_bAutoBytesPerRow && GetStyle() & ES_MULTILINE) {
		int iFreeSpace = m_tPaintDetails.cPaintingRect.Width() - m_tPaintDetails.nAddressLen;
		if(m_bShowAscii) {			
			iFreeSpace -= DATA_ASCII_SPACE;
			if(iFreeSpace < 0) {
				m_tPaintDetails.nBytesPerRow = 1;
			} else {
				m_tPaintDetails.nBytesPerRow = iFreeSpace / (4*m_tPaintDetails.nCharacterWidth) ; // 2(HEXDATA)+1(Space)+1(Ascii) = 4
				if( (iFreeSpace%(4*m_tPaintDetails.nCharacterWidth)) >= (3*m_tPaintDetails.nCharacterWidth) ) {
					m_tPaintDetails.nBytesPerRow++; // we actually only need n-1 spaces not n (n = nBytesPerRow)
				}
			}
		} else {
			if(iFreeSpace < 0) {
				m_tPaintDetails.nBytesPerRow = 1;
			} else {
				m_tPaintDetails.nBytesPerRow = iFreeSpace / (3*m_tPaintDetails.nCharacterWidth) ; // 2(HEXDATA)+1(Space) = 3
				if( (iFreeSpace%(3*m_tPaintDetails.nCharacterWidth)) >= (2*m_tPaintDetails.nCharacterWidth) ) {
					m_tPaintDetails.nBytesPerRow++; // we actually only need n-1 spaces not n (n = nBytesPerRow)
				}
			}
		}
		//remark: m_nBytesPerRow=0 is a valid thing... (not very lucky thing, but valid)
	} else {		
		m_tPaintDetails.nBytesPerRow = m_nBytesPerRow;
	}
	if(!(GetStyle() & ES_MULTILINE)) {
		m_tPaintDetails.nBytesPerRow = m_nLength;
	}
	if(m_tPaintDetails.nBytesPerRow == 0) {
		m_tPaintDetails.nBytesPerRow = 1;
	}

	// position & size of the hex-data
	m_tPaintDetails.nHexPos = m_tPaintDetails.nAddressPos + m_tPaintDetails.nAddressLen;
	m_tPaintDetails.nHexLen = (m_tPaintDetails.nBytesPerRow*2 + m_tPaintDetails.nBytesPerRow-1)*m_tPaintDetails.nCharacterWidth;
														//2(HEXData) + 1(Space) (only n-1 spaces needed)
	iWidth = m_tPaintDetails.nHexPos + m_tPaintDetails.nHexLen;
	m_tPaintDetails.nHexLen += DATA_ASCII_SPACE;
	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -