home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.funduc.com
/
2014.08.ftp.funduc.com.tar
/
ftp.funduc.com
/
fshedcode-072212.zip
/
fshedView.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
2012-07-03
|
168KB
|
4,619 lines
/////////////////////////////////////////////////////////////////////////////
// License (GPLv2+):
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
/////////////////////////////////////////////////////////////////////////////
// fshedView.cpp : implementation of the CFshedView class
//
#include "stdafx.h"
#include "atlbase.h"
#include "fshed.h"
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <io.h>
#include <mbstring.h>
//#include "fshedDoc.h"
#include "fshedView.h"
#include "AddBookmarkDlg.h"
#include "RemoveBookmarkDlg.h"
#include "HexDumpDlg.h"
#include "AppendDialog.h"
#include "ManipulateBitsDlg.h"
#include "SelectBlockDlg.h"
#include "PasteSpecialDlg.h"
#include "GotoDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define SUB_RELEASE_NO "156"
#define NO_FILE (Doc->filename[0] == '\0')
#define LASTBYTE (Doc->DataArray.GetUpperBound ())
//--------------------------------------------------------------------------------------------
// FIND_BYTES
// Arguments:
// ps = Start position.
// ls = Length of src array.
// pb = Start of searchstring.
// lb = Length searchstring.
// mode = -1 : backwards search.
// 1 : forward search.
// cmp = pointer to function that is applied to data before comparing.
//
// Return:
// Position of found string or -1 if not there.
int find_bytes (char* ps, int ls, char* pb, int lb, int mode, char (*cmp) (char))
{
int start, inc, end, i;
if (mode == 1)
{
start = 0;
inc = 1;
end = ls - lb + 1;
}
else
{
start = ls - lb;
inc = -1;
end = 1;
}
for (; mode * start < end; start += inc)
{
for (i = start; i < start + lb; i++)
{
if (cmp (ps[i]) != cmp (pb[i - start]))
break;
}
if (i == start + lb)
return start;
}
return -1;
}
#ifndef _UNICODE
extern AFX_DATA const BOOL _afxDBCS;
#endif
typedef int (_cdecl * AFX_COMPARE_PROC)(LPCSTR str1, LPCSTR str2);
int find_bytes (char* ps, int ls, long lStartSel, long lEndSel,
const char* lpszFind, int lb, BOOL bNext, BOOL bCase, BOOL bWholeWord)
{
UINT nLen = ls;
int nStartChar = lStartSel, nEndChar = lEndSel;
if (bWholeWord)
++nStartChar;
UINT nStart = nStartChar;
int iDir = bNext ? +1 : -1;
// can't find a match before the first character
if (nStart == 0 && iDir < 0)
return FALSE;
CWaitCursor wait;
LPCSTR lpszText = ps;
if (iDir < 0)
{
// always go back one for search backwards
nStart -= (UINT)((lpszText+nStart) - (LPCSTR)
_mbsdec((const unsigned char *)lpszText, (const unsigned char *)lpszText+nStart));
}
else if (nStartChar != nEndChar) // && SameAsSelected(lpszFind, bCase))
{
// easy to go backward/forward with SBCS
if (_istlead(lpszText[nStart]))
nStart++;
nStart += iDir;
}
// handle search with nStart past end of buffer
size_t nLenFind = strlen(lpszFind);
if (nStart+nLenFind-1 >= nLen)
{
if (iDir < 0 && nLen >= nLenFind)
{
#ifndef _UNICODE
if (_afxDBCS)
{
// walk back to previous character n times
nStart = nLen;
int n = nLenFind;
while (n--)
{
nStart -= (lpszText+nStart) - (LPSTR)
_mbsdec((const unsigned char *)lpszText, (const unsigned char *)lpszText+nStart);
}
}
else
#endif
{
// single-byte character set is easy and fast
nStart = nLen - (UINT)nLenFind;
}
ASSERT(nStart+nLenFind-1 <= nLen);
}
else
{
return -1;
}
}
// start the search at nStart
LPCSTR lpsz = lpszText + nStart;
AFX_COMPARE_PROC pfnCompare = bCase ? strcmp : _strcmpi;
#ifndef _UNICODE
if (_afxDBCS)
{
// double-byte string search
LPCSTR lpszStop;
if (iDir > 0)
{
// start at current and find _first_ occurrance
lpszStop = lpszText + nLen - nLenFind + 1;
}
else
{
// start at top and find _last_ occurrance
lpszStop = lpsz;
lpsz = lpszText;
}
LPCSTR lpszFound = NULL;
while (lpsz <= lpszStop)
{
if (!bCase || (*lpsz == *lpszFind &&
(!_istlead(*lpsz) || lpsz[1] == lpszFind[1])))
{
LPTSTR lpch = (LPTSTR)(lpsz + nLenFind);
TCHAR chSave = *lpch;
*lpch = '\0';
int nResult = (*pfnCompare)(lpsz, lpszFind);
*lpch = chSave;
if (nResult == 0)
{
lpszFound = lpsz;
if (iDir > 0)
break;
}
}
lpsz = (LPCSTR)_mbsinc((const unsigned char *)lpsz);
}
if (lpszFound != NULL)
{
int n = (int)(lpszFound - lpszText);
return n;
}
}
else
#endif
{
// single-byte string search
UINT nCompare;
if (iDir < 0)
nCompare = (UINT)(lpsz - lpszText) + 1;
else
nCompare = nLen - (UINT)(lpsz - lpszText) - (UINT)nLenFind + 1;
while (nCompare > 0)
{
ASSERT(lpsz >= lpszText);
ASSERT(lpsz+nLenFind-1 <= lpszText+nLen-1);
LPSTR lpch = (LPSTR)(lpsz + nLenFind);
char chSave = *lpch;
*lpch = '\0';
int nResult = (*pfnCompare)(lpsz, lpszFind);
*lpch = chSave;
if (nResult == 0)
{
int n = (int)(lpsz - lpszText);
return n;
}
// restore character at end of search
*lpch = chSave;
// move on to next substring
nCompare--;
lpsz += iDir;
}
}
return -1;
}
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;
}
/////////////////////////////////////////////////////////////////////////////
// CFshedView
static const UINT _myMsgForFindReplace = ::RegisterWindowMessage(FINDMSGSTRING);
IMPLEMENT_DYNCREATE(CFshedView, CView)
BEGIN_MESSAGE_MAP(CFshedView, CView)
//{{AFX_MSG_MAP(CFshedView)
ON_WM_CREATE()
ON_WM_LBUTTONDOWN()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
ON_WM_SIZE()
ON_WM_KEYDOWN()
ON_WM_CHAR()
ON_WM_TIMER()
ON_WM_VSCROLL()
ON_WM_HSCROLL()
ON_WM_KILLFOCUS()
ON_WM_SETFOCUS()
ON_WM_MOUSEWHEEL()
ON_COMMAND(ID_EDIT_FIND, OnEditFind)
ON_COMMAND(ID_EDIT_CUT, OnEditCut)
ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
ON_COMMAND(ID_EDIT_REPEAT, OnEditRepeat)
ON_COMMAND(ID_EDIT_REPLACE, OnEditReplace)
ON_COMMAND_RANGE(IDM_BOOKMARK1, IDM_BOOKMARK9, OnBookmark)
ON_COMMAND(IDM_REMOVE_BKM, OnRemoveBkm)
ON_COMMAND(IDM_CLEARALL_BMK, OnClearallBmk)
ON_COMMAND(IDM_ADDBOOKMARK, OnAddbookmark)
ON_COMMAND(IDM_COPY_HEXDUMP, OnCopyHexdump)
ON_COMMAND(IDM_INSERTFILE, OnInsertfile)
ON_COMMAND(IDM_SAVESELAS, OnSaveselas)
ON_COMMAND(ID_EDIT_CLEAR, OnEditClear)
ON_COMMAND(ID_EDIT_SELECT_ALL, OnEditSelectAll)
ON_COMMAND(IDA_INSERTMODETOGGLE, OnInsertmodetoggle)
ON_COMMAND(IDM_CHANGE_MODE, OnChangeMode)
ON_COMMAND(IDM_EDIT_READONLYMODE, OnEditReadonlymode)
ON_COMMAND(IDM_EDIT_APPEND, OnEditAppend)
ON_COMMAND(IDM_EDIT_MANIPULATEBITS, OnEditManipulatebits)
ON_COMMAND(IDM_SELECT_BLOCK, OnSelectBlock)
ON_COMMAND(IDM_READFLOAT, OnReadfloat)
ON_COMMAND(IDM_READ_UNICODE, OnReadUnicode)
ON_COMMAND(IDM_READ_UTF8, OnReadUtf8)
ON_COMMAND(IDM_PROPERTIES, OnProperties)
ON_COMMAND(IDM_REVERT, OnRevert)
ON_COMMAND(IDM_GO_TO, OnGoto)
ON_COMMAND(ID_BOOKMARKS_GOTOBOOKMARK, OnBookmarksGotobookmark)
ON_UPDATE_COMMAND_UI(ID_BOOKMARKS_GOTOBOOKMARK, OnUpdateBookmarksGotobookmark)
ON_UPDATE_COMMAND_UI(IDM_EDIT_READONLYMODE, OnUpdateEditReadonlymode)
ON_COMMAND(ID_EDIT_PASTE_SPECIAL, OnEditPasteSpecial)
ON_WM_CONTEXTMENU()
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
ON_REGISTERED_MESSAGE(_myMsgForFindReplace, OnFindReplaceCmd)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CFshedView construction/destruction
CFshedView::CFshedView()
{
hFont = NULL;
iCutMode = BST_CHECKED;
bDontMarkCurrentPos = FALSE;
bInsertingHex = FALSE;
iWindowX = CW_USEDEFAULT;
iWindowY = CW_USEDEFAULT;
iWindowWidth = CW_USEDEFAULT;
iWindowHeight = CW_USEDEFAULT;
iWindowShowCmd = SW_SHOW;
iHexWidth = 3;
// iClipboardEncode = TRUE;
pcGotoDlgBuffer = NULL;
iGotoDlgBufLen = 0;
iBmkCount=0;
szFileName[0] = '\0';
iInsertMode = FALSE;
bSelected = FALSE;
bLButtonIsDown = FALSE;
iStartOfSelection = 0;
iEndOfSelection = 0;
m_stScreenSettings.iByteSpace = 2;
m_stScreenSettings.iCharSpace = 1;
m_stScreenSettings.iCharsPerLine = App->m_iOffsetLen + m_stScreenSettings.iByteSpace +
App->m_iBytesPerLine * 3 + m_stScreenSettings.iCharSpace +
App->m_iBytesPerLine;
m_iEnteringMode = BYTES;
// m_iFileChanged = FALSE;
// Read in the last saved preferences.
// count_instances();
// read_ini_data ();
bSelected = FALSE;
bLButtonIsDown = FALSE;
// m_iFileChanged = FALSE;
m_bFirstSearch = TRUE;
m_pFindReplaceDlg = NULL; // find or replace dialog
m_bFindOnly = TRUE; // Is pFindReplace the find or replace?
m_bCase = FALSE; // TRUE==case sensitive, FALSE==not
m_bNext = TRUE; // TRUE==search down, FALSE== search up
m_bWord = FALSE; // TRUE==match whole word, FALSE==not
m_lInitialSearchPos = 0;
}
CFshedView::~CFshedView()
{
if (hFont != NULL)
DeleteObject (hFont);
if( pcGotoDlgBuffer != NULL )
delete [] pcGotoDlgBuffer;
if (m_pFindReplaceDlg)
delete m_pFindReplaceDlg;
}
BOOL CFshedView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CFshedView drawing
void CFshedView::OnDraw(CDC* pDC)
{
CFshedDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
// PAINTSTRUCT ps;
// HDC hdc = ::BeginPaint (m_hWnd, &ps);
HDC hdc = pDC->m_hDC;
//-------------------------------------------------------
HideCaret ();
// Delete remains of last position.
int a, b;
b = min (m_stScreenSettings.iCurLine + m_stScreenSettings.cyBuffer, m_stScreenSettings.iNumlines-1);
iBkColor = PALETTERGB (GetRValue(App->m_clrBk),GetGValue(App->m_clrBk),GetBValue(App->m_clrBk));
iTextColor = PALETTERGB (GetRValue(App->m_clrText),GetGValue(App->m_clrText),GetBValue(App->m_clrText));
SetTextColor (hdc, iTextColor);
SetBkColor (hdc, iBkColor);
HPEN pen1 = CreatePen (PS_SOLID, 1, iBkColor);
HPEN oldpen = (HPEN) SelectObject (hdc, pen1);
HBRUSH brush1 = CreateSolidBrush (iBkColor);
HBRUSH oldbrush = (HBRUSH) SelectObject (hdc, brush1);
// Delete lower border if there are empty lines on screen.
if ((b-m_stScreenSettings.iCurLine+1)*m_stScreenSettings.cyChar+CLIENT_BORDER_WIDTH < m_stScreenSettings.cyClient-CLIENT_BORDER_WIDTH)
Rectangle (hdc, CLIENT_BORDER_WIDTH, (b-m_stScreenSettings.iCurLine+1)*m_stScreenSettings.cyChar+CLIENT_BORDER_WIDTH + m_stScreenSettings.iToolbarHeight, m_stScreenSettings.cxClient-CLIENT_BORDER_WIDTH,
m_stScreenSettings.cyClient-CLIENT_BORDER_WIDTH + m_stScreenSettings.iToolbarHeight);
// Delete right border.
Rectangle (hdc, ((m_stScreenSettings.iHscrollMax+1)-m_stScreenSettings.iHscrollPos)*m_stScreenSettings.cxChar+CLIENT_BORDER_WIDTH, CLIENT_BORDER_WIDTH + m_stScreenSettings.iToolbarHeight,
m_stScreenSettings.cxClient-CLIENT_BORDER_WIDTH, m_stScreenSettings.cyClient-CLIENT_BORDER_WIDTH + m_stScreenSettings.iToolbarHeight);
SelectObject (hdc, oldpen);
SelectObject (hdc, oldbrush);
DeleteObject (pen1);
DeleteObject (brush1);
// Get font.
HFONT oldfont = (HFONT) SelectObject (hdc, hFont);
HPEN sep_pen = CreatePen (PS_SOLID, 1, App->m_clrSep);
oldpen = (HPEN) SelectObject (hdc, sep_pen);
if( Linebuffer.GetSize() < m_stScreenSettings.iCharsPerLine )
{
// Linebuffer too small.
if( Linebuffer.SetSize( m_stScreenSettings.iCharsPerLine ) )
{
Linebuffer.ExpandToSize();
// Linebuffer successfully resized.
HBRUSH hbr = CreateSolidBrush( App->m_clrBmk );
if (iUpdateLine == -1)
{
for (a = m_stScreenSettings.iCurLine; a <= b; a++)
print_line( hdc, a, Linebuffer, hbr );
}
else
{
print_line( hdc, iUpdateLine, Linebuffer, hbr );
}
DeleteObject( hbr );
SelectObject (hdc, oldpen);
DeleteObject (sep_pen);
SelectObject (hdc, oldfont);
// Mark character.
mark_char (hdc);
// Draw client-border.
draw_client_border (hdc);
ShowCaret ();
// ::EndPaint (m_hWnd, &ps);
set_caret_pos ();
set_wnd_title ();
iUpdateLine = -1;
}
else
{
// Could not allocate line buffer.
Rectangle( hdc, 0, m_stScreenSettings.iToolbarHeight, m_stScreenSettings.cxClient, m_stScreenSettings.cyClient + m_stScreenSettings.iToolbarHeight);
TCHAR buf[] = _T("Error: could not allocate line buffer.\nPlease save your changes and restart frhed.");
RECT r;
r.top = CLIENT_BORDER_WIDTH + m_stScreenSettings.iToolbarHeight;
r.left = CLIENT_BORDER_WIDTH;
r.right = m_stScreenSettings.cxClient;
r.bottom = m_stScreenSettings.cyClient + m_stScreenSettings.iToolbarHeight;
DrawText( hdc, buf, -1, &r, DT_LEFT );
}
}
else
{
// Linebuffer large enough.
HBRUSH hbr = CreateSolidBrush( App->m_clrBmk );
if (iUpdateLine == -1)
{
for (a = m_stScreenSettings.iCurLine; a <= b; a++)
print_line( hdc, a, Linebuffer, hbr );
}
else
{
print_line( hdc, iUpdateLine, Linebuffer, hbr );
}
DeleteObject( hbr );
SelectObject (hdc, oldpen);
DeleteObject (sep_pen);
SelectObject (hdc, oldfont);
// Mark character.
mark_char (hdc);
// Draw client-border.
draw_client_border (hdc);
ShowCaret ();
// ::EndPaint (m_hWnd, &ps);
set_caret_pos ();
set_wnd_title ();
iUpdateLine = -1;
}
}
/////////////////////////////////////////////////////////////////////////////
// CFshedView printing
BOOL CFshedView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CFshedView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
{
m_saveSettings.CopySettings(m_stScreenSettings);
int nHeight = -::MulDiv(App->m_iFontSize, pDC->GetDeviceCaps(LOGPIXELSY), 72);
make_font(pDC->GetSafeHdc(), nHeight);
HFONT of = (HFONT) SelectObject (pDC->GetSafeHdc(), hFont);
TEXTMETRIC tm;
pDC->GetTextMetrics(&tm);
m_stScreenSettings.cxClient = pDC->GetDeviceCaps(HORZRES);
m_stScreenSettings.cyClient = pDC->GetDeviceCaps(VERTRES);
m_stScreenSettings.cxChar = tm.tmAveCharWidth;
m_stScreenSettings.cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * m_stScreenSettings.cxChar / 2;
m_stScreenSettings.cyChar = tm.tmHeight + tm.tmExternalLeading;
m_stScreenSettings.cxBuffer = max (1, m_stScreenSettings.cxClient / m_stScreenSettings.cxChar);
m_stScreenSettings.cyBuffer = max (1, m_stScreenSettings.cyClient / m_stScreenSettings.cyChar);
SelectObject (pDC->GetSafeHdc(), of);
// Adjust bytes per line to width of window.
// m_stScreenSettings.cxBuffer = maximal width of client-area in chars.
if( App->m_bAutomaticBPL )
{
int bytemax = m_stScreenSettings.cxBuffer - App->m_iOffsetLen - m_stScreenSettings.iByteSpace - m_stScreenSettings.iCharSpace;
App->m_iBytesPerLine = bytemax / 4;
if (App->m_iBytesPerLine < 1)
App->m_iBytesPerLine = 1;
}
// Caret or end of selection will be vertically centered if line not visible.
if( bSelected )
{
if( iEndOfSelection / App->m_iBytesPerLine < m_stScreenSettings.iCurLine || iEndOfSelection / App->m_iBytesPerLine > m_stScreenSettings.iCurLine + m_stScreenSettings.cyBuffer )
m_stScreenSettings.iCurLine = max( 0, iEndOfSelection / App->m_iBytesPerLine - m_stScreenSettings.cyBuffer / 2 );
}
else
{
if( m_stScreenSettings.iCurByte/App->m_iBytesPerLine < m_stScreenSettings.iCurLine || m_stScreenSettings.iCurByte/App->m_iBytesPerLine > m_stScreenSettings.iCurLine + m_stScreenSettings.cyBuffer )
m_stScreenSettings.iCurLine = max( 0, m_stScreenSettings.iCurByte/App->m_iBytesPerLine-m_stScreenSettings.cyBuffer/2 );
}
m_stScreenSettings.iCharsPerLine = App->m_iOffsetLen + m_stScreenSettings.iByteSpace + App->m_iBytesPerLine*3 + m_stScreenSettings.iCharSpace + App->m_iBytesPerLine;
// Get number of lines to display.
if ((Doc->DataArray.GetLength()+1) % App->m_iBytesPerLine == 0)
m_stScreenSettings.iNumlines = (Doc->DataArray.GetLength()+1) / App->m_iBytesPerLine;
else
m_stScreenSettings.iNumlines = (Doc->DataArray.GetLength()+1) / App->m_iBytesPerLine + 1;
if (m_stScreenSettings.iNumlines <= 0xffff)
m_stScreenSettings.iVscrollMax = m_stScreenSettings.iNumlines-1;
else
m_stScreenSettings.iVscrollMax = 0xffff;
//keydown(VK_HOME);
pInfo->SetMaxPage((m_stScreenSettings.iNumlines + m_stScreenSettings.cyBuffer - 1) / m_stScreenSettings.cyBuffer);
}
void CFshedView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
m_stScreenSettings.CopySettings(m_saveSettings);
update_for_new_datasize();
}
/////////////////////////////////////////////////////////////////////////////
// CFshedView diagnostics
#ifdef _DEBUG
void CFshedView::AssertValid() const
{
CView::AssertValid();
}
void CFshedView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CFshedDoc* CFshedView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CFshedDoc)));
return (CFshedDoc*)m_pDocument;
}
#endif //_DEBUG
//-------------------------------------------------------------------
int CFshedView::read_ini_data ()
{
return 0;
}
//-------------------------------------------------------------------
int CFshedView::save_ini_data ()
{
return 0;
}
//-------------------------------------------------------------------
// Find char c from pointer to array src on, return it's position.
int CFshedView::find_byte_pos (const char* src, char c)
{
int i=0;
while (src[i] != c)
{
i++;
}
return i;
}
//-------------------------------------------------------------------
// dest must be set to right length before calling.
int CFshedView::create_bc_translation (char* dest, const char* src, int srclen, int charmode, int binmode)
{
int i, di=0, bclen;
for (i=0; i<srclen; i++)
{
if ((bclen = is_bytecode (&(src[i]), srclen-i)) > 0) // Get length of byte-code.
{
// Bytecode found.
translate_bytecode (&(dest[di]), &(src[i]), srclen-i, binmode);
di += bclen;
i += find_byte_pos (&(src[i]), '>');
}
else // Normal character.
{
if (src[i] == '\\') // Special char "\<" or "\\"?
{
if (i+1 < srclen)
{
if (src[i+1] == '<')
{
dest[di++] = '<'; // Special char recognized.
i++;
}
else if( src[i+1] == '\\' )
{
dest[di++] = '\\'; // Special char recognized.
i++;
}
else
dest[di++] = src[i]; // Unknown special char.
}
else
dest[di++] = src[i]; // Not enough space for special char.
}
else
{
// No special char.
switch (charmode)
{
case ANSI_SET:
dest[di++] = src[i];
break;
case OEM_SET:
dest[di++] = TranslateAnsiToOem (src[i]);
break;
}
}
}
}
return di;
}
//-------------------------------------------------------------------
// Get value of one code.
// Return: value of code.
// bytecode must be checked before.
int CFshedView::translate_bytecode (char* dest, const char* src, int srclen, int binmode)
{
int i, k=0;
char buf[50];
for (i=4; i<srclen; i++)
{
if (src[i]=='>')
break;
else
{
buf[k++] = src[i];
}
}
buf[k] = 0;
int value;
float fvalue;
double dvalue;
switch (src[2]) // Get value from text.
{
case 'd':
sscanf (buf, "%d", &value);
break;
case 'h':
sscanf (buf, "%x", &value);
break;
case 'l':
sscanf (buf, "%f", &fvalue);
break;
case 'o':
sscanf (buf, "%lf", &dvalue);
break;
}
if (binmode == LITTLEENDIAN_MODE)
{
switch (src[1])
{
case 'b':
dest[0] = (char) value;
break;
case 'w':
dest[0] = (value & 0xff);
dest[1] = (value & 0xff00)>>8;
break;
case 'l':
dest[0] = (value & 0xff);
dest[1] = (value & 0xff00)>>8;
dest[2] = (value & 0xff0000)>>16;
dest[3] = (value & 0xff000000)>>24;
break;
case 'f':
*((float*)dest) = fvalue;
break;
case 'd':
*((double*)dest) = dvalue;
break;
}
}
else // BIGENDIAN_MODE
{
switch (src[1])
{
case 'b':
dest[0] = (char) value;
break;
case 'w':
dest[0] = HIBYTE (LOWORD (value));
dest[1] = LOBYTE (LOWORD (value));
break;
case 'l':
dest[0] = HIBYTE (HIWORD (value));
dest[1] = LOBYTE (HIWORD (value));
dest[2] = HIBYTE (LOWORD (value));
dest[3] = LOBYTE (LOWORD (value));
break;
case 'f':
{
char* p = (char*) &fvalue;
int i;
for (i=0; i<4; i++)
{
dest[i] = p[3-i];
}
}
break;
case 'd':
{
char* p = (char*) &dvalue;
int i;
for (i=0; i<8; i++)
{
dest[i] = p[7-i];
}
}
break;
}
}
return value;
}
//-------------------------------------------------------------------
// Get length of code.
int CFshedView::calc_bctrans_destlen (const char* src, int srclen)
{
int i, destlen = 0, l, k;
for (i=0; i<srclen; i++)
{
if ((l = is_bytecode (&(src[i]), srclen-i)) == 0)
{
if (src[i] == '\\')
{
if (i+1 < srclen)
{
if (src[i+1] == '<')
{
// Code for "<" alone without decoding.
destlen++;
i++;
}
else if( src[i+1] == '\\' )
{
// Code for "\\".
destlen++;
i++;
}
else
{
destlen++;
}
}
else
{
destlen++;
}
}
else
{
destlen++;
}
}
else
{
destlen += l;
for (k=i; i<srclen; k++)
{
if (src[k]=='>')
break;
}
i = k;
}
}
return destlen;
}
//-------------------------------------------------------------------
// Bytecode?
// Return = 0 if no bytecode
// = Length 1/2/4 if bytecode
int CFshedView::is_bytecode (const char* src, int len)
{
int i=0;
if (src[i] == '<')
{
if (i+1 < len)
{
switch (src[i+1])
{
case 'b': case 'w': case 'l': case 'f': case 'd':
if (i+2 < len)
{
switch (src[i+2])
{
case 'd': case 'h': case 'l': case 'o':
if (i+3 < len)
{
if (src[i+3] == ':')
{
int j,k;
for (j=4; j < len; j++)
{
if (src[i+j] == '>')
break;
}
if (j==4 || j==len)
return FALSE;
for (k=4; k<j; k++)
{
switch (src[i+2])
{
case 'd':
if ((src[i+k]>='0' && src[i+k]<='9') || src[i+k]=='-')
continue;
else
return FALSE; // Non-digit found.
break;
case 'h':
if ((src[i+k]>='0' && src[i+k]<='9') ||
(src[i+k]>='a' && src[i+k]<='f'))
continue;
else
return FALSE; // Non-hex-digit.
break;
case 'o': case 'l': // float or double.
if ((src[i+k]>='0' && src[i+k]<='9') || src[i+k]=='-' || src[i+k]=='.' || src[i+k]=='e' || src[i+k]=='E')
continue;
else
return FALSE;
break;
}
}
switch (src[i+1])
{
default:
case 'b': return 1;
case 'w': return 2;
case 'l': return 4;
case 'f': return 4;
case 'd': return 8;
}
}
else
return FALSE; // No ':'.
}
else
return FALSE; // No space for ':'.
break;
default:
return FALSE; // Wrong second option.
}
}
else
return FALSE; // No space for option 2.
break;
default:
return FALSE; // Wrong first option.
break;
}
}
else
return FALSE; // No space for option 1;
}
else
return FALSE; // No '<'.
}
#ifdef _UNICODE
int CFshedView::create_bc_translation (char** ppd, LPCTSTR src, int srclen, int charmode, int binmode)
{
int destLen = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)src, (int)_tcslen(src), NULL, NULL, NULL, NULL);
char *charstring = new char[destLen + 1];
WideCharToMultiByte(CP_ACP, 0, (LPWSTR)src, (int)_tcslen(src),
charstring, destLen, NULL, NULL);
charstring[destLen] = 0;
int nRtn = create_bc_translation(ppd, charstring, srclen, charmode, binmode);
delete charstring;
return nRtn;
}
#endif
//-------------------------------------------------------------------
// Create translation of bytecode-string.
// Return: Length of resulting string.
// ppd = pointer to pointer to result, must be delete[]-ed later.
// If the input string was empty, no translated array is created and zero is returned.
int CFshedView::create_bc_translation (char** ppd, const char* src, int srclen, int charmode, int binmode)
{
int destlen = calc_bctrans_destlen (src, srclen);
if (destlen > 0)
{
*ppd = new char[destlen];
create_bc_translation (*ppd, src, srclen, charmode, binmode);
return destlen;
}
else
{
// Empty input string => don't allocate anything and return 0.
*ppd = NULL;
return 0;
}
}
//-------------------------------------------------------------------
// Translate an array of bytes to a text string using special syntax.
// Return: Length of string including zero-byte.
int CFshedView::translate_bytes_to_BC (CString &strTranslated, unsigned char* src, int srclen)
{
int i, k = 0;
char buf[16];
strTranslated.Empty();
for (i=0; i<srclen; i++)
{
if (src[i] == '<')
{
strTranslated += '\\';
strTranslated += '<';
}
else if( src[i] == '\\' )
{
strTranslated += '\\';
strTranslated += '\\';
}
else if (src[i] >= 32 && src[i] < 127)
{
strTranslated += src[i];
}
else if( src[i]==10 || src[i]==13 )
{
strTranslated += src[i];
}
else
{
strTranslated += '<';
strTranslated += 'b';
strTranslated += 'h';
strTranslated += ':';
sprintf (buf, "%2.2x", src[i]);
strTranslated += buf[0];
strTranslated += buf[1];
strTranslated += '>';
}
}
return strTranslated.GetLength();
}
//-------------------------------------------------------------------
// Used with translate_bytes_to_BC.
// Return: Length of bytecode-string including zero-byte.
int CFshedView::byte_to_BC_destlen (char* src, int srclen)
{
int i, destlen = 1;
for (i=0; i<srclen; i++)
{
if (src[i] == '<')
destlen+=2; // Escapecode needed.
else if( src[i] == '\\' )
destlen+=2; // Escapecode needed.
else if (src[i] >= 32 && src[i] < 127)
destlen++; // Normal char.
else if( src[i]==10 || src[i]==13 )
destlen++; // LF/CR.
else
destlen+=7; // Escapecode needed.
}
return destlen;
}
//-------------------------------------------------------------------
// If filesize changes, scrollbars etc. must be adjusted.
void CFshedView::update_for_new_datasize ()
{
RECT r;
GetClientRect (&r);
resize_window (r.right, r.bottom);
}
//-------------------------------------------------------------------
char CFshedView::TranslateAnsiToOem (char c)
{
TCHAR sbuf[2];
char dbuf[2];
sbuf[0]=c;
sbuf[1]=0;
CharToOemBuff (sbuf, dbuf, 1);
return dbuf[0];
}
//--------------------------------------------------------------------------------------------
// Window was resized to new width of cx and new height of cy.
int CFshedView::resize_window (int cx, int cy)
{
// Get font data.
HDC hdc = ::GetDC (m_hWnd);
if (make_font (hdc))
{
HFONT of = (HFONT) SelectObject( hdc, hFont );
TEXTMETRIC tm;
GetTextMetrics (hdc, &tm);
m_stScreenSettings.cxChar = tm.tmAveCharWidth;
m_stScreenSettings.cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * m_stScreenSettings.cxChar / 2;
m_stScreenSettings.cyChar = tm.tmHeight + tm.tmExternalLeading;
SelectObject (hdc, of);
}
::ReleaseDC (m_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);
int y3 = 0;
// ::GetWindowRect (hwndToolBar, &rWindow);
// m_stScreenSettings.iToolbarHeight = y3 = rWindow.bottom - rWindow.top;
// x = 0;
// y = 0;
// x2 = cx;
// ::MoveWindow (hwndToolBar, x, y, x2, y3, TRUE);
// Get client size.
m_stScreenSettings.cxClient = cx;
m_stScreenSettings.cyClient = cy - y2 - y3;
// Resize scrollbars.
int cyh = GetSystemMetrics (SM_CYHSCROLL),
cxv = GetSystemMetrics (SM_CXVSCROLL);
::MoveWindow (hwndHBar, 0, m_stScreenSettings.cyClient - cyh + y3, m_stScreenSettings.cxClient - cxv, cyh, FALSE);
::MoveWindow (hwndVBar, m_stScreenSettings.cxClient - cxv, y3, cxv, m_stScreenSettings.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.
m_stScreenSettings.cxClient -= cxv;
m_stScreenSettings.cyClient -= cyh;
//--------------------------------------------
// Set statusbar divisions.
int statbarw;
if (IsZoomed())
statbarw = cx;
else
statbarw = m_stScreenSettings.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);
//--------------------------------------------
m_stScreenSettings.cxBuffer = max (1, m_stScreenSettings.cxClient / m_stScreenSettings.cxChar);
m_stScreenSettings.cyBuffer = max (1, m_stScreenSettings.cyClient / m_stScreenSettings.cyChar);
// Adjust bytes per line to width of window.
// m_stScreenSettings.cxBuffer = maximal width of client-area in chars.
if( App->m_bAutomaticBPL )
{
int bytemax = m_stScreenSettings.cxBuffer-App->m_iOffsetLen-m_stScreenSettings.iByteSpace-m_stScreenSettings.iCharSpace;
App->m_iBytesPerLine = bytemax / 4;
if (App->m_iBytesPerLine < 1)
App->m_iBytesPerLine = 1;
}
// Caret or end of selection will be vertically centered if line not visible.
if( bSelected )
{
if( iEndOfSelection / App->m_iBytesPerLine < m_stScreenSettings.iCurLine || iEndOfSelection / App->m_iBytesPerLine > m_stScreenSettings.iCurLine + m_stScreenSettings.cyBuffer )
m_stScreenSettings.iCurLine = max( 0, iEndOfSelection / App->m_iBytesPerLine - m_stScreenSettings.cyBuffer / 2 );
}
else
{
if( m_stScreenSettings.iCurByte/App->m_iBytesPerLine < m_stScreenSettings.iCurLine || m_stScreenSettings.iCurByte/App->m_iBytesPerLine > m_stScreenSettings.iCurLine + m_stScreenSettings.cyBuffer )
m_stScreenSettings.iCurLine = max( 0, m_stScreenSettings.iCurByte/App->m_iBytesPerLine-m_stScreenSettings.cyBuffer/2 );
}
ASSERT(m_stScreenSettings.iCurLine >= 0);
adjust_vscrollbar();
m_stScreenSettings.iCharsPerLine = App->m_iOffsetLen + m_stScreenSettings.iByteSpace + App->m_iBytesPerLine*3 + m_stScreenSettings.iCharSpace + App->m_iBytesPerLine;
// Get number of lines to display.
if ((Doc->DataArray.GetLength()+1) % App->m_iBytesPerLine == 0)
m_stScreenSettings.iNumlines = (Doc->DataArray.GetLength()+1) / App->m_iBytesPerLine;
else
m_stScreenSettings.iNumlines = (Doc->DataArray.GetLength()+1) / App->m_iBytesPerLine + 1;
TRACE("Num Bytes %d, per line %d\n", Doc->DataArray.GetLength(), App->m_iBytesPerLine);
// if (m_stScreenSettings.iNumlines <= 0xffff)
m_stScreenSettings.iVscrollMax = m_stScreenSettings.iNumlines-1;
// else
// m_stScreenSettings.iVscrollMax = 0xffff;
SCROLLINFO si;
memset(&si, 0, sizeof(si));
si.cbSize = sizeof(si);
si.fMask = SIF_POS | SIF_RANGE;
si.nMax = m_stScreenSettings.iVscrollMax;
si.nPos = m_stScreenSettings.iVscrollPos;
TRACE("Range max %d, pos %d\n", si.nMax, si.nPos);
::SetScrollInfo(hwndVBar, SB_CTL, &si, TRUE);
// ::SetScrollRange (hwndVBar, SB_CTL, 0, m_stScreenSettings.iVscrollMax, FALSE);
// ::SetScrollPos (hwndVBar, SB_CTL, m_stScreenSettings.iVscrollPos, TRUE);
m_stScreenSettings.iHscrollMax = m_stScreenSettings.iCharsPerLine - 1;
m_stScreenSettings.iHscrollPos = 0;
memset(&si, 0, sizeof(si));
si.cbSize = sizeof(si);
si.fMask = SIF_POS | SIF_RANGE;
si.nMax = m_stScreenSettings.iHscrollMax;
si.nPos = m_stScreenSettings.iHscrollPos;
::SetScrollInfo(hwndHBar, SB_CTL, &si, TRUE);
// ::SetScrollRange (hwndHBar, SB_CTL, 0, m_stScreenSettings.iHscrollMax, FALSE);
// ::SetScrollPos (hwndHBar, SB_CTL, m_stScreenSettings.iHscrollPos, TRUE);
set_wnd_title ();
if (this == GetFocus ())
set_caret_pos ();
repaint ();
return TRUE;
}
//--------------------------------------------------------------------------------------------
// Set the window title and the statusbar text.
void CFshedView::set_wnd_title()
{
TCHAR buf[512];
if (_tcslen (Doc->filename) != 0)
{
// Change window title.
if (Doc->bFilestatusChanged)
{
_stprintf (buf, _T("[%s"), Doc->filename);
if (GetDocument()->IsModified())
_tcscat (buf, _T(" *"));
_tcscat (buf, _T("]"));
if (Doc->bPartialOpen==TRUE)
_tcscat (buf, _T(" - P"));
_tcscat (buf, _T(" - frhed"));
SetWindowText (buf);
Doc->bFilestatusChanged = FALSE;
}
// Selection going on.
if (bSelected == TRUE)
{
if (iEndOfSelection >= iStartOfSelection)
{
_stprintf (buf, _T("Selected: Offset %d=0x%x to %d=0x%x (%d byte(s))"), iStartOfSelection, iStartOfSelection,
iEndOfSelection, iEndOfSelection, iEndOfSelection-iStartOfSelection+1);
}
else
{
_stprintf (buf, _T("Selected: Offset %d=0x%x to %d=0x%x (%d byte(s))"), iEndOfSelection, iEndOfSelection,
iStartOfSelection, iStartOfSelection, iStartOfSelection-iEndOfSelection+1);
}
::SendMessage (hwndStatusBar, SB_SETTEXT, 0, (LPARAM) buf);
}
else // Normal display.
{
//Pabs changed - \t removed from end of string literal ("Offset %d=0x%x\t" -> "Offset %d=0x%x")
_stprintf (buf, _T("Offset %d=0x%x"), m_stScreenSettings.iCurByte, m_stScreenSettings.iCurByte);
//end
int wordval, longval;
TCHAR buf2[80];
//Pabs changed - line insert
if (Doc->DataArray.GetLength()-m_stScreenSettings.iCurByte > 0){//if we are not looking at the End byte
// R. Kibria: changed the output slightly (used to be "Bits = 0b").
_tcscat (buf, _T(" Bits="));//append stuff to status text
TCHAR zzz = Doc->DataArray[m_stScreenSettings.iCurByte];//quicker to have a tmp var than to call operator[] 8 times
for(int i=0;i<8;i++)buf2[i]=((zzz>>i)&0x1?'1':'0');//Extract bits
for(int i=0;i<4;i++)swap(buf2[i],buf2[7-i]);//flip order-for some reason it doesn't display correctly going i-- or i++ in for loop
buf2[8]='\0';//terminate string
_tcscat (buf, buf2);//append to status text
}
_tcscat (buf, _T("\t"));//add that \t back on to the status text
//end
if (App->m_bUnsignedView) // Values signed/unsigned?
{
// UNSIGNED
if (App->m_iBinaryMode == LITTLEENDIAN_MODE)
{
// UNSIGNED LITTLEENDIAN_MODE
// Decimal value of byte.
if (Doc->DataArray.GetLength ()-m_stScreenSettings.iCurByte >= 1)
{
_stprintf (buf2, _T("\tUnsigned: B:%u"), (unsigned int) Doc->DataArray[m_stScreenSettings.iCurByte]);
_tcscat (buf, buf2);
}
else
{
_tcscpy(buf2, _T("\tEND"));
_tcscat(buf, buf2);
}
// Space enough for a word?
if (Doc->DataArray.GetLength ()-m_stScreenSettings.iCurByte >= 2)
{
// Space enough for a word.
wordval = (Doc->DataArray[m_stScreenSettings.iCurByte+1] << 8) | Doc->DataArray[m_stScreenSettings.iCurByte];
_stprintf (buf2, _T(",W:%u"), (unsigned int) wordval);
_tcscat (buf, buf2);
}
if (Doc->DataArray.GetLength ()-m_stScreenSettings.iCurByte >= 4)
{
// Space enough for a longword.
longval = wordval | (((Doc->DataArray[m_stScreenSettings.iCurByte + 3] << 8) | Doc->DataArray[m_stScreenSettings.iCurByte + 2]) << 16);
_stprintf (buf2, _T(",L:%u"), (unsigned int) longval);
_tcscat (buf, buf2);
}
}
else
{
// UNSIGNED BIGENDIAN_MODE
// Decimal value of byte.
if (Doc->DataArray.GetLength ()-m_stScreenSettings.iCurByte >= 1)
{
_stprintf (buf2, _T("\tUnsigned: B:%u"), (unsigned int) Doc->DataArray[m_stScreenSettings.iCurByte]);
_tcscat(buf, buf2);
}
else
{
_tcscpy(buf2, _T("\tEND"));
_tcscat(buf, buf2);
}
// Space enough for a word?
if (Doc->DataArray.GetLength ()-m_stScreenSettings.iCurByte >= 2)
{
// Space enough for a word.
wordval = (Doc->DataArray[m_stScreenSettings.iCurByte] << 8) | Doc->DataArray[m_stScreenSettings.iCurByte+1];
_stprintf(buf2, _T(",W:%u"), (unsigned int) wordval);
_tcscat (buf, buf2);
}
if (Doc->DataArray.GetLength ()-m_stScreenSettings.iCurByte >= 4)
{
// Space enough for a longword.
longval = (wordval<<16) | (Doc->DataArray[m_stScreenSettings.iCurByte+2]<<8) | (Doc->DataArray[m_stScreenSettings.iCurByte+3]);
_stprintf (buf2, _T(",L:%u"), (unsigned int) longval);
_tcscat (buf, buf2);
}
}
}
else // SIGNED
{
if (App->m_iBinaryMode == LITTLEENDIAN_MODE)
{
// SIGNED LITTLEENDIAN_MODE
// Decimal value of byte.
if (Doc->DataArray.GetLength ()-m_stScreenSettings.iCurByte >= 1)
{
_stprintf(buf2, _T("\tSigned: B:%d"), (int) (signed char) Doc->DataArray[m_stScreenSettings.iCurByte]);
_tcscat(buf, buf2);
}
else
{
_stprintf (buf2, _T("\tEND"));
_tcscat (buf, buf2);
}
// Space enough for a word?
if (Doc->DataArray.GetLength ()-m_stScreenSettings.iCurByte >= 2)
{
// Space enough for a word.
wordval = (Doc->DataArray[m_stScreenSettings.iCurByte + 1] << 8) | Doc->DataArray[m_stScreenSettings.iCurByte];
_stprintf (buf2, _T(",W:%d"), (int) (signed short) wordval);
_tcscat (buf, buf2);
}
if (Doc->DataArray.GetLength ()-m_stScreenSettings.iCurByte >= 4)
{
// Space enough for a longword.
longval = wordval | (((Doc->DataArray[m_stScreenSettings.iCurByte + 3] << 8) | Doc->DataArray[m_stScreenSettings.iCurByte + 2]) << 16);
_stprintf (buf2, _T(",L:%d"), (signed int) longval);
_tcscat (buf, buf2);
}
}
else
{
// SIGNED BIGENDIAN_MODE
// Decimal value of byte.
if (Doc->DataArray.GetLength ()-m_stScreenSettings.iCurByte >= 1)
{
_stprintf (buf2, _T("\tSigned: B:%d"), (signed char) Doc->DataArray[m_stScreenSettings.iCurByte]);
_tcscat (buf, buf2);
}
else
{
_stprintf (buf2, _T("\tEND"));
_tcscat (buf, buf2);
}
// Space enough for a word.
if (Doc->DataArray.GetLength ()-m_stScreenSettings.iCurByte >= 2)
{
// Space enough for a longword.
wordval = (Doc->DataArray[m_stScreenSettings.iCurByte] << 8) | Doc->DataArray[m_stScreenSettings.iCurByte+1];
_stprintf (buf2, _T(",W:%d"), (int) (signed short) wordval);
_tcscat (buf, buf2);
}
if (Doc->DataArray.GetLength ()-m_stScreenSettings.iCurByte >= 4)
{
// Space enough for a longword.
longval = (wordval<<16) | (Doc->DataArray[m_stScreenSettings.iCurByte+2]<<8) | (Doc->DataArray[m_stScreenSettings.iCurByte+3]);
_stprintf (buf2, _T(",L:%d"), (signed int) longval);
_tcscat (buf, buf2);
}
}
}
::SendMessage (hwndStatusBar, SB_SETTEXT, 0, (LPARAM) buf);
// Character set, input mode or read-only, binary mode.
switch (App->m_iCharacterSet)
{
case ANSI_FIXED_FONT:
_tcscpy(buf, _T("\tANSI"));
break;
case OEM_FIXED_FONT:
_tcscpy(buf, _T("\tOEM"));
break;
}
if (Doc->bReadOnly)
{
_tcscpy(buf2, _T(" / READ"));
_tcscat (buf, buf2);
}
else if (iInsertMode)
{
_tcscpy(buf2, _T(" / INS"));
_tcscat (buf, buf2);
}
else
{
_tcscpy(buf2, _T(" / OVR"));
_tcscat (buf, buf2);
}
if (App->m_iBinaryMode == LITTLEENDIAN_MODE)
{
_tcscpy(buf2, _T(" / L")); // Intel
_tcscat (buf, buf2);
}
else if (App->m_iBinaryMode == BIGENDIAN_MODE)
{
_tcscpy(buf2, _T(" / B")); // Motorola
_tcscat (buf, buf2);
}
::SendMessage (hwndStatusBar, SB_SETTEXT, 1, (LPARAM) buf);
// File size.
_stprintf (buf, _T("\tSize: %u"), Doc->DataArray.GetLength ());
::SendMessage (hwndStatusBar, SB_SETTEXT, 2, (LPARAM) buf);
}
}
else
{
SetWindowText (_T("fshed"));
::SendMessage (hwndStatusBar, WM_SETTEXT, 0, (LPARAM) _T("No file loaded"));
}
}
//--------------------------------------------------------------------------------------------
// Set Caret position.
void CFshedView::set_caret_pos ()
{
if (bSelected)
{
::SetCaretPos (-m_stScreenSettings.cxChar, -m_stScreenSettings.cyChar + m_stScreenSettings.iToolbarHeight);
return;
}
int iCaretLine = m_stScreenSettings.iCurByte / App->m_iBytesPerLine,
iBottomLine = m_stScreenSettings.iCurLine + m_stScreenSettings.cyBuffer - 1;
switch (m_iEnteringMode)
{
case CHARS:
if (iCaretLine >= m_stScreenSettings.iCurLine && iCaretLine <= iBottomLine && Doc->filename[0] != '\0')
{
int y = iCaretLine - m_stScreenSettings.iCurLine,
x = App->m_iOffsetLen+m_stScreenSettings.iByteSpace+App->m_iBytesPerLine*3+m_stScreenSettings.iCharSpace
- m_stScreenSettings.iHscrollPos + (m_stScreenSettings.iCurByte%App->m_iBytesPerLine);
::SetCaretPos (CLIENT_BORDER_WIDTH + x*m_stScreenSettings.cxChar, CLIENT_BORDER_WIDTH + y*m_stScreenSettings.cyChar + m_stScreenSettings.iToolbarHeight);
}
else
::SetCaretPos (-m_stScreenSettings.cxChar, -m_stScreenSettings.cyChar + m_stScreenSettings.iToolbarHeight);
break;
case BYTES:
// If caret in vertical visible area...
if (iCaretLine >= m_stScreenSettings.iCurLine && iCaretLine <= iBottomLine && Doc->filename[0] != '\0')
{
int y = iCaretLine - m_stScreenSettings.iCurLine,
x = App->m_iOffsetLen+m_stScreenSettings.iByteSpace + (m_stScreenSettings.iCurByte%App->m_iBytesPerLine)*3 - m_stScreenSettings.iHscrollPos + m_stScreenSettings.iCurNibble;
::SetCaretPos (CLIENT_BORDER_WIDTH + x*m_stScreenSettings.cxChar, CLIENT_BORDER_WIDTH + y*m_stScreenSettings.cyChar + m_stScreenSettings.iToolbarHeight);
}
else
::SetCaretPos (-m_stScreenSettings.cxChar, -m_stScreenSettings.cyChar + m_stScreenSettings.iToolbarHeight);
}
}
//--------------------------------------------------------------------------------------------
// Repaints the whole window.
int CFshedView::repaint( int line )
{
HideCaret();
iUpdateLine = line;
InvalidateRect(NULL, FALSE );
UpdateWindow();
ShowCaret();
return 0;
}
//--------------------------------------------------------------------------------------------
// Clear everything up.
void CFshedView::clear_all ()
{
App->m_iOffsetLen = 8;
m_stScreenSettings.iByteSpace = 2;
App->m_iBytesPerLine = 16;
m_stScreenSettings.iCharSpace = 1;
m_stScreenSettings.iCharsPerLine = App->m_iOffsetLen + m_stScreenSettings.iByteSpace + App->m_iBytesPerLine*3 + m_stScreenSettings.iCharSpace + App->m_iBytesPerLine;
Doc->DataArray.ClearAll ();
Doc->filename[0] = '\0';
m_stScreenSettings.iVscrollMax = 0;
m_stScreenSettings.iVscrollPos = 0;
m_stScreenSettings.iVscrollInc = 0;
m_stScreenSettings.iHscrollMax = 0;
m_stScreenSettings.iHscrollPos = 0;
m_stScreenSettings.iHscrollInc = 0;
m_stScreenSettings.iCurLine = 0;
m_stScreenSettings.iCurByte = 0;
m_stScreenSettings.iCurNibble = 0;
}
//--------------------------------------------------------------------------------------------
// Set the vertical scrollbar position.
void CFshedView::adjust_vscrollbar ()
{
m_stScreenSettings.iVscrollPos = (int) ((float)m_stScreenSettings.iCurLine * ((float)m_stScreenSettings.iVscrollMax)/(float)(m_stScreenSettings.iNumlines-1));
SCROLLINFO si;
memset(&si, 0, sizeof(si));
si.cbSize = sizeof(si);
si.fMask = SIF_POS;
si.nPos = m_stScreenSettings.iVscrollPos;
::SetScrollInfo(hwndVBar, SB_CTL, &si, TRUE);
// ::SetScrollPos (hwndVBar, SB_CTL, m_stScreenSettings.iVscrollPos, TRUE);
}
//--------------------------------------------------------------------------------------------
// Set the horizontal scrollbar position.
void CFshedView::adjust_hscrollbar ()
{
SCROLLINFO si;
memset(&si, 0, sizeof(si));
si.cbSize = sizeof(si);
si.fMask = SIF_POS;
si.nPos = m_stScreenSettings.iHscrollPos;
::SetScrollInfo(hwndHBar, SB_CTL, &si, TRUE);
// ::SetScrollPos (hwndHBar, SB_CTL, m_stScreenSettings.iHscrollPos, TRUE);
}
//-------------------------------------------------------------------
int CFshedView::make_font(HDC hdc, int nHeight)
{
//if (m_bPrinting)
// return 0;
if (hFont != NULL)
DeleteObject (hFont);
//HDC hdc = ::GetDC (m_hWnd);
if (nHeight == 0)
nHeight = -MulDiv(App->m_iFontSize, GetDeviceCaps(hdc, LOGPIXELSY), 72);
//::ReleaseDC (m_hWnd, hdc);
int cset;
if (App->m_iCharacterSet==ANSI_FIXED_FONT)
cset = ANSI_CHARSET;
else
cset = OEM_CHARSET;
hFont = CreateFont (nHeight,0,0,0,0,0,0,0,cset,OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,FIXED_PITCH | FF_DONTCARE,0);
return 1;
}
//--------------------------------------------------------------------------------------------
// Repaint one line in the window.
void CFshedView::print_line (HDC hdc, int line, char* linbuf, HBRUSH hbr )
{
// line = absolute line number.
// if line not visible:
if (line < m_stScreenSettings.iCurLine || line > m_stScreenSettings.iCurLine + m_stScreenSettings.cyBuffer)
return;
if (line < 0)
{
TRACE("Invalid line %d not drawn\n", line);
return;
}
int startpos = line * App->m_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 > Doc->DataArray.GetUpperBound() + 1 )
{
return;
}
// Write offset.
sprintf (buf, "%%%d.%dx", App->m_iOffsetLen, App->m_iOffsetLen);
for (m=0; m<m_stScreenSettings.iByteSpace; m++)
buf[5+m] = ' ';
buf[5+m] = '\0';
sprintf (linbuf, buf, startpos);
// Last line reached? Then only write rest of bytes.
// startpos+App->m_iBytesPerLine-1 = Last byte in current line.
if (startpos+App->m_iBytesPerLine > Doc->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 = Doc->DataArray.GetUpperBound()+1;
}
else
{
// Print the bytes up to the end of this line, they are all valid.
endpos = startpos+App->m_iBytesPerLine-1;
}
// Could happen on arrow down, so that last line is on bottom of window:
if( endpos < startpos )
{
endpos = startpos;
}
// Write bytes.
m = App->m_iOffsetLen+m_stScreenSettings.iByteSpace; // Index of first byte in line.
for (i=startpos; i<=endpos; i++)
{
if (i == Doc->DataArray.GetLength())
{
linbuf[m++] = '_';
linbuf[m++] = '_';
linbuf[m++] = ' ';
}
else
{
c = (Doc->DataArray[i] >> 4);
if( c < 10 )
c += '0';
else
c = c - 10 + 'a';
linbuf[m++] = c;
c = (Doc->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 < App->m_iBytesPerLine-1)
{
for (i=0; i<App->m_iBytesPerLine-1-(endpos-startpos); i++)
{
linbuf[m++] = ' ';
linbuf[m++] = ' ';
linbuf[m++] = ' ';
}
}
// Write offset to chars.
for (i=0; i<m_stScreenSettings.iCharSpace; i++)
linbuf[m++] = ' ';
// Write ASCIIs.
for (i=startpos; i<=endpos; i++)
{
if (i == Doc->DataArray.GetLength())
{
linbuf[m++] = ' ';
}
else if (App->m_iCharacterSet == OEM_FIXED_FONT && Doc->DataArray[i]!=0)
{
linbuf[m++] = Doc->DataArray[i];
}
else if ((Doc->DataArray[i]>=32 && Doc->DataArray[i]<=126) || (Doc->DataArray[i]>=160 && Doc->DataArray[i]<=255) || (Doc->DataArray[i]>=145 && Doc->DataArray[i]<=146))
{
linbuf[m++] = Doc->DataArray[i];
}
else
{
linbuf[m++] = '.';
}
}
// Write spaces for nonexisting chars.
if (endpos-startpos < App->m_iBytesPerLine-1)
for (i=0; i<App->m_iBytesPerLine-1-(endpos-startpos); i++)
linbuf[m++] = ' ';
// TRACE("Offset %d to %d\n", startpos, endpos);
// TRACE("Line Buffer: %s\n", linbuf);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int line_len = m; // Length of the line in chars.
// Set normal text colors.
iBkColor = PALETTERGB (GetRValue(App->m_clrBk),GetGValue(App->m_clrBk),GetBValue(App->m_clrBk));
iTextColor = PALETTERGB (GetRValue(App->m_clrText),GetGValue(App->m_clrText),GetBValue(App->m_clrText));
SetTextColor (hdc, iTextColor);
SetBkColor (hdc, iBkColor);
// How much of offset and byte-space is visible? Print it in normal text colors.
if( m_stScreenSettings.iHscrollPos < App->m_iOffsetLen + m_stScreenSettings.iByteSpace )
{
// A part of offset+byte-space is visible.
// Write offset to screen.
TextOutA( hdc, CLIENT_BORDER_WIDTH, CLIENT_BORDER_WIDTH + ( line - m_stScreenSettings.iCurLine ) * m_stScreenSettings.cyChar + m_stScreenSettings.iToolbarHeight, linbuf + m_stScreenSettings.iHscrollPos, App->m_iOffsetLen + m_stScreenSettings.iByteSpace - m_stScreenSettings.iHscrollPos );
}
int iHexStart = App->m_iOffsetLen + m_stScreenSettings.iByteSpace;
int iHexXStart = iHexStart * m_stScreenSettings.cxChar;
// Write char-space, if it is visible.
if( m_stScreenSettings.iHscrollPos < App->m_iOffsetLen + m_stScreenSettings.iByteSpace + App->m_iBytesPerLine * iHexWidth )
{
// Char-space is visible.
TextOutA( hdc,
CLIENT_BORDER_WIDTH + ( iHexStart + App->m_iBytesPerLine * iHexWidth - m_stScreenSettings.iHscrollPos ) * m_stScreenSettings.cxChar,
CLIENT_BORDER_WIDTH + ( line - m_stScreenSettings.iCurLine ) * m_stScreenSettings.cyChar + m_stScreenSettings.iToolbarHeight,
linbuf + iHexStart + App->m_iBytesPerLine * iHexWidth,
m_stScreenSettings.iCharSpace );
}
iSelBkColor = PALETTERGB (GetRValue(App->m_clrSelBk),GetGValue(App->m_clrSelBk),GetBValue(App->m_clrSelBk));
iSelTextColor = PALETTERGB (GetRValue(App->m_clrSelText),GetGValue(App->m_clrSelText),GetBValue(App->m_clrSelText));
BOOL last_normtext = TRUE;
int p, el = startpos + App->m_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 = App->m_iOffsetLen + m_stScreenSettings.iByteSpace + ( p - startpos + 1 ) * iHexWidth;
e = s - iHexWidth;
// Print only if at least a part of the hex is visible.
if( m_stScreenSettings.iHscrollPos < s && m_stScreenSettings.iHscrollPos + m_stScreenSettings.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.
TextOutA( hdc,
CLIENT_BORDER_WIDTH + ( iHexStart + ( p - startpos ) * iHexWidth - m_stScreenSettings.iHscrollPos ) * m_stScreenSettings.cxChar,
CLIENT_BORDER_WIDTH + ( line - m_stScreenSettings.iCurLine ) * m_stScreenSettings.cyChar + m_stScreenSettings.iToolbarHeight,
linbuf + iHexStart + ( p - startpos ) * iHexWidth,
iHexWidth );
}
s = App->m_iOffsetLen + m_stScreenSettings.iByteSpace + App->m_iBytesPerLine * iHexWidth + m_stScreenSettings.iCharSpace + ( p - startpos + 1);
// Write char, if it is visible.
if( m_stScreenSettings.iHscrollPos < s && m_stScreenSettings.iHscrollPos + m_stScreenSettings.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.
TextOutA( hdc,
CLIENT_BORDER_WIDTH + ( iHexStart + App->m_iBytesPerLine * iHexWidth + m_stScreenSettings.iCharSpace + ( p - startpos ) - m_stScreenSettings.iHscrollPos ) * m_stScreenSettings.cxChar,
CLIENT_BORDER_WIDTH + ( line - m_stScreenSettings.iCurLine ) * m_stScreenSettings.cyChar + m_stScreenSettings.iToolbarHeight,
linbuf + iHexStart + App->m_iBytesPerLine * iHexWidth + m_stScreenSettings.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 = App->m_iOffsetLen + m_stScreenSettings.iByteSpace + ( p - startpos + 1 ) * iHexWidth;
e = s - iHexWidth;
// Print only if at least a part of the hex is visible.
if( m_stScreenSettings.iHscrollPos < s && m_stScreenSettings.iHscrollPos + m_stScreenSettings.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.
TextOutA( hdc,
CLIENT_BORDER_WIDTH + ( iHexStart + ( p - startpos ) * iHexWidth - m_stScreenSettings.iHscrollPos ) * m_stScreenSettings.cxChar + 2 * m_stScreenSettings.cxChar,
CLIENT_BORDER_WIDTH + ( line - m_stScreenSettings.iCurLine ) * m_stScreenSettings.cyChar + m_stScreenSettings.iToolbarHeight,
" ",
1 );
// Set selection colors.
SetTextColor (hdc, iSelTextColor);
SetBkColor (hdc, iSelBkColor);
last_normtext = FALSE;
last_normtext = TRUE;
// Write hex.
TextOutA( hdc,
CLIENT_BORDER_WIDTH + ( iHexStart + ( p - startpos ) * iHexWidth - m_stScreenSettings.iHscrollPos ) * m_stScreenSettings.cxChar,
CLIENT_BORDER_WIDTH + ( line - m_stScreenSettings.iCurLine ) * m_stScreenSettings.cyChar + m_stScreenSettings.iToolbarHeight,
linbuf + iHexStart + ( p - startpos ) * iHexWidth,
iHexWidth - 1 );
}
else
{
// Write hex.
TextOutA( hdc,
CLIENT_BORDER_WIDTH + ( iHexStart + ( p - startpos ) * iHexWidth - m_stScreenSettings.iHscrollPos ) * m_stScreenSettings.cxChar,
CLIENT_BORDER_WIDTH + ( line - m_stScreenSettings.iCurLine ) * m_stScreenSettings.cyChar + m_stScreenSettings.iToolbarHeight,
linbuf + iHexStart + ( p - startpos ) * iHexWidth,
iHexWidth - 1 );
// Set normal text colors.
SetTextColor (hdc, iTextColor);
SetBkColor (hdc, iBkColor);
last_normtext = TRUE;
// Output the last space.
TextOutA( hdc,
CLIENT_BORDER_WIDTH + ( iHexStart + ( p - startpos ) * iHexWidth - m_stScreenSettings.iHscrollPos ) * m_stScreenSettings.cxChar + 2 * m_stScreenSettings.cxChar,
CLIENT_BORDER_WIDTH + ( line - m_stScreenSettings.iCurLine ) * m_stScreenSettings.cyChar + m_stScreenSettings.iToolbarHeight,
" ",
1 );
}
}
else
{
// Non-selected hex.
if( !last_normtext )
{
// Set normal text colors.
SetTextColor (hdc, iTextColor);
SetBkColor (hdc, iBkColor);
last_normtext = TRUE;
}
// Hex is visible.
TextOutA( hdc,
CLIENT_BORDER_WIDTH + ( iHexStart + ( p - startpos ) * iHexWidth - m_stScreenSettings.iHscrollPos ) * m_stScreenSettings.cxChar,
CLIENT_BORDER_WIDTH + ( line - m_stScreenSettings.iCurLine ) * m_stScreenSettings.cyChar + m_stScreenSettings.iToolbarHeight,
linbuf + iHexStart + ( p - startpos ) * iHexWidth,
iHexWidth );
}
}
s = App->m_iOffsetLen + m_stScreenSettings.iByteSpace + App->m_iBytesPerLine * iHexWidth + m_stScreenSettings.iCharSpace + ( p - startpos + 1);
// Write char, if it is visible.
if( m_stScreenSettings.iHscrollPos < s && m_stScreenSettings.iHscrollPos + m_stScreenSettings.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.
TextOutA( hdc,
CLIENT_BORDER_WIDTH + ( iHexStart + App->m_iBytesPerLine * iHexWidth + m_stScreenSettings.iCharSpace + ( p - startpos ) - m_stScreenSettings.iHscrollPos ) * m_stScreenSettings.cxChar,
CLIENT_BORDER_WIDTH + ( line - m_stScreenSettings.iCurLine ) * m_stScreenSettings.cyChar + m_stScreenSettings.iToolbarHeight,
linbuf + iHexStart + App->m_iBytesPerLine * iHexWidth + m_stScreenSettings.iCharSpace + ( p - startpos ),
1 );
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Separators.
for (i = 0; i < (App->m_iBytesPerLine / 4) + 1; i++)
{
m = (App->m_iOffsetLen+m_stScreenSettings.iByteSpace)*m_stScreenSettings.cxChar - m_stScreenSettings.cxChar/2 + 3*m_stScreenSettings.cxChar*4*i - m_stScreenSettings.cxChar*m_stScreenSettings.iHscrollPos;
MoveToEx (hdc, CLIENT_BORDER_WIDTH+m, CLIENT_BORDER_WIDTH+(line-m_stScreenSettings.iCurLine)*m_stScreenSettings.cyChar + m_stScreenSettings.iToolbarHeight, NULL);
LineTo (hdc, CLIENT_BORDER_WIDTH+m, CLIENT_BORDER_WIDTH+(line-m_stScreenSettings.iCurLine+1)*m_stScreenSettings.cyChar + m_stScreenSettings.iToolbarHeight);
}
// Separator for chars.
m = CHARSTART*m_stScreenSettings.cxChar - m_stScreenSettings.cxChar*m_stScreenSettings.iHscrollPos - 2;
MoveToEx (hdc, CLIENT_BORDER_WIDTH+m, CLIENT_BORDER_WIDTH+(line-m_stScreenSettings.iCurLine)*m_stScreenSettings.cyChar + m_stScreenSettings.iToolbarHeight, NULL);
LineTo (hdc, CLIENT_BORDER_WIDTH+m, CLIENT_BORDER_WIDTH+(line-m_stScreenSettings.iCurLine+1)*m_stScreenSettings.cyChar + m_stScreenSettings.iToolbarHeight);
// Second separator.
MoveToEx (hdc, CLIENT_BORDER_WIDTH+m+2, CLIENT_BORDER_WIDTH+(line-m_stScreenSettings.iCurLine)*m_stScreenSettings.cyChar + m_stScreenSettings.iToolbarHeight, NULL);
LineTo (hdc, CLIENT_BORDER_WIDTH+m+2, CLIENT_BORDER_WIDTH+(line-m_stScreenSettings.iCurLine+1)*m_stScreenSettings.cyChar + m_stScreenSettings.iToolbarHeight);
// Print bookmark indicators.
// Are there bookmarks in this line?
el = startpos + App->m_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 <= Doc->DataArray.GetUpperBound() )
{
// Found a bookmark in this line.
// Mark hex.
chpos = App->m_iOffsetLen + m_stScreenSettings.iByteSpace + ( pbmkList[i].offset % App->m_iBytesPerLine )*3 - m_stScreenSettings.iHscrollPos;
r.left = CLIENT_BORDER_WIDTH + chpos * m_stScreenSettings.cxChar;
r.top = CLIENT_BORDER_WIDTH + ( pbmkList[i].offset / App->m_iBytesPerLine - m_stScreenSettings.iCurLine ) * m_stScreenSettings.cyChar + m_stScreenSettings.iToolbarHeight;
r.right = CLIENT_BORDER_WIDTH + r.left + 2*m_stScreenSettings.cxChar;
r.bottom = CLIENT_BORDER_WIDTH + ( pbmkList[i].offset / App->m_iBytesPerLine - m_stScreenSettings.iCurLine + 1 ) * m_stScreenSettings.cyChar + m_stScreenSettings.iToolbarHeight;
FrameRect( hdc, &r, hbr );
// Mark char.
chpos = App->m_iOffsetLen + m_stScreenSettings.iByteSpace + App->m_iBytesPerLine*3 + m_stScreenSettings.iCharSpace
+ ( pbmkList[i].offset % App->m_iBytesPerLine ) - m_stScreenSettings.iHscrollPos;
r.left = CLIENT_BORDER_WIDTH + chpos * m_stScreenSettings.cxChar;
r.top = CLIENT_BORDER_WIDTH + ( pbmkList[i].offset / App->m_iBytesPerLine - m_stScreenSettings.iCurLine) * m_stScreenSettings.cyChar + m_stScreenSettings.iToolbarHeight;
r.right = CLIENT_BORDER_WIDTH + ( chpos + 1 ) * m_stScreenSettings.cxChar;
r.bottom = CLIENT_BORDER_WIDTH + ( pbmkList[i].offset / App->m_iBytesPerLine - m_stScreenSettings.iCurLine + 1 ) * m_stScreenSettings.cyChar + m_stScreenSettings.iToolbarHeight;
FrameRect( hdc, &r, hbr );
}
}
return;
}
//--------------------------------------------------------------------------------------------
// Highlight (invert) the character/byte at the current offset.
void CFshedView::mark_char (HDC hdc)
{
if( bDontMarkCurrentPos )
return;
if (bSelected)
{
::SetCaretPos (-m_stScreenSettings.cxChar, -m_stScreenSettings.cyChar);
return;
}
int DC_was_allocated = FALSE;
if (hdc == 0)
{
hdc = ::GetDC (m_hWnd);
DC_was_allocated = TRUE;
}
int chpos;
RECT r;
switch (m_iEnteringMode)
{
case CHARS:
chpos = App->m_iOffsetLen + m_stScreenSettings.iByteSpace + (m_stScreenSettings.iCurByte%App->m_iBytesPerLine)*3 - m_stScreenSettings.iHscrollPos;
r.left = CLIENT_BORDER_WIDTH + chpos * m_stScreenSettings.cxChar;
r.top = CLIENT_BORDER_WIDTH + (m_stScreenSettings.iCurByte/App->m_iBytesPerLine-m_stScreenSettings.iCurLine)*m_stScreenSettings.cyChar + m_stScreenSettings.iToolbarHeight;
r.right = CLIENT_BORDER_WIDTH + r.left + 2*m_stScreenSettings.cxChar;
r.bottom = CLIENT_BORDER_WIDTH + (m_stScreenSettings.iCurByte/App->m_iBytesPerLine-m_stScreenSettings.iCurLine+1)*m_stScreenSettings.cyChar + m_stScreenSettings.iToolbarHeight;
InvertRect (hdc, &r);
break;
case BYTES:
chpos = App->m_iOffsetLen + m_stScreenSettings.iByteSpace + App->m_iBytesPerLine*3 + m_stScreenSettings.iCharSpace
+ (m_stScreenSettings.iCurByte % App->m_iBytesPerLine) - m_stScreenSettings.iHscrollPos;
r.left = CLIENT_BORDER_WIDTH + chpos * m_stScreenSettings.cxChar;
r.top = CLIENT_BORDER_WIDTH + (m_stScreenSettings.iCurByte/App->m_iBytesPerLine-m_stScreenSettings.iCurLine)*m_stScreenSettings.cyChar + m_stScreenSettings.iToolbarHeight;
r.right = CLIENT_BORDER_WIDTH + (chpos+1)*m_stScreenSettings.cxChar;
r.bottom = CLIENT_BORDER_WIDTH + (m_stScreenSettings.iCurByte/App->m_iBytesPerLine-m_stScreenSettings.iCurLine+1)*m_stScreenSettings.cyChar + m_stScreenSettings.iToolbarHeight;
InvertRect (hdc, &r);
}
if (DC_was_allocated)
::ReleaseDC (m_hWnd, hdc);
}
//-------------------------------------------------------------------
void CFshedView::draw_client_border (HDC hdc)
{
// Border for client-area.
int DC_was_allocated = FALSE;
if (hdc == 0)
{
hdc = ::GetDC (m_hWnd);
DC_was_allocated = TRUE;
}
RECT r;
r.left = 0;
r.top = m_stScreenSettings.iToolbarHeight;
r.right = m_stScreenSettings.cxClient;
r.bottom = m_stScreenSettings.cyClient + m_stScreenSettings.iToolbarHeight;
DrawEdge (hdc, &r, EDGE_SUNKEN, BF_RECT);
if (DC_was_allocated)
{
::ReleaseDC (m_hWnd, hdc);
}
}
//--------------------------------------------------------------------------------------------
// Handler for character keys.
int CFshedView::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( Doc->bReadOnly && ch != '\t' )
{
::MessageBox( m_hWnd, _T("Can't change file because read-only mode is engaged!"), _T("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 >= m_stScreenSettings.iHscrollPos+m_stScreenSettings.cxBuffer) // Cursor too far right...
m_stScreenSettings.iHscrollPos = log_column-(m_stScreenSettings.cxBuffer-1); // Cursor to right border.
else if (log_column < m_stScreenSettings.iHscrollPos) // Cursor too far left.
m_stScreenSettings.iHscrollPos = log_column; // Cursor to left border.
adjust_hscrollbar ();
repaint ();
return 0;
}
// If read-only mode, return.
if( Doc->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 (m_stScreenSettings.iCurByte == Doc->DataArray.GetLength())
{
if (Doc->DataArray.InsertAtGrow(m_stScreenSettings.iCurByte, 0, 1) == TRUE)
{
m_stScreenSettings.iCurNibble = 0;
iInsertMode = FALSE;
character (ch);
update_for_new_datasize ();
return 1;
}
else
{
::MessageBox (NULL, _T("Not enough memory for inserting character."), _T("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;
Doc->DataArray[m_stScreenSettings.iCurByte] = (Doc->DataArray[m_stScreenSettings.iCurByte] & 0xf0) | x;
Doc->SetModifiedFlag();
Doc->bFilestatusChanged = TRUE;
m_stScreenSettings.iCurByte++;
m_stScreenSettings.iCurNibble = 0;
update_for_new_datasize();
}
else
{
// Insert a new byte with the high nibble set to value just typed.
if( Doc->DataArray.InsertAtGrow( m_stScreenSettings.iCurByte, 0, 1 ) == TRUE )
{
bInsertingHex = TRUE;
if (c >= 'a' && c <= 'f')
x = c - 0x61 + 0x0a;
else
x = c - 0x30;
Doc->DataArray[m_stScreenSettings.iCurByte] = (Doc->DataArray[m_stScreenSettings.iCurByte] & 0x0f) | (x << 4);
Doc->SetModifiedFlag();
Doc->bFilestatusChanged = TRUE;
m_stScreenSettings.iCurNibble = 1;
update_for_new_datasize();
}
else
{
::MessageBox (NULL, _T("Not enough memory for inserting."), _T("Insert mode error"), MB_OK | MB_ICONERROR);
return 0;
}
}
}
return 1;
}
else if (m_iEnteringMode == CHARS)
{
if (Doc->DataArray.InsertAtGrow(m_stScreenSettings.iCurByte, 0, 1) == TRUE)
{
m_stScreenSettings.iCurNibble = 0;
iInsertMode = FALSE;
character (ch);
iInsertMode = TRUE;
m_stScreenSettings.iCurNibble = 0;
update_for_new_datasize ();
}
else
{
::MessageBox (NULL, _T("Not enough memory for inserting."), _T("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 (m_stScreenSettings.iCurNibble == 0)
Doc->DataArray[m_stScreenSettings.iCurByte] = (Doc->DataArray[m_stScreenSettings.iCurByte] & 0x0f) | (x << 4);
else
Doc->DataArray[m_stScreenSettings.iCurByte] = (Doc->DataArray[m_stScreenSettings.iCurByte] & 0xf0) | x;
Doc->SetModifiedFlag();
Doc->bFilestatusChanged = TRUE;
keydown (VK_RIGHT);
}
// Char-mode.
else if (m_iEnteringMode == CHARS)
{
switch (App->m_iCharacterSet)
{
case ANSI_FIXED_FONT:
Doc->DataArray[m_stScreenSettings.iCurByte] = ch;
break;
case OEM_FIXED_FONT:
{
TCHAR src[2];
char dst[2];
src[0] = ch;
src[1] = 0;
CharToOem (src, dst);
Doc->DataArray[m_stScreenSettings.iCurByte] = dst[0];
}
break;
}
Doc->SetModifiedFlag();
Doc->bFilestatusChanged = TRUE;
keydown (VK_RIGHT);
}
}
return 0;
}
//--------------------------------------------------------------------------------------------
// Handler for non-character keys (arrow keys, page up/down etc.)
int CFshedView::keydown (int key)
{
if (Doc->filename[0] == '\0' || m_stScreenSettings.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:
m_stScreenSettings.iCurByte = iEndOfSelection;
bSelected = FALSE;
adjust_vscrollbar ();
repaint ();
default:
break;
}
switch (key)
{
case VK_HOME:
{
m_stScreenSettings.iCurByte = BYTELINE * App->m_iBytesPerLine;
m_stScreenSettings.iCurNibble = 0;
if (m_iEnteringMode == BYTES)
log_column = BYTES_LOGICAL_COLUMN;
else
log_column = CHARS_LOGICAL_COLUMN;
if (log_column < m_stScreenSettings.iHscrollPos) // Cursor too far to the left?
{
m_stScreenSettings.iHscrollPos = log_column;
adjust_hscrollbar ();
repaint ();
}
else
{
repaint (BYTELINE);
}
if (CURSOR_TOO_HIGH || CURSOR_TOO_LOW)
{
m_stScreenSettings.iCurLine = max (0, m_stScreenSettings.iCurByte/App->m_iBytesPerLine-m_stScreenSettings.cyBuffer/2);
adjust_vscrollbar ();
repaint ();
}
break;
}
case VK_END:
{
// Set position:
m_stScreenSettings.iCurByte = (BYTELINE + 1) * App->m_iBytesPerLine - 1;
if (m_stScreenSettings.iCurByte > LASTBYTE+1)
m_stScreenSettings.iCurByte = LASTBYTE+1;
m_stScreenSettings.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)
{
m_stScreenSettings.iHscrollPos = log_column - m_stScreenSettings.cxBuffer + 1;
adjust_hscrollbar ();
repaint ();
}
else
{
repaint (BYTELINE);
}
if (CURSOR_TOO_HIGH || CURSOR_TOO_LOW)
{
m_stScreenSettings.iCurLine = max (0, m_stScreenSettings.iCurByte/App->m_iBytesPerLine-m_stScreenSettings.cyBuffer/2);
adjust_vscrollbar ();
repaint ();
}
break;
}
case VK_UP:
// If possible, cursor one line up.
if (m_stScreenSettings.iCurByte >= App->m_iBytesPerLine)
m_stScreenSettings.iCurByte -= App->m_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 < m_stScreenSettings.iHscrollPos || log_column > LAST_LOG_COLUMN)
{
m_stScreenSettings.iHscrollPos = log_column;
adjust_hscrollbar ();
repaint ();
break;
}
else if (!scrollflag)
{
repaint (BYTELINE+1);
repaint (BYTELINE);
}
else // scrollflag
{
if (m_stScreenSettings.iCurLine-BYTELINE==1) // One line up.
{
m_stScreenSettings.iCurLine = BYTELINE;
RECT r;
r.left = CLIENT_BORDER_WIDTH;
r.top = CLIENT_BORDER_WIDTH + m_stScreenSettings.iToolbarHeight;
r.right = m_stScreenSettings.cxClient - CLIENT_BORDER_WIDTH;
r.bottom = m_stScreenSettings.cyClient - CLIENT_BORDER_WIDTH;
// ScrollWindow (0, m_stScreenSettings.cyChar, &r, &r);
// repaint (BYTELINE+1);
// repaint (BYTELINE);
repaint ();
}
else
{
m_stScreenSettings.iCurLine = BYTELINE;
repaint ();
}
ASSERT(m_stScreenSettings.iCurLine >= 0);
}
break;
case VK_DOWN:
// If possible cursor one line down.
if (m_stScreenSettings.iCurByte+App->m_iBytesPerLine <= Doc->DataArray.GetLength())
m_stScreenSettings.iCurByte += App->m_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 < m_stScreenSettings.iHscrollPos || log_column > LAST_LOG_COLUMN)
{
m_stScreenSettings.iHscrollPos = log_column;
adjust_hscrollbar ();
repaint ();
break;
}
else if (!scrollflag)
{
repaint (BYTELINE-1);
repaint (BYTELINE);
}
else // scrollflag
{
int nLine = BYTELINE;
if (BYTELINE==m_stScreenSettings.iCurLine+m_stScreenSettings.cyBuffer) // Cursor one line down.
{
m_stScreenSettings.iCurLine = max (0, BYTELINE-(m_stScreenSettings.cyBuffer-1)); // Cursor at bottom of screen.
RECT r;
r.left = CLIENT_BORDER_WIDTH;
r.top = CLIENT_BORDER_WIDTH + m_stScreenSettings.iToolbarHeight;
r.right = m_stScreenSettings.cxClient - CLIENT_BORDER_WIDTH;
r.bottom = m_stScreenSettings.cyClient - CLIENT_BORDER_WIDTH;
// ScrollWindow (0, -m_stScreenSettings.cyChar, &r, &r);
// repaint (BYTELINE-1);
// repaint (BYTELINE);
// repaint (BYTELINE+1);
repaint ();
mark_char( 0 );
}
else
{
m_stScreenSettings.iCurLine = max (0, BYTELINE-(m_stScreenSettings.cyBuffer-1));
repaint ();
}
ASSERT(m_stScreenSettings.iCurLine >= 0);
}
break;
case VK_LEFT:
{
if (m_iEnteringMode == BYTES) // BYTE-Mode.
{
if (m_stScreenSettings.iCurNibble == 1) // 1 nibble to the left...
m_stScreenSettings.iCurNibble = 0;
else if (m_stScreenSettings.iCurByte != 0) // Or 1 byte to the left.
{
m_stScreenSettings.iCurByte--;
m_stScreenSettings.iCurNibble = 1;
}
}
else // CHAR-Mode.
{
if (m_stScreenSettings.iCurByte != 0)
m_stScreenSettings.iCurByte--; // 1 Byte to the left.
}
// If new line not visible, then scroll.
scrollflag = FALSE;
if (CURSOR_TOO_HIGH || CURSOR_TOO_LOW)
{
m_stScreenSettings.iCurLine = BYTELINE;
ASSERT(m_stScreenSettings.iCurLine >= 0);
adjust_vscrollbar ();
scrollflag = TRUE;
}
if (m_iEnteringMode == BYTES)
log_column = BYTES_LOGICAL_COLUMN;
else
log_column = CHARS_LOGICAL_COLUMN;
if (log_column < m_stScreenSettings.iHscrollPos)
{
m_stScreenSettings.iHscrollPos = log_column;
adjust_hscrollbar ();
repaint ();
break;
}
else if (log_column > LAST_LOG_COLUMN)
{
m_stScreenSettings.iHscrollPos = log_column-(m_stScreenSettings.cxBuffer-1);
adjust_hscrollbar ();
repaint ();
break;
}
else if (!scrollflag)
{
if (m_stScreenSettings.iCurByte%App->m_iBytesPerLine==App->m_iBytesPerLine-1) // Just got to previous line.
repaint (BYTELINE+1);
repaint (BYTELINE);
}
else
repaint ();
break;
}
case VK_RIGHT:
{
if (m_iEnteringMode == BYTES)
{
if (m_stScreenSettings.iCurNibble == 0)
m_stScreenSettings.iCurNibble = 1;
else if (m_stScreenSettings.iCurByte <= LASTBYTE)
{
m_stScreenSettings.iCurNibble = 0;
m_stScreenSettings.iCurByte++;
}
}
else
{
if (m_stScreenSettings.iCurByte <= LASTBYTE)
m_stScreenSettings.iCurByte++;
}
scrollflag = FALSE;
if (CURSOR_TOO_HIGH || CURSOR_TOO_LOW)
{
m_stScreenSettings.iCurLine = max (BYTELINE-m_stScreenSettings.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 >= m_stScreenSettings.iHscrollPos+m_stScreenSettings.cxBuffer)
{
m_stScreenSettings.iHscrollPos = log_column-(m_stScreenSettings.cxBuffer-1);
adjust_hscrollbar ();
repaint ();
break;
}
else if (log_column < m_stScreenSettings.iHscrollPos)
{
m_stScreenSettings.iHscrollPos = log_column;
adjust_hscrollbar ();
repaint ();
break;
}
else if (scrollflag != TRUE) // If one line down but cursor not too far horiz.
{
if (m_stScreenSettings.iCurByte%App->m_iBytesPerLine==0)
repaint (BYTELINE-1);
repaint (BYTELINE);
}
else
repaint ();
break;
}
case VK_PRIOR:
if (BYTELINE >= m_stScreenSettings.cyBuffer)
{
m_stScreenSettings.iCurByte -= m_stScreenSettings.cyBuffer * App->m_iBytesPerLine; // 1 page up.
m_stScreenSettings.iCurLine -= m_stScreenSettings.cyBuffer;
if (m_stScreenSettings.iCurLine < 0)
m_stScreenSettings.iCurLine = BYTELINE;
}
else
{
m_stScreenSettings.iCurLine = 0; // To top.
m_stScreenSettings.iCurByte = BYTEPOS;
}
if (CURSOR_TOO_HIGH || CURSOR_TOO_LOW)
m_stScreenSettings.iCurLine = m_stScreenSettings.iCurByte/App->m_iBytesPerLine;
ASSERT(m_stScreenSettings.iCurLine >= 0);
adjust_vscrollbar ();
repaint ();
break;
case VK_NEXT:
m_stScreenSettings.iCurByte += m_stScreenSettings.cyBuffer*App->m_iBytesPerLine;
if (m_stScreenSettings.iCurByte > LASTBYTE+1)
{
m_stScreenSettings.iCurByte = (LASTBYTE+1)/App->m_iBytesPerLine*App->m_iBytesPerLine + BYTEPOS;
if (m_stScreenSettings.iCurByte > LASTBYTE+1)
m_stScreenSettings.iCurByte = LASTBYTE+1;
m_stScreenSettings.iCurLine = BYTELINE;
adjust_view_for_caret ();
}
else
{
m_stScreenSettings.iCurLine += m_stScreenSettings.cyBuffer;
if (m_stScreenSettings.iCurLine > LASTLINE)
m_stScreenSettings.iCurLine = BYTELINE;
}
ASSERT(m_stScreenSettings.iCurLine >= 0);
if (CURSOR_TOO_HIGH || CURSOR_TOO_LOW)
m_stScreenSettings.iCurLine = max (BYTELINE-m_stScreenSettings.cyBuffer+1, 0);
adjust_vscrollbar ();
repaint ();
break;
}
return 0;
}
//--------------------------------------------------------------------------------------------
// Set horizontal scroll position so that caret is visible.
void CFshedView::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 >= m_stScreenSettings.iHscrollPos+m_stScreenSettings.cxBuffer)
m_stScreenSettings.iHscrollPos = log_column-(m_stScreenSettings.cxBuffer-1);
else if (log_column < m_stScreenSettings.iHscrollPos)
m_stScreenSettings.iHscrollPos = log_column;
adjust_hscrollbar ();
}
//-------------------------------------------------------------------
int CFshedView::timer ()
{
if (!bSelected || !bTimerSet)
return 0;
if (iMouseY > m_stScreenSettings.cyBuffer*m_stScreenSettings.cyChar)
{
// Lower border reached.
if (m_stScreenSettings.iCurLine < LASTLINE)
m_stScreenSettings.iCurLine++;
adjust_vscrollbar ();
repaint ();
}
else if (iMouseY < 0)
{
// Upper border reached.
if (m_stScreenSettings.iCurLine > 0)
m_stScreenSettings.iCurLine--;
adjust_vscrollbar ();
repaint ();
}
return 1;
}
//-------------------------------------------------------------------
void CFshedView::adjust_view_for_selection ()
{
if( bSelected )
{
// EOS above current upper line?
if( iEndOfSelection / App->m_iBytesPerLine < m_stScreenSettings.iCurLine )
// => then set current line to EOS.
m_stScreenSettings.iCurLine = iEndOfSelection / App->m_iBytesPerLine;
// EOS under current last line?
else if( iEndOfSelection/App->m_iBytesPerLine > m_stScreenSettings.iCurLine+m_stScreenSettings.cyBuffer - 1 )
{
// => then EOS is in new last line.
m_stScreenSettings.iCurLine = iEndOfSelection / App->m_iBytesPerLine - m_stScreenSettings.cyBuffer + 1;
if( m_stScreenSettings.iCurLine < 0 )
m_stScreenSettings.iCurLine = 0;
}
ASSERT(m_stScreenSettings.iCurLine >= 0);
adjust_vscrollbar();
}
}
/////////////////////////////////////////////////////////////////////////////
// CFshedView message handlers
int CFshedView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// Create Statusbar.
InitCommonControls ();
hwndStatusBar = CreateStatusWindow (
CCS_BOTTOM | WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP,
_T("Ready"), m_hWnd, 2);
// hwndToolBar = CreateTBar(hInstance, m_hWnd, IDB_TOOLBAR);
// Create Scrollbars.
hwndHBar = CreateWindow (_T("scrollbar"), NULL, WS_CHILD | WS_VISIBLE | SBS_HORZ,
0,0,0,0, m_hWnd, (HMENU) 1, AfxGetInstanceHandle(), NULL);
hwndVBar = CreateWindow (_T("scrollbar"), NULL, WS_CHILD | WS_VISIBLE | SBS_VERT,
0,0,0,0, m_hWnd, (HMENU) 2, AfxGetInstanceHandle(), NULL);
m_stScreenSettings.iVscrollMax = 0;
m_stScreenSettings.iVscrollPos = 0;
m_stScreenSettings.iVscrollInc = 0;
m_stScreenSettings.iHscrollMax = 0;
m_stScreenSettings.iHscrollPos = 0;
m_stScreenSettings.iHscrollInc = 0;
m_stScreenSettings.iCurLine = 0;
m_stScreenSettings.iCurByte = 0;
m_stScreenSettings.iCurNibble = 0;
DragAcceptFiles(TRUE ); // Accept files dragged into window.
return 0;
}
void CFshedView::OnPaint()
{
// CPaintDC dc(this); // device context for painting
}
void CFshedView::OnLButtonDown(UINT nFlags, CPoint point)
{
if (NO_FILE)
return;
int yPos = point.y;
int xPos = point.x;
yPos -= m_stScreenSettings.iToolbarHeight;
int scr_column = xPos / m_stScreenSettings.cxChar,
scr_row = yPos / m_stScreenSettings.cyChar,
log_column = scr_column + m_stScreenSettings.iHscrollPos,
line = m_stScreenSettings.iCurLine + scr_row;
iLBDownX = xPos;
iLBDownY = yPos;
// Is the Shift-key held? If yes, then set the position clicked on
// as end of selection.
if( nFlags & MK_SHIFT )
{
// Set start of selection.
// Click on bytes.
if (log_column >= App->m_iOffsetLen + m_stScreenSettings.iByteSpace && log_column <= m_stScreenSettings.iCharsPerLine - 1 - App->m_iBytesPerLine - m_stScreenSettings.iCharSpace - 1)
{
// Not clicked on empty place:
if ((log_column-App->m_iOffsetLen-(m_stScreenSettings.iByteSpace-1))%3 != 0)
{
int bytenum = (log_column-App->m_iOffsetLen-(m_stScreenSettings.iByteSpace-1))/3,
nibblenum = ((log_column-App->m_iOffsetLen-(m_stScreenSettings.iByteSpace-1))%3)-1;
int newpos = line * App->m_iBytesPerLine + bytenum;
if( newpos <= LASTBYTE )
{
// If no selection yet, select from current caret position.
if( !bSelected )
{
bSelected = TRUE;
iStartOfSelection = m_stScreenSettings.iCurByte;
}
iEndOfSelection = newpos;
}
}
}
// Click on chars.
else if (log_column > m_stScreenSettings.iCharsPerLine - 1 - App->m_iBytesPerLine && log_column < m_stScreenSettings.iCharsPerLine)
{
int newpos = line * App->m_iBytesPerLine + (log_column - (m_stScreenSettings.iCharsPerLine - App->m_iBytesPerLine));
if( newpos <= LASTBYTE )
{
// If no selection yet, select from current caret position.
if( !bSelected )
{
bSelected = TRUE;
iStartOfSelection = m_stScreenSettings.iCurByte;
}
iEndOfSelection = newpos;
}
}
return;
}
// Set start of selection.
// Click on bytes.
if (log_column >= App->m_iOffsetLen + m_stScreenSettings.iByteSpace && log_column <= m_stScreenSettings.iCharsPerLine - 1 - App->m_iBytesPerLine - m_stScreenSettings.iCharSpace - 1)
{
// Not clicked on empty place:
if ((log_column-App->m_iOffsetLen-(m_stScreenSettings.iByteSpace-1))%3 != 0)
{
bLButtonIsDown = TRUE;
bSelected = FALSE;
int bytenum = (log_column-App->m_iOffsetLen-(m_stScreenSettings.iByteSpace-1))/3,
nibblenum = ((log_column-App->m_iOffsetLen-(m_stScreenSettings.iByteSpace-1))%3)-1;
int newpos = line * App->m_iBytesPerLine + bytenum;
if( newpos <= LASTBYTE )
{
iStartOfSelection = newpos;
iEndOfSelection = newpos;
}
else if( newpos == LASTBYTE + 1 )
{
bLButtonIsDown = FALSE; // Don't select, this can only set caret to END.
}
}
}
// Click on chars.
else if (log_column > m_stScreenSettings.iCharsPerLine - 1 - App->m_iBytesPerLine && log_column < m_stScreenSettings.iCharsPerLine)
{
bLButtonIsDown = TRUE;
bSelected = FALSE;
int newpos = line * App->m_iBytesPerLine + (log_column - (m_stScreenSettings.iCharsPerLine - App->m_iBytesPerLine));
if( newpos <= LASTBYTE )
{
iStartOfSelection = newpos;
iEndOfSelection = newpos;
}
else if( newpos == LASTBYTE + 1 )
{
bLButtonIsDown = FALSE; // Don't select, this can only set caret to END.
}
}
CView::OnLButtonDown(nFlags, point);
}
void CFshedView::OnMouseMove(UINT nFlags, CPoint point)
{
int yPos = point.y;
int xPos = point.x;
yPos -= m_stScreenSettings.iToolbarHeight;
iMouseX = xPos;
iMouseY = yPos;
// If not selecting at the moment.
if (bLButtonIsDown == FALSE)
return;
bSelected = TRUE;
// Capture mouse.
if (GetCapture() == NULL)
{
SetCapture ();
SetCursor( LoadCursor( NULL, IDC_IBEAM ) );
}
int scr_column = xPos / m_stScreenSettings.cxChar,
scr_row = yPos / m_stScreenSettings.cyChar,
log_column = scr_column + m_stScreenSettings.iHscrollPos,
line = m_stScreenSettings.iCurLine + scr_row;
// Set end of selection according to cursor pos.
// Scroll if cursor above or under window.
if (yPos>m_stScreenSettings.cyBuffer*m_stScreenSettings.cyChar || yPos<0)
{
if (bTimerSet==FALSE)
{
// Set timer for scrolling.
SetTimer (TIMERID, TIMERDURATION, NULL);
bTimerSet = TRUE;
}
}
// If cursor on bytes.
else if (log_column >= App->m_iOffsetLen + m_stScreenSettings.iByteSpace && log_column <= m_stScreenSettings.iCharsPerLine - 1 - App->m_iBytesPerLine - m_stScreenSettings.iCharSpace - 1)
{
KillTimer (TIMERID);
bTimerSet = FALSE;
// If not clicked on empty place.
if ((log_column-App->m_iOffsetLen-(m_stScreenSettings.iByteSpace-1))%3 != 0)
{
int bytenum = (log_column-App->m_iOffsetLen-(m_stScreenSettings.iByteSpace-1))/3,
nibblenum = ((log_column-App->m_iOffsetLen-(m_stScreenSettings.iByteSpace-1))%3)-1;
int newpos = line * App->m_iBytesPerLine + bytenum;
if (newpos <= LASTBYTE)
{
iEndOfSelection = newpos;
repaint ();
}
}
}
// If cursor on chars.
else if (log_column > m_stScreenSettings.iCharsPerLine - 1 - App->m_iBytesPerLine && log_column < m_stScreenSettings.iCharsPerLine)
{
KillTimer (TIMERID);
bTimerSet = FALSE;
int newpos = line * App->m_iBytesPerLine + (log_column - (m_stScreenSettings.iCharsPerLine - App->m_iBytesPerLine));
if (newpos <= LASTBYTE)
{
iEndOfSelection = newpos;
repaint ();
}
}
CView::OnMouseMove(nFlags, point);
}
void CFshedView::OnLButtonUp(UINT nFlags, CPoint point)
{
int yPos = point.y;
int xPos = point.x;
// Kill timer.
KillTimer (TIMERID);
bTimerSet = FALSE;
// Reset cursor from I-beam to arrow.
SetCursor( LoadCursor( NULL, IDC_ARROW ) );
// Release mouse.
ReleaseCapture ();
bLButtonIsDown = FALSE;
yPos -= m_stScreenSettings.iToolbarHeight;
// If button released where it was pressed (set caret).
if (iLBDownX == xPos && iLBDownY == yPos)
{
int scr_column = xPos / m_stScreenSettings.cxChar, // Column on the screen.
scr_row = yPos / m_stScreenSettings.cyChar, // Line on the screen.
log_column = scr_column + m_stScreenSettings.iHscrollPos, // Logical column.
line = m_stScreenSettings.iCurLine + scr_row; // Absolute line number.
// If click on bytes: set caret there.
if (log_column >= App->m_iOffsetLen + m_stScreenSettings.iByteSpace && log_column <= m_stScreenSettings.iCharsPerLine - 1 - App->m_iBytesPerLine - m_stScreenSettings.iCharSpace - 1)
{
// If not clicked on empty place:
if ((log_column-App->m_iOffsetLen-(m_stScreenSettings.iByteSpace-1))%3 != 0)
{
int bytenum = (log_column-App->m_iOffsetLen-(m_stScreenSettings.iByteSpace-1))/3,
nibblenum = ((log_column-App->m_iOffsetLen-(m_stScreenSettings.iByteSpace-1))%3)-1;
int newpos = line * App->m_iBytesPerLine + bytenum;
if( newpos <= LASTBYTE + 1 )
{
m_stScreenSettings.iCurByte = newpos;
m_stScreenSettings.iCurNibble = nibblenum;
m_iEnteringMode = BYTES;
repaint ();
}
}
}
// If click on chars: set caret there.
else if (log_column > m_stScreenSettings.iCharsPerLine - 1 - App->m_iBytesPerLine && log_column < m_stScreenSettings.iCharsPerLine)
{
int newpos = line * App->m_iBytesPerLine + (log_column - (m_stScreenSettings.iCharsPerLine - App->m_iBytesPerLine));
if( newpos <= LASTBYTE + 1 )
{
m_stScreenSettings.iCurByte = newpos;
m_iEnteringMode = CHARS;
repaint ();
}
}
}
CView::OnLButtonUp(nFlags, point);
}
void CFshedView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
resize_window(cx, cy);
}
void CFshedView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
keydown( nChar );
CView::OnKeyDown(nChar, nRepCnt, nFlags);
}
void CFshedView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
character( nChar );
CView::OnChar(nChar, nRepCnt, nFlags);
}
void CFshedView::OnTimer(UINT_PTR nIDEvent)
{
timer();
CView::OnTimer(nIDEvent);
}
void CFshedView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
if (NO_FILE || Doc->DataArray.GetLength()==0)
return;
m_stScreenSettings.iVscrollInc = 0;
SCROLLINFO si;
memset(&si, 0, sizeof(si));
si.cbSize = sizeof(si);
switch (nSBCode)
{
case SB_TOP:
m_stScreenSettings.iCurLine = 0;
break;
case SB_BOTTOM:
m_stScreenSettings.iCurLine = m_stScreenSettings.iNumlines-1;
break;
case SB_LINEUP:
if (m_stScreenSettings.iCurLine > 0)
m_stScreenSettings.iCurLine -= 1;
break;
case SB_LINEDOWN:
if (m_stScreenSettings.iCurLine < m_stScreenSettings.iNumlines-1)
m_stScreenSettings.iCurLine += 1;
break;
case SB_PAGEUP:
if (m_stScreenSettings.iCurLine >= m_stScreenSettings.cyBuffer)
m_stScreenSettings.iCurLine -= m_stScreenSettings.cyBuffer;
else
m_stScreenSettings.iCurLine = 0;
break;
case SB_PAGEDOWN:
if (m_stScreenSettings.iCurLine <= m_stScreenSettings.iNumlines-1-m_stScreenSettings.cyBuffer)
m_stScreenSettings.iCurLine += m_stScreenSettings.cyBuffer;
else
m_stScreenSettings.iCurLine = m_stScreenSettings.iNumlines-1;
break;
case SB_THUMBTRACK:
// case SB_THUMBPOSITION:
// case SB_ENDSCROLL:
si.fMask = SIF_TRACKPOS;
::GetScrollInfo(hwndVBar, SB_CTL, &si);
si.fMask = SIF_POS;
TRACE("Track by %u, track pos %u\n", nPos, si.nTrackPos);
nPos = si.nTrackPos;
m_stScreenSettings.iCurLine = (int) (nPos * ((float)(m_stScreenSettings.iNumlines-1)/(float)m_stScreenSettings.iVscrollMax));
si.nPos = si.nTrackPos;
::SetScrollInfo(hwndVBar, SB_CTL, &si, TRUE);
// ::SetScrollPos (hwndVBar, SB_CTL, nPos, TRUE);
if (m_stScreenSettings.iCurLine > m_stScreenSettings.iNumlines-1)
m_stScreenSettings.iCurLine = m_stScreenSettings.iNumlines-1;
// Make sure the number of empty lines is as small as possible.
if( m_stScreenSettings.iNumlines - m_stScreenSettings.iCurLine < m_stScreenSettings.cyBuffer )
{
m_stScreenSettings.iCurLine = ( ( Doc->DataArray.GetUpperBound() + 1 ) / App->m_iBytesPerLine ) - ( m_stScreenSettings.cyBuffer - 1 );
if( m_stScreenSettings.iCurLine < 0 )
m_stScreenSettings.iCurLine = 0;
}
else
ASSERT(m_stScreenSettings.iCurLine >= 0);
repaint();
return;
default:
break;
}
m_stScreenSettings.iVscrollPos = (int) ((float)m_stScreenSettings.iCurLine * ((float)m_stScreenSettings.iVscrollMax)/(float)(m_stScreenSettings.iNumlines-1));
si.fMask = SIF_POS;
si.nPos = m_stScreenSettings.iVscrollPos;
TRACE("Vert scroll to offset %d\n", si.nPos);
::SetScrollInfo(hwndVBar, SB_CTL, &si, TRUE);
// ::SetScrollPos (hwndVBar, SB_CTL, m_stScreenSettings.iVscrollPos, TRUE);
if (m_stScreenSettings.iCurLine > m_stScreenSettings.iNumlines-1)
m_stScreenSettings.iCurLine = m_stScreenSettings.iNumlines-1;
repaint ();
// CView::OnVScroll(nSBCode, nPos, pScrollBar);
}
void CFshedView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
if (NO_FILE || Doc->DataArray.GetLength()==0)
return;
m_stScreenSettings.iHscrollInc = 0;
switch (nSBCode)
{
case SB_TOP:
m_stScreenSettings.iHscrollInc = -m_stScreenSettings.iHscrollPos;
break;
case SB_BOTTOM:
m_stScreenSettings.iHscrollInc = m_stScreenSettings.iHscrollMax - m_stScreenSettings.iHscrollPos;
break;
case SB_LINEUP:
if (m_stScreenSettings.iHscrollPos > 0)
m_stScreenSettings.iHscrollInc = -1;
break;
case SB_LINEDOWN:
if (m_stScreenSettings.iHscrollPos < m_stScreenSettings.iHscrollMax)
m_stScreenSettings.iHscrollInc = 1;
break;
case SB_PAGEUP:
if (m_stScreenSettings.iHscrollPos >= m_stScreenSettings.cxBuffer)
m_stScreenSettings.iHscrollInc = -m_stScreenSettings.cxBuffer;
else
m_stScreenSettings.iHscrollInc = -m_stScreenSettings.iHscrollPos;
break;
case SB_PAGEDOWN:
if (m_stScreenSettings.iHscrollPos <= m_stScreenSettings.iHscrollMax-m_stScreenSettings.cxBuffer)
m_stScreenSettings.iHscrollInc = m_stScreenSettings.cxBuffer;
else
m_stScreenSettings.iHscrollInc = m_stScreenSettings.iHscrollMax - m_stScreenSettings.iHscrollPos;
break;
case SB_THUMBTRACK:
m_stScreenSettings.iHscrollInc = nPos - m_stScreenSettings.iHscrollPos;
break;
default:
break;
}
m_stScreenSettings.iHscrollPos += m_stScreenSettings.iHscrollInc;
SCROLLINFO si;
memset(&si, 0, sizeof(si));
si.cbSize = sizeof(si);
si.fMask = SIF_POS;
si.nPos = m_stScreenSettings.iHscrollPos;
::SetScrollInfo(hwndHBar, SB_CTL, &si, TRUE);
// ::SetScrollPos (hwndHBar, SB_CTL, m_stScreenSettings.iHscrollPos, TRUE);
InvalidateRect (NULL, FALSE);
UpdateWindow ();
// CView::OnHScroll(nSBCode, nPos, pScrollBar);
}
void CFshedView::OnKillFocus(CWnd* pNewWnd)
{
// CView::OnKillFocus(pNewWnd);
HideCaret ();
DestroyCaret ();
}
void CFshedView::OnSetFocus(CWnd* pOldWnd)
{
// CView::OnSetFocus(pOldWnd);
if (m_stScreenSettings.cxChar == 0 || m_stScreenSettings.cyChar == 0)
{
HDC hdc = ::GetDC (m_hWnd);
if (make_font (hdc))
{
HFONT of = (HFONT) SelectObject (hdc, hFont);
TEXTMETRIC tm;
GetTextMetrics (hdc, &tm);
m_stScreenSettings.cxChar = tm.tmAveCharWidth;
m_stScreenSettings.cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * m_stScreenSettings.cxChar / 2;
m_stScreenSettings.cyChar = tm.tmHeight + tm.tmExternalLeading;
SelectObject (hdc, of);
}
::ReleaseDC (m_hWnd, hdc);
}
update_for_new_datasize ();
::CreateCaret (m_hWnd, NULL, m_stScreenSettings.cxChar, m_stScreenSettings.cyChar);
set_caret_pos ();
ShowCaret ();
}
void CFshedView::OnEditCut()
{
int iCutOffset, iCutNumberOfBytes;
if (bSelected) // If selecting...
{
if (iEndOfSelection >= iStartOfSelection)
{
iCutOffset = iStartOfSelection;
iCutNumberOfBytes = iEndOfSelection-iStartOfSelection+1;
}
else
{
iCutOffset = iEndOfSelection;
iCutNumberOfBytes = iStartOfSelection-iEndOfSelection+1;
}
}
else // No selection: cut current byte.
{
iCutOffset = m_stScreenSettings.iCurByte;
iCutNumberOfBytes = 1;
}
iCutMode = BST_CHECKED;
// if (DialogBox (hInstance, MAKEINTRESOURCE (IDD_CUTDIALOG), hwnd, (DLGPROC) CutDlgProc))
{
// Can requested number be cut?
// DataArray.GetLength ()-iCutOffset = number of bytes from current pos. to end.
if( Doc->DataArray.GetLength() - iCutOffset >= iCutNumberOfBytes )
{
// OK
int newlen = Doc->DataArray.GetLength () - iCutNumberOfBytes;
// Cut to clipboard?
switch (iCutMode)
{
case BST_CHECKED:
{
// Transfer to clipboard.
int destlen = byte_to_BC_destlen ((char*) &(Doc->DataArray[iCutOffset]), iCutNumberOfBytes);
HGLOBAL hGlobal = GlobalAlloc (GHND, destlen * sizeof(TCHAR));
if (hGlobal != NULL)
{
CWaitCursor zzz;
char* pd = (char*) GlobalLock (hGlobal);
CString strData;
translate_bytes_to_BC (strData, &(Doc->DataArray[iCutOffset]), iCutNumberOfBytes);
memcpy(pd, strData, destlen * sizeof(TCHAR));
GlobalUnlock (hGlobal);
OpenClipboard ();
EmptyClipboard ();
SetClipboardData (CF_UNICODETEXT, hGlobal);
CloseClipboard ();
}
else
{
// Not enough memory for clipboard.
AfxMessageBox (IDS_ERR_ACC_CLIP);
return;
}
break;
}
default:
break;
}
// Cut data.
if (Doc->DataArray.RemoveAt (iCutOffset, iCutNumberOfBytes) == FALSE)
{
AfxMessageBox(IDS_ERR_CUT);
return;
}
m_stScreenSettings.iCurByte = iCutOffset;
if (m_stScreenSettings.iCurByte > LASTBYTE)
m_stScreenSettings.iCurByte = LASTBYTE;
if (m_stScreenSettings.iCurByte<0)
m_stScreenSettings.iCurByte=0;
Doc->SetModifiedFlag();
Doc->bFilestatusChanged = TRUE;
bSelected = FALSE;
update_for_new_datasize ();
repaint ();
}
else
{
// Too many bytes to cut.
AfxMessageBox(IDS_ERR_CUT_BYTES);
}
}
}
void CFshedView::OnEditCopy()
{
int iCopyStartOffset, iCopyEndOffset;
if (!bSelected)
{
// No selection: copy current byte.
iCopyStartOffset = m_stScreenSettings.iCurByte;
iCopyEndOffset = m_stScreenSettings.iCurByte;
}
else
{
// Copy selection.
if (iEndOfSelection >= iStartOfSelection)
{
iCopyStartOffset = iStartOfSelection;
iCopyEndOffset = iEndOfSelection;
}
else
{
iCopyStartOffset = iEndOfSelection;
iCopyEndOffset = iStartOfSelection;
}
}
// if (DialogBox (hInstance, MAKEINTRESOURCE (IDD_COPYDIALOG), hwnd, (DLGPROC) CopyDlgProc) != FALSE)
{
// Get dialogue values.
iStartOfSelection = iCopyStartOffset;
iEndOfSelection = iCopyEndOffset;
if (iEndOfSelection >= iStartOfSelection)
{
int destlen = byte_to_BC_destlen ((char*) &(Doc->DataArray[iStartOfSelection]), iEndOfSelection-iStartOfSelection+1);
HGLOBAL hGlobal = GlobalAlloc (GHND, destlen * sizeof(TCHAR));
if (hGlobal != NULL)
{
CWaitCursor zzz;
TCHAR* pd = (TCHAR*) GlobalLock (hGlobal);
CString strData;
translate_bytes_to_BC (strData, &(Doc->DataArray[iStartOfSelection]), iEndOfSelection-iStartOfSelection+1);
memcpy(pd, strData, destlen * sizeof(TCHAR));
GlobalUnlock (hGlobal);
OpenClipboard ();
EmptyClipboard ();
SetClipboardData (CF_UNICODETEXT, hGlobal);
CloseClipboard ();
}
else
AfxMessageBox (IDS_ERR_COPY_MEM);
}
else
{
AfxMessageBox(IDS_ERR_END_OFFSET);
}
}
adjust_view_for_selection ();
}
void CFshedView::OnEditPaste()
{
//Pabs changed - line comment out
// iPasteTimes = 1;
// iPasteAsText = FALSE;
//end
UINT iRtn = AfxMessageBox(IDS_INSERT_OVR, MB_YESNOCANCEL);
if (iRtn == IDCANCEL)
return;
char *pcPasteText = NULL;
if (OpenClipboard ())
{
HGLOBAL hClipMemory = GetClipboardData (CF_TEXT);
if (hClipMemory != NULL)
{
int gsize = (int)GlobalSize (hClipMemory);
if (gsize > 0)
{
char* pClipMemory = (char*) GlobalLock (hClipMemory);
pcPasteText = new char[gsize];
memcpy (pcPasteText, pClipMemory, gsize);
}
GlobalUnlock (hClipMemory);
}
else
return;
CloseClipboard ();
}
else
return;
int iPasteMode, iPasteAsText = TRUE, iPasteSkip = 0, iPasteTimes = 1;
if( iRtn == IDYES )
iPasteMode = 2;
else
iPasteMode = 1;
// if (DialogBox (hInstance, MAKEINTRESOURCE (IDD_PASTEDIALOG), hwnd, (DLGPROC) PasteDlgProc))
{
switch( iPasteMode )
{
case 1: // Overwrite.
{
char* pcPastestring;
// Create findstring.
int destlen;
if (iPasteAsText == TRUE )
{
destlen = (int)strlen( pcPasteText );
pcPastestring = new char[ destlen ];
memcpy( pcPastestring, pcPasteText, destlen );
}
else
{
destlen = create_bc_translation (&pcPastestring, pcPasteText, (int)strlen (pcPasteText), App->m_iCharacterSet, App->m_iBinaryMode);
}
if (destlen > 0)
{
// Enough space for writing?
// DataArray.GetLength()-m_stScreenSettings.iCurByte = number of bytes from including curbyte to end.
//Pabs changed - "(iPasteSkip+destlen)" used to be "destlen"
if (Doc->DataArray.GetLength()-m_stScreenSettings.iCurByte >= (iPasteSkip+destlen)*iPasteTimes)
//end
{
// Overwrite data.
CWaitCursor zzz;
int i,k;
for (k=0; k<iPasteTimes; k++)
{
for (i=0; i<destlen; i++)
{
Doc->DataArray[(m_stScreenSettings.iCurByte+k*(iPasteSkip+destlen))+i] = pcPastestring[i];
}
}
Doc->SetModifiedFlag();
Doc->bFilestatusChanged = TRUE;
}
else
AfxMessageBox (IDS_ERR_OVR_SPACE);
delete [] pcPastestring;
}
delete [] pcPasteText;
repaint ();
break;
}
case 2: // Insert.
{
char* pcPastestring;
int destlen;
if( iPasteAsText == TRUE )
{
destlen = (int)strlen( pcPasteText );
pcPastestring = new char[ destlen ];
memcpy( pcPastestring, pcPasteText, destlen );
}
else
{
destlen = create_bc_translation( &pcPastestring, pcPasteText, (int)strlen( pcPasteText ), App->m_iCharacterSet, App->m_iBinaryMode );
}
if( destlen > 0 )
{
// Insert at m_stScreenSettings.iCurByte. Bytes there will be pushed up.
CWaitCursor zzz;
int i, k;
for( k = 0,i=m_stScreenSettings.iCurByte; k < iPasteTimes; k++ ){
if (!Doc->DataArray.InsertAtGrow(m_stScreenSettings.iCurByte,(unsigned char*)pcPastestring,0,destlen)){
delete [] pcPastestring;
delete [] pcPasteText;
AfxMessageBox(IDS_ERR_MEM_INSERT);
update_for_new_datasize ();
return;
}
Doc->SetModifiedFlag();
Doc->bFilestatusChanged = TRUE;
m_stScreenSettings.iCurByte+=destlen+iPasteSkip;
}
m_stScreenSettings.iCurByte=i;
Doc->SetModifiedFlag();
Doc->bFilestatusChanged = TRUE;
update_for_new_datasize ();
delete [] pcPastestring;
}
else
{
delete [] pcPasteText;
AfxMessageBox(IDS_ERR_INS_ZERO);
update_for_new_datasize ();
return;
}
delete [] pcPasteText;
repaint ();
break;
}
default:
break;
}
}
}
void CFshedView::OnPrint(CDC* pDC, CPrintInfo* pInfo)
{
m_stScreenSettings.iCurLine = (pInfo->m_nCurPage - 1) * m_stScreenSettings.cyBuffer;
TRACE("Page %d, Lines %d to %d\n", pInfo->m_nCurPage, m_stScreenSettings.iCurLine, m_stScreenSettings.iCurLine + m_stScreenSettings.cyBuffer - 1);
int nHeight = -::MulDiv(App->m_iFontSize, pDC->GetDeviceCaps(LOGPIXELSY), 72);
if (make_font(pDC->GetSafeHdc(), nHeight))
{
HFONT of = (HFONT) SelectObject(pDC->GetSafeHdc(), hFont);
TEXTMETRIC tm;
pDC->GetTextMetrics(&tm);
m_stScreenSettings.cxChar = tm.tmAveCharWidth;
m_stScreenSettings.cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * m_stScreenSettings.cxChar / 2;
m_stScreenSettings.cyChar = tm.tmHeight + tm.tmExternalLeading;
SelectObject(pDC->GetSafeHdc(), of);
}
OnDraw(pDC);
}
//-------------------------------------------------------------------
int CFshedView::GotoBookmark( int cmd )
{
if( pbmkList[ cmd - IDM_BOOKMARK1 ].offset >= 0 && pbmkList[ cmd - IDM_BOOKMARK1 ].offset <= Doc->DataArray.GetLength() )
{
m_stScreenSettings.iCurByte = pbmkList[ cmd - IDM_BOOKMARK1 ].offset;
update_for_new_datasize();
adjust_vscrollbar();
repaint();
}
else
{
AfxMessageBox (IDS_ERR_BAD_BOOKMARK);
}
return 0;
}
void CFshedView::OnBookmark(UINT nId)
{
GotoBookmark(nId);
}
void CFshedView::OnRemoveBkm()
{
if (iBmkCount==0)
{
AfxMessageBox (IDS_ERR_NOBK2REMOVE);
return;
}
CRemoveBookmarkDlg dlgRemBk(this);
dlgRemBk.m_pbmkRemove = pbmkList;
dlgRemBk.m_nNumBookmarks = iBmkCount;
if (dlgRemBk.DoModal() == IDOK)
{
if (pbmkList[dlgRemBk.m_nSelBookmark].name != NULL)
delete [] (pbmkList[dlgRemBk.m_nSelBookmark].name);
int i;
for (i = dlgRemBk.m_nSelBookmark; i < iBmkCount-1; i++)
pbmkList[i] = pbmkList[i+1];
iBmkCount--;
repaint();
}
}
void CFshedView::OnClearallBmk()
{
if (AfxMessageBox(IDS_PRMPT_CLEARALLBK, MB_YESNO | MB_ICONQUESTION ) == IDYES )
{
int i;
for (i=0; i<iBmkCount; i++)
if (pbmkList[i].name != NULL)
delete [] (pbmkList[i].name);
iBmkCount = 0;
repaint();
}
}
void CFshedView::OnAddbookmark()
{
if (Doc->DataArray.GetLength()<=0)
{
AfxMessageBox (IDS_ERR_NOBK_EMPTY);
return;
}
if (iBmkCount < BMKMAX)
{
CAddBookmarkDlg dlgBk(this);
dlgBk.m_nOffset = m_stScreenSettings.iCurByte;
if (dlgBk.DoModal() == IDOK)
{
if (dlgBk.m_nOffset >=0 && dlgBk.m_nOffset <= Doc->DataArray.GetLength())
{
// Is there already a bookmark on this offset?
int i;
for (i = 0; i < iBmkCount; i++)
{
if (pbmkList[ i ].offset == dlgBk.m_nOffset)
{
AfxMessageBox(IDS_ERR_ALREADY_BK);
return;
}
}
// No bookmark on that position yet.
pbmkList[iBmkCount].offset = dlgBk.m_nOffset;
if (dlgBk.m_strName.GetLength() > 0)
{
pbmkList[iBmkCount].name = new TCHAR[dlgBk.m_strName.GetLength() + 1];
_tcscpy (pbmkList[iBmkCount].name, dlgBk.m_strName);
}
else
pbmkList[iBmkCount].name = NULL;
iBmkCount++;
repaint();
}
else
{
AfxMessageBox (IDS_ERR_NOBK_POS);
return;
}
}
}
else
{
AfxMessageBox(IDS_ERR_NOMORE_BK);
}
}
void CFshedView::OnCopyHexdump()
{
if (Doc->DataArray.GetLength() <= 0)
{
AfxMessageBox (IDS_ERR_DUMP_EMPTY);
return;
}
CHexDumpDlg dlgDump(this);
if( !bSelected )
{
// Assume whole file is to be hexdumped.
dlgDump.m_nEndOffset = ((Doc->DataArray.GetUpperBound())/App->m_iBytesPerLine)*App->m_iBytesPerLine;
}
else
{
// Assume selected area is to be hexdumped.
// Make sure end of selection is greater than start of selection.
if( iEndOfSelection < iStartOfSelection )
{
int i = iEndOfSelection;
iEndOfSelection = iStartOfSelection;
iStartOfSelection = i;
}
dlgDump.m_nStartOffset = ( iStartOfSelection / App->m_iBytesPerLine ) * App->m_iBytesPerLine;
dlgDump.m_nEndOffset = ( iEndOfSelection / App->m_iBytesPerLine ) * App->m_iBytesPerLine;
}
if (dlgDump.DoModal() == IDOK)
{
// Show wait cursor.
if (dlgDump.m_nStartOffset % App->m_iBytesPerLine != 0 || dlgDump.m_nEndOffset % App->m_iBytesPerLine != 0)
{
AfxMessageBox(IDS_ERR_DUMPOFFSETS);
return;
}
SetCursor (LoadCursor (NULL, IDC_WAIT));
// Number of lines to copy:
int linecount = (dlgDump.m_nEndOffset - dlgDump.m_nStartOffset) / App->m_iBytesPerLine + 1;
// Req'd mem for lines:
// (Every line ended with CR+LF ('\r'+'\n'))
int buflen = linecount * (m_stScreenSettings.iCharsPerLine+2) + 1;
// Create hexdump.
int a,b,k,m,n,j,l;
char buf1[128], buf2[128];
char* pMem = new char[buflen];
for (n=0; n < buflen; n++)
pMem[n] = ' ';
// Write hexdump.
// a = first byte of first line of hexdump.
// b = first byte of last line of hexdump.
b = dlgDump.m_nEndOffset;
// a = Offset of current line.
// k = Offset in text array.
for (k = 0, a = dlgDump.m_nStartOffset; a <= b; a += App->m_iBytesPerLine, k += m_stScreenSettings.iCharsPerLine + 2)
{
// Write offset.
sprintf (buf1, "%%%d.%dx", App->m_iOffsetLen, App->m_iOffsetLen);
for (m = 0; m < m_stScreenSettings.iByteSpace; m++)
strcat (buf1, " ");
sprintf (buf2, buf1, a); // buf2 = Offset+Spaces.
l = 0; // l = Offset in line, relative to k.
n = 0;
while (buf2[n] != '\0')
pMem[k + (l++)] = buf2[n++]; // Copy Offset. l = next empty place after spaces.
// Write bytes and chars.
for (j = 0; j < App->m_iBytesPerLine; j++)
{
if (a+j > Doc->DataArray.GetUpperBound ())
{
// Nonexistant byte.
pMem[k + l + j*3 ] = ' ';
pMem[k + l + j*3 + 1] = ' ';
pMem[k + l + j*3 + 2] = ' ';
// Nonexistant char.
pMem[k + l + App->m_iBytesPerLine*3 + m_stScreenSettings.iCharSpace + j] = ' ';
}
else
{
// Write byte.
sprintf (buf1, "%2.2x ", Doc->DataArray[a + j]);
pMem[k + l + j*3 ] = buf1[0];
pMem[k + l + j*3 + 1] = buf1[1];
pMem[k + l + j*3 + 2] = buf1[2];
// Write char.
if( App->m_iCharacterSet == OEM_FIXED_FONT && Doc->DataArray[a + j] != 0 )
pMem[k + l + App->m_iBytesPerLine*3 + m_stScreenSettings.iCharSpace + j] = Doc->DataArray[a + j];
else if( (Doc->DataArray[a + j] >= 32 && Doc->DataArray[a + j] <= 126) ||
(Doc->DataArray[a + j]>=160 && Doc->DataArray[a + j] <= 255) ||
(Doc->DataArray[a + j] >= 145 && Doc->DataArray[a + j] <= 146) )
pMem[k + l + App->m_iBytesPerLine*3 + m_stScreenSettings.iCharSpace + j] = Doc->DataArray[a + j];
else
pMem[k + l + App->m_iBytesPerLine*3 + m_stScreenSettings.iCharSpace + j] = '.';
}
}
pMem[k + m_stScreenSettings.iCharsPerLine ] = '\r';
pMem[k + m_stScreenSettings.iCharsPerLine + 1] = '\n';
}
pMem[buflen-1] = '\0';
// Remove wait cursor.
SetCursor (LoadCursor (NULL, IDC_ARROW));
if (dlgDump.m_nExportTo == 1)
{
// To clipboard.
HGLOBAL hGlobal = GlobalAlloc (GHND, buflen);
if (hGlobal != NULL)
{
char* pDest = (char*) GlobalLock (hGlobal);
memcpy (pDest, pMem, buflen);
GlobalUnlock (hGlobal);
OpenClipboard ();
EmptyClipboard ();
SetClipboardData (CF_TEXT, hGlobal);
CloseClipboard ();
}
else
AfxMessageBox(IDS_ERR_HEX_NOMEM);
}
else
{
// to file.
TCHAR szFileName[_MAX_PATH];
TCHAR szTitleName[_MAX_FNAME + _MAX_EXT];
_tcscpy (szFileName, _T("hexdump.txt"));
OPENFILENAME ofn;
ofn.lStructSize = sizeof (OPENFILENAME);
ofn.hwndOwner = m_hWnd;
ofn.hInstance = NULL;
ofn.lpstrFilter = _T("All Files (*.*)\0*.*\0\0");
ofn.lpstrCustomFilter = NULL;
ofn.nMaxCustFilter = 0;
ofn.nFilterIndex = 0;
ofn.lpstrFile = szFileName;
ofn.nMaxFile = _MAX_PATH;
ofn.lpstrFileTitle = szTitleName;
ofn.nMaxFileTitle = _MAX_FNAME + _MAX_EXT;
ofn.lpstrInitialDir = NULL;
ofn.lpstrTitle = NULL;
ofn.Flags = OFN_HIDEREADONLY | OFN_CREATEPROMPT;
ofn.nFileOffset = 0;
ofn.nFileExtension = 0;
ofn.lpstrDefExt = NULL;
ofn.lCustData = 0L;
ofn.lpfnHook = NULL;
ofn.lpTemplateName = NULL;
if (GetSaveFileName (&ofn))
{
int filehandle;
if ((filehandle = _topen(szFileName, _O_RDWR|_O_CREAT|_O_TRUNC|_O_BINARY,_S_IREAD|_S_IWRITE)) != -1)
{
// Write file.
if ((_write (filehandle, pMem, buflen-1)) != -1)
{
AfxMessageBox(IDS_OK_SAVING);
}
else
AfxMessageBox(IDS_ERR_HEX_SAVE);
_close (filehandle);
}
else
AfxMessageBox(IDS_ERR_HEX_SAVE);
}
repaint ();
}
delete [] pMem;
}
}
void CFshedView::OnInsertfile()
{
TCHAR szFileName[_MAX_PATH];
TCHAR szTitleName[_MAX_FNAME + _MAX_EXT];
szFileName[0] = '\0';
OPENFILENAME ofn;
ofn.lStructSize = sizeof (OPENFILENAME);
ofn.hwndOwner = m_hWnd;
ofn.hInstance = NULL;
ofn.lpstrFilter = _T("All Files (*.*)\0*.*\0\0");
ofn.lpstrCustomFilter = NULL;
ofn.nMaxCustFilter = 0;
ofn.nFilterIndex = 0;
ofn.lpstrFile = szFileName;
ofn.nMaxFile = _MAX_PATH;
ofn.lpstrFileTitle = szTitleName;
ofn.nMaxFileTitle = _MAX_FNAME + _MAX_EXT;
ofn.lpstrInitialDir = NULL;
ofn.lpstrTitle = NULL;
ofn.Flags = OFN_HIDEREADONLY | OFN_CREATEPROMPT;
ofn.nFileOffset = 0;
ofn.nFileExtension = 0;
ofn.lpstrDefExt = NULL;
ofn.lCustData = 0L;
ofn.lpfnHook = NULL;
ofn.lpTemplateName = NULL;
if (GetOpenFileName (&ofn))
{
// RK: don't allow inserting same file we're editing right now.
if( _tcscmp( szFileName, Doc->filename ) == 0 )
{
AfxMessageBox(IDS_ERR_NOSELFINS);
return;
}
int fhandle;
if ((fhandle=_topen(szFileName,_O_RDONLY|_O_BINARY))!=-1)
{
int inslen;
if ((inslen = _filelength (fhandle)) != -1)
{
if (inslen)
{
unsigned char* insbuf = new unsigned char[inslen];
if (insbuf!=NULL){
if (_read (fhandle, insbuf, inslen) != -1)
{
if (!Doc->DataArray.InsertAtGrow(m_stScreenSettings.iCurByte,insbuf,0,inslen))
AfxMessageBox(IDS_ERR_INS_DATA);
// RK: changed "true" to TRUE.
else
{
// RK: Added a call to update_for_new_datasize().
// m_iFileChanged = TRUE;
Doc->bFilestatusChanged = TRUE;
Doc->SetModifiedFlag();
update_for_new_datasize();
repaint();
}
}
else
AfxMessageBox(IDS_ERR_READING_FILE);
delete []insbuf;
}
else
AfxMessageBox(IDS_ERR_MEM_READFILE);
}
}
// RK: Spelling of "size"!
else
AfxMessageBox(IDS_ERR_CHK_FILESIZE);
_close (fhandle);
}
else
AfxMessageBox(IDS_ERR_FILEOPEN);
}
}
void CFshedView::OnSaveselas()
{
TCHAR szFileName[_MAX_PATH];
TCHAR szTitleName[_MAX_FNAME + _MAX_EXT];
OPENFILENAME ofn;
szTitleName[0] = szFileName[0] = '\0';
ofn.lStructSize = sizeof (OPENFILENAME);
ofn.hwndOwner = m_hWnd;
ofn.hInstance = NULL;
ofn.lpstrFilter = _T("All Files (*.*)\0*.*\0\0");
ofn.lpstrCustomFilter = NULL;
ofn.nMaxCustFilter = 0;
ofn.nFilterIndex = 0;
ofn.lpstrFile = szFileName;
ofn.nMaxFile = _MAX_PATH;
ofn.lpstrFileTitle = szTitleName;
ofn.nMaxFileTitle = _MAX_FNAME + _MAX_EXT;
ofn.lpstrInitialDir = NULL;
ofn.lpstrTitle = NULL;
ofn.Flags = OFN_HIDEREADONLY | OFN_CREATEPROMPT;
ofn.nFileOffset = 0;
ofn.nFileExtension = 0;
ofn.lpstrDefExt = NULL;
ofn.lCustData = 0L;
ofn.lpfnHook = NULL;
ofn.lpTemplateName = NULL;
if (GetSaveFileName (&ofn))
{
int filehandle;
if ((filehandle = _topen (szFileName, _O_RDWR|_O_CREAT|_O_TRUNC|_O_BINARY,_S_IREAD|_S_IWRITE)) != -1)
{
CWaitCursor zzz;
if (iStartOfSelection > iEndOfSelection)
swap(iStartOfSelection, iEndOfSelection);
if (!((_write (filehandle, &Doc->DataArray[iStartOfSelection], iEndOfSelection - iStartOfSelection+1)) != -1))
AfxMessageBox (IDS_ERR_FILESAVE);
_close (filehandle);
}
else
AfxMessageBox(IDS_ERR_FILESAVE);
}
repaint ();
}
void CFshedView::OnEditClear()
{
iCutMode = BST_UNCHECKED;
OnEditCut();
}
void CFshedView::OnEditSelectAll()
{
if (Doc->DataArray.GetLength() > 0)
{
bSelected = TRUE;
iStartOfSelection = 0;
iEndOfSelection = Doc->DataArray.GetUpperBound ();
adjust_view_for_selection ();
repaint ();
}
}
void CFshedView::OnInsertmodetoggle()
{
iInsertMode = (iInsertMode) ? FALSE : TRUE;
set_wnd_title();
}
void CFshedView::OnChangeMode()
{
character ('\t');
}
void CFshedView::OnEditReadonlymode()
{
if (Doc->bReadOnly == FALSE )
Doc->bReadOnly = TRUE;
else
Doc->bReadOnly = FALSE;
set_wnd_title();
update_for_new_datasize();
}
void CFshedView::OnEditAppend()
{
// iManipPos = m_stScreenSettings.iCurByte;
CAppendDialog dlgAppend(this);
if (dlgAppend.DoModal() == IDOK)
{
int i, oldupbound = Doc->DataArray.GetLength();
CWaitCursor zzz;
if (Doc->DataArray.SetSize (Doc->DataArray.GetSize() + dlgAppend.m_nNumBytes) == FALSE)
{
AfxMessageBox(IDS_ERR_APPEND_MEM);
return;
}
Doc->DataArray.SetUpperBound(Doc->DataArray.GetUpperBound() + dlgAppend.m_nNumBytes);
for (i=0; i < dlgAppend.m_nNumBytes; i++)
Doc->DataArray[oldupbound+i] = 0;
Doc->bFilestatusChanged = TRUE;
Doc->SetModifiedFlag();
update_for_new_datasize ();
repaint ();
}
}
void CFshedView::OnEditManipulatebits()
{
if (Doc->DataArray.GetLength() == 0)
{
AfxMessageBox(IDS_ERR_EMPTY_FILE);
return;
}
if (m_stScreenSettings.iCurByte < 0 || m_stScreenSettings.iCurByte > LASTBYTE)
{
AfxMessageBox (IDS_ERR_SELBYTE);
return;
}
CManipulateBitsDlg dlgManip(this);
dlgManip.m_chValue = Doc->DataArray[m_stScreenSettings.iCurByte];
dlgManip.m_nBitPos = m_stScreenSettings.iCurByte;
if (dlgManip.DoModal() == IDOK)
{
Doc->DataArray[m_stScreenSettings.iCurByte] = dlgManip.m_chValue;
Doc->bFilestatusChanged = TRUE;
Doc->SetModifiedFlag();
repaint ();
}
}
void CFshedView::OnSelectBlock()
{
CSelectBlockDlg dlgSelBlock(this);
dlgSelBlock.m_nStartOffset = dlgSelBlock.m_nEndOffset = m_stScreenSettings.iCurByte;
if (dlgSelBlock.DoModal() == IDOK)
{
iStartOfSelection = dlgSelBlock.m_nStartOffset ;
iEndOfSelection = dlgSelBlock.m_nEndOffset;
bSelected = TRUE;
adjust_view_for_selection ();
repaint ();
}
}
void MessageCopyBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType, HWND hwnd)
{
int len=(int)_tcslen(lpText);//get the # bytes needed to store the string (not counting '\0')
//& get where we have to put a '\0' character later
// RK: Added "?" to end of string.
CString strText;
strText.LoadString(IDS_MSG_COPY_TO_CLIP);
strText = lpText + strText;
if (IDYES == MessageBox (hWnd, strText, lpCaption, MB_YESNO | uType))
{
//user wants to copy output
len++;//1 extra for '\0'
HGLOBAL hGlobal = GlobalAlloc (GHND, len * sizeof(TCHAR)); //alloc clip mem
if (hGlobal != NULL)//succesful in above
{
TCHAR* pd = (TCHAR*) GlobalLock (hGlobal);// get pointer to clip data
if(pd)
{
//succesfuly got pointer
_tcscpy(pd,lpText);//copy lpText into global mem
GlobalUnlock (hGlobal);//unlock global mem
if(OpenClipboard(hwnd))
{
CWaitCursor zzz;
// open clip
EmptyClipboard(); //empty clip
SetClipboardData (CF_UNICODETEXT, hGlobal);//copy to clip
CloseClipboard (); //close clip
}
else //failed to open clip
AfxMessageBox(IDS_ERR_ACC_CLIP);
}
else
{//failed to get pointer to global mem
GlobalFree(hGlobal);
AfxMessageBox (IDS_ERR_HEX_NOMEM);
}
}
else// failed to allocate global mem
AfxMessageBox (IDS_ERR_HEX_NOMEM);
}
//user doesn't want to copy output
}
void CFshedView::OnReadfloat()
{
CString strBuf;
float floatval;
int len = (iEndOfSelection - iStartOfSelection + 1);
if (len >= 4)
{
// enough space for float.
if (App->m_iBinaryMode == LITTLEENDIAN_MODE)
floatval = *((float*)&(Doc->DataArray[iStartOfSelection]));
else // BIGENDIAN_MODE
{
char* pf = (char*) &floatval;
int i;
for (i = 0; i < 4; i++)
pf[i] = Doc->DataArray[iStartOfSelection + 3 - i];
}
strBuf.Format(IDS_FMT_FLOAT_SIZE, floatval);
}
else
strBuf.LoadString(IDS_FMT_FLOAT_NOSPACE);
double dval;
CString strBuf2;
if (len >= 8)
{
// enough space for double.
if (App->m_iBinaryMode == LITTLEENDIAN_MODE)
dval = *((double*)&(Doc->DataArray[iStartOfSelection]));
else // BIGENDIAN_MODE
{
char* pd = (char*) &dval;
int i;
for (i=0; i<8; i++)
pd[i] = Doc->DataArray[iStartOfSelection+7-i];
}
strBuf2.Format(IDS_FMT_DOUBLE_VAL, dval);
}
else
strBuf2.LoadString(IDS_FMT_DOUBLE_NOSPACE);
strBuf += strBuf2;
strBuf2.LoadString(IDS_LAB_FLOATVALS);
MessageCopyBox (NULL, strBuf, strBuf2, MB_ICONINFORMATION, m_hWnd);
}
void CFshedView::OnProperties()
{
CString strBuf;
strBuf.LoadString(IDS_LAB_FN_PATH);
LPTSTR pc;
CString strBuf2;
GetFullPathName (Doc->filename, MAX_PATH, strBuf2.GetBuffer(MAX_PATH), &pc);
strBuf2.ReleaseBuffer();
strBuf += strBuf2;
if (Doc->bPartialOpen)
{
strBuf2.Format(IDS_LAB_PART_OPEN, Doc->iPartialOffset, Doc->iPartialOffset,
Doc->DataArray.GetLength(), Doc->DataArray.GetLength() / 1024);
}
else
{
strBuf2.Format(IDS_LAB_FILE_SIZE, Doc->DataArray.GetLength(),
Doc->DataArray.GetLength() / 1024);
}
strBuf += strBuf2;
strBuf2.Format(IDS_LAB_NUM_LINES, m_stScreenSettings.iNumlines);
strBuf += strBuf2;
strBuf2.LoadString(IDS_TTL_FILE_PROP);
MessageCopyBox (NULL, strBuf, strBuf2, MB_ICONINFORMATION, m_hWnd);
}
void CFshedView::OnRevert()
{
if (Doc->load_file (Doc->filename))
{
m_stScreenSettings.iVscrollMax = m_stScreenSettings.iVscrollPos = m_stScreenSettings.iVscrollInc = m_stScreenSettings.iHscrollMax = m_stScreenSettings.iHscrollPos =
m_stScreenSettings.iHscrollInc = m_stScreenSettings.iCurLine = m_stScreenSettings.iCurByte = m_stScreenSettings.iCurNibble = 0;
Doc->SetModifiedFlag(FALSE);
Doc->bFilestatusChanged = TRUE;
Doc->bFileNeverSaved = FALSE;
bSelected=FALSE;
RECT rc;
GetClientRect (&rc);
SendMessage (WM_SIZE, 0, (rc.bottom << 16) | rc.right);
InvalidateRect (NULL, FALSE);
UpdateWindow ();
}
}
void CFshedView::OnBookmarksGotobookmark()
{
CRemoveBookmarkDlg dlgRemBk(this);
dlgRemBk.m_pbmkRemove = pbmkList;
dlgRemBk.m_nNumBookmarks = iBmkCount;
dlgRemBk.m_uWindowTitle = IDS_TTL_GOTO_BK;
if (dlgRemBk.DoModal() == IDOK)
{
m_stScreenSettings.iCurByte = pbmkList[dlgRemBk.m_nSelBookmark].offset;
update_for_new_datasize();
adjust_vscrollbar();
repaint();
}
}
void CFshedView::OnUpdateBookmarksGotobookmark(CCmdUI* pCmdUI)
{
pCmdUI->Enable(iBmkCount);
}
void CFshedView::OnUpdateEditReadonlymode(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(Doc->bReadOnly);
}
void CFshedView::OnEditPasteSpecial()
{
CPasteSpecialDlg dlgPaste;
if (dlgPaste.DoModal() == IDOK)
{
char* pcPastestring;
// Create findstring.
int destlen;
if (dlgPaste.m_bPasteAsText == TRUE)
{
destlen = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)(LPCTSTR)dlgPaste.m_strClipText,
dlgPaste.m_strClipText.GetLength(), NULL, NULL, NULL, NULL);
pcPastestring = new char[destlen + 1];
WideCharToMultiByte(CP_ACP, 0, (LPWSTR)(LPCTSTR)dlgPaste.m_strClipText, dlgPaste.m_strClipText.GetLength(),
pcPastestring, destlen, NULL, NULL); // use it to call OLE here
pcPastestring[destlen] = 0;
}
else
destlen = create_bc_translation (&pcPastestring, dlgPaste.m_strClipText, (int)_tcslen(dlgPaste.m_strClipText), App->m_iCharacterSet, App->m_iBinaryMode);
if (destlen > 0)
{
if (!dlgPaste.m_nInsertMode) // Overwrite.
{
// Enough space for writing?
// DataArray.GetLength()-m_stScreenSettings.iCurByte = number of bytes from including curbyte to end.
if ((Doc->DataArray.GetLength() - m_stScreenSettings.iCurByte) >=
(dlgPaste.m_nSkipBytes + destlen) * dlgPaste.m_nNumTimes)
{
// Overwrite data.
CWaitCursor zzz;
int i,k;
for (k = 0; k < dlgPaste.m_nNumTimes; k++)
{
for (i=0; i<destlen; i++)
{
Doc->DataArray[(m_stScreenSettings.iCurByte + k * (dlgPaste.m_nSkipBytes + destlen)) + i] = pcPastestring[i];
}
}
Doc->SetModifiedFlag();
Doc->bFilestatusChanged = TRUE;
}
else
{
AfxMessageBox(_T("Not enough space for overwriting."), MB_OK | MB_ICONERROR);
}
delete [] pcPastestring;
}
else // Insert.
{
CWaitCursor zzz;
// Insert at m_stScreenSettings.iCurByte. Byte there will be pushed up.
int i, k;
for (k = 0,i = m_stScreenSettings.iCurByte; k < dlgPaste.m_nNumTimes; k++)
{
if (!Doc->DataArray.InsertAtGrow(m_stScreenSettings.iCurByte,(unsigned char*)pcPastestring,0,destlen))
{
delete [] pcPastestring;
AfxMessageBox (_T("Not enough memory for inserting."), MB_OK | MB_ICONERROR);
update_for_new_datasize ();
return;
}
Doc->SetModifiedFlag();
Doc->bFilestatusChanged = TRUE;
m_stScreenSettings.iCurByte += destlen + dlgPaste.m_nSkipBytes;
}
m_stScreenSettings.iCurByte=i;
Doc->SetModifiedFlag();
Doc->bFilestatusChanged = TRUE;
update_for_new_datasize ();
delete [] pcPastestring;
}
repaint ();
}
}
}
void CFshedView::OnEditFindReplace(BOOL bFindOnly)
{
ASSERT_VALID(this);
m_bFirstSearch = TRUE;
if (m_pFindReplaceDlg != NULL)
{
if (m_bFindOnly == bFindOnly)
{
m_pFindReplaceDlg->SetActiveWindow();
m_pFindReplaceDlg->ShowWindow(SW_SHOW);
return;
}
else
{
ASSERT(m_bFindOnly != bFindOnly);
m_pFindReplaceDlg->SendMessage(WM_CLOSE);
ASSERT(m_pFindReplaceDlg == NULL);
ASSERT_VALID(this);
}
}
CString strFind = GetSelText();
// if selection is empty or spans multiple lines use old find text
if (strFind.IsEmpty() || (strFind.FindOneOf(_T("\n\r")) != -1))
strFind = m_strFind;
CString strReplace = m_strReplace;
m_pFindReplaceDlg = new CFindReplaceDialog;
ASSERT(m_pFindReplaceDlg != NULL);
DWORD dwFlags = NULL;
if (m_bNext)
dwFlags |= FR_DOWN;
if (m_bCase)
dwFlags |= FR_MATCHCASE;
if (m_bWord)
dwFlags |= FR_WHOLEWORD;
// hide stuff that RichEdit doesn't support
// dwFlags |= FR_HIDEUPDOWN;
if (!m_pFindReplaceDlg->Create(bFindOnly, strFind, strReplace, dwFlags, this))
{
m_pFindReplaceDlg = NULL;
ASSERT_VALID(this);
return;
}
ASSERT(m_pFindReplaceDlg != NULL);
m_bFindOnly = bFindOnly;
m_pFindReplaceDlg->SetActiveWindow();
m_pFindReplaceDlg->ShowWindow(SW_SHOW);
ASSERT_VALID(this);
}
BOOL CFshedView::FindTextSimple(LPCTSTR lpszFind, BOOL bCase, BOOL bWord, BOOL m_bNext)
{
USES_CONVERSION;
ASSERT(lpszFind != NULL);
FINDTEXTEX ft;
GetSel(ft.chrg);
if (m_bFirstSearch)
{
m_lInitialSearchPos = ft.chrg.cpMin;
m_bFirstSearch = FALSE;
}
ft.lpstrText = lpszFind;
if (ft.chrg.cpMin != ft.chrg.cpMax) // i.e. there is a selection
{
#ifndef _UNICODE
// If byte at beginning of selection is a DBCS lead byte,
// increment by one extra byte.
TEXTRANGE textRange;
TCHAR ch[2];
textRange.chrg.cpMin = ft.chrg.cpMin;
textRange.chrg.cpMax = ft.chrg.cpMin + 1;
textRange.lpstrText = ch;
SendMessage(EM_GETTEXTRANGE, 0, (LPARAM)&textRange);
if (_istlead(ch[0]))
{
ASSERT(ft.chrg.cpMax - ft.chrg.cpMin >= 2);
ft.chrg.cpMin++;
}
#endif
ft.chrg.cpMin++;
}
if (m_lInitialSearchPos >= 0)
ft.chrg.cpMax = GetTextLength();
else
ft.chrg.cpMax = GetTextLength()+m_lInitialSearchPos;
DWORD dwFlags = bCase ? FR_MATCHCASE : 0;
dwFlags |= bWord ? FR_WHOLEWORD : 0;
// if we find the text return TRUE
if (FindAndSelect(dwFlags, ft, m_bNext) != -1)
return TRUE;
// if the original starting point was not the beginning of the buffer
// and we haven't already been here
else if (m_lInitialSearchPos > 0)
{
ft.chrg.cpMin = 0;
ft.chrg.cpMax = m_lInitialSearchPos;
m_lInitialSearchPos = m_lInitialSearchPos - GetTextLength();
return FindAndSelect(dwFlags, ft, m_bNext) != -1;
}
// not found
else
return FALSE;
}
long CFshedView::FindAndSelect(DWORD dwFlags, FINDTEXTEX& ft, BOOL bNext)
{
long index = FindText(dwFlags, bNext, &ft);
if (index != -1) // i.e. we found something
SetSel(ft.chrgText);
return index;
}
void CFshedView::TextNotFound(LPCTSTR lpszFind)
{
ASSERT_VALID(this);
m_bFirstSearch = TRUE;
OnTextNotFound(lpszFind);
}
void CFshedView::OnTextNotFound(LPCTSTR)
{
MessageBeep(MB_ICONHAND);
}
BOOL CFshedView::FindText(LPCTSTR lpszFind, BOOL bCase, BOOL bWord, BOOL bNext)
{
ASSERT_VALID(this);
CWaitCursor wait;
return FindTextSimple(lpszFind, bCase, bWord, bNext);
}
void CFshedView::OnReplaceSel(LPCTSTR lpszFind, BOOL bNext, BOOL bCase,
BOOL bWord, LPCTSTR lpszReplace)
{
ASSERT_VALID(this);
m_strFind = lpszFind;
m_strReplace = lpszReplace;
m_bCase = bCase;
m_bWord = bWord;
m_bNext = bNext;
if (!SameAsSelected(m_strFind, m_bCase, m_bWord))
{
if (!FindText(m_strFind, m_bCase, m_bWord))
TextNotFound(m_strFind);
else
AdjustDialogPosition(m_pFindReplaceDlg);
return;
}
ReplaceSel(m_strReplace);
if (!FindText(m_strFind, m_bCase, m_bWord))
TextNotFound(m_strFind);
else
AdjustDialogPosition(m_pFindReplaceDlg);
ASSERT_VALID(this);
}
void CFshedView::OnFindNext(LPCTSTR lpszFind, BOOL bNext, BOOL bCase, BOOL bWord)
{
ASSERT_VALID(this);
m_strFind = lpszFind;
m_bCase = bCase;
m_bWord = bWord;
m_bNext = bNext;
if (!FindText(m_strFind, m_bCase, m_bWord, m_bNext))
TextNotFound(m_strFind);
else
AdjustDialogPosition(m_pFindReplaceDlg);
ASSERT_VALID(this);
}
void CFshedView::OnReplaceAll(LPCTSTR lpszFind, LPCTSTR lpszReplace, BOOL bCase, BOOL bWord)
{
ASSERT_VALID(this);
m_strFind = lpszFind;
m_strReplace = lpszReplace;
m_bCase = bCase;
m_bWord = bWord;
m_bNext = TRUE;
CWaitCursor wait;
// no selection or different than what looking for
if (!SameAsSelected(m_strFind, m_bCase, m_bWord))
{
if (!FindText(m_strFind, m_bCase, m_bWord))
{
TextNotFound(m_strFind);
return;
}
}
HideSelection(TRUE, FALSE);
do
{
ReplaceSel(m_strReplace);
} while (FindTextSimple(m_strFind, m_bCase, m_bWord));
TextNotFound(m_strFind);
HideSelection(FALSE, FALSE);
ASSERT_VALID(this);
}
LRESULT CFshedView::OnFindReplaceCmd(WPARAM, LPARAM lParam)
{
ASSERT_VALID(this);
CFindReplaceDialog* pDialog = CFindReplaceDialog::GetNotifier(lParam);
ASSERT(pDialog != NULL);
ASSERT(pDialog == m_pFindReplaceDlg);
if (pDialog->IsTerminating())
m_pFindReplaceDlg = NULL;
else if (pDialog->FindNext())
{
OnFindNext(pDialog->GetFindString(), pDialog->SearchDown(),
pDialog->MatchCase(), pDialog->MatchWholeWord());
}
else if (pDialog->ReplaceCurrent())
{
ASSERT(!m_bFindOnly);
OnReplaceSel(pDialog->GetFindString(),
pDialog->SearchDown(), pDialog->MatchCase(), pDialog->MatchWholeWord(),
pDialog->GetReplaceString());
}
else if (pDialog->ReplaceAll())
{
ASSERT(!m_bFindOnly);
OnReplaceAll(pDialog->GetFindString(), pDialog->GetReplaceString(),
pDialog->MatchCase(), pDialog->MatchWholeWord());
}
ASSERT_VALID(this);
return 0;
}
BOOL CFshedView::SameAsSelected(LPCTSTR lpszCompare, BOOL bCase, BOOL /*bWord*/)
{
// check length first
size_t nLen = lstrlen(lpszCompare);
long lStartChar, lEndChar;
GetSel(lStartChar, lEndChar);
if (nLen != (size_t)(lEndChar - lStartChar))
return FALSE;
// length is the same, check contents
CString strSelect = GetSelText();
return (bCase && lstrcmp(lpszCompare, strSelect) == 0) ||
(!bCase && lstrcmpi(lpszCompare, strSelect) == 0);
}
void CFshedView::OnEditFind()
{
ASSERT_VALID(this);
OnEditFindReplace(TRUE);
}
void CFshedView::OnEditReplace()
{
ASSERT_VALID(this);
OnEditFindReplace(FALSE);
}
void CFshedView::OnEditRepeat()
{
ASSERT_VALID(this);
if (!FindText(m_strFind, m_bCase, m_bWord))
TextNotFound(m_strFind);
}
void CFshedView::AdjustDialogPosition(CDialog* pDlg)
{
ASSERT(pDlg != NULL);
long lStart, lEnd;
GetSel(lStart, lEnd);
CPoint point = GetCharPos(lStart);
ClientToScreen(&point);
CRect rectDlg;
pDlg->GetWindowRect(&rectDlg);
if (rectDlg.PtInRect(point))
{
if (point.y > rectDlg.Height())
rectDlg.OffsetRect(0, point.y - rectDlg.bottom - 20);
else
{
int nVertExt = GetSystemMetrics(SM_CYSCREEN);
if (point.y + rectDlg.Height() < nVertExt)
rectDlg.OffsetRect(0, 40 + point.y - rectDlg.top);
}
pDlg->MoveWindow(&rectDlg);
}
}
// Rich edit compatible functions
long CFshedView::GetTextLength( )
{
return Doc->DataArray.GetLength();
}
long CFshedView::FindText( DWORD dwFlags, BOOL bNext, FINDTEXTEX* pFindText )
{
CWaitCursor zzz;
long lStart, lEnd;
GetSel(lStart, lEnd);
int destLen = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)pFindText->lpstrText, (int)_tcslen(pFindText->lpstrText), NULL, NULL, NULL, NULL);
char *charstring = new char[destLen + 1];
WideCharToMultiByte(CP_ACP, 0, (LPWSTR)pFindText->lpstrText, (int)_tcslen(pFindText->lpstrText),
charstring, destLen, NULL, NULL);
charstring[destLen] = 0;
long i = find_bytes((char*) &Doc->DataArray.GetRefAt(0), Doc->DataArray.GetLength(),
lStart, lEnd,
charstring, (int)strlen(charstring), bNext,
(dwFlags & FR_MATCHCASE) ? TRUE : FALSE, (dwFlags & FR_WHOLEWORD) ? TRUE : FALSE);
delete charstring;
if (i != -1)
{
m_stScreenSettings.iCurByte = i;
pFindText->chrgText.cpMin = m_stScreenSettings.iCurByte;
pFindText->chrgText.cpMax = m_stScreenSettings.iCurByte + (long)_tcslen(pFindText->lpstrText) - 1;
}
return i;
}
CPoint CFshedView::GetCharPos( long lChar ) const
{
CPoint pt(0, 0);
return pt;
}
void CFshedView::HideSelection( BOOL bHide, BOOL bPerm )
{
}
CString CFshedView::GetSelText( )
{
CString strText;
if (bSelected)
{
strText = CString((char*)&Doc->DataArray.GetRefAt(iStartOfSelection), iEndOfSelection - iStartOfSelection + 1);
}
return strText;
}
void CFshedView::GetSel( CHARRANGE& cr ) const
{
cr.cpMin = iStartOfSelection;
cr.cpMax = iEndOfSelection + 1;
}
void CFshedView::GetSel( long& nStartChar, long& nEndChar ) const
{
nStartChar = iStartOfSelection;
nEndChar = iEndOfSelection + 1;
}
void CFshedView::SetSel( CHARRANGE& cr )
{
iStartOfSelection = cr.cpMin;
iEndOfSelection = cr.cpMax;
bSelected = TRUE;
adjust_view_for_selection();
repaint();
}
void CFshedView::SetSel( long nStartChar, long nEndChar )
{
iStartOfSelection = nStartChar;
iEndOfSelection = nEndChar;
bSelected = TRUE;
adjust_view_for_selection();
repaint();
}
void CFshedView::ReplaceSel( LPCTSTR lpszNewText, BOOL bCanUndo)
{
int nSelLen = iEndOfSelection - iStartOfSelection + 1;
int nRepLen = WideCharToMultiByte(CP_ACP, 0, lpszNewText, (int)_tcslen(lpszNewText), NULL, NULL, NULL, NULL);
if (nSelLen < nRepLen)
Doc->DataArray.InsertAtGrow(iStartOfSelection, ' ', nRepLen - nSelLen);
else if (nSelLen > nRepLen)
Doc->DataArray.RemoveAt(iStartOfSelection, nSelLen - nRepLen);
WideCharToMultiByte(CP_ACP, 0, (LPWSTR)lpszNewText, (int)_tcslen(lpszNewText),
(LPSTR)Doc->DataArray.GetBuffer(iStartOfSelection, nRepLen), nRepLen, NULL, NULL);
//Doc->DataArray.CopyFrom(iStartOfSelection, (unsigned char *)lpszNewText, nRepLen);
Doc->SetModifiedFlag();
Doc->bFilestatusChanged = TRUE;
repaint ();
}
void CFshedView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
update_for_new_datasize ();
}
BOOL CFshedView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
if (zDelta < 0)
SendMessage(WM_VSCROLL,SB_LINEDOWN);
else
SendMessage(WM_VSCROLL,SB_LINEUP);
return CView::OnMouseWheel(nFlags,zDelta,pt);
}
void CFshedView::OnGoto()
{
CGotoDlg dlgGoto(this);
dlgGoto.m_nOffset = m_stScreenSettings.iCurByte;
if (dlgGoto.DoModal() == IDOK)
{
if (dlgGoto.m_bRelative)
iEndOfSelection = iStartOfSelection += dlgGoto.m_nOffset;
else
iEndOfSelection = iStartOfSelection = dlgGoto.m_nOffset;
bSelected = TRUE;
adjust_view_for_selection ();
repaint ();
}
}
void CFshedView::OnContextMenu(CWnd* pWnd, CPoint point)
{
// TODO: Add your message handler code here
// Load the desired menu
CMenu mnuPopup;
mnuPopup.LoadMenu(IDM_HEX_CONTEXT);
// Find the rectangle
CRect rect;
GetWindowRect(&rect);
// Get a pointer to the first item of the menu
CMenu *mnuPopupMenu = mnuPopup.GetSubMenu(0);
ASSERT(mnuPopupMenu);
// Find out if the user right-clicked the button
// because we are interested only in the button
if( rect.PtInRect(point) ) // Since the user right-clicked the button, display the context menu
mnuPopupMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this);
}
void CFshedView::OnReadUnicode()
{
int len = max(2, (iEndOfSelection - iStartOfSelection + 1) / 2 * 2);
unsigned char* pf = new unsigned char[len + sizeof(TCHAR)];
if (App->m_iBinaryMode == LITTLEENDIAN_MODE)
{
memcpy(pf, Doc->DataArray + iStartOfSelection, len);
}
else // BIGENDIAN_MODE
{
for (int i = 0; i < len; i += 2)
{
pf[i] = Doc->DataArray[iStartOfSelection + i + 1];
pf[i + 1] = Doc->DataArray[iStartOfSelection + i];
}
}
pf[len - 1] = pf[len - 2] = 0;
CString strCaption;
strCaption.LoadString(IDS_UNICODE_STRING);
MessageCopyBox (NULL, (LPCTSTR)pf, strCaption, MB_ICONINFORMATION, m_hWnd);
delete pf;
}
void CFshedView::OnReadUtf8()
{
int len = (iEndOfSelection - iStartOfSelection + 1);
// we want to convert an MBCS string in lpszA
int nWideLen = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)&Doc->DataArray.GetRefAt(iStartOfSelection), len, NULL, NULL);
wchar_t *szUnicode = new wchar_t[nWideLen + 1];
MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)&Doc->DataArray.GetRefAt(iStartOfSelection), len, szUnicode, nWideLen);
szUnicode[nWideLen] = 0;
CString strCaption;
strCaption.LoadString(IDS_UNICODE_STRING);
MessageCopyBox (NULL, szUnicode, strCaption, MB_ICONINFORMATION, m_hWnd);
delete szUnicode;
}