📄 hexedvw.cpp
字号:
Move(0,0);
}
break;
case VK_INSERT:
SelInsert(m_currentAddress, max(1, m_selEnd-m_selStart));
RedrawWindow();
break;
case VK_DELETE:
if(IsSelected())
{
OnEditClear();
}
else
{
SelDelete(m_currentAddress, m_currentAddress+1);
RedrawWindow();
}
break;
case _T ('\t'):
switch(m_currentMode)
{
case EDIT_NONE:
m_currentMode = EDIT_HIGH;
break;
case EDIT_HIGH:
case EDIT_LOW:
m_currentMode = EDIT_ASCII;
break;
case EDIT_ASCII:
m_currentMode = EDIT_HIGH;
break;
}
Move(0,0);
break;
}
if (bac)
m_dwFlags |= HVW_NO_ADDRESS_CHANGE;
else
m_dwFlags &= ~HVW_NO_ADDRESS_CHANGE;
}
void CHexEditView::Move(int x, int y)
{
switch(m_currentMode)
{
case EDIT_NONE:
return;
case EDIT_HIGH:
if(x != 0)
m_currentMode = EDIT_LOW;
if(x == -1)
m_currentAddress --;
m_currentAddress += y* m_bpr;
break;
case EDIT_LOW:
if(x != 0)
m_currentMode = EDIT_HIGH;
if(x == 1)
m_currentAddress++;
m_currentAddress += y* m_bpr;
break;
case EDIT_ASCII:
{
m_currentAddress += x;
m_currentAddress += y*m_bpr;
}
break;
}
if(m_currentAddress < 0)
m_currentAddress = 0;
if(m_currentAddress >= *m_length)
{
m_currentAddress -= x;
m_currentAddress -= y*m_bpr;
}
m_dwFlags |= HVW_NO_ADDRESS_CHANGE;
if(m_currentAddress < m_topindex)
{
OnVScroll(SB_LINEUP, 0, NULL);
}
if(m_currentAddress >= m_topindex + m_lpp*m_bpr)
{
OnVScroll(SB_LINEDOWN, 0, NULL);
}
m_dwFlags &= ~HVW_NO_ADDRESS_CHANGE;
//ScrollIntoView(m_currentAddress);
RepositionCaret(m_currentAddress);
}
void CHexEditView::SetSel(int s, int e)
{
DestroyCaret();
m_selStart = s;
m_selEnd = e;
RedrawWindow();
if(m_editPos.x == 0 && (m_dwFlags & HVW_SHOW_ADDRESS))
CreateAddressCaret();
else
CreateEditCaret();
SetCaretPos(m_editPos);
ShowCaret();
}
void CHexEditView::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 CHexEditView::ScrollIntoView(int p)
{
if(p < m_topindex || p > m_topindex + m_lpp*m_bpr)
{
m_topindex = (p/m_bpr) * m_bpr;
m_topindex -= (m_lpp / 3) * m_bpr;
if(m_topindex < 0)
m_topindex = 0;
UpdateScrollbars();
RedrawWindow();
}
}
void CHexEditView::OnContextMenu(CWnd*, 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(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(_T ("BinaryData"))))
pPopup->EnableMenuItem(ID_EDIT_PASTE, MF_GRAYED|MF_DISABLED|MF_BYCOMMAND);
}
}
pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this); }
}
void CHexEditView::OnEditClear()
{
m_currentAddress = m_selStart;
SelDelete(m_selStart, m_selEnd);
RepositionCaret(m_currentAddress);
RedrawWindow();
}
void CHexEditView::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
LPTSTR p = (LPTSTR)::GlobalLock(hMemb);
memcpy(p, (*m_pData)+m_selStart, dwLen);
::GlobalUnlock(hMemb);
// copy ascii
p = (LPTSTR)::GlobalLock(hMema);
for(int i = 0; i < dwLen;)
{
TOHEX((*m_pData)[m_selStart+i], p);
*p++ = _T (' ');
i++;
}
::GlobalUnlock(hMema);
pSource->CacheGlobalData(RegisterClipboardFormat(_T ("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 = _T ('.');
::GlobalUnlock(hMema);
pSource->CacheGlobalData(RegisterClipboardFormat(_T ("BinaryData")), hMemb);
pSource->CacheGlobalData(CF_TEXT, hMema);
}
pSource->SetClipboard();
}
void CHexEditView::OnEditCut()
{
OnEditCopy();
SelDelete(m_selStart, m_selEnd);
RedrawWindow();
}
void CHexEditView::OnEditPaste()
{
COleDataObject obj;
if (obj.AttachClipboard())
{
HGLOBAL hmem = NULL;
if (obj.IsDataAvailable(RegisterClipboardFormat(_T ("BinaryData"))))
{
hmem = obj.GetGlobalData(RegisterClipboardFormat(_T ("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 CHexEditView::OnEditSelectAll()
{
m_selStart = 0;
m_selEnd = *m_length;
DestroyCaret();
RedrawWindow();
}
void CHexEditView::OnEditUndo()
{
// TODO: Add your command handler code here
}
void CHexEditView::NormalizeSel()
{
if(m_selStart > m_selEnd)
m_selStart ^= m_selEnd ^= m_selStart ^= m_selEnd;
}
void CHexEditView::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);
CDocument *pDoc = GetDocument ();
pDoc->SetModifiedFlag ();
if(m_currentAddress > *m_length)
{
m_currentAddress = *m_length;
RepositionCaret(m_currentAddress);
}
m_dwFlags |= HVW_UPDATE;
}
void CHexEditView::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;
CDocument *pDoc = GetDocument ();
pDoc->SetModifiedFlag ();
m_dwFlags |= HVW_UPDATE;
}
CSize CHexEditView::GetSel()
{
return CSize(m_selStart, m_selEnd);
}
void CHexEditView::SetData(LPBYTE p, int len)
{
free(*m_pData);
LPBYTE pp = (LPBYTE) malloc(len);
memcpy(pp, p, len);
SetOrigData(pp, len);
}
void CHexEditView::SetOrigData(LPBYTE p, int len)
{
*m_pData = p;
*m_length = len;
ResetView ();
}
void CHexEditView::ResetView ()
{
SetSel(-1, -1);
m_currentAddress = 0;
m_editPos.x = m_editPos.y = 0;
m_currentMode = EDIT_HIGH;
m_topindex = 0;
m_dwFlags |= HVW_UPDATE;
}
int CHexEditView::GetData(LPBYTE p, int len)
{
memcpy(p, *m_pData, min(len, *m_length));
return *m_length;
}
int CHexEditView::GetOrigData(LPBYTE &p)
{
p = *m_pData;
return *m_length;
}
void CHexEditView::OnReadOnly()
{
m_dwFlags ^= HVW_READ_ONLY;
m_dwFlags |= HVW_UPDATE;
RedrawWindow ();
}
void CHexEditView::OnUpdateReadOnly (CCmdUI * pCmdUI)
{
pCmdUI->SetCheck ((m_dwFlags & HVW_READ_ONLY) != 0);
}
void CHexEditView::OnFormatShowAddress()
{
m_dwFlags ^= HVW_SHOW_ADDRESS;
m_dwFlags |= HVW_UPDATE;
RedrawWindow ();
}
void CHexEditView::OnUpdateFormatShowAddress (CCmdUI * pCmdUI)
{
pCmdUI->SetCheck ((m_dwFlags & HVW_SHOW_ADDRESS) != 0);
}
void CHexEditView::OnFormatShowAscii()
{
m_dwFlags ^= HVW_SHOW_ASCII;
m_dwFlags |= HVW_UPDATE;
RedrawWindow ();
}
void CHexEditView::OnUpdateFormatShowAscii (CCmdUI * pCmdUI)
{
pCmdUI->SetCheck ((m_dwFlags & HVW_SHOW_ASCII) != 0);
}
void CHexEditView::OnFormatShowHex()
{
m_dwFlags ^= HVW_SHOW_HEX;
m_dwFlags |= HVW_UPDATE;
RedrawWindow ();
}
void CHexEditView::OnUpdateFormatShowHex (CCmdUI * pCmdUI)
{
pCmdUI->SetCheck ((m_dwFlags & HVW_SHOW_HEX) != 0);
}
void CHexEditView::OnFormatWideAddress()
{
m_dwFlags ^= HVW_WIDE_ADDRESS;
m_dwFlags |= HVW_UPDATE;
RedrawWindow ();
}
void CHexEditView::OnUpdateFormatWideAddress (CCmdUI * pCmdUI)
{
pCmdUI->SetCheck ((m_dwFlags & HVW_WIDE_ADDRESS) != 0);
}
void CHexEditView::OnBpr (UINT nCmd)
{
SetBPR(nCmd - ID_FORMAT_BPR_FIRST + 1);
RedrawWindow ();
}
void CHexEditView::OnUpdateBpr (CCmdUI * pCmdUI)
{
pCmdUI->SetCheck (pCmdUI->m_nID - ID_FORMAT_BPR_FIRST + 1 == (UINT) m_bpr);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -