📄 hexwnd.cpp
字号:
{
// Set position:
iCurByte = (BYTELINE + 1) * iBytesPerLine - 1;
if (iCurByte > LASTBYTE+1)
iCurByte = LASTBYTE+1;
iCurNibble = 1;
if (m_iEnteringMode == BYTES)
log_column = BYTES_LOGICAL_COLUMN;
else
log_column = CHARS_LOGICAL_COLUMN;
// If logical column too far to right:
if (log_column > LAST_LOG_COLUMN)
{
iHscrollPos = log_column - cxBuffer + 1;
adjust_hscrollbar ();
repaint ();
}
else
{
repaint (BYTELINE);
}
if (CURSOR_TOO_HIGH || CURSOR_TOO_LOW)
{
iCurLine = max (0, iCurByte/iBytesPerLine-cyBuffer/2);
adjust_vscrollbar ();
repaint ();
}
break;
}
case VK_UP:
// If possible, cursor one line up.
if (iCurByte >= iBytesPerLine)
iCurByte -= iBytesPerLine;
// If cursor pos. before or behind visible area...
scrollflag = FALSE;
if (CURSOR_TOO_HIGH || CURSOR_TOO_LOW)
{
adjust_vscrollbar ();
scrollflag = TRUE;
}
if (m_iEnteringMode == BYTES)
log_column = BYTES_LOGICAL_COLUMN;
else
log_column = CHARS_LOGICAL_COLUMN;
// If cursor too far horiz.
if (log_column < iHscrollPos || log_column > LAST_LOG_COLUMN)
{
iHscrollPos = log_column;
adjust_hscrollbar ();
repaint ();
break;
}
else if (!scrollflag)
{
repaint (BYTELINE+1);
repaint (BYTELINE);
}
else // scrollflag
{
if (iCurLine-BYTELINE==1) // One line up.
{
iCurLine = BYTELINE;
RECT r;
r.left = CLIENT_BORDER_WIDTH;
r.top = CLIENT_BORDER_WIDTH;
r.right = cxClient - CLIENT_BORDER_WIDTH;
r.bottom = cyClient - CLIENT_BORDER_WIDTH;
ScrollWindow (hwnd, 0, cyChar, &r, &r);
repaint (BYTELINE+1);
repaint (BYTELINE);
}
else
{
iCurLine = BYTELINE;
repaint ();
}
}
break;
case VK_DOWN:
// If possible cursor one line down.
if (iCurByte+iBytesPerLine <= DataArray.GetLength())
iCurByte += iBytesPerLine;
scrollflag = FALSE;
if (CURSOR_TOO_HIGH || CURSOR_TOO_LOW)
{
adjust_vscrollbar ();
scrollflag = TRUE;
}
if (m_iEnteringMode == BYTES)
log_column = BYTES_LOGICAL_COLUMN;
else
log_column = CHARS_LOGICAL_COLUMN;
if (log_column < iHscrollPos || log_column > LAST_LOG_COLUMN)
{
iHscrollPos = log_column;
adjust_hscrollbar ();
repaint ();
break;
}
else if (!scrollflag)
{
repaint (BYTELINE-1);
repaint (BYTELINE);
}
else // scrollflag
{
if (BYTELINE==iCurLine+cyBuffer) // Cursor one line down.
{
iCurLine = max (0, BYTELINE-(cyBuffer-1)); // Cursor at bottom of screen.
RECT r;
r.left = CLIENT_BORDER_WIDTH;
r.top = CLIENT_BORDER_WIDTH;
r.right = cxClient - CLIENT_BORDER_WIDTH;
r.bottom = cyClient - CLIENT_BORDER_WIDTH;
ScrollWindow (hwnd, 0, -cyChar, &r, &r);
repaint (BYTELINE-1);
repaint (BYTELINE);
repaint (BYTELINE+1);
mark_char( 0 );
}
else
{
iCurLine = max (0, BYTELINE-(cyBuffer-1));
repaint ();
}
}
break;
case VK_LEFT:
{
if (m_iEnteringMode == BYTES) // BYTE-Mode.
{
if (iCurNibble == 1) // 1 nibble to the left...
iCurNibble = 0;
else if (iCurByte != 0) // Or 1 byte to the left.
{
iCurByte--;
iCurNibble = 1;
}
}
else // CHAR-Mode.
{
if (iCurByte != 0)
iCurByte--; // 1 Byte to the left.
}
// If new line not visible, then scroll.
scrollflag = FALSE;
if (CURSOR_TOO_HIGH || CURSOR_TOO_LOW)
{
iCurLine = BYTELINE;
adjust_vscrollbar ();
scrollflag = TRUE;
}
if (m_iEnteringMode == BYTES)
log_column = BYTES_LOGICAL_COLUMN;
else
log_column = CHARS_LOGICAL_COLUMN;
if (log_column < iHscrollPos)
{
iHscrollPos = log_column;
adjust_hscrollbar ();
repaint ();
break;
}
else if (log_column > LAST_LOG_COLUMN)
{
iHscrollPos = log_column-(cxBuffer-1);
adjust_hscrollbar ();
repaint ();
break;
}
else if (!scrollflag)
{
if (iCurByte%iBytesPerLine==iBytesPerLine-1) // Just got to previous line.
repaint (BYTELINE+1);
repaint (BYTELINE);
}
else
repaint ();
break;
}
case VK_RIGHT:
{
if (m_iEnteringMode == BYTES)
{
if (iCurNibble == 0)
iCurNibble = 1;
else if (iCurByte <= LASTBYTE)
{
iCurNibble = 0;
iCurByte++;
}
}
else
{
if (iCurByte <= LASTBYTE)
iCurByte++;
}
scrollflag = FALSE;
if (CURSOR_TOO_HIGH || CURSOR_TOO_LOW)
{
iCurLine = max (BYTELINE-cyBuffer+1, 0);
adjust_vscrollbar ();
scrollflag = TRUE;
}
if (m_iEnteringMode == BYTES)
log_column = BYTES_LOGICAL_COLUMN;
else
log_column = CHARS_LOGICAL_COLUMN;
if (log_column >= iHscrollPos+cxBuffer)
{
iHscrollPos = log_column-(cxBuffer-1);
adjust_hscrollbar ();
repaint ();
break;
}
else if (log_column < iHscrollPos)
{
iHscrollPos = log_column;
adjust_hscrollbar ();
repaint ();
break;
}
else if (scrollflag != TRUE) // If one line down but cursor not too far horiz.
{
if (iCurByte%iBytesPerLine==0)
repaint (BYTELINE-1);
repaint (BYTELINE);
}
else
repaint ();
break;
}
case VK_PRIOR:
if (BYTELINE >= cyBuffer)
{
iCurByte -= cyBuffer * iBytesPerLine; // 1 page up.
iCurLine -= cyBuffer;
if (iCurLine < 0)
iCurLine = BYTELINE;
}
else
{
iCurLine = 0; // To top.
iCurByte = BYTEPOS;
}
if (CURSOR_TOO_HIGH || CURSOR_TOO_LOW)
iCurLine = iCurByte/iBytesPerLine;
adjust_vscrollbar ();
repaint ();
break;
case VK_NEXT:
iCurByte += cyBuffer*iBytesPerLine;
if (iCurByte > LASTBYTE+1)
{
iCurByte = (LASTBYTE+1)/iBytesPerLine*iBytesPerLine + BYTEPOS;
if (iCurByte > LASTBYTE+1)
iCurByte = LASTBYTE+1;
iCurLine = BYTELINE;
adjust_view_for_caret ();
}
else
{
iCurLine += cyBuffer;
if (iCurLine > LASTLINE)
iCurLine = BYTELINE;
}
if (CURSOR_TOO_HIGH || CURSOR_TOO_LOW)
iCurLine = max (BYTELINE-cyBuffer+1, 0);
adjust_vscrollbar ();
repaint ();
break;
}
return 0;
}
//--------------------------------------------------------------------------------------------
// Handler for character keys.
int HexEditorWindow::character (char ch)
{
// If there is selection return now.
if (bSelected)
return 0;
// If we are in read-only mode, give a warning and return,
// except if TAB was pressed.
if( bReadOnly && ch != '\t' )
{
MessageBox( hwnd, "Can't change file because read-only mode is engaged!", "Keyboard editing", MB_OK | MB_ICONERROR );
return 0;
}
char x, c = tolower (ch);
if (ch == '\t') // TAB => change EnteringMode.
{
if (m_iEnteringMode == BYTES)
m_iEnteringMode = CHARS;
else
m_iEnteringMode = BYTES;
int log_column;
if (m_iEnteringMode == BYTES)
log_column = BYTES_LOGICAL_COLUMN;
else
log_column = CHARS_LOGICAL_COLUMN;
if (log_column >= iHscrollPos+cxBuffer) // Cursor too far right...
iHscrollPos = log_column-(cxBuffer-1); // Cursor to right border.
else if (log_column < iHscrollPos) // Cursor too far left.
iHscrollPos = log_column; // Cursor to left border.
adjust_hscrollbar ();
repaint ();
return 0;
}
// If read-only mode, return.
if( bReadOnly )
return 1;
// If in bytes and char is not a hex digit, return.
if (m_iEnteringMode==BYTES && !((c>='a'&&c<='f')||(c>='0'&&c<='9')))
return 1;
// If caret at EOF.
if (iCurByte == DataArray.GetLength())
{
if (DataArray.InsertAtGrow(iCurByte, 0, 1) == TRUE)
{
iCurNibble = 0;
iInsertMode = FALSE;
character (ch);
update_for_new_datasize ();
return 1;
}
else
{
MessageBox (NULL, "Not enough memory for inserting character.", "Insert mode error", MB_OK | MB_ICONERROR);
}
return 0;
}
if( iInsertMode )
{
// INSERT
if( m_iEnteringMode == BYTES )
{
if( ( c >= 'a' && c <= 'f' ) || ( c >= '0' && c <= '9' ) )
{
if( bInsertingHex )
{
// Expecting the lower nibble of the recently inserted byte now.
// The bInsertingHex mode must be turned off if anything other is done
// except entering a valid hex digit. This is checked for in the
// HexEditorWindow::OnWndMsg() method.
bInsertingHex = FALSE;
if (c >= 'a' && c <= 'f')
x = c - 0x61 + 0x0a;
else
x = c - 0x30;
DataArray[iCurByte] = (DataArray[iCurByte] & 0xf0) | x;
m_iFileChanged = TRUE;
bFilestatusChanged = TRUE;
iCurByte++;
iCurNibble = 0;
update_for_new_datasize();
}
else
{
// Insert a new byte with the high nibble set to value just typed.
if( DataArray.InsertAtGrow( iCurByte, 0, 1 ) == TRUE )
{
bInsertingHex = TRUE;
if (c >= 'a' && c <= 'f')
x = c - 0x61 + 0x0a;
else
x = c - 0x30;
DataArray[iCurByte] = (DataArray[iCurByte] & 0x0f) | (x << 4);
m_iFileChanged = TRUE;
bFilestatusChanged = TRUE;
iCurNibble = 1;
update_for_new_datasize();
}
else
{
MessageBox (NULL, "Not enough memory for inserting.", "Insert mode error", MB_OK | MB_ICONERROR);
return 0;
}
}
}
return 1;
}
else if (m_iEnteringMode == CHARS)
{
if (DataArray.InsertAtGrow(iCurByte, 0, 1) == TRUE)
{
iCurNibble = 0;
iInsertMode = FALSE;
character (ch);
iInsertMode = TRUE;
iCurNibble = 0;
update_for_new_datasize ();
}
else
{
MessageBox (NULL, "Not enough memory for inserting.", "Insert mode error", MB_OK | MB_ICONERROR);
return 0;
}
}
return 1;
}
else
{
// OVERWRITE
// TAB => change mode.
// Byte-mode: only a-f, 0-9 allowed.
if ((m_iEnteringMode == BYTES) && ((c >= 'a' && c <= 'f') || (c >= '0' && c <= '9')))
{
if (c >= 'a' && c <= 'f')
x = c - 0x61 + 0x0a;
else
x = c - 0x30;
if (iCurNibble == 0)
DataArray[iCurByte] = (DataArray[iCurByte] & 0x0f) | (x << 4);
else
DataArray[iCurByte] = (DataArray[iCurByte] & 0xf0) | x;
m_iFileChanged = TRUE;
bFilestatusChanged = TRUE;
keydown (VK_RIGHT);
}
// Char-mode.
else if (m_iEnteringMode == CHARS)
{
switch (iCharacterSet)
{
case ANSI_FIXED_FONT:
DataArray[iCurByte] = ch;
break;
case OEM_FIXED_FONT:
{
char src[2], dst[2];
src[0] = ch;
src[1] = 0;
CharToOem (src, dst);
DataArray[iCurByte] = dst[0];
}
break;
}
m_iFileChanged = TRUE;
bFilestatusChanged = TRUE;
keydown (VK_RIGHT);
}
}
return 0;
}
//--------------------------------------------------------------------------------------------
// Handler for vertical scrollbar.
int HexEditorWindow::vscroll (int cmd, int pos)
{
if (NO_FILE || DataArray.GetLength()==0)
return 0;
iVscrollInc = 0;
switch (cmd)
{
case SB_TOP:
iCurLine = 0;
break;
case SB_BOTTOM:
iCurLine = iNumlines-1;
break;
case SB_LINEUP:
if (iCurLine > 0)
iCurLine -= 1;
break;
case SB_LINEDOWN:
if (iCurLine < iNumlines-1)
iCurLine += 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -