?? hexeditctrl.cpp
字號:
{
switch(nChar)
{
case 0x03:
if(IsSelected())
{
NormalizeSel();
OnEditCopy();
}
return;
case 0x16:
OnEditPaste();
return;
case 0x18:
if(IsSelected())
{
NormalizeSel();
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';
// This block allows for dynamically adding to the end of the buffer
if (m_currentAddress >= m_length)
{
LPBYTE p = (LPBYTE) calloc(m_length + 1, 1);
memcpy(p, m_pData, m_length);
free(m_pData);
m_pData = p;
SetSel(-1, -1);
m_length = m_length + 1;
m_bUpdate = TRUE;
}
// End mod
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::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
nFlags; nRepCnt;
BOOL bShift = GetKeyState(VK_SHIFT) & 0x80000000;
BOOL bac = m_bNoAddressChange;
m_bNoAddressChange = TRUE;
switch(nChar)
{
case VK_DOWN:
if(bShift)
{
if(!IsSelected())
{
m_selStart = m_currentAddress;
}
Move(0,1);
m_selEnd = m_currentAddress;
if(m_currentMode == EDIT_HIGH || m_currentMode == EDIT_LOW)
m_selEnd++;
RedrawWindow();
break;
}
else
SetSel(-1, -1);
Move(0,1);
break;
case VK_UP:
if(bShift)
{
if(!IsSelected())
{
m_selStart = m_currentAddress;
}
Move(0,-1);
m_selEnd = m_currentAddress;
RedrawWindow();
break;
}
else
SetSel(-1, -1);
Move(0,-1);
break;
case VK_LEFT:
if(bShift)
{
if(!IsSelected())
{
m_selStart = m_currentAddress;
}
Move(-1,0);
m_selEnd = m_currentAddress;
RedrawWindow();
break;
}
else
SetSel(-1, -1);
Move(-1,0);
break;
case VK_RIGHT:
if(bShift)
{
if(!IsSelected())
{
m_selStart = m_currentAddress;
}
Move(1,0);
m_selEnd = m_currentAddress;
if(m_currentMode == EDIT_HIGH || m_currentMode == EDIT_LOW)
m_selEnd++;
RedrawWindow();
break;
}
else
SetSel(-1, -1);
Move(1,0);
break;
case VK_PRIOR:
if(bShift)
{
if(!IsSelected())
{
m_selStart = m_currentAddress;
}
OnVScroll(SB_PAGEUP, 0, NULL);
Move(0,0);
m_selEnd = m_currentAddress;
RedrawWindow();
break;
}
else
SetSel(-1, -1);
OnVScroll(SB_PAGEUP, 0, NULL);
Move(0,0);
break;
case VK_NEXT:
if(bShift)
{
if(!IsSelected())
{
m_selStart = m_currentAddress;
}
OnVScroll(SB_PAGEDOWN, 0, NULL);
Move(0,0);
m_selEnd = m_currentAddress;
RedrawWindow();
break;
}
else
SetSel(-1, -1);
OnVScroll(SB_PAGEDOWN, 0, NULL);
Move(0,0);
break;
case VK_HOME:
if(bShift)
{
if(!IsSelected())
{
m_selStart = m_currentAddress;
}
if(GetKeyState(VK_CONTROL) & 0x80000000)
{
OnVScroll(SB_THUMBTRACK, 0, NULL);
Move(0,0);
}
else
{
m_currentAddress /= m_bpr;
m_currentAddress *= m_bpr;
Move(0,0);
}
m_selEnd = m_currentAddress;
RedrawWindow();
break;
}
else
SetSel(-1, -1);
if(GetKeyState(VK_CONTROL) & 0x80000000)
{
OnVScroll(SB_THUMBTRACK, 0, NULL);
m_currentAddress = 0;
Move(0,0);
}
else
{
m_currentAddress /= m_bpr;
m_currentAddress *= m_bpr;
Move(0,0);
}
break;
case VK_END:
if(bShift)
{
if(!IsSelected())
{
m_selStart = m_currentAddress;
}
if(GetKeyState(VK_CONTROL) & 0x80000000)
{
m_currentAddress = m_length-1;
OnVScroll(SB_THUMBTRACK, ((m_length+(m_bpr/2)) / m_bpr) - m_lpp, NULL);
Move(0,0);
}
else
{
m_currentAddress /= m_bpr;
m_currentAddress *= m_bpr;
m_currentAddress += m_bpr - 1;
if(m_currentAddress > m_length)
m_currentAddress = m_length-1;
Move(0,0);
}
m_selEnd = m_currentAddress;
RedrawWindow();
break;
}
else
SetSel(-1, -1);
if(GetKeyState(VK_CONTROL) & 0x80000000)
{
m_currentAddress = m_length-1;
if(m_bHalfPage)
OnVScroll(SB_THUMBTRACK, 0, NULL);
else
OnVScroll(SB_THUMBTRACK, ((m_length+(m_bpr/2)) / m_bpr) - m_lpp, NULL);
Move(0,0);
}
else
{
m_currentAddress /= m_bpr;
m_currentAddress *= m_bpr;
m_currentAddress += m_bpr - 1;
if(m_currentAddress > m_length)
m_currentAddress = m_length-1;
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':
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;
}
m_bNoAddressChange = bac;
}
void CHexEdit::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;
m_bNoAddressChange = TRUE;
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_bNoAddressChange = FALSE;
//ScrollIntoView(m_currentAddress);
RepositionCaret(m_currentAddress);
}
void CHexEdit::SetSel(int s, int e)
{
DestroyCaret();
m_selStart = s;
m_selEnd = e;
if (! IsWindow(m_hWnd) )
return;
RedrawWindow();
if(m_editPos.x == 0 && m_bShowAddress)
CreateAddressCaret();
else
CreateEditCaret();
SetCaretPos(m_editPos);
ShowCaret();
}
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::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 CHexEdit::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(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()
{
// TODO: Add your command handler code here
}
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);
m_pData = p;
SetSel(-1, -1);
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);
m_pData = p;
SetSel(-1, -1);
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;
}
int CHexEdit::GetLen()
{
return m_length;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -