//////////////////////////////////////////////// //CFGHexEdit V.1.00 //Programma realizzato da Francesco Germinara //www.germinara.it 2005 FREEWARE //info@germinara.it //http://www.germinara.it //programmatore PINEROLO TORINO ITALIA //Data realizzazione: 10/luglio/2005 //////////////////////////////////////////////// // // Thanks to Eugene Pavlov (http://www.softerra.com) for the good job on the // ACTIVEX HEX EDIT CONTRON. // // Some Method are taken from Eugene Pavlov source code. // // CFGHexEdit.cpp : implementation file // #include "stdafx.h" #include "FGEdit.h" #include "CFGHexEdit.h" #include ".\cfghexedit.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif const ID_SCROLL_TIMER = 1; ///////////////////////////////////////////////////////////////////////////// // CFGHexEdit CFGHexEdit::CFGHexEdit() { m_strWindowClass = AfxRegisterWndClass ( CS_DBLCLKS, ::LoadCursor(0, IDC_IBEAM) ); //Winodow Behavior m_fontHeight=16; bkColor=RGB(192,192,255); bkTextColor=RGB(0,0,0); fgTextAsciiColor=RGB(255,255,255); bkTextAsciiColor=RGB(0,0,192); fgTextHexColor=RGB(0,0,192); bkTextHexColor=RGB(255,255,0); posXAddress=1; posXHexValue=10; posXDecValue=62; nRow=0; m_viewPos.x=0; m_viewPos.y=0; //Editing m_bMouseDown=false; m_bMouseMove=false; m_posMouseDown=false; m_selStart=-1; m_selEnd=-1; m_currentEditPosition=0; m_bTimer=false; m_nEditType=0; m_selectedBYTE=0x00; m_nNowEditDigit=0; //Data managment m_data.RemoveAll(); m_bytesInAddress=8; m_bytesInData=2; m_nStartAddress=0x00; m_columns=0x10; //for(int i=0; i < 256; i++) // m_data.Add(i); } CFGHexEdit::~CFGHexEdit() { } BEGIN_MESSAGE_MAP(CFGHexEdit, CEdit) //{{AFX_MSG_MAP(CFGHexEdit) ON_WM_PAINT() ON_WM_ERASEBKGND() ON_WM_SIZE() ON_WM_HSCROLL() ON_WM_VSCROLL() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_WM_KILLFOCUS() ON_WM_SETFOCUS() ON_WM_MOUSEMOVE() ON_WM_LBUTTONDBLCLK() ON_WM_TIMER() ON_WM_KEYDOWN() ON_WM_CHAR() ON_WM_GETDLGCODE() //}}AFX_MSG_MAP ON_WM_CONTEXTMENU() END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CFGHexEdit message handlers void CFGHexEdit::OnPaint() { CPaintDC tdc(this); // device context for painting CRect rc; GetClientRect(rc); CDC dc; dc.CreateCompatibleDC(&tdc); CBitmap bm; bm.CreateCompatibleBitmap(&tdc, rc.Width(), rc.Height()); dc.SelectObject(bm); CBrush bkBrush(bkColor); dc.FillRect(rc, &bkBrush); CFont font; font.CreateFont ( m_fontHeight, 0, 0, 0, FW_NORMAL, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, 0 ); CFont* oldFont = dc.SelectObject ( &font ); dc.SetBoundsRect(&rc, DCB_DISABLE); //Header int nPosHeader=0; CString hexValue; dc.SetTextColor(bkTextColor); dc.SetBkColor(bkColor); dc.TextOut((posXAddress-m_viewPos.x)*m_cellSize.cx,(nPosHeader-m_viewPos.y)*m_cellSize.cy,"Address"); //4Bytes hexValue.Format("Hex values: %0.2X %s",m_selectedBYTE,BinaryRapresentation()); dc.TextOut((posXHexValue-m_viewPos.x)*m_cellSize.cx,(nPosHeader-m_viewPos.y)*m_cellSize.cy,hexValue); //4Bytes dc.TextOut((posXDecValue-m_viewPos.x)*m_cellSize.cx,(nPosHeader-m_viewPos.y)*m_cellSize.cy,"ASCII values"); //4Bytes nPosHeader+=2; //Data int nRowData=GetNumberOfRows(); m_nStartAddress=0x00; for(nRow=m_viewPos.y; nRow m_charInWindow.cy ){ break; } m_nStartAddress=(nRow-m_viewPos.y)*m_columns*(m_bytesInData/2)+((m_viewPos.y)*m_columns*(m_bytesInData/2)); // normal text colors dc.SetTextColor(bkTextColor); dc.SetBkColor(fgTextAsciiColor); dc.TextOut((posXAddress-m_viewPos.x)*m_cellSize.cx,(nPosHeader+nRow-m_viewPos.y)*m_cellSize.cy,GetAddrFmt()); bool nIsSelected=false; for(int nItem=0; nItem < m_columns; nItem++){ int nPosBuffer=0; CString strByte=GetDataFmtSingleByte(nRow,nItem,nPosBuffer); nPosBuffer=(nPosBuffer*3); if(nPosBuffer >= m_selStart && nPosBuffer <= m_selEnd){ dc.SetBkColor(::GetSysColor ( COLOR_HIGHLIGHT )); dc.SetTextColor(::GetSysColor ( COLOR_HIGHLIGHTTEXT )); nIsSelected=true; }else{ dc.SetTextColor(fgTextHexColor); dc.SetBkColor(bkTextHexColor); nIsSelected=false; } dc.TextOut((posXHexValue-m_viewPos.x+(nItem*3))*m_cellSize.cx,(nPosHeader+nRow-m_viewPos.y)*m_cellSize.cy,strByte); CString strDec; int nValue=0; sscanf(strByte.GetBuffer(0),"%x",&nValue); strDec.Format("%c",isprint ( nValue ) ? nValue : '.'); if(nIsSelected){ dc.SetBkColor(::GetSysColor ( COLOR_HIGHLIGHT )); dc.SetTextColor(::GetSysColor ( COLOR_HIGHLIGHTTEXT )); }else{ dc.SetTextColor(fgTextAsciiColor); dc.SetBkColor(bkTextAsciiColor); } dc.TextOut((posXDecValue-m_viewPos.x+nItem)*m_cellSize.cx,(nPosHeader+nRow-m_viewPos.y)*m_cellSize.cy,strDec); } } //Select Original Object dc.SelectObject ( oldFont ); tdc.BitBlt(0, 0, rc.Width(), rc.Height(), &dc, 0, 0, SRCCOPY); } BOOL CFGHexEdit::PreCreateWindow(CREATESTRUCT& cs) { return CEdit::PreCreateWindow(cs); } BOOL CFGHexEdit::OnEraseBkgnd(CDC* pDC) { return true; } //Get Address Formatted CString CFGHexEdit::GetAddrFmt(){ CString m_strAddrFmt; //Address formatted data for display if(m_bytesInAddress==0x02) m_strAddrFmt.Format("%0.2X",m_nStartAddress); if(m_bytesInAddress==0x04) m_strAddrFmt.Format("%0.4X",m_nStartAddress); if(m_bytesInAddress==0x08) m_strAddrFmt.Format("%0.8X",m_nStartAddress); return m_strAddrFmt; } //Get Address Formatted CString CFGHexEdit::GetDataFmt(int nDataRow){ CString m_strDataFmt; //Address formatted data for display BYTE byData; CString strResult; int nIndex=0; int nMaxBytes=(m_bytesInData/2) * m_columns; int nBytesPresent=m_data.GetSize(); int nOffset=nDataRow *nMaxBytes; strResult=""; for(nIndex=nOffset;nIndexSelectObject ( &font ); m_cellSize = pdc->GetTextExtent(_T("A")); pdc->LPtoDP ( &m_cellSize ); pdc->SelectObject ( oldFont ); ReleaseDC ( pdc ); CRect rcClient; GetClientRect ( rcClient ); if (GetStyle() & WS_VSCROLL) rcClient.right += ::GetSystemMetrics(SM_CXVSCROLL); if (GetStyle() & WS_HSCROLL) rcClient.bottom += ::GetSystemMetrics(SM_CYHSCROLL); m_charInWindow.cx = (rcClient.Width() - m_cellSize.cx/2) / m_cellSize.cx; m_charInWindow.cy = rcClient.Height() / m_cellSize.cy; UpdateScrollBars(); if(m_viewPos.y > GetNumberOfRows()-m_charInWindow.cy+2) m_viewPos.y=GetNumberOfRows()-m_charInWindow.cy+2; if(m_viewPos.y <0) m_viewPos.y=0; Invalidate(); SetScrollPos ( SB_VERT, m_viewPos.y); } void CFGHexEdit::OnSize(UINT nType, int cx, int cy) { CEdit::OnSize(nType, cx, cy); RecalcLayout(); } bool CFGHexEdit::UpdateScrollBars() { bool bRepaint = false; SCROLLINFO si, prevSI; int nVisbleRows=GetNumberOfRows()+1; //header 2 - 1 if(m_charInWindow.cy > nVisbleRows ) nVisbleRows=m_charInWindow.cy-1; si.cbSize = prevSI.cbSize = sizeof(SCROLLINFO); si.fMask = SIF_ALL; si.nMin = 0; si.nMax = nVisbleRows; si.nPage = m_charInWindow.cy; si.nPos = m_viewPos.y; if ( !bRepaint && ( !GetScrollInfo(SB_VERT, &prevSI, SIF_POS ) || si.nPos != prevSI.nPos )) // if scrollbar is about to show or its position changed, the control needs repainting bRepaint = true; if(si.nMax >= int(si.nPage)) { ShowScrollBar(SB_VERT); } else { ShowScrollBar(SB_VERT, FALSE); m_viewPos.y=0; } VERIFY(SetScrollInfo(SB_VERT, &si, TRUE)); si.fMask = SIF_ALL; si.nMin = 0; si.nMax = 78; //Max Char Displayed si.nPage = m_charInWindow.cx; si.nPos = m_viewPos.x; if ( si.nMax > (int)si.nPage && si.nPos+int(si.nPage) > si.nMax ) si.nPos = m_viewPos.x = si.nMax - si.nPage + 1; if ( !bRepaint && ( !GetScrollInfo(SB_HORZ, &prevSI, SIF_POS ) || si.nPos != prevSI.nPos )) // if scrollbar is about to show or its position changed, the control needs repainting bRepaint = true; if(si.nMax >= (int)si.nPage ) { ShowScrollBar(SB_HORZ); } else { ShowScrollBar(SB_HORZ, FALSE); m_viewPos.x=0; } VERIFY(SetScrollInfo(SB_HORZ, &si, TRUE)); return bRepaint; } //Number of row for data rapresentation int CFGHexEdit::GetNumberOfRows(){ int nBytes=m_data.GetSize(); int nRowData=(int)(nBytes / m_columns); if((nRowData * m_columns) != nBytes) nRowData++; return nRowData; } void CFGHexEdit::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { int nPrevHorzScroll = m_viewPos.x; switch(nSBCode) { case SB_LINELEFT: m_viewPos.x--; break; case SB_PAGELEFT: m_viewPos.x -= m_charInWindow.cx; break; case SB_LINERIGHT: m_viewPos.x++; break; case SB_PAGERIGHT: m_viewPos.x += m_charInWindow.cx; break; case SB_THUMBTRACK: SCROLLINFO si; si.cbSize = sizeof(si); GetScrollInfo ( SB_HORZ, &si, SIF_TRACKPOS ); m_viewPos.x = si.nTrackPos; if(m_viewPos.x > m_charInWindow.cx) m_viewPos.x++; break; } int scrBarOffSet=0; if (GetStyle() & WS_VSCROLL){ scrBarOffSet=-1; } if ( m_viewPos.x < 0 ) m_viewPos.x = 0; else if ( m_viewPos.x > 78-m_charInWindow.cx - scrBarOffSet +2) m_viewPos.x = 78-m_charInWindow.cx - scrBarOffSet +2; if ( nPrevHorzScroll != m_viewPos.x ) { Invalidate(); SetScrollPos ( SB_HORZ, m_viewPos.x ); SetCaretPosition(); } } void CFGHexEdit::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { int nPrevViewPos = m_viewPos.y; switch(nSBCode) { case SB_LINEDOWN: m_viewPos.y += 1; break; case SB_LINEUP: m_viewPos.y -= 1; break; case SB_PAGEDOWN: m_viewPos.y += m_charInWindow.cy; break; case SB_PAGEUP: m_viewPos.y -= m_charInWindow.cy; break; case SB_THUMBTRACK: SCROLLINFO si; si.cbSize = sizeof(si); GetScrollInfo ( SB_VERT, &si, SIF_TRACKPOS ); m_viewPos.y = si.nTrackPos; if(m_viewPos.y > m_charInWindow.cy) m_viewPos.y++; break; } int scrBarOffSet=0; if (GetStyle() & WS_HSCROLL){ scrBarOffSet=-1; } if(m_viewPos.y > GetNumberOfRows()-m_charInWindow.cy-scrBarOffSet+2) m_viewPos.y=GetNumberOfRows()-m_charInWindow.cy-scrBarOffSet+2; if ( m_viewPos.y < 0 ) m_viewPos.y = 0; if ( m_viewPos.y != nPrevViewPos ) { Invalidate(); SetScrollPos ( SB_VERT, m_viewPos.y); SetCaretPosition(); } } void CFGHexEdit::OnLButtonDown(UINT nFlags, CPoint point) { if(m_data.GetSize()==0) return; m_bMouseDown = true; if ( !IsSelectionEmpty() ) ClearSelection(); if ( nFlags & MK_SHIFT ) { if(m_nEditType==0) m_posMouseDown = m_currentEditPosition; else m_posMouseDown = m_currentEditPosition*3; RecalcSelection(point); m_bMouseMove = true; } else { CalculateEditPosition ( point ); if(m_nEditType==0) m_posMouseDown = m_currentEditPosition; else m_posMouseDown = m_currentEditPosition*3; } SetCapture(); HideCaret(); CEdit::OnLButtonDown(nFlags, point); } void CFGHexEdit::ClearSelection() { m_selStart = m_selEnd = -1; Invalidate(); } bool CFGHexEdit::IsSelectionEmpty() { return ( m_selStart == -1 ); } void CFGHexEdit::CalculateEditPosition(CPoint pt) { CPoint ptClicked=pt; int nLeftChars=(pt.x / m_cellSize.cx)+m_viewPos.x; int nRow=(pt.y / m_cellSize.cy)+m_viewPos.y; int sizeHexZoneEnd=(m_columns*(m_bytesInData+1))+posXHexValue-2; int selectedRow=nRow-2; if(selectedRow > GetNumberOfRows()) return; if((nLeftChars >= posXHexValue && nLeftChars <= sizeHexZoneEnd) && selectedRow>=0){ m_nEditType=0; if(!(nLeftChars % 3)) nLeftChars++; m_currentEditPosition=(nLeftChars-posXHexValue)+(selectedRow*(m_columns*(m_bytesInData+1))); } //Editing Dec Value if((nLeftChars >= posXDecValue && nLeftChars <= posXDecValue+16)&& selectedRow>=0){ m_nEditType=1; m_currentEditPosition=nLeftChars-posXDecValue+(selectedRow*16); } } void CFGHexEdit::OnLButtonUp(UINT nFlags, CPoint point) { if(m_data.GetSize()==0) return; if ( m_bMouseDown ) { if ( m_bMouseMove ) RecalcSelection(point); ReleaseCapture(); m_bMouseDown = false; m_bMouseMove = false; if ( m_bTimer ) { KillTimer(ID_SCROLL_TIMER); m_bTimer = false; } if ( !IsSelectionEmpty() ) { if ( m_currentEditPosition == m_selEnd ) m_currentEditPosition++; } } SetCaretPosition(); ShowCaret(); CEdit::OnLButtonUp(nFlags, point); } void CFGHexEdit::SetCaretPosition() { if(m_nEditType == 0){ //HEX Edit int nLeftChar=m_currentEditPosition % (m_columns*(m_bytesInData+1)); int nRow=(int)m_currentEditPosition / (m_columns*(m_bytesInData+1)); POINT pt; pt.x = (posXHexValue + nLeftChar - m_viewPos.x)*m_cellSize.cx; pt.y = (nRow - m_viewPos.y+2)*m_cellSize.cy; SetCaretPos (pt); } if(m_nEditType == 1){ //Dec Edit int nLeftChar=m_currentEditPosition % 16; int nRow=(int)m_currentEditPosition / 16; POINT pt; pt.x = (posXDecValue + nLeftChar - m_viewPos.x)*m_cellSize.cx; pt.y = (nRow - m_viewPos.y+2)*m_cellSize.cy; SetCaretPos (pt); } m_selectedBYTE=GetByteFromEditPosition(); RecalcLayout(); // CString msg; // msg.Format("valore: %0.2X",GetByteFromEditPosition()); // AfxMessageBox(msg); } BYTE CFGHexEdit::GetByteFromEditPosition(){ BYTE bValue=0x00; int nIndex=0; if(m_nEditType == 0){ //HEX Edit nIndex=(m_currentEditPosition / 3); if(nIndex < m_data.GetSize()){ bValue=m_data.GetAt(nIndex); } return bValue; } if(m_nEditType == 1){ //Dec Edit nIndex=m_currentEditPosition; if(nIndex < m_data.GetSize()){ bValue=m_data.GetAt(nIndex); } return bValue; } return bValue; } void CFGHexEdit::RecalcSelection(CPoint point) { if ( m_data.GetSize() == 0 ) return; if ( m_bMouseDown ) { int nPrevSelStart = m_selStart, nPrevSelEnd = m_selEnd; CalculateEditPosition ( point ); if(m_nEditType==0){ if ( m_posMouseDown < m_currentEditPosition ) { m_currentEditPosition--; m_selStart = m_posMouseDown; m_selEnd = m_currentEditPosition; m_currentEditPosition = m_selEnd; } else { m_selStart = m_currentEditPosition; m_selEnd = m_posMouseDown; m_currentEditPosition = m_selStart; } } if(m_nEditType==1){ if ( m_posMouseDown < m_currentEditPosition *3) { m_selStart = m_posMouseDown; m_selEnd = m_currentEditPosition * 3; } else { m_selStart = m_currentEditPosition *3; m_selEnd = m_posMouseDown; } } if ( nPrevSelStart != m_selStart || nPrevSelEnd != m_selEnd ) Invalidate(); } } void CFGHexEdit::OnKillFocus(CWnd* pNewWnd) { DestroyCaret (); } //Called after create void CFGHexEdit::Initialize(){ CreateSolidCaret (m_cellSize.cx, m_cellSize.cy ); SetCaretPosition(); if (!m_bMouseDown ) ShowCaret(); } void CFGHexEdit::OnSetFocus(CWnd* pOldWnd) { CEdit::OnSetFocus(pOldWnd); Initialize(); } void CFGHexEdit::OnMouseMove(UINT nFlags, CPoint point) { if ( m_data.GetSize() == 0 ) return; CRect rcClient; GetClientRect ( rcClient ); if ( m_bMouseDown ) { m_bMouseMove = true; if ( !m_bTimer && !rcClient.PtInRect(point)) { SetTimer ( ID_SCROLL_TIMER, 100, 0 ); m_bTimer = true; } else if ( m_bTimer && rcClient.PtInRect(point)) { KillTimer ( ID_SCROLL_TIMER ); m_bTimer = false; } m_prevMousePoint = point; RecalcSelection(point); } CEdit::OnMouseMove(nFlags, point); } void CFGHexEdit::OnLButtonDblClk(UINT nFlags, CPoint point) { if ( m_data.GetSize() == 0 ) return; CalculateEditPosition ( point ); if(m_nEditType==0){ m_selStart = m_selEnd = m_currentEditPosition--; m_currentEditPosition++; } if(m_nEditType==1){ m_selStart = m_selEnd = m_currentEditPosition*3; } SetCaretPosition(); m_bMouseDown = false; ReleaseCapture(); CEdit::OnLButtonDblClk(nFlags, point); } void CFGHexEdit::OnTimer(UINT nIDEvent) { if ( nIDEvent == ID_SCROLL_TIMER ) { RecalcSelection ( m_prevMousePoint ); NeedToScroll(); UpdateScrollBars (); } else CEdit::OnTimer(nIDEvent); } void CFGHexEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { BOOL bShift = ::GetKeyState(VK_SHIFT) & 0x80000000; BOOL bControl = ::GetKeyState(VK_CONTROL) & 0x80000000; if ( nChar == VK_TAB ) { CWnd* pParent = GetParentOwner(); if ( !pParent ) return; if ( bShift && !bControl ) { ::SendMessage(pParent->m_hWnd, WM_NEXTDLGCTL, 1, 0); return; } else if ( !bControl && !bShift ) { ::SendMessage(pParent->m_hWnd, WM_NEXTDLGCTL, 0, 0); return; } } if ( m_data.GetSize() == 0 ) return; if ( bShift && !bControl ) { int prevEditPos = m_currentEditPosition; switch ( nChar ) // SHIFT+arrows - modify selection { case VK_LEFT: ChangeEditPos ( -1, 0 ); break; case VK_RIGHT: ChangeEditPos ( 1, 0 ); break; case VK_UP: ChangeEditPos ( 0, -1 ); break; case VK_DOWN: ChangeEditPos ( 0, 1 ); break; case VK_PRIOR: ChangeEditPos ( 0, - 10); break; case VK_NEXT: ChangeEditPos ( 0, 10); break; case VK_HOME: m_currentEditPosition = 0; ChangeEditPos ( 0, 0 ); break; case VK_END: if(m_nEditType == 0) m_currentEditPosition = m_data.GetSize() * 3; else m_currentEditPosition = m_data.GetSize(); ChangeEditPos ( 0, 0 ); break; default: CEdit::OnKeyDown(nChar, nRepCnt, nFlags); return; } //Selection on Hex View if(m_nEditType==0){ if (IsSelectionEmpty()){ if ( m_currentEditPosition < prevEditPos ){ m_selStart = m_currentEditPosition; m_selEnd = prevEditPos-1; }else if ( m_currentEditPosition > prevEditPos ){ m_selStart = prevEditPos; m_selEnd = m_currentEditPosition-1; } } else{ if(prevEditPos-1 == m_selEnd ){ m_selEnd = m_currentEditPosition-1; }else{ m_selStart = m_currentEditPosition; } if(m_selStart == m_selEnd+1) ClearSelection(); } } Invalidate(); } else { if ( bControl && !bShift) { switch ( nChar ) { case VK_HOME: m_currentEditPosition = 0; ChangeEditPos ( 0, 0 ); break; case VK_END: if(m_nEditType == 0) m_currentEditPosition = m_data.GetSize() * 3 -3; else m_currentEditPosition = m_data.GetSize()-1; ChangeEditPos ( 0, 0 ); break; default: CEdit::OnKeyDown(nChar, nRepCnt, nFlags); break; } } else if ( !bControl && !bShift ) { switch ( nChar ) { case VK_LEFT: ChangeEditPos ( -1, 0 ); break; case VK_RIGHT: ChangeEditPos ( 1, 0 ); break; case VK_UP: ChangeEditPos ( 0, -1 ); break; case VK_DOWN: ChangeEditPos ( 0, 1 ); break; case VK_PRIOR: ChangeEditPos ( 0, -10); break; case VK_NEXT: ChangeEditPos ( 0, 10 ); break; case VK_HOME: m_currentEditPosition = 0; ChangeEditPos ( 0, 0 ); break; case VK_END: if(m_nEditType == 0) m_currentEditPosition = m_data.GetSize() * 3 -3; else m_currentEditPosition = m_data.GetSize()-1; ChangeEditPos ( 0, 0 ); break; case VK_DELETE: if ( IsSelectionEmpty() ) { if ( m_currentEditPosition > 0 ) { //Delete data value m_selectedBYTE=0x00; int nIndex=GetIndexFromEditPosition(); if(m_data.GetSize() > nIndex) m_data.SetAt(nIndex,m_selectedBYTE); ChangeEditPos ( 1, 0, true ); } } else DeleteDataInSelection(); ChangeEditPos ( 0, 0, true ); break; case VK_BACK: if ( IsSelectionEmpty() ) { if ( m_currentEditPosition > 0 ) { //Delete data value m_selectedBYTE=0x00; int nIndex=GetIndexFromEditPosition(); if(m_data.GetSize() > nIndex) m_data.SetAt(nIndex,m_selectedBYTE); ChangeEditPos ( -1, 0, true ); } } else DeleteDataInSelection(); ChangeEditPos ( 0, 0, true ); break; case VK_INSERT: if ( IsSelectionEmpty() ) { if ( m_currentEditPosition > 0 ) { //Delete data value m_selectedBYTE=0xFF; int nIndex=GetIndexFromEditPosition(); if(m_data.GetSize() > nIndex) m_data.SetAt(nIndex,m_selectedBYTE); ChangeEditPos ( 1, 0, true ); } } else SetFFDataInSelection(); ChangeEditPos ( 0, 0, true ); break; default: CEdit::OnKeyDown(nChar, nRepCnt, nFlags); return; } if ( !IsSelectionEmpty() ) { ClearSelection(); Invalidate(); } } } } void CFGHexEdit::ChangeEditPos(long dx, long dy, bool bRepaint /* = false */) { if(m_nEditType == 0){ m_currentEditPosition += dy*m_columns*3 + dx; if(m_currentEditPosition <0) m_currentEditPosition=0; if(m_currentEditPosition/3 >= m_data.GetSize()) m_currentEditPosition=m_data.GetSize() * 3 - 1; } if(m_nEditType == 1){ m_currentEditPosition += dy*m_columns + dx; if(m_currentEditPosition <0) m_currentEditPosition=0; if(m_currentEditPosition >= m_data.GetSize()) m_currentEditPosition=m_data.GetSize()-1; } NeedToScroll(); if ( UpdateScrollBars ()) bRepaint = true; if ( bRepaint ) Invalidate(); SetCaretPosition(); } void CFGHexEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) { if ( m_data.GetSize() == 0 ) return; if (m_nEditType==0) { if((nChar >= '0' && nChar <= '9') || (nChar >= 'a' && nChar <= 'f') || (nChar >= 'A' && nChar <= 'F')) { UINT b = nChar - '0'; if(b > 9) { if (b <= 'F' - '0') b = 10 + nChar - 'A'; else b = 10 + nChar - 'a'; } BYTE nNewValue=0x00; m_nNowEditDigit=(m_currentEditPosition % 3); if(m_nNowEditDigit == 0){ b=b<<4; //Is the MSB nNewValue=b | (m_selectedBYTE % 16); //Change MSB on value }else{ m_selectedBYTE ^= (m_selectedBYTE % 16); //Clear LSB m_selectedBYTE|=b; //Assign new value to LSB nNewValue=m_selectedBYTE; //Assign data value } int nIndex=GetIndexFromEditPosition(); if(nIndex < m_data.GetSize()) m_data.SetAt(nIndex,nNewValue); ChangeEditPos(1, 0, false); m_nNowEditDigit++; if ( m_nNowEditDigit == m_bytesInData ){ ChangeEditPos(1, 0, false); m_nNowEditDigit=0; }else{ UpdateScrollBars(); SetCaretPosition(); } } } else // EDIT_ASCII { if ( nChar >= ' ' ) { int nIndex=GetIndexFromEditPosition(); if(nIndex < m_data.GetSize()) m_data.SetAt(nIndex,nChar); ChangeEditPos(1, 0, false); } } } //Return Index of Byte Value by current edit position int CFGHexEdit::GetIndexFromEditPosition(){ BYTE bValue=0x00; int nIndex=0; if(m_nEditType == 0){ //HEX Edit nIndex=(m_currentEditPosition / 3); if(nIndex < m_data.GetSize()){ bValue=m_data.GetAt(nIndex); } return nIndex; } if(m_nEditType == 1){ //Dec Edit nIndex=m_currentEditPosition; if(nIndex < m_data.GetSize()){ bValue=m_data.GetAt(nIndex); } return nIndex; } return 0; } void CFGHexEdit::DeleteDataInSelection(){ int nIndex=0; int nIndexByte=0; for(nIndex=m_selStart; nIndex <= m_selEnd; nIndex++){ nIndexByte=(nIndex / 3); if(nIndexByte < m_data.GetSize()) m_data.SetAt(nIndexByte,0x00); } } void CFGHexEdit::SetFFDataInSelection(){ int nIndex=0; int nIndexByte=0; for(nIndex=m_selStart; nIndex <= m_selEnd; nIndex++){ nIndexByte=(nIndex / 3); if(nIndexByte < m_data.GetSize()) m_data.SetAt(nIndexByte,0xFF); } } CString CFGHexEdit::BinaryRapresentation(){ int nBit=0; CString result,fmt; result=" Bit Values: "; int mask=0x01; for(nBit=7; nBit >= 4; nBit--){ mask= ((BYTE)0x01) << nBit; ((m_selectedBYTE & mask)==mask) ? fmt="1" : fmt="0"; result+=fmt; } result+=" "; for(nBit=3; nBit >= 0; nBit--){ mask= ((BYTE)0x01) << nBit; ((m_selectedBYTE & mask)==mask) ? fmt="1" : fmt="0"; result+=fmt; } return result; } //Set the data to display void CFGHexEdit::SetData(CByteArray& theData){ m_data.RemoveAll(); m_data.Copy(theData); RecalcLayout(); } //Get the edit data CByteArray& CFGHexEdit::GetData(){ return m_data; } //Set the data to display void CFGHexEdit::SetAllDataValue(BYTE byteValue){ int nBytes=m_data.GetSize(); for(int nIndex=0; nIndex < nBytes; nIndex++) m_data.SetAt(nIndex,byteValue); Invalidate(); } UINT CFGHexEdit::OnGetDlgCode() { return CEdit::OnGetDlgCode() | DLGC_WANTARROWS | DLGC_WANTCHARS | DLGC_WANTTAB; } //Create window BOOL CFGHexEdit::Create(CRect rcSize,CWnd *pParent,int edtID){ return CreateEx(WS_EX_LEFT | WS_EX_NOPARENTNOTIFY | WS_EX_CLIENTEDGE ,"edit","",WS_CHILDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_OVERLAPPED | WS_MAXIMIZEBOX| WS_BORDER | WS_TABSTOP | WS_HSCROLL | WS_VSCROLL |WS_VISIBLE , rcSize, pParent,edtID); } void CFGHexEdit::NeedToScroll() { int currentRow=0; if(m_nEditType==0) currentRow=(m_currentEditPosition / (m_columns * (m_bytesInData +1)))+3; else currentRow=(m_currentEditPosition / m_columns)+3; if(currentRow-m_viewPos.y <= 3){ if((currentRow-m_viewPos.y) <=0) m_viewPos.y=0; else m_viewPos.y--; if(m_viewPos.y<0) m_viewPos.y=0; return; } if( currentRow-m_viewPos.y > m_charInWindow.cy ){ m_viewPos.y = currentRow - m_charInWindow.cy; } } //Set Colors scheme void CFGHexEdit::SetColorScheme(COLORREF clrForeWnd,COLORREF clrBackWnd,COLORREF clrForeHex,COLORREF clrBackHex,COLORREF clrForeASCII,COLORREF clrBackACII){ bkColor=clrForeWnd; bkTextColor=clrBackWnd; fgTextAsciiColor=clrForeASCII; bkTextAsciiColor=clrBackACII; fgTextHexColor=clrForeHex; bkTextHexColor=clrBackHex; } void CFGHexEdit::OnLoadFile(){ CString m_strDest; char BASED_CODE szInputFilter[] = "All Files (*.*) |"; UpdateData(TRUE); CFileDialog wndInputFileDlg ( TRUE, NULL, "*.*", OFN_LONGNAMES | OFN_EXPLORER | OFN_NOVALIDATE | OFN_NOCHANGEDIR, szInputFilter ); wndInputFileDlg.m_ofn.Flags|=OFN_EXPLORER | OFN_HIDEREADONLY; if(wndInputFileDlg.DoModal () == IDOK ){ m_strDest=wndInputFileDlg.GetPathName(); ReadFile(m_strDest); } } void CFGHexEdit::OnSaveFile(){ CString m_strDest; char BASED_CODE szInputFilter[] = "All Files (*.*) |"; UpdateData(TRUE); CFileDialog wndInputFileDlg ( FALSE, NULL, "*.*", OFN_LONGNAMES | OFN_EXPLORER | OFN_NOVALIDATE | OFN_NOCHANGEDIR, szInputFilter ); //strcpy(wndInputFileDlg.m_ofn.lpstrFile,""); wndInputFileDlg.m_ofn.Flags|=OFN_EXPLORER | OFN_HIDEREADONLY; if(wndInputFileDlg.DoModal () == IDOK ){ m_strDest=wndInputFileDlg.GetPathName(); WriteFile(m_strDest); } } //Load data from file void CFGHexEdit::ReadFile(CString m_strDest){ CFile localData; CFileException fe; if(!localData.Open(m_strDest,CFile::modeRead,&fe)){ fe.ReportError(); return; } m_data.RemoveAll(); long int len=localData.GetLength(); m_data.SetSize(len,1024); unsigned char byteRead=0x0; int bytesRead=0; bytesRead= localData.Read( m_data.GetData(), len ); localData.Close(); m_selStart=-1; m_selEnd=-1; m_currentEditPosition=0; m_bTimer=false; m_nEditType=0; m_selectedBYTE=0x00; m_nNowEditDigit=0; m_viewPos.x=0; m_viewPos.y=0; Invalidate(); } //Save data from file void CFGHexEdit::WriteFile(CString m_strDest){ CFile localData; CFileException fe; if(!localData.Open(m_strDest,CFile::modeCreate | CFile::modeReadWrite,&fe)){ fe.ReportError(); return; } localData.Write(m_data.GetData(),m_data.GetSize()); localData.Close(); } void CFGHexEdit::OnContextMenu(CWnd* /*pWnd*/, CPoint /*point*/) { }