📄 hexeditbase.cpp
字号:
if( (nFlags & MK_LBUTTON) && (m_nSelectingBeg != NOSECTION_VAL)) {
// first make a self built drag-detect (one that doesn't block)
if(!m_cDragRect.PtInRect(point)) {
m_cDragRect = CRect(-1, -1, -1, -1); // when once, out, kill it...
} else {
return; // okay, still not draging
}
if( !m_tPaintDetails.cPaintingRect.PtInRect(point) && (GetStyle()&ES_MULTILINE) ) {
int iRepSpeed = 0;
int iDelta = 0;
if(point.y < m_tPaintDetails.cPaintingRect.top) {
iDelta = -1;
iRepSpeed = (int)m_tPaintDetails.cPaintingRect.top + 1 - (int)point.y;
} else if(point.y > m_tPaintDetails.cPaintingRect.bottom ) {
iDelta = 1;
iRepSpeed = (int)point.y - (int)m_tPaintDetails.cPaintingRect.bottom + 1;
}
if(iDelta != 0) {
iRepSpeed /= 5;
if(iRepSpeed > 5) {
iRepSpeed = 6;
}
StartMouseRepeat(point, iDelta, (short)(7 - iRepSpeed));
}
m_cMouseRepPoint = point; // make sure we always have the latest point
} else {
StopMouseRepeat();
}
GetAddressFromPoint(point, m_nCurrentAddress, m_bHighBits);
SetEditCaretPos(m_nCurrentAddress, m_bHighBits);
m_nSelectingEnd = m_nCurrentAddress;
m_nSelectionBegin = m_nSelectingBeg;
m_nSelectionEnd = m_nSelectingEnd;
NORMALIZE_SELECTION(m_nSelectionBegin, m_nSelectionEnd);
Invalidate();
}
}
void CHexEditBase::OnTimer(UINT nTimerID)
{
if( (m_pData == NULL) || (m_nLength < 1) ) {
return;
}
if(m_bIsMouseRepActive && (nTimerID == MOUSEREP_TIMER_TID) ) {
if(m_nMouseRepCounter > 0) {
m_nMouseRepCounter--;
} else {
m_nMouseRepCounter = m_nMouseRepSpeed;
MoveScrollPostionY(m_iMouseRepDelta, false);
GetAddressFromPoint(m_cMouseRepPoint, m_nCurrentAddress, m_bHighBits);
SetEditCaretPos(m_nCurrentAddress, m_bHighBits);
m_nSelectingEnd = m_nCurrentAddress;
m_nSelectionBegin = m_nSelectingBeg;
m_nSelectionEnd = m_nSelectingEnd;
NORMALIZE_SELECTION(m_nSelectionBegin, m_nSelectionEnd);
Invalidate();
}
}
}
void CHexEditBase::StartMouseRepeat(const CPoint& cPoint, int iDelta, WORD nSpeed)
{
if( (m_pData == NULL) || (m_nLength < 1) ) {
return;
}
m_cMouseRepPoint = cPoint;
m_nMouseRepSpeed = nSpeed;
m_iMouseRepDelta = iDelta;
if(!m_bIsMouseRepActive && (GetStyle() & ES_MULTILINE)) {
m_bIsMouseRepActive = true;
m_nMouseRepCounter = nSpeed;
SetTimer(MOUSEREP_TIMER_TID, MOUSEREP_TIMER_ELAPSE, NULL);
}
}
void CHexEditBase::StopMouseRepeat()
{
if(m_bIsMouseRepActive) {
m_bIsMouseRepActive = false;
KillTimer(MOUSEREP_TIMER_TID);
}
}
bool CHexEditBase::OnEditInput(WORD nInput)
{
// ASSERT(m_nCurrentAddress < m_nLength);
if( (nInput > 255) || (m_pData == NULL) || m_bReadOnly) {
return false;
}
if (m_bInputAscii)
{
m_pData[m_nCurrentAddress] = (char)nInput;
MoveCurrentAddress(1, true);
}
else
{
BYTE nValue = 255;
char nKey = (char)tolower(nInput);
if( (nKey >= 'a') && (nKey <= 'f') ) {
nValue = nKey - (BYTE)'a' + (BYTE)0xa;
} else if ( (nKey >= '0') && (nKey <= '9') ) {
nValue = nKey - (BYTE)'0';
}
if(nValue != 255) {
if(m_bHighBits) {
nValue <<= 4;
m_pData[m_nCurrentAddress] &= 0x0f;
m_pData[m_nCurrentAddress] |= nValue;
MoveCurrentAddress(0, false);
} else {
m_pData[m_nCurrentAddress] &= 0xf0;
m_pData[m_nCurrentAddress] |= nValue;
MoveCurrentAddress(1, true);
}
Invalidate();
NotifyParent(HEN_CHANGE);
} else {
return false;
}
}
return true;
}
LRESULT CHexEditBase::OnUmSetScrollRange(WPARAM, LPARAM)
{
SetScrollbarRanges();
return 0;
}
LRESULT CHexEditBase::OnWMSetFont(WPARAM wParam, LPARAM lParam)
{
if(wParam != NULL) {
CFont *pFont = CFont::FromHandle((HFONT)wParam);
if(pFont != NULL) {
LOGFONT tLogFont;
memset(&tLogFont, 0, sizeof(LOGFONT));
if( pFont->GetLogFont(&tLogFont) && ((tLogFont.lfPitchAndFamily & 3) == FIXED_PITCH) ) {
if((HFONT)m_cFont != NULL) {
m_cFont.DeleteObject();
ASSERT((HFONT)m_cFont == NULL);
}
m_cFont.CreateFontIndirect(&tLogFont);
}
}
}
if((HFONT)m_cFont == NULL) {
//if we failed so far, we just create a new system font
m_cFont.CreateStockObject(SYSTEM_FIXED_FONT);
}
m_bRecalc = true;
if(lParam && ::IsWindow(m_hWnd)) {
Invalidate();
}
return 0; // no return value needed
}
LRESULT CHexEditBase::OnWMGetFont(WPARAM wParam, LPARAM lParam)
{
wParam = 0;
lParam = 0;
return (LRESULT)((HFONT)m_cFont);
}
LRESULT CHexEditBase::OnWMChar(WPARAM wParam, LPARAM)
{
if(wParam == 0x08) {
//example: backspace-processing, (if once needed)
//OnEditBackspace();
//return 0;
} /* other special processing here (insert: "else if() {}" ) */ else {
if(OnEditInput((WORD)wParam)) {
return 0;
}
}
return 1;
}
BOOL CHexEditBase::PreTranslateMessage(MSG* pMsg)
{
if(pMsg->message == WM_KEYDOWN) {
if(GetKeyState(VK_CONTROL) & 0x80000000) {
switch(pMsg->wParam) {
case 'C': // ctrl + c: copy
OnEditCopy();
return TRUE;
case 'V': // ctrl + v: paste
OnEditPaste();
return TRUE;
case 'A': // ctrl + a: select all
OnEditSelectAll();
return TRUE;
}
}
}
return CWnd::PreTranslateMessage(pMsg);
}
void CHexEditBase::SetScrollPositionY(UINT nPosition, bool bUpdate)
{
if(!(GetStyle() & ES_MULTILINE)) {
return;
}
if(nPosition > m_nScrollRangeY) {
nPosition = m_nScrollRangeY;
}
SetScrollPos(SB_VERT, (int)nPosition, TRUE);
if( (nPosition != m_nScrollPostionY) && bUpdate && ::IsWindow(m_hWnd) ) {
m_nScrollPostionY = nPosition;
Invalidate();
}
SetEditCaretPos(m_nCurrentAddress, m_bHighBits);
m_nScrollPostionY = nPosition;
}
void CHexEditBase::SetScrollPositionX(UINT nPosition, bool bUpdate)
{
if(nPosition > m_nScrollRangeX) {
nPosition = m_nScrollRangeX;
}
SetScrollPos(SB_HORZ, (int)nPosition, TRUE);
if((nPosition != m_nScrollPostionX) && bUpdate && ::IsWindow(m_hWnd) ) {
m_nScrollPostionX = nPosition;
Invalidate();
SetEditCaretPos(m_nCurrentAddress, m_bHighBits);
}
m_nScrollPostionX = nPosition;
}
void CHexEditBase::MoveCurrentAddress(int iDeltaAdr, bool bHighBits)
{
bool bIsShift = (GetKeyState(VK_SHIFT) & 0x80000000) == 0x80000000;
if(m_pData == NULL) {
return;
}
UINT nAddress = m_nCurrentAddress;
if(!bIsShift) {
m_nSelectingBeg = NOSECTION_VAL;
m_nSelectionBegin = NOSECTION_VAL;
m_nSelectingEnd = NOSECTION_VAL;
m_nSelectionEnd = NOSECTION_VAL;
}
if(iDeltaAdr > 0) {
// go down
if(nAddress + iDeltaAdr >= m_nLength) {
// we reached the end
nAddress = m_nLength - 1;
bHighBits = false;
} else {
nAddress += iDeltaAdr;
}
} else if (iDeltaAdr < 0) {
if((UINT)(-iDeltaAdr) <= nAddress) {
nAddress -= (UINT)(-iDeltaAdr);
} else {
nAddress = 0;
bHighBits = true;
}
}
if(bIsShift && (m_nSelectingBeg != NOSECTION_VAL)) {
m_nSelectingEnd = nAddress;
m_nSelectionBegin = m_nSelectingBeg;
m_nSelectionEnd = m_nSelectingEnd;
NORMALIZE_SELECTION(m_nSelectionBegin, m_nSelectionEnd);
}
MakeVisible(nAddress, nAddress, true);
SetEditCaretPos(nAddress, bHighBits);
}
void CHexEditBase::OnKeyDown(UINT nChar, UINT, UINT)
{
bool bIsShift = (GetKeyState(VK_SHIFT) & 0x80000000) == 0x80000000;
if( bIsShift && (m_nSelectingBeg == NOSECTION_VAL) ) {
// start with selecting
m_nSelectingBeg = m_nCurrentAddress;
}
switch(nChar) {
case VK_DOWN:
MoveCurrentAddress(m_tPaintDetails.nBytesPerRow, m_bHighBits);
break;
case VK_UP:
MoveCurrentAddress(-(int)m_tPaintDetails.nBytesPerRow, m_bHighBits);
break;
case VK_RIGHT:
if (m_bInputAscii)
{
MoveCurrentAddress(1, true);
}
else
{
if(m_bHighBits) {
// offset stays the same, caret moves to low-byte
MoveCurrentAddress(0, false);
} else {
MoveCurrentAddress(1, true);
}
}
break;
case VK_LEFT:
if (m_bInputAscii)
{
MoveCurrentAddress(-1, true);
}
else
{
if(!m_bHighBits) {
// offset stays the same, caret moves to high-byte
MoveCurrentAddress(0, true);
} else {
MoveCurrentAddress(-1, false);
}
}
break;
case VK_PRIOR:
MoveCurrentAddress(-(int)(m_tPaintDetails.nBytesPerRow*(m_tPaintDetails.nVisibleLines-1)), m_bHighBits);
break;
case VK_NEXT:
MoveCurrentAddress(m_tPaintDetails.nBytesPerRow*(m_tPaintDetails.nVisibleLines-1), m_bHighBits);
break;
case VK_HOME:
MoveCurrentAddress(-0x8000000, true);
break;
case VK_END:
MoveCurrentAddress(0x7ffffff, false);
break;
case VK_INSERT:
// not suported yet
break;
case VK_DELETE:
// not suported yet
break;
case VK_RETURN:
// not suported yet
break;
case VK_TAB:
GetParent()->GetNextDlgTabItem(this, bIsShift)->SetFocus();
break;
}
}
void CHexEditBase::OnContextMenu(CWnd*, CPoint cPoint)
{
CString cString;
if( (cPoint.x == -1) && (cPoint.y == -1) ) {
//keystroke invocation
cPoint = CPoint(5, 5);
ClientToScreen(&cPoint);
} else {
CPoint cRelPoint(cPoint);
ScreenToClient(&cRelPoint);
bool bHigh;
UINT nAdr;
GetAddressFromPoint(cRelPoint, nAdr, bHigh);
if( !IsSelection() || (nAdr < m_nSelectionBegin) || (nAdr > m_nSelectionEnd) ) {
// no selection or outside of selection
if(IsSelection()) {
// kill selection
SetSelection(NOSECTION_VAL, NOSECTION_VAL, false, true);
}
SetEditCaretPos(nAdr, true); //always high, because of paste...
}
}
CMenu cMenu;
if(!cMenu.CreatePopupMenu()) {
TRACE("CHexEditBase::OnContextMenu: ERROR: couldn't create PopupMenue\n");
return;
}
// menue-item: copy
cMenu.AppendMenu(IsSelection() ? MF_STRING : MF_GRAYED|MF_DISABLED|MF_STRING, ID_EDIT_COPY, (LPCSTR)m_cContextCopy);
// menue-item: paste
COleDataObject cSource;
cSource.AttachClipboard();
cMenu.AppendMenu(cSource.IsDataAvailable(m_nBinDataClipboardFormat) && !m_bReadOnly ? MF_STRING : MF_GRAYED|MF_DISABLED|MF_STRING,
ID_EDIT_PASTE, (LPCSTR)m_cContextPaste);
cSource.Release();
OnExtendContextMenu(cMenu);
cMenu.TrackPopupMenu(TPM_LEFTALIGN, cPoint.x, cPoint.y, this, CRect(0,0,100,100));
}
void CHexEditBase::OnEditCopy()
{
if( (m_nSelectionBegin != NOSECTION_VAL) && (m_nSelectionEnd != NOSECTION_VAL) ) {
ASSERT(m_nSelectionEnd >= m_nSelectionBegin);
BYTE *pData = m_pData + m_nSelectionBegin;
BYTE *pDataEnd = m_pData + m_nSelectionEnd;
CString cStr;
COleDataSource *pSource = new COleDataSource;
char* pBuf = new char[m_tPaintDetails.nBytesPerRow*3+2];
try {
memset(pBuf, ' ', m_tPaintDetails.nBytesPerRow*3);
UINT nColumn = m_nSelectionBegin%m_tPaintDetails.nBytesPerRow;
if((UINT)(pDataEnd - pData) <= m_tPaintDetails.nBytesPerRow) {
nColumn = 0;
}
UINT nAdr = m_nSelectionBegin;
while(pData <= pDataEnd ) {
CString cStr2;
//cStr2.Format(_T("%0*X: "), (int)m_nAdrSize, nAdr);
for(; nColumn<m_tPaintDetails.nBytesPerRow && pData <= pDataEnd; ++nColumn, ++pData, ++nAdr) {
pBuf[nColumn*3] = tabHexCharacters[*pData>>4];
pBuf[nColumn*3+1] = tabHexCharacters[*pData&0xf];
}
pBuf[(nColumn-1)*3+2] = '\0';
cStr += cStr2;
cStr += pBuf;
cStr += _T("\n");
nColumn = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -