📄 hexwnd.cpp
字号:
}
if (DC_was_allocated)
ReleaseDC (hwnd, hdc);
}
//--------------------------------------------------------------------------------------------
// Repaint one line in the window.
void HexEditorWindow::print_line (HDC hdc, int line, char* linbuf, HBRUSH hbr )
{
// line = absolute line number.
// if line not visible:
if (line < iCurLine || line > iCurLine + cyBuffer)
return;
int startpos = line * iBytesPerLine, endpos, i = 0, m;
char buf[80], c;
// Return if this line does not even contain the end-of-file double
// underscore (at index upperbound+1).
if( startpos > DataArray.GetUpperBound() + 1 )
{
return;
}
// Write offset.
sprintf (buf, "%%%d.%dx", iOffsetLen, iOffsetLen);
for (m=0; m<iByteSpace; m++)
buf[5+m] = ' ';
buf[5+m] = '\0';
sprintf (linbuf, buf, startpos);
// Last line reached? Then only write rest of bytes.
// startpos+iBytesPerLine-1 = Last byte in current line.
if (startpos+iBytesPerLine > DataArray.GetLength ())
{
// If the first byte of the next line would not be valid, then
// only print the bytes up to and including the last byte of the file.
endpos = DataArray.GetUpperBound()+1;
}
else
{
// Print the bytes up to the end of this line, they are all valid.
endpos = startpos+iBytesPerLine-1;
}
// Could happen on arrow down, so that last line is on bottom of window:
if( endpos < startpos )
{
endpos = startpos;
}
// Write bytes.
m = iOffsetLen+iByteSpace; // Index of first byte in line.
for (i=startpos; i<=endpos; i++)
{
if (i == DataArray.GetLength())
{
linbuf[m++] = '_';
linbuf[m++] = '_';
linbuf[m++] = ' ';
}
else
{
c = (DataArray[i] >> 4);
if( c < 10 )
c += '0';
else
c = c - 10 + 'a';
linbuf[m++] = c;
c = (DataArray[i] & 0x0f);
if( c < 10 )
c += '0';
else
c = c - 10 + 'a';
linbuf[m++] = c;
linbuf[m++] = ' ';
}
}
// Write spaces for non-existant bytes.
if (endpos-startpos < iBytesPerLine-1)
{
for (i=0; i<iBytesPerLine-1-(endpos-startpos); i++)
{
linbuf[m++] = ' ';
linbuf[m++] = ' ';
linbuf[m++] = ' ';
}
}
// Write offset to chars.
for (i=0; i<iCharSpace; i++)
linbuf[m++] = ' ';
// Write ASCIIs.
for (i=startpos; i<=endpos; i++)
{
if (i == DataArray.GetLength())
{
linbuf[m++] = ' ';
}
else if (iCharacterSet == OEM_FIXED_FONT && DataArray[i]!=0)
{
linbuf[m++] = DataArray[i];
}
else if ((DataArray[i]>=32 && DataArray[i]<=126) || (DataArray[i]>=160 && DataArray[i]<=255) || (DataArray[i]>=145 && DataArray[i]<=146))
{
linbuf[m++] = DataArray[i];
}
else
{
linbuf[m++] = '.';
}
}
// Write spaces for nonexisting chars.
if (endpos-startpos < iBytesPerLine-1)
for (i=0; i<iBytesPerLine-1-(endpos-startpos); i++)
linbuf[m++] = ' ';
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int line_len = m; // Length of the line in chars.
// Set normal text colors.
iBkColor = PALETTERGB (GetRValue(iBkColorValue),GetGValue(iBkColorValue),GetBValue(iBkColorValue));
iTextColor = PALETTERGB (GetRValue(iTextColorValue),GetGValue(iTextColorValue),GetBValue(iTextColorValue));
SetTextColor (hdc, iTextColor);
SetBkColor (hdc, iBkColor);
// How much of offset and byte-space is visible? Print it in normal text colors.
if( iHscrollPos < iOffsetLen + iByteSpace )
{
// A part of offset+byte-space is visible.
// Write offset to screen.
TextOut( hdc, CLIENT_BORDER_WIDTH, CLIENT_BORDER_WIDTH + ( line - iCurLine ) * cyChar, linbuf + iHscrollPos, iOffsetLen + iByteSpace - iHscrollPos );
}
int iHexStart = iOffsetLen + iByteSpace;
int iHexXStart = iHexStart * cxChar;
// Write char-space, if it is visible.
if( iHscrollPos < iOffsetLen + iByteSpace + iBytesPerLine * iHexWidth )
{
// Char-space is visible.
TextOut( hdc,
CLIENT_BORDER_WIDTH + ( iHexStart + iBytesPerLine * iHexWidth - iHscrollPos ) * cxChar,
CLIENT_BORDER_WIDTH + ( line - iCurLine ) * cyChar,
linbuf + iHexStart + iBytesPerLine * iHexWidth,
iCharSpace );
}
iSelBkColor = PALETTERGB (GetRValue(iSelBkColorValue),GetGValue(iSelBkColorValue),GetBValue(iSelBkColorValue));
iSelTextColor = PALETTERGB (GetRValue(iSelTextColorValue),GetGValue(iSelTextColorValue),GetBValue(iSelTextColorValue));
BOOL last_normtext = TRUE;
int p, el = startpos + iBytesPerLine - 1 - 1, s, e;
for( p = startpos; p <= el; p++ )
{
// Write hex, if it is visible.
// s = Position in string of last character of current hex.
s = iOffsetLen + iByteSpace + ( p - startpos + 1 ) * iHexWidth;
e = s - iHexWidth;
// Print only if at least a part of the hex is visible.
if( iHscrollPos < s && iHscrollPos + cxBuffer >= e )
{
// Selected bytes must be printed in selection colors.
if( bSelected && IN_BOUNDS( p, iStartOfSelection, iEndOfSelection ) )
{
if( last_normtext )
{
// Set selection colors.
SetTextColor (hdc, iSelTextColor);
SetBkColor (hdc, iSelBkColor);
last_normtext = FALSE;
}
}
else
{
if( !last_normtext )
{
// Set normal text colors.
SetTextColor (hdc, iTextColor);
SetBkColor (hdc, iBkColor);
last_normtext = TRUE;
}
}
// Hex is visible.
TextOut( hdc,
CLIENT_BORDER_WIDTH + ( iHexStart + ( p - startpos ) * iHexWidth - iHscrollPos ) * cxChar,
CLIENT_BORDER_WIDTH + ( line - iCurLine ) * cyChar,
linbuf + iHexStart + ( p - startpos ) * iHexWidth,
iHexWidth );
}
s = iOffsetLen + iByteSpace + iBytesPerLine * iHexWidth + iCharSpace + ( p - startpos + 1);
// Write char, if it is visible.
if( iHscrollPos < s && iHscrollPos + cxBuffer >= s - 1 )
{
// Selected bytes must be printed in selection colors.
if( bSelected && IN_BOUNDS( p, iStartOfSelection, iEndOfSelection ) )
{
if( last_normtext )
{
// Set selection colors.
SetTextColor (hdc, iSelTextColor);
SetBkColor (hdc, iSelBkColor);
last_normtext = FALSE;
}
}
else
{
if( !last_normtext )
{
// Set normal text colors.
SetTextColor (hdc, iTextColor);
SetBkColor (hdc, iBkColor);
last_normtext = TRUE;
}
}
// Char is visible.
TextOut( hdc,
CLIENT_BORDER_WIDTH + ( iHexStart + iBytesPerLine * iHexWidth + iCharSpace + ( p - startpos ) - iHscrollPos ) * cxChar,
CLIENT_BORDER_WIDTH + ( line - iCurLine ) * cyChar,
linbuf + iHexStart + iBytesPerLine * iHexWidth + iCharSpace + ( p - startpos ),
1 );
}
}
// The last hex in the line is not completely in selection colors. It's
// succeding space must be printed in normal text colors (visually more
// appealing).
// Write hex, if it is visible.
// s = Position in string of last character of current hex.
s = iOffsetLen + iByteSpace + ( p - startpos + 1 ) * iHexWidth;
e = s - iHexWidth;
// Print only if at least a part of the hex is visible.
if( iHscrollPos < s && iHscrollPos + cxBuffer >= e )
{
// Selected bytes must be printed in selection colors.
if( bSelected && IN_BOUNDS( p, iStartOfSelection, iEndOfSelection ) )
{
if( last_normtext )
{
// Output the last space first.
TextOut( hdc,
CLIENT_BORDER_WIDTH + ( iHexStart + ( p - startpos ) * iHexWidth - iHscrollPos ) * cxChar + 2 * cxChar,
CLIENT_BORDER_WIDTH + ( line - iCurLine ) * cyChar,
" ",
1 );
// Set selection colors.
SetTextColor (hdc, iSelTextColor);
SetBkColor (hdc, iSelBkColor);
last_normtext = FALSE;
last_normtext = TRUE;
// Write hex.
TextOut( hdc,
CLIENT_BORDER_WIDTH + ( iHexStart + ( p - startpos ) * iHexWidth - iHscrollPos ) * cxChar,
CLIENT_BORDER_WIDTH + ( line - iCurLine ) * cyChar,
linbuf + iHexStart + ( p - startpos ) * iHexWidth,
iHexWidth - 1 );
}
else
{
// Write hex.
TextOut( hdc,
CLIENT_BORDER_WIDTH + ( iHexStart + ( p - startpos ) * iHexWidth - iHscrollPos ) * cxChar,
CLIENT_BORDER_WIDTH + ( line - iCurLine ) * cyChar,
linbuf + iHexStart + ( p - startpos ) * iHexWidth,
iHexWidth - 1 );
// Set normal text colors.
SetTextColor (hdc, iTextColor);
SetBkColor (hdc, iBkColor);
last_normtext = TRUE;
// Output the last space.
TextOut( hdc,
CLIENT_BORDER_WIDTH + ( iHexStart + ( p - startpos ) * iHexWidth - iHscrollPos ) * cxChar + 2 * cxChar,
CLIENT_BORDER_WIDTH + ( line - iCurLine ) * cyChar,
" ",
1 );
}
}
else
{
// Non-selected hex.
if( !last_normtext )
{
// Set normal text colors.
SetTextColor (hdc, iTextColor);
SetBkColor (hdc, iBkColor);
last_normtext = TRUE;
}
// Hex is visible.
TextOut( hdc,
CLIENT_BORDER_WIDTH + ( iHexStart + ( p - startpos ) * iHexWidth - iHscrollPos ) * cxChar,
CLIENT_BORDER_WIDTH + ( line - iCurLine ) * cyChar,
linbuf + iHexStart + ( p - startpos ) * iHexWidth,
iHexWidth );
}
}
s = iOffsetLen + iByteSpace + iBytesPerLine * iHexWidth + iCharSpace + ( p - startpos + 1);
// Write char, if it is visible.
if( iHscrollPos < s && iHscrollPos + cxBuffer >= s - 1 )
{
// Selected bytes must be printed in selection colors.
if( bSelected && IN_BOUNDS( p, iStartOfSelection, iEndOfSelection ) )
{
if( last_normtext )
{
// Set selection colors.
SetTextColor (hdc, iSelTextColor);
SetBkColor (hdc, iSelBkColor);
}
}
else
{
if( !last_normtext )
{
// Set normal text colors.
SetTextColor (hdc, iTextColor);
SetBkColor (hdc, iBkColor);
}
}
// Char is visible.
TextOut( hdc,
CLIENT_BORDER_WIDTH + ( iHexStart + iBytesPerLine * iHexWidth + iCharSpace + ( p - startpos ) - iHscrollPos ) * cxChar,
CLIENT_BORDER_WIDTH + ( line - iCurLine ) * cyChar,
linbuf + iHexStart + iBytesPerLine * iHexWidth + iCharSpace + ( p - startpos ),
1 );
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Separators.
for (i = 0; i < (iBytesPerLine / 4) + 1; i++)
{
m = (iOffsetLen+iByteSpace)*cxChar - cxChar/2 + 3*cxChar*4*i - cxChar*iHscrollPos;
MoveToEx (hdc, CLIENT_BORDER_WIDTH+m, CLIENT_BORDER_WIDTH+(line-iCurLine)*cyChar, NULL);
LineTo (hdc, CLIENT_BORDER_WIDTH+m, CLIENT_BORDER_WIDTH+(line-iCurLine+1)*cyChar);
}
// Separator for chars.
m = CHARSTART*cxChar - cxChar*iHscrollPos - 2;
MoveToEx (hdc, CLIENT_BORDER_WIDTH+m, CLIENT_BORDER_WIDTH+(line-iCurLine)*cyChar, NULL);
LineTo (hdc, CLIENT_BORDER_WIDTH+m, CLIENT_BORDER_WIDTH+(line-iCurLine+1)*cyChar);
// Second separator.
MoveToEx (hdc, CLIENT_BORDER_WIDTH+m+2, CLIENT_BORDER_WIDTH+(line-iCurLine)*cyChar, NULL);
LineTo (hdc, CLIENT_BORDER_WIDTH+m+2, CLIENT_BORDER_WIDTH+(line-iCurLine+1)*cyChar);
// Print bookmark indicators.
// Are there bookmarks in this line?
el = startpos + iBytesPerLine - 1;
int chpos;
RECT r;
// Brush for bookmark borders.
for( i = 0; i < iBmkCount; i++ )
{
// Print the bookmark if it is within the file.
if( IN_BOUNDS( pbmkList[i].offset, startpos, el ) && pbmkList[i].offset <= DataArray.GetUpperBound() )
{
// Found a bookmark in this line.
// Mark hex.
chpos = iOffsetLen + iByteSpace + ( pbmkList[i].offset % iBytesPerLine )*3 - iHscrollPos;
r.left = CLIENT_BORDER_WIDTH + chpos * cxChar;
r.top = CLIENT_BORDER_WIDTH + ( pbmkList[i].offset / iBytesPerLine - iCurLine ) * cyChar;
r.right = CLIENT_BORDER_WIDTH + r.left + 2*cxChar;
r.bottom = CLIENT_BORDER_WIDTH + ( pbmkList[i].offset / iBytesPerLine - iCurLine + 1 ) * cyChar;
FrameRect( hdc, &r, hbr );
// Mark char.
chpos = iOffsetLen + iByteSpace + iBytesPerLine*3 + iCharSpace
+ ( pbmkList[i].offset % iBytesPerLine ) - iHscrollPos;
r.left = CLIENT_BORDER_WIDTH + chpos * cxChar;
r.top = CLIENT_BORDER_WIDTH + ( pbmkList[i].offset / iBytesPerLine - iCurLine) * cyChar;
r.right = CLIENT_BORDER_WIDTH + ( chpos + 1 ) * cxChar;
r.bottom = CLIENT_BORDER_WIDTH + ( pbmkList[i].offset / iBytesPerLine - iCurLine + 1 ) * cyChar;
FrameRect( hdc, &r, hbr );
}
}
return;
}
//--------------------------------------------------------------------------------------------
// Dialogue procedure for Go-to dialogue.
BOOL CALLBACK GoToDlgProc (HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
switch (iMsg)
{
case WM_INITDIALOG:
if( iGotoDlgBufLen == 0 )
{
// Maximal length of text in Edit-Control:
iGotoDlgBufLen = SendMessage( GetDlgItem( hDlg, IDC_EDIT1 ), EM_GETLIMITTEXT, 0, 0 );
// Memory for returning text to caller.
pcGotoDlgBuffer = new char[iGotoDlgBufLen];
if( pcGotoDlgBuffer == NULL )
MessageBox( NULL, "Could not allocate Goto buffer.", "Go to error", MB_OK | MB_ICONERROR );
memset( pcGotoDlgBuffer, 0, iGotoDlgBufLen );
}
if( pcGotoDlgBuffer != NULL )
SetWindowText( GetDlgItem (hDlg, IDC_EDIT1), pcGotoDlgBuffer );
SetFocus (GetDlgItem (hDlg, IDC_EDIT1));
return FALSE;
case WM_COMMAND:
switch (LOWORD (wParam))
{
case IDOK:
// Copy text in Edit-Control.
EndDialog( hDlg, GetDlgItemText( hDlg, IDC_EDIT1, pcGotoDlgBuffer, iGotoDlgBufLen ) );
return TRUE;
case IDCANCEL:
EndDialog( hDlg, 0 );
return TRUE;
}
break;
}
return FALSE;
}
//--------------------------------------------------------------------------------------------
// Dialogue procedure for Find dialogue.
BOOL CALLBACK FindDlgProc( HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam )
{
switch( iMsg )
{
case WM_INITDIALOG:
// Is the buffer containing the data to find from the last find command empty?
// if( iFindDlgBufLen == 0 )
{
// Maximal Length of text in Edit-Control:
// iFindDlgBufLen = SendMessage( GetDlgItem( hDlg, IDC_EDIT1 ), EM_GETLIMITTEXT, 0, 0 );
// SendMessage( GetDlgItem( hDlg, IDC_EDIT1 ), EM_GETLIMITTEXT, 0, 0 );
// Memory for returning text to caller.
// pcFindDlgBuffer = new char[iFindDlgBufLen];
}
SetFocus( GetDlgItem( hDlg, IDC_EDIT1 ) );
// if( iFindDlgLastLen != 0 )
{
int res = SendMessage( GetDlgItem( hDlg, IDC_EDIT1 ), EM_SETLIMITTEXT, iFindDlgBufLen, 0 );
res = SetWindowText( GetDlgItem( hDlg, IDC_EDIT1 ), pcFindDlgBuffer );
CheckDlgButton( hDlg, IDC_RADIO2, BST_CHECKED );
}
return FALSE;
case WM_COMMAND:
iFindDlgMatchCase = IsDlgButtonChecked (hDlg, IDC_CHECK1);
if (IsDlgButtonChecked (hDlg, IDC_RADIO1) == BST_CHECKED)
iFindDlgDirection = -1;
else
iFindDlgDirection = 1;
switch (LOWORD (wParam))
{
case IDOK:
{
// Copy text in Edit-Control. Return the number of characters
// in the Edit-control minus the zero byte at the end.
int len = GetDlgItemText (hDlg, IDC_EDIT1, pcFindDlgBuffer, iFindDlgBufLen);
int res = EndDialog (hDlg, len );
return TRUE;
}
case IDCANCEL:
EndDialog (hDlg, 0);
return TRUE;
}
break;
}
return FALSE;
}
//--------------------------------------------------------------------------------------------
// Set horizontal scroll position so that caret is visible.
void HexEditorWindow::adjust_view_for_caret ()
{
int log_column;
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);
else if (log_column < iHscrollPos)
iHscrollPos = log_column;
adjust_hscrollbar ();
}
//--------------------------------------------------------------------------------------------
// Initialize main menu items.
int HexEditorWindow::initmenupopup( WPARAM w, LPARAM l )
{
// Submenu "File":
if( l == 0 )
{
//GK16AUG2K: for WindowsBlinds WM_INITMENUPOPUP
// The GetMenuItemID function retrieves the menu item identifier of a menu item
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -