📄 hexwnd.cpp
字号:
//============================================================================================
// Frhed main definition file.
BOOL CALLBACK EnumWindowsProc( HWND hwnd, LPARAM lParam )
{
char buf[64];
if( GetClassName( hwnd, buf, 64 ) != 0 )
{
if( strcmp( buf, "frhed wndclass" ) == 0 )
{
g_iInstCount++;
}
}
return TRUE;
}
void count_instances()
{
g_iInstCount = 0;
EnumWindows( (WNDENUMPROC) EnumWindowsProc, 0 );
}
class WaitCursor
{
public:
WaitCursor()
{
SetCursor( LoadCursor( NULL, IDC_WAIT ) );
}
~WaitCursor()
{
SetCursor( LoadCursor( NULL, IDC_ARROW ) );
}
};
//--------------------------------------------------------------------------------------------
// Required for the find function.
inline char equal (char c)
{
return c;
}
inline char lower_case (char c)
{
if (c >= 'A' && c <= 'Z')
return 'a' + c - 'A';
else
return c;
}
//Pabs changed - line insert
//used to swap tmpstart and tmpend if start>end
template<class T>void swap(T& x, T& y){
T temp = x;
x = y;
y = temp;
}
//--------------------------------------------------------------------------------------------
HexEditorWindow::HexEditorWindow ()
{
bDontMarkCurrentPos = FALSE;
bInsertingHex = FALSE;
BrowserName = "iexplore";
TexteditorName.SetToString( "notepad.exe" );
iWindowX = CW_USEDEFAULT;
iWindowY = CW_USEDEFAULT;
iWindowWidth = CW_USEDEFAULT;
iWindowHeight = CW_USEDEFAULT;
iWindowShowCmd = SW_SHOW;
iHexWidth = 3;
// iClipboardEncode = TRUE;
iBmkColor = RGB( 255, 0, 0 );
iSelBkColorValue = RGB( 255, 255, 0 );
iSelTextColorValue = RGB( 0, 0, 0 );
pcGotoDlgBuffer = NULL;
iGotoDlgBufLen = 0;
bOpenReadOnly = bReadOnly = FALSE;
iPartialOffset=0;
bPartialOpen=FALSE;
iBmkCount=0;
int i;
for (i=1; i<=MRUMAX; i++)
sprintf (&(strMRU[i-1][0]), "dummy%d", i);
iMRU_count = 0;
bFilestatusChanged = TRUE;
iBinaryMode = LITTLEENDIAN_MODE;
szFileName[0] = '\0';
bUnsignedView = TRUE;
iFontSize = 10;
iInsertMode = FALSE;
iTextColorValue = RGB (0,0,0);
iBkColorValue = RGB (255,255,255);
iSepColorValue = RGB (192,192,192);
iAutomaticBPL = BST_CHECKED;
bSelected = FALSE;
bLButtonIsDown = FALSE;
iStartOfSelection = 0;
iEndOfSelection = 0;
hwnd = 0;
iOffsetLen = 6;
iByteSpace = 2;
iBytesPerLine = 16;
iCharSpace = 1;
iCharsPerLine = iOffsetLen + iByteSpace + iBytesPerLine*3 + iCharSpace + iBytesPerLine;
filename = new char[_MAX_PATH];
filename[0] = '\0';
m_iEnteringMode = BYTES;
m_iFileChanged = FALSE;
bFileNeverSaved = TRUE;
iFindDlgBufLen = 64 * 1024 - 1;
pcFindDlgBuffer = new char[ iFindDlgBufLen ];
if( pcFindDlgBuffer == NULL )
MessageBox( NULL, "Could not allocate Find buffer!", "frhed", MB_OK );
pcFindDlgBuffer[0] = '\0';
iCopyHexdumpDlgStart = 0;
iCopyHexdumpDlgEnd = 0;
iCharacterSet = ANSI_FIXED_FONT;
// Read in the last saved preferences.
count_instances();
read_ini_data ();
bFileNeverSaved = TRUE;
bSelected = FALSE;
bLButtonIsDown = FALSE;
m_iFileChanged = FALSE;
iVscrollMax = 0;
iVscrollPos = 0;
iVscrollInc = 0;
iHscrollMax = 0;
iHscrollPos = 0;
iHscrollInc = 0;
iCurLine = 0;
iCurByte = 0;
DataArray.ClearAll ();
DataArray.SetGrowBy (100);
sprintf (filename, "Untitled");
}
//--------------------------------------------------------------------------------------------
HexEditorWindow::~HexEditorWindow ()
{
if (hFont != NULL)
DeleteObject (hFont);
if (filename != NULL)
delete [] filename;
if (pcFindDlgBuffer != NULL)
delete [] pcFindDlgBuffer;
if( pcGotoDlgBuffer != NULL )
delete [] pcGotoDlgBuffer;
}
//--------------------------------------------------------------------------------------------
int HexEditorWindow::load_file (char* fname)
{
if (file_is_loadable (fname))
{
int filehandle;
if ((filehandle = _open (fname,_O_RDONLY|_O_BINARY,_S_IREAD|_S_IWRITE)) != -1)
{
int filelen = _filelength (filehandle);
DataArray.ClearAll ();
// Try to allocate memory for the file.
if (DataArray.SetSize (filelen) == TRUE)
{
// If read-only mode on opening is enabled:
if( bOpenReadOnly )
bReadOnly = TRUE;
else
bReadOnly = FALSE;
if( filelen == 0)
{
// This is an empty file. Don't need to read anything.
_close( filehandle );
strcpy( filename, fname );
bFileNeverSaved = FALSE;
bPartialOpen=FALSE;
// Update MRU list.
update_MRU ();
bFilestatusChanged = TRUE;
update_for_new_datasize();
return TRUE;
}
else
{
// Load the file.
SetCursor (LoadCursor (NULL, IDC_WAIT));
DataArray.SetUpperBound (filelen-1);
if (_read (filehandle, DataArray, DataArray.GetLength ()) != -1)
{
_close (filehandle);
strcpy (filename, fname);
bFileNeverSaved = FALSE;
bPartialOpen=FALSE;
// Update MRU list.
update_MRU ();
bFilestatusChanged = TRUE;
update_for_new_datasize();
SetCursor (LoadCursor (NULL, IDC_ARROW));
return TRUE;
}
else
{
_close (filehandle);
SetCursor (LoadCursor (NULL, IDC_ARROW));
MessageBox (NULL, "Error while reading from file.", "Load error", MB_OK | MB_ICONERROR);
return FALSE;
}
}
}
else
{
MessageBox (NULL, "Not enough memory to load file.", "Load error", MB_OK | MB_ICONERROR);
return FALSE;
}
}
else
{
char buf[500];
sprintf (buf, "Error code 0x%x occured while opening file %s.", errno, fname);
MessageBox (NULL, buf, "Load error", MB_OK | MB_ICONERROR);
return FALSE;
}
}
else
return FALSE;
}
//--------------------------------------------------------------------------------------------
int HexEditorWindow::file_is_loadable (char* fname)
{
int filehandle;
if ((filehandle = _open (fname,_O_RDONLY|_O_BINARY,_S_IREAD|_S_IWRITE)) != -1)
{
_close (filehandle);
return TRUE;
}
else
return FALSE;
}
//--------------------------------------------------------------------------------------------
int HexEditorWindow::at_window_create (HWND hw, HINSTANCE hI)
{
hwnd = hw;
hMainWnd = hw;
hInstance = hI;
// Create Statusbar.
InitCommonControls ();
hwndStatusBar = CreateStatusWindow (
CCS_BOTTOM | WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP,
"Ready", hwnd, 2);
// Create Scrollbars.
hwndHBar = CreateWindow ("scrollbar", NULL, WS_CHILD | WS_VISIBLE | SBS_HORZ,
0,0,0,0, hwnd, (HMENU) 1, hInstance, NULL);
hwndVBar = CreateWindow ("scrollbar", NULL, WS_CHILD | WS_VISIBLE | SBS_VERT,
0,0,0,0, hwnd, (HMENU) 2, hInstance, NULL);
iVscrollMax = 0;
iVscrollPos = 0;
iVscrollInc = 0;
iHscrollMax = 0;
iHscrollPos = 0;
iHscrollInc = 0;
iCurLine = 0;
iCurByte = 0;
iCurNibble = 0;
DragAcceptFiles( hwnd, TRUE ); // Accept files dragged into window.
return TRUE;
}
//--------------------------------------------------------------------------------------------
// Window was resized to new width of cx and new height of cy.
int HexEditorWindow::resize_window (int cx, int cy)
{
// Get font data.
HDC hdc = GetDC (hwnd);
make_font ();
HFONT of = (HFONT) SelectObject( hdc, hFont );
TEXTMETRIC tm;
GetTextMetrics (hdc, &tm);
cxChar = tm.tmAveCharWidth;
cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2;
cyChar = tm.tmHeight + tm.tmExternalLeading;
SelectObject (hdc, of);
ReleaseDC (hwnd, hdc);
//--------------------------------------------
// Resize statusbar.
int x, y, x2, y2;
RECT rWindow;
GetWindowRect (hwndStatusBar, &rWindow);
y2 = rWindow.bottom - rWindow.top;
x = 0;
y = cy - y2;
x2 = cx;
MoveWindow (hwndStatusBar, x, y, x2, y2, TRUE);
// Get client size.
cxClient = cx;
cyClient = cy - y2;
// Resize scrollbars.
int cyh = GetSystemMetrics (SM_CYHSCROLL),
cxv = GetSystemMetrics (SM_CXVSCROLL);
MoveWindow (hwndHBar, 0, cyClient - cyh, cxClient - cxv, cyh, FALSE);
MoveWindow (hwndVBar, cxClient - cxv, 0, cxv, cyClient, FALSE);
RedrawWindow (hwndHBar, NULL, NULL, RDW_INVALIDATE | RDW_ERASENOW | RDW_ALLCHILDREN);
RedrawWindow (hwndVBar, NULL, NULL, RDW_INVALIDATE | RDW_ERASENOW | RDW_ALLCHILDREN);
// Resize client area.
cxClient -= cxv;
cyClient -= cyh;
//--------------------------------------------
// Set statusbar divisions.
int statbarw;
if (IsZoomed (hwnd))
statbarw = cx;
else
statbarw = cxClient;
// Allocate an array for holding the right edge coordinates.
HLOCAL hloc = LocalAlloc (LHND, sizeof(int) * 3);
int* lpParts = (int*) LocalLock(hloc);
// Calculate the right edge coordinate for each part, and
// copy the coordinates to the array.
lpParts[0] = statbarw*4/6;
lpParts[1] = statbarw*5/6;
lpParts[2] = statbarw;
// Tell the status window to create the window parts.
SendMessage (hwndStatusBar, SB_SETPARTS, (WPARAM) 3,
(LPARAM) lpParts);
// Free the array, and return.
LocalUnlock(hloc);
LocalFree(hloc);
//--------------------------------------------
cxBuffer = max (1, cxClient / cxChar);
cyBuffer = max (1, cyClient / cyChar);
// Adjust bytes per line to width of window.
// cxBuffer = maximal width of client-area in chars.
if( iAutomaticBPL )
{
int bytemax = cxBuffer-iOffsetLen-iByteSpace-iCharSpace;
iBytesPerLine = bytemax / 4;
if (iBytesPerLine < 1)
iBytesPerLine = 1;
}
// Caret or end of selection will be vertically centered if line not visible.
if( bSelected )
{
if( iEndOfSelection / iBytesPerLine < iCurLine || iEndOfSelection / iBytesPerLine > iCurLine + cyBuffer )
iCurLine = max( 0, iEndOfSelection / iBytesPerLine - cyBuffer / 2 );
}
else
{
if( iCurByte/iBytesPerLine < iCurLine || iCurByte/iBytesPerLine > iCurLine + cyBuffer )
iCurLine = max( 0, iCurByte/iBytesPerLine-cyBuffer/2 );
}
adjust_vscrollbar();
iCharsPerLine = iOffsetLen + iByteSpace + iBytesPerLine*3 + iCharSpace + iBytesPerLine;
// Get number of lines to display.
if ((DataArray.GetLength()+1) % iBytesPerLine == 0)
iNumlines = (DataArray.GetLength()+1) / iBytesPerLine;
else
iNumlines = (DataArray.GetLength()+1) / iBytesPerLine + 1;
if (iNumlines <= 0xffff)
iVscrollMax = iNumlines-1;
else
iVscrollMax = 0xffff;
SetScrollRange (hwndVBar, SB_CTL, 0, iVscrollMax, FALSE);
SetScrollPos (hwndVBar, SB_CTL, iVscrollPos, TRUE);
iHscrollMax = iCharsPerLine - 1;
iHscrollPos = 0;
SetScrollRange (hwndHBar, SB_CTL, 0, iHscrollMax, FALSE);
SetScrollPos (hwndHBar, SB_CTL, iHscrollPos, TRUE);
set_wnd_title ();
if (hwnd == GetFocus ())
set_caret_pos ();
repaint ();
return TRUE;
}
//--------------------------------------------------------------------------------------------
// When focus is gained.
int HexEditorWindow::set_focus ()
{
if (cxChar == 0 || cyChar == 0)
{
make_font ();
HDC hdc = GetDC (hwnd);
HFONT of = (HFONT) SelectObject (hdc, hFont);
TEXTMETRIC tm;
GetTextMetrics (hdc, &tm);
cxChar = tm.tmAveCharWidth;
cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2;
cyChar = tm.tmHeight + tm.tmExternalLeading;
SelectObject (hdc, of);
ReleaseDC (hwnd, hdc);
}
update_for_new_datasize ();
CreateCaret (hwnd, NULL, cxChar, cyChar);
set_caret_pos ();
ShowCaret (hwnd);
return 0;
}
//--------------------------------------------------------------------------------------------
// What to do when focus is lost.
int HexEditorWindow::kill_focus ()
{
HideCaret (hwnd);
DestroyCaret ();
return TRUE;
}
//--------------------------------------------------------------------------------------------
// Handler for non-character keys (arrow keys, page up/down etc.)
int HexEditorWindow::keydown (int key)
{
if (filename[0] == '\0' || iCurByte<0)
return 0;
int log_column, scrollflag;
if (bSelected)
switch (key)
{
case VK_END:
case VK_HOME:
case VK_LEFT:
case VK_RIGHT:
case VK_UP:
case VK_DOWN:
case VK_PRIOR:
case VK_NEXT:
iCurByte = iEndOfSelection;
bSelected = FALSE;
adjust_vscrollbar ();
repaint ();
default:
break;
}
switch (key)
{
case VK_HOME:
{
iCurByte = BYTELINE * iBytesPerLine;
iCurNibble = 0;
if (m_iEnteringMode == BYTES)
log_column = BYTES_LOGICAL_COLUMN;
else
log_column = CHARS_LOGICAL_COLUMN;
if (log_column < iHscrollPos) // Cursor too far to the left?
{
iHscrollPos = log_column;
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_END:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -