📄 fshedview.cpp
字号:
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 '<'.
}
//-------------------------------------------------------------------
// 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)
{
char sbuf[2], 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 ())
{
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()
{
char buf[512];
if (strlen (Doc->filename) != 0)
{
// Change window title.
if (Doc->bFilestatusChanged)
{
sprintf (buf, "[%s", Doc->filename);
if (GetDocument()->IsModified())
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -