📄 hexedit.cpp
字号:
return CPoint(-1,-1);
}
void CHexEdit::CreateAddressCaret()
{
DestroyCaret();
CreateSolidCaret(m_nullWidth * (m_bAddressIsWide ? 8 : 4), m_lineHeight);
}
void CHexEdit::CreateEditCaret()
{
DestroyCaret();
CreateSolidCaret(m_nullWidth, m_lineHeight);
}
void CHexEdit::OnMouseMove(UINT nFlags, CPoint point)
{
if(!m_pData)
return;
if(nFlags & MK_LBUTTON && m_selStart != 0xffffffff)
{
CRect rc;
GetClientRect(&rc);
if(!rc.PtInRect(point))
{
if(point.y < 0)
{
OnVScroll(SB_LINEUP, 0, NULL);
point.y = 0;
}
else if(point.y > rc.Height())
{
OnVScroll(SB_LINEDOWN, 0, NULL);
point.y = rc.Height() -1;
}
}
//
// we are selecting
//
int seo = m_selEnd;
CPoint pt = CalcPos(point.x, point.y);
if(pt.x > -1)
{
m_selEnd = m_currentAddress;
if(m_currentMode == EDIT_HIGH || m_currentMode == EDIT_LOW)
m_selEnd++;
}
if(IsSelected())
DestroyCaret();
if(seo != m_selEnd)
RedrawWindow();
}
}
void CHexEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
nFlags;nRepCnt;
if(!m_pData)
return;
if(nChar == '\t')
return;
if(GetKeyState(VK_CONTROL) & 0x80000000)
{
switch(nChar)
{
case 0x03:
if(IsSelected())
OnEditCopy();
return;
case 0x16:
OnEditPaste();
return;
case 0x18:
if(IsSelected())
OnEditCut();
return;
case 0x1a:
OnEditUndo();
return;
}
}
if(nChar == 0x08)
{
if(m_currentAddress > 0)
{
m_currentAddress--;
SelDelete(m_currentAddress, m_currentAddress+1);
RepositionCaret(m_currentAddress);
RedrawWindow();
}
return;
}
SetSel(-1, -1);
switch(m_currentMode)
{
case EDIT_NONE:
return;
case EDIT_HIGH:
case EDIT_LOW:
if((nChar >= '0' && nChar <= '9') || (nChar >= 'a' && nChar <= 'f'))
{
UINT b = nChar - '0';
if(b > 9)
b = 10 + nChar - 'a';
if(m_currentMode == EDIT_HIGH)
{
m_pData[m_currentAddress] = (unsigned char)((m_pData[m_currentAddress] & 0x0f) | (b << 4));
}
else
{
m_pData[m_currentAddress] = (unsigned char)((m_pData[m_currentAddress] & 0xf0) | b);
}
Move(1,0);
}
break;
case EDIT_ASCII:
m_pData[m_currentAddress] = (unsigned char)nChar;
Move(1,0);
break;
}
RedrawWindow();
}
void CHexEdit::RepositionCaret(int p)
{
int x, y;
y = (p - m_topindex) / m_bpr;
x = (p - m_topindex) % m_bpr;
switch(m_currentMode)
{
case EDIT_NONE:
CreateAddressCaret();
x = 0;
break;
case EDIT_HIGH:
CreateEditCaret();
x *= m_nullWidth*3;
x += m_offHex;
break;
case EDIT_LOW:
CreateEditCaret();
x *= m_nullWidth*3;
x += m_nullWidth;
x += m_offHex;
break;
case EDIT_ASCII:
CreateEditCaret();
x *= m_nullWidth;
x += m_offAscii;
break;
}
m_editPos.x = x;
m_editPos.y = y*m_lineHeight;
CRect rc;
GetClientRect(&rc);
if(rc.PtInRect(m_editPos))
{
SetCaretPos(m_editPos);
ShowCaret();
}
}
void CHexEdit::OnContextMenu(CWnd* pWnd, CPoint point)
{
// CG: This block was added by the Pop-up Menu component
{
if (point.x == -1 && point.y == -1)
{
//keystroke invocation
CRect rect;
GetClientRect(rect);
ClientToScreen(rect);
point = rect.TopLeft();
point.Offset(5, 5);
}
CMenu menu;
VERIFY(menu.LoadMenu(CG_IDR_POPUP_HEX_EDIT));
CMenu* pPopup = menu.GetSubMenu(0);
ASSERT(pPopup != NULL);
pPopup->EnableMenuItem(ID_EDIT_UNDO, MF_GRAYED|MF_DISABLED|MF_BYCOMMAND);
if(!IsSelected())
{
pPopup->EnableMenuItem(ID_EDIT_CLEAR, MF_GRAYED|MF_DISABLED|MF_BYCOMMAND);
pPopup->EnableMenuItem(ID_EDIT_CUT, MF_GRAYED|MF_DISABLED|MF_BYCOMMAND);
pPopup->EnableMenuItem(ID_EDIT_COPY, MF_GRAYED|MF_DISABLED|MF_BYCOMMAND);
}
{
COleDataObject obj;
if (obj.AttachClipboard())
{
if(!obj.IsDataAvailable(CF_TEXT) && !obj.IsDataAvailable(RegisterClipboardFormat("BinaryData")))
pPopup->EnableMenuItem(ID_EDIT_PASTE, MF_GRAYED|MF_DISABLED|MF_BYCOMMAND);
}
}
pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,
this);
}
}
void CHexEdit::OnEditClear()
{
m_currentAddress = m_selStart;
SelDelete(m_selStart, m_selEnd);
RepositionCaret(m_currentAddress);
RedrawWindow();
}
void CHexEdit::OnEditCopy()
{
COleDataSource* pSource = new COleDataSource();
EmptyClipboard();
if(m_currentMode != EDIT_ASCII)
{
int dwLen = (m_selEnd-m_selStart);
HGLOBAL hMemb = ::GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE|GMEM_ZEROINIT, m_selEnd-m_selStart);
HGLOBAL hMema = ::GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE|GMEM_ZEROINIT, (dwLen) * 3);
if (!hMema)
return;
// copy binary
LPBYTE p = (BYTE*)::GlobalLock(hMemb);
memcpy(p, m_pData+m_selStart, dwLen);
::GlobalUnlock(hMemb);
// copy ascii
p = (BYTE*)::GlobalLock(hMema);
for(int i = 0; i < dwLen;)
{
TOHEX(m_pData[m_selStart+i], p);
*p++ = ' ';
i++;
}
::GlobalUnlock(hMema);
pSource->CacheGlobalData(RegisterClipboardFormat("BinaryData"), hMemb);
pSource->CacheGlobalData(CF_TEXT, hMema);
}
else
{
HGLOBAL hMemb = ::GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE|GMEM_ZEROINIT, m_selEnd-m_selStart);
HGLOBAL hMema = ::GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE|GMEM_ZEROINIT, m_selEnd-m_selStart);
if (!hMemb || !hMema)
return;
// copy binary
LPBYTE p = (BYTE*)::GlobalLock(hMemb);
int dwLen = m_selEnd-m_selStart;
memcpy(p, m_pData+m_selStart, dwLen);
::GlobalUnlock(hMemb);
// copy ascii
p = (BYTE*)::GlobalLock(hMema);
memcpy(p, m_pData+m_selStart, dwLen);
for(int i = 0; i < dwLen; p++, i++)
if(!isprint(*p))
*p = '.';
::GlobalUnlock(hMema);
pSource->CacheGlobalData(RegisterClipboardFormat("BinaryData"), hMemb);
pSource->CacheGlobalData(CF_TEXT, hMema);
}
pSource->SetClipboard();
}
void CHexEdit::OnEditCut()
{
OnEditCopy();
SelDelete(m_selStart, m_selEnd);
RedrawWindow();
}
void CHexEdit::OnEditPaste()
{
COleDataObject obj;
if (obj.AttachClipboard())
{
HGLOBAL hmem = NULL;
if (obj.IsDataAvailable(RegisterClipboardFormat("BinaryData")))
{
hmem = obj.GetGlobalData(RegisterClipboardFormat("BinaryData"));
}
else if (obj.IsDataAvailable(CF_TEXT))
{
hmem = obj.GetGlobalData(CF_TEXT);
}
if(hmem)
{
LPBYTE p = (BYTE*)::GlobalLock(hmem);
DWORD dwLen = ::GlobalSize(hmem);
int insert;
int oa = m_currentAddress;
NormalizeSel();
if(m_selStart == 0xffffffff)
{
if(m_currentMode == EDIT_LOW)
m_currentAddress++;
insert = m_currentAddress;
SelInsert(m_currentAddress, dwLen);
}
else
{
insert = m_selStart;
SelDelete(m_selStart, m_selEnd);
SelInsert(insert, dwLen);
SetSel(-1, -1);
}
memcpy(m_pData+insert, p, dwLen);
m_currentAddress = oa;
RedrawWindow();
::GlobalUnlock(hmem);
}
}
}
void CHexEdit::OnEditSelectAll()
{
m_selStart = 0;
m_selEnd = m_length;
DestroyCaret();
RedrawWindow();
}
void CHexEdit::OnEditUndo()
{
//DEL // TODO: Add your command handler code here
//DEL
}
void CHexEdit::NormalizeSel()
{
if(m_selStart > m_selEnd)
m_selStart ^= m_selEnd ^= m_selStart ^= m_selEnd;
}
void CHexEdit::SelDelete(int s, int e)
{
LPBYTE p = (LPBYTE) malloc(m_length - (e-s)+1);
memcpy(p, m_pData, s);
if(s < m_length-(e-s))
memcpy(p+s, m_pData+e, (m_length -e));
free(m_pData);
SetSel(-1, -1);
m_pData = p;
m_length = m_length-(e-s);
if(m_currentAddress > m_length)
{
m_currentAddress = m_length;
RepositionCaret(m_currentAddress);
}
m_bUpdate = TRUE;
}
void CHexEdit::SelInsert(int s, int l)
{
LPBYTE p = (LPBYTE) calloc(m_length + l, 1);
memcpy(p, m_pData, s);
memcpy(p+s+l, m_pData+s, (m_length-s));
free(m_pData);
SetSel(-1, -1);
m_pData = p;
m_length = m_length+l;
m_bUpdate = TRUE;
}
CSize CHexEdit::GetSel()
{
return CSize(m_selStart, m_selEnd);
}
void CHexEdit::SetData(LPBYTE p, int len)
{
free(m_pData);
m_pData = (LPBYTE) malloc(len);
memcpy(m_pData, p, len);
SetSel(-1, -1);
m_length = len;
m_currentAddress = 0;
m_editPos.x = m_editPos.y = 0;
m_currentMode = EDIT_HIGH;
m_topindex = 0;
m_bUpdate = TRUE;
}
int CHexEdit::GetData(LPBYTE p, int len)
{
memcpy(p, m_pData, min(len, m_length));
return m_length;
}
void CHexEdit::AppendData(LPBYTE p, int addlen)
{
LPBYTE oldData=m_pData;
int oldlen=m_length;
m_pData = (LPBYTE) malloc(oldlen+addlen);
m_length = oldlen+addlen;
memcpy(m_pData, oldData, oldlen);
free(oldData);
memcpy(m_pData+oldlen,p,addlen);
SetSel(oldlen, m_length);
m_currentAddress = oldlen;
m_editPos.x = m_editPos.y = 0;
m_currentMode = EDIT_HIGH;
m_topindex = 0;
m_bUpdate = TRUE;
}
void CHexEdit::Clear()
{
free(m_pData);
m_pData = NULL; // pointer to data
m_length = 0;
m_selStart = 0xffffffff;
m_selEnd = 0xffffffff;
m_bUpdate=TRUE;
}
BOOL CHexEdit::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
return CEdit::OnEraseBkgnd(pDC);
}
void CHexEdit::OnLButtonDblClk(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
// CEdit::OnLButtonDblClk(nFlags, point);
}
void CHexEdit::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// TODO: Add your message handler code here and/or call default
CEdit::OnHScroll(nSBCode, nPos, pScrollBar);
}
void CHexEdit::OnSize(UINT nType, int cx, int cy)
{
CEdit::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -