mmvari/Dump.cpp
2013-07-05 15:09:45 -05:00

1667 lines
40 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//Copyright+LGPL
//-----------------------------------------------------------------------------------------------------------------------------------------------
// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba
//-----------------------------------------------------------------------------------------------------------------------------------------------
// This file is part of MMVARI.
// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
// MMVARI 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 Lesser General Public License for more details.
// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see
// <http://www.gnu.org/licenses/>.
//-----------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <mbstring.h>
#include "Dump.h"
#include "ComLib.h"
#include "Dsp.h"
#define LXW(c) ((c*4)/5)
#if DEBUG
//---------------------------------------------------------------------------
void __fastcall CDump::Debug(LPSTR t)
{
sprintf(t, "DT:%d,WL:%d,ML:%d,RL:%d,WC:%d,MC:%d,RC:%d,Last:%d,Window:%d,Count:%d",
m_DTop,
m_WLine, m_MLine, m_RLine,
m_WCol, m_MCol, m_RCol,
m_fLastCP, m_fWindow, GetCharCount(TRUE)
);
}
#endif
//---------------------------------------------------------------------------
__fastcall CDump::CDump(void)
{
m_fDisEvent = FALSE;
m_pPanel = NULL;
m_pBase = NULL;
m_pPaintBox = NULL;
m_pFont = NULL;
m_pCanvas = NULL;
m_pScrollBar = NULL;
m_ScreenColMax = DUMPCOLMAX;
m_wfp = NULL;
m_hWnd = NULL;
m_pMBCS = NULL;
m_Color[0].c = clWhite;
m_Color[1].c = clBlack;
m_Color[2].c = clBlue;
m_Color[3].c = clRed;
m_Color[4].c = TColor(RGB(224,224,224));
m_CursorColor = TColor(128,128,128);
m_CursorColor = clBlue;
m_fConvAlpha = FALSE;
m_fShowCtrlCode = FALSE;
m_CursorType = csCARET;
m_Cursor = 0;
m_fActive = FALSE;
m_CRCount = 0;
m_MouseWheelCount = 0;
m_fRTTY = FALSE;
m_ScreenXW = m_ScreenYW = 0;
memset(&m_LogFont, 0, sizeof(m_LogFont));
}
//---------------------------------------------------------------------------
__fastcall CDump::~CDump()
{
DeleteStg();
}
//---------------------------------------------------------------------------
void __fastcall CDump::DeleteStg(void)
{
if( m_pBase ){
int i;
for( i = 0; i < m_StgLineMax; i++ ){
delete m_pBase[i];
}
delete m_pBase;
m_pBase = NULL;
}
}
//---------------------------------------------------------------------------
void __fastcall CDump::Create(HWND hWnd, TPanel *pPanel, TPaintBox *pPaintBox, TFont *pFont, TScrollBar *pBar, int line)
{
m_hWnd = hWnd;
m_pPanel = pPanel;
m_pPaintBox = pPaintBox;
m_pFont = pFont;
m_pScrollBar = pBar;
m_pCanvas = pPaintBox->Canvas;
m_ScreenYW = pPaintBox->Height;
m_ScreenXW = pPaintBox->Width;
m_rcScreen.Left = 0;
m_rcScreen.Top = 0;
m_rcScreen.Right = m_ScreenXW;
m_rcScreen.Bottom = m_ScreenYW;
if( !m_pBase || (m_StgLineMax != line) ){
DeleteStg();
m_pBase = new int *[line];
for( int i = 0; i < line; i++ ){
int *ip = new int[DUMPCOLMAX+1];
memset(ip, 0, sizeof(int)*(DUMPCOLMAX+1));
m_pBase[i] = ip;
}
}
m_StgLineMax = line;
m_fLastCP = TRUE;
m_MLine = m_WLine = m_WCol = m_DTop = 0;
m_MCol = m_RLine = m_RCol = 0;
m_X = m_Y = 0;
m_RX = m_RY = 0;
m_fKanji = FALSE;
m_fWindow = TRUE;
m_fCR = FALSE;
m_CRCount = 0;
m_fSelText = FALSE;
m_fSelect = FALSE;
m_SLine = m_SCol = 0;
m_FLine = 0;
m_pCanvas->Font = pFont;
m_FontXW = m_pCanvas->TextWidth("W");
m_FontYW = m_pCanvas->TextHeight("|");
if( !m_FontXW ) m_FontXW = 8;
if( !m_FontYW ) m_FontYW = 8;
m_ScreenLXW = LXW(m_ScreenXW);
m_ScreenLineMax = m_ScreenYW / m_FontYW;
if( m_ScreenLineMax >= m_StgLineMax ) m_ScreenLineMax = m_StgLineMax - 1;
GetLogFont(&m_LogFont, pFont);
SetScrollBar();
}
//---------------------------------------------------------------------------
void __fastcall CDump::SetFont(TFont *pFont)
{
if( !m_hWnd ) return;
m_pCanvas->Font = pFont;
m_FontXW = m_pCanvas->TextWidth("W");
m_FontYW = m_pCanvas->TextHeight("|");
if( !m_FontXW ) m_FontXW = 8;
if( !m_FontYW ) m_FontYW = 8;
m_ScreenLXW = LXW(m_ScreenXW);
GetLogFont(&m_LogFont, pFont);
Resize();
int *ip = m_pBase[m_WLine];
m_X = 0;
for( ; *ip; ip++ ){
m_X += CharWidth(*ip);
}
ip = m_pBase[m_RLine];
int col = m_RCol;
m_RX = 0;
for( ; *ip && col; ip++, col-- ){
m_RX += CharWidth(*ip);
}
}
//---------------------------------------------------------------------------
void __fastcall CDump::Resize(void)
{
if( !m_hWnd ) return;
Cursor(FALSE);
m_ScreenXW = m_pPaintBox->Width;
m_ScreenYW = m_pPaintBox->Height;
int lmax = m_ScreenYW / m_FontYW;
if( !lmax ) lmax++;
if( lmax >= m_StgLineMax ) lmax = m_StgLineMax - 1;
if( lmax != m_ScreenLineMax ){
m_ScreenLineMax = lmax;
if( m_WLine >= (lmax-1) ){
m_DTop = m_WLine - lmax + 1;
if( m_DTop < 0 ) m_DTop = 0;
}
else {
m_DTop = 0;
}
m_Y = (m_WLine - m_DTop) * m_FontYW;
m_RY = (m_RLine - m_DTop) * m_FontYW;
}
SetScrollBar();
SetCursorPos();
m_fWindow = TRUE;
Cursor(TRUE);
}
//---------------------------------------------------------------------------
void __fastcall CDump::OpenSelect(void)
{
if( !m_fSelect && !m_fSelText ){
m_SLine = m_WLine;
m_SCol = m_WCol;
}
m_fSelect = TRUE;
}
//---------------------------------------------------------------------------
void __fastcall CDump::CloseSelect(void)
{
m_fSelect = FALSE;
}
//---------------------------------------------------------------------------
BOOL __fastcall CDump::ClearSelect(BOOL fPaint)
{
BOOL r = FALSE;
if( m_fSelText ){
r = ClearAllSelect(fPaint);
}
return r;
}
//---------------------------------------------------------------------------
void __fastcall CDump::UpdateSelect(void)
{
if( !m_fSelect ) return;
ClearSelect(FALSE);
int sno = m_SLine * DUMPCOLMAX + m_SCol;
int wno = m_WLine * DUMPCOLMAX + m_WCol;
int *ip;
int i;
int sline, wline, scol, wcol;
if( sno < wno ){
sline = m_SLine; wline = m_WLine;
scol = m_SCol; wcol = m_WCol;
}
else {
sline = m_WLine; wline = m_SLine;
scol = m_WCol; wcol = m_SCol;
}
BOOL f = FALSE;
for( i = sline; i <= wline; i++ ){
ip = m_pBase[i];
int col = 0;
for( ; *ip; ip++, col++ ){
if( (i == sline) && (col < scol) ){
continue;
}
else if( (i == wline) && (col >= wcol) ){
continue;
}
else {
f = TRUE;
*ip |= 0x80000000;
}
}
}
m_fSelText = f;
}
//---------------------------------------------------------------------------
BOOL __fastcall CDump::GetSelText(AnsiString &as)
{
BOOL f = FALSE;
as = "";
if( !m_fSelText ) return f;
int i, c;
int *ip;
for( i = 0; i < m_StgLineMax; i++ ){
ip = m_pBase[i];
for( ; *ip; ip++ ){
if( *ip & 0x80000000 ){
f = TRUE;
c = *ip & 0x0000ffff;
if( c >= 0x8100 ){
as += char(c>>8);
}
as += char(c);
if( c == '\r' ) as += '\n';
}
}
}
return f;
}
//---------------------------------------------------------------------------
BOOL __fastcall CDump::DeleteSelText(void)
{
if( !m_fSelText ) return FALSE;
if( !CanEdit() ) return FALSE;
// if( m_RLine > m_SLine ) return FALSE;
// if( (m_RLine == m_SLine) && (m_RCol >= m_SCol) ) return FALSE;
int i, col;
int *ip;
for( i = 0; i < m_StgLineMax; i++ ){
ip = m_pBase[i];
col = 0;
for( ; *ip; ip++, col++ ){
if( *ip & 0x80000000 ){
m_WLine = i;
m_WCol = col;
int *bp = CreateContP(i, col, 0);
for( ip = bp; *ip; ip++ ){
if( !(*ip & 0x80000000) ) break;
}
CloseContP(i, col, bp, ip - bp);
m_Y = (m_WLine - m_DTop) * m_FontYW;
m_X = 0;
col = 0;
ip = m_pBase[m_WLine];
for( ; *ip && (col < m_WCol); ip++, col++ ){
m_X += CharWidth(*ip);
}
SetCursorPos();
m_fSelText = FALSE;
return TRUE;
}
}
}
m_fSelText = FALSE;
return FALSE;
}
//---------------------------------------------------------------------------
void __fastcall CDump::MoveCursor(int SX, int SY, BOOL fDown)
{
Cursor(FALSE);
BOOL fPaint = ClearSelect(FALSE);
int line = SY/m_FontYW + m_DTop;
if( line > m_MLine ){
if( fPaint ) Paint();
MoveCursor(dmpMoveLAST);
return;
}
int *bp = m_pBase[line];
int *ip = bp;
int x, xw;
int col = 0;
for( x = 0; *ip; ip++ ){
xw = CharWidth(*ip);
if( (x + (xw/2)) >= SX ) break;
x += xw;
col++;
}
if( fDown && !*ip ){
if( fPaint ) Paint();
MoveCursor(dmpMoveLAST);
return;
}
m_WLine = line;
m_WCol = col;
m_X = x;
m_Y = (m_WLine - m_DTop) * m_FontYW;
if( m_fSelect ){
UpdateSelect();
fPaint = TRUE;
}
m_fWindow = (m_WLine >= m_DTop) && (m_WLine < (m_ScreenLineMax + m_DTop));
m_fLastCP = (m_WLine == m_MLine) && (m_WCol == m_MCol);
SetCursorPos();
Cursor(TRUE);
if( fPaint ) Paint();
}
//---------------------------------------------------------------------------
void __fastcall CDump::MoveCursor(int Key)
{
Cursor(FALSE);
switch(Key){
case VK_LEFT:
if( m_WCol ){
m_WCol--;
int *ip = m_pBase[m_WLine] + m_WCol;
int xw = CharWidth(*ip);
m_X -= xw;
}
else if( m_WLine ){
m_WLine--;
m_Y -= m_FontYW;
int *ip = m_pBase[m_WLine];
m_X = 0;
for( ; *ip; ip++ ){
m_X += CharWidth(*ip);
m_WCol++;
}
}
break;
case VK_RIGHT:
{
int *ip = m_pBase[m_WLine] + m_WCol;
if( *ip && ((*ip & 0x0000ffff) != '\r') ){
m_WCol++;
m_X += CharWidth(*ip);
}
else if( m_WLine < m_MLine ){
m_WLine++;
m_Y += m_FontYW;
m_WCol = 0;
m_X = 0;
}
}
break;
case VK_UP:
if( m_WLine ){
m_WLine--;
m_Y -= m_FontYW;
int *ip = m_pBase[m_WLine];
m_WCol = 0;
int x = 0;
for( ; *ip && (x < m_X); ip++ ){
x += CharWidth(*ip);
m_WCol++;
}
m_X = x;
}
break;
case VK_DOWN:
if( m_WLine < m_MLine ){
m_WLine++;
m_Y += m_FontYW;
int *ip = m_pBase[m_WLine];
m_WCol = 0;
int x = 0;
for( ; *ip && (x < m_X); ip++ ){
x += CharWidth(*ip);
m_WCol++;
}
m_X = x;
}
break;
case VK_HOME:
if( m_WLine == m_RLine ){
m_WCol = m_RCol;
m_X = 0;
int *ip = m_pBase[m_WLine];
int col = 0;
for( ; *ip && (col < m_WCol); ip++, col++ ){
m_X += CharWidth(*ip);
}
}
else {
m_WCol = 0;
m_X = 0;
}
break;
case dmpMoveTOP:
case VK_HOME+0x0100:
{
m_WLine = m_RLine;
m_WCol = m_RCol;
m_X = 0;
int *ip = m_pBase[m_WLine];
int col = 0;
for( ; *ip && (col < m_WCol); ip++, col++ ){
m_X += CharWidth(*ip);
}
m_Y = (m_WLine - m_DTop) * m_FontYW;
}
break;
case VK_END:
if( !m_fLastCP ){
int *ip = m_pBase[m_WLine];
m_WCol = 0;
int x = 0;
for( ; *ip; ip++ ){
x += CharWidth(*ip);
m_WCol++;
}
m_X = x;
}
break;
case VK_END + 0x0100:
case dmpMoveLAST:
if( !m_fLastCP ){
m_WLine = m_MLine;
m_Y = (m_WLine - m_DTop) * m_FontYW;
int *ip = m_pBase[m_WLine];
m_WCol = 0;
int x = 0;
for( ; *ip; ip++ ){
x += CharWidth(*ip);
m_WCol++;
}
m_X = x;
}
break;
}
if( m_WCol ){
int *ip = m_pBase[m_WLine] + m_WCol - 1;
if( (*ip & 0x0000ffff) == '\r' ) m_WCol--;
}
BOOL fPaint;
if( m_fSelect ){
UpdateSelect();
fPaint = TRUE;
}
else {
fPaint = ClearSelect(FALSE);
}
if( (m_Y < 0) || (m_WLine < m_DTop) ){
m_DTop = m_WLine;
m_Y = (m_WLine - m_DTop) * m_FontYW;
fPaint = TRUE;
}
else if( (m_Y >= m_ScreenYW) || ((m_WLine - m_DTop) >= (m_ScreenLineMax - 1)) ){
m_DTop = m_WLine - m_ScreenLineMax + 1;
m_Y = (m_WLine - m_DTop) * m_FontYW;
fPaint = TRUE;
}
m_RY = (m_RLine - m_DTop) * m_FontYW;
if( fPaint ) Paint();
SetScrollBar();
m_fLastCP = (m_WLine == m_MLine) && (m_WCol == m_MCol);
SetCursorPos();
Cursor(TRUE);
}
//---------------------------------------------------------------------------
void __fastcall CDump::FollowRP(void)
{
if( m_WLine > m_RLine ) return;
if( m_WLine < m_RLine ){
m_RLine = m_WLine;
m_RCol = m_WCol;
m_RX = m_X;
}
else if( m_WCol < m_RCol ){
m_RCol = m_WCol;
m_RX = m_X;
}
}
//---------------------------------------------------------------------------
void __fastcall CDump::SetBuffer(int c)
{
c &= 0x0000ffff;
LPSTR t = m_Buffer;
if( c == 0x0200 ){
strcpy(t, "(i)"); t += 3;
}
else if( c >= 0x0020 ){
if( c >= 0x8140 ){
*t++ = BYTE(c >> 8);
}
*t++ = BYTE(c);
}
else if( m_fShowCtrlCode && (c != '\r') ){
sprintf(t, "[$%02X]", c); t += strlen(t);
}
*t = 0;
}
int __fastcall CDump::CharWidth(int c)
{
SetBuffer(c);
return m_Buffer[0] ? m_pCanvas->TextWidth(m_Buffer) : 0;
}
int __fastcall CDump::DrawChar(int x, int y, int c, BOOL f)
{
SetBuffer(c);
if( m_Buffer[0] ){
if( f && (x>=0)&&(y>=0)&&(x<m_ScreenXW)&&(y<m_ScreenYW) ){
int col = (c >> 16) & 3;
if( c & 0x80000000 ){
TRect rc;
rc.Left = x; rc.Top = y;
rc.Right = x + m_pCanvas->TextWidth(m_Buffer);
rc.Bottom = y + m_FontYW;
m_pCanvas->Brush->Color = m_Color[col].c;
m_pCanvas->FillRect(rc);
m_pCanvas->Brush->Color = m_fWindow ? m_Color[0].c : m_Color[4].c;
col = 0;
}
m_pCanvas->Font->Color = m_Color[col].c;
::SetBkMode(m_pCanvas->Handle, TRANSPARENT);
m_pCanvas->TextOut(x, y, m_Buffer);
}
x += m_pCanvas->TextWidth(m_Buffer);
}
return x;
}
void __fastcall CDump::MemScroll(void)
{
int i;
int **ip = m_pBase;
int *bp = *ip;
for( i = 0; i < (m_StgLineMax - 1); i++, ip++ ){
*ip = *(ip+1);
}
*ip = bp;
*bp = 0;
if( m_RLine ) m_RLine--;
if( m_FLine ) m_FLine--;
m_SML--;
}
void __fastcall CDump::FlushLogFile(void)
{
if( m_wfp ) fflush(m_wfp);
}
void __fastcall CDump::OpenLogFile(LPCSTR pName)
{
CloseLogFile();
FILE *fp = fopen(pName, "rb");
BOOL f = FALSE;
if( fp ){
fclose(fp);
f = TRUE;
}
m_wfp = fopen(pName, "ab");
if( !m_wfp ){
ErrorMB(sys.m_MsgEng ? "Can not create '%s'":"%s<><73><EFBFBD><EFBFBD>ł<EFBFBD><C582>܂<EFBFBD><DC82><EFBFBD>.", pName);
}
else if( !f ){ // <20><><EFBFBD><EFBFBD><EFBFBD>̃I<CC83>[<5B>v<EFBFBD><76>
for( int i = 0; i < m_WLine; i++ ){
WriteLine(i);
}
}
}
void __fastcall CDump::CloseLogFile(void)
{
if( m_wfp ){
fclose(m_wfp);
m_wfp = NULL;
}
}
void __fastcall CDump::WriteLine(AnsiString &as, int line)
{
int *ip = m_pBase[line];
int c;
for( ; *ip; ip++ ){
c = *ip & 0x0000ffff;
if( c == '\r' ){
as += '\r';
as += '\n';
}
else if( c >= 0x100 ){
as += char(c>>8);
as += char(c);
}
else {
as += char(c);
}
}
}
void __fastcall CDump::WriteLine(int line)
{
if( !m_wfp ) return;
int *ip = m_pBase[line];
int c;
for( ; *ip; ip++ ){
c = *ip & 0x0000ffff;
if( c == '\r' ){
fputc('\r', m_wfp);
fputc('\n', m_wfp);
}
else if( c >= 0x100 ){
fputc(c>>8, m_wfp);
fputc(c&0x00ff, m_wfp);
}
else {
fputc(c, m_wfp);
}
}
}
void __fastcall CDump::PutScroll(void)
{
if( m_wfp ) WriteLine(m_WLine);
m_WCol = 0;
m_X = 0;
m_WLine++;
if( m_WLine >= m_StgLineMax ){
m_WLine--;
MemScroll();
}
if( m_fLastCP ){
m_MLine = m_WLine; m_MCol = m_WCol;
}
m_Y += m_FontYW;
if( m_WLine >= m_ScreenLineMax ){
m_Y -= m_FontYW;
if( m_fWindow ){
m_DTop++;
if( m_DTop >= (m_StgLineMax - m_ScreenLineMax + 1) ){
m_DTop--;
}
m_RY = (m_RLine - m_DTop) * m_FontYW;
Paint();
}
}
SetScrollBar();
}
//---------------------------------------------------------------------------
void __fastcall CDump::SetScrollBar(void)
{
if( !m_pScrollBar ) return;
int max = m_MLine - m_ScreenLineMax + 1;
if( max < 0 ) max = 0;
m_fDisEvent++;
m_pScrollBar->SetParams(m_DTop, 0, max);
m_pScrollBar->Enabled = (m_MLine >= m_ScreenLineMax);
m_fWindow = (m_WLine >= m_DTop) && (m_WLine < (m_ScreenLineMax + m_DTop));
m_fLastCP = (m_WLine == m_MLine) && (m_WCol == m_MCol);
m_fDisEvent--;
}
//---------------------------------------------------------------------------
void __fastcall CDump::OnScrollBarChange(void)
{
if( !m_pScrollBar ) return;
if( m_fDisEvent ) return;
if( m_DTop != m_pScrollBar->Position ){
m_DTop = m_pScrollBar->Position;
m_Y = (m_WLine - m_DTop) * m_FontYW;
m_RY = (m_RLine - m_DTop) * m_FontYW;
m_fWindow = (m_WLine >= m_DTop) && (m_WLine < (m_ScreenLineMax + m_DTop));
m_fLastCP = (m_WLine == m_MLine) && (m_WCol == m_MCol);
Paint();
}
}
//---------------------------------------------------------------------------
void CALLBACK TimeProc(UINT IDEvent, UINT uReserved, DWORD dwUser, DWORD dwReserved1, DWORD dwReserved2)
{
if( !dwUser ) return;
CDump *pDump = (CDump *)dwUser;
pDump->OnTimer();
}
//---------------------------------------------------------------------------
BOOL __fastcall CDump::OnTimer(void)
{
BOOL f = FALSE;
// Application->MainForm->Caption = m_MouseWheelCount;
if( m_MouseWheelCount ){
m_MouseWheelCount -= 3;
if( m_MouseWheelCount > 0 ){
f = TRUE;
}
else {
m_MouseWheelCount = 0;
}
}
return f;
}
//---------------------------------------------------------------------------
BOOL __fastcall CDump::OnMouseWheel(int z)
{
if( !m_pScrollBar ) return FALSE;
if( !m_pScrollBar->Enabled ) return FALSE;
m_MouseWheelCount++;
if( m_MouseWheelCount > 6 ) m_MouseWheelCount = 6;
int div = 120;
if( m_MouseWheelCount >= 6 ){
div = 20;
}
else if( m_MouseWheelCount >= 4 ){
div = 30;
}
else if( m_MouseWheelCount >= 2 ){
div = 60;
}
z /= div;
DoWheel(z);
return TRUE;
}
//---------------------------------------------------------------------------
void __fastcall CDump::DoWheel(int z)
{
while( z ){
if( z > 0 ){
if( m_pScrollBar->Position ){
m_pScrollBar->Position--;
}
else {
break;
}
z--;
}
else {
if( m_pScrollBar->Position < m_pScrollBar->Max ){
m_pScrollBar->Position++;
}
else {
break;
}
z++;
}
}
}
//---------------------------------------------------------------------------
void __fastcall CDump::Clear(void)
{
Cursor(FALSE);
m_fLastCP = TRUE;
m_MLine = m_WLine = m_WCol = m_DTop = 0;
m_MCol = m_RLine = m_RCol = 0;
m_X = m_Y = 0;
m_RX = m_RY = 0;
m_fKanji = FALSE;
m_fWindow = TRUE;
m_fCR = FALSE;
m_CRCount = 0;
m_fSelText = FALSE;
m_fSelect = FALSE;
m_SLine = m_SCol = 0;
for( int i = 0; i < m_StgLineMax; i++ ){
*m_pBase[i] = 0;
}
SetScrollBar();
SetCursorPos();
Paint();
// Invalidate();
}
//---------------------------------------------------------------------------
void __fastcall CDump::DeleteCR2(void)
{
for( int i = 0; i < m_MLine; i++ ){
int *ip = m_pBase[i];
for( ; *ip; ip++ ){
if( ((*ip & 0x0000ffff) == '\r') && (*(ip+1) & 0x0000ffff) ){
int *rp = ip;
for( ; *rp; rp++ ){
*rp = *(rp+1);
}
}
}
}
}
//---------------------------------------------------------------------------
void __fastcall CDump::DeleteChar(BOOL fForce)
{
if( !fForce && !CanEdit() ) return;
if( m_fSelText ){
DeleteSelText();
Invalidate();
return;
}
if( m_fLastCP ) return;
Cursor(FALSE);
int *bp = CreateContP(m_WLine, m_WCol, 0);
CloseContP(m_WLine, m_WCol, bp, 1);
SetScrollBar();
Invalidate();
Cursor(TRUE);
}
//---------------------------------------------------------------------------
BOOL __fastcall CDump::CanEdit(void)
{
if( m_fSelText ){
if( m_RLine > m_SLine ) return FALSE;
if( (m_RLine == m_SLine) && (m_RCol > m_SCol) ) return FALSE;
}
if( m_RLine == m_WLine ){
if( m_RCol <= m_WCol ) return TRUE;
}
else if( m_RLine < m_WLine ){
return TRUE;
}
return FALSE;
}
//---------------------------------------------------------------------------
// <20>A<EFBFBD><41><EFBFBD>f<EFBFBD>[<5B>^<5E><><EFBFBD><EFBFBD><EC90AC><EFBFBD><EFBFBD>
int *__fastcall CDump::CreateContP(int line, int col, int add)
{
int SLine = m_MLine - line + 1;
int *bp = new int[DUMPCOLMAX*SLine + add + 1];
int *wp = bp;
wp += add;
int *ip = m_pBase[line] + col;
while(line <= m_MLine){
while(*ip){
*wp++ = *ip++;
}
line++;
ip = m_pBase[line];
}
*wp = 0;
return bp;
}
//---------------------------------------------------------------------------
void __fastcall CDump::DupeText(int col)
{
if( !m_WLine ) return;
if( !CanEdit() ) return;
int bf[DUMPCOLMAX+1];
memcpy(bf, m_pBase[m_WLine-1], sizeof(int)*DUMPCOLMAX);
int *ip = bf;
for( ; *ip; ip++ ){
PutChar(*ip & 0x0000ffff, col);
}
}
//---------------------------------------------------------------------------
// <20>A<EFBFBD><41><EFBFBD>f<EFBFBD>[<5B>^<5E><><EFBFBD>ݒ肷<DD92><E882B7>
void __fastcall CDump::CloseContP(int line, int col, int *bp, int offset)
{
int cc = 0;
int x = 0;
int *ip = m_pBase[line];
for( ; *ip && (cc < col); ip++, cc++ ){
x += CharWidth(*ip);
}
int *wp = bp + offset;
if( !*bp ) wp = bp;
m_MCol = col;
while(*wp && (line < m_StgLineMax)){
int cc = *wp++;
*ip++ = cc;
m_MCol++;
x += CharWidth(cc);
if( (cc & 0x0000ffff) == '\r' ){
m_MCol = 0;
x = 0;
*ip = 0;
line++;
ip = m_pBase[line];
}
else if( (x >= (m_ScreenXW - 32)) || (((cc&0x0000ffff)==' ') && (x >= m_ScreenLXW)) ){
m_MCol = 0;
x = 0;
*ip = 0;
line++;
ip = m_pBase[line];
}
}
// if( m_MCol ) *ip = 0;
*ip = 0;
delete bp;
m_MLine = line;
if( m_MLine >= m_StgLineMax ) m_MLine = m_StgLineMax - 1;
ip = m_pBase[m_MLine] + m_MCol;
*ip = 0;
if( m_MLine < (m_DTop + m_ScreenLineMax - 1) ){
m_DTop = m_MLine - m_ScreenLineMax + 1;
if( m_DTop < 0 ) m_DTop = 0;
m_Y = (m_WLine - m_DTop) * m_FontYW;
m_RY = (m_RLine - m_DTop) * m_FontYW;
SetCursorPos();
}
m_fLastCP = (m_WLine == m_MLine) && (m_WCol == m_MCol);
}
//---------------------------------------------------------------------------
void __fastcall CDump::InsChar(int c, int col)
{
if( !CanEdit() ) return;
if( m_MLine >= (m_StgLineMax - 1) ){ // <20>P<EFBFBD>s<EFBFBD>̗]<5D>T<EFBFBD><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if( !m_WLine ) return;
MemScroll();
if( m_WLine ) m_WLine--;
if( m_DTop ) m_DTop--;
m_MLine--;
}
int *bp = CreateContP(m_WLine, m_WCol, 1);
*bp = c | (col << 16);
CloseContP(m_WLine, m_WCol, bp, 0);
m_X += CharWidth(c);
m_WCol++;
if( ((c & 0x0000ffff) == '\r') || (m_X >= m_ScreenXW - 32) ){
m_X = 0;
m_WCol = 0;
m_WLine++;
m_Y += m_FontYW;
}
if( (m_Y >= m_ScreenYW) || ((m_WLine - m_DTop) >= m_ScreenLineMax) ){
m_DTop++;
m_Y -= m_FontYW;
m_RY = (m_RLine - m_DTop) * m_FontYW;
}
m_fLastCP = (m_WLine == m_MLine) && (m_WCol == m_MCol);
SetScrollBar();
Invalidate();
}
//---------------------------------------------------------------------------
BOOL __fastcall CDump::PutChar(int c, int col)
{
BOOL r = FALSE;
if( m_pMBCS && m_fConvAlpha ) c = m_pMBCS->ConvAlpha(c);
if( m_fSelText ) ClearSelect(TRUE);
Cursor(FALSE);
if( (c == '\r') || (c == '\n') ){
if( ((c == '\r') || !m_fCR) && (m_CRCount < DUMPCRLIMIT) ){
if( m_fLastCP ){
m_CRCount++;
int *ip = m_pBase[m_WLine] + m_WCol;
*ip++ = ('\r' | (col << 16));
*ip = 0;
PutScroll();
}
else {
InsChar(('\r' | (col << 16)), col);
}
}
m_fCR = (c == '\r') ? TRUE : FALSE;
r = TRUE;
}
else if( c == '\t' ){
m_CRCount = 0;
int ax = m_FontXW*4;
int xx = m_X + ax;
xx = xx - (xx % ax);
while(m_X < xx){
ax = m_X;
PutChar(' ', col);
if( ax >= m_X ) break;
}
m_fCR = FALSE;
r = TRUE;
}
else if( c == '\b' ){
m_CRCount = 0;
r = BackSpace();
m_fCR = FALSE;
}
// else if( (c >= 0x0020) || (m_fShowCtrlCode && c) ){
else if( c ){
m_CRCount = 0;
if( c < 0x0020 ) col = 3;
m_fCR = FALSE;
if( c ){
int *ip = m_pBase[m_WLine] + m_WCol;
c = c | (col << 16);
if( m_fLastCP ){
*ip++ = c;
*ip = 0;
m_X = DrawChar(m_X, m_Y, c, m_fWindow);
m_WCol++;
if( (m_X >= (m_ScreenXW - 32) ) || (m_WCol >= DUMPCOLMAX) ){
PutScroll();
}
else if( ((c & 0xffff) == ' ') && (m_X >= m_ScreenLXW) ){
PutScroll();
}
}
else if( CanEdit() ){
InsChar(c, col);
}
}
r = TRUE;
}
if( m_fLastCP ){
m_MLine = m_WLine; m_MCol = m_WCol;
}
SetCursorPos();
Cursor(TRUE);
return r;
}
//---------------------------------------------------------------------------
BOOL __fastcall CDump::PutKey(char c, int col)
{
BOOL r = FALSE;
int key = BYTE(c);
if( m_fKanji ){
m_fKanji += key;
r = PutChar(m_fKanji, col);
m_fKanji = 0;
}
else if( m_pMBCS ){
if( m_pMBCS->IsLead(c) ){
m_fKanji = key << 8;
}
else {
r = PutChar(key, col);
}
}
else {
if( _mbsbtype((unsigned char *)&key, 0) == _MBC_LEAD ){
m_fKanji = key << 8;
}
else {
r = PutChar(key, col);
}
}
return r;
}
//---------------------------------------------------------------------------
void CDump::PutStatus(int col, LPCSTR pFmt, ...)
{
va_list pp;
char bf[1024];
va_start(pp, pFmt);
vsprintf( bf, pFmt, pp );
va_end(pp);
if( !bf[0] ) return;
if( m_WCol ){
// Cursor(FALSE);
// PutScroll();
PutChar('\r', col);
}
LPCSTR p = bf;
for( ; *p; p++ ){
PutKey(*p, col);
}
}
//---------------------------------------------------------------------------
BOOL __fastcall CDump::BackSpace(void)
{
Cursor(FALSE);
BOOL r = FALSE;
if( m_WCol ){
m_WCol--;
int *ip = m_pBase[m_WLine] + m_WCol;
int xw = CharWidth(*ip);
m_X -= xw;
if( m_fWindow ){
TRect rc;
rc.Left = m_X; rc.Top = m_Y;
rc.Right = m_X + xw; rc.Bottom = m_Y + m_FontYW;
m_pCanvas->Brush->Color = m_Color[0].c;
m_pCanvas->FillRect(rc);
}
if( m_fLastCP ){
*ip = 0;
}
else {
for( ; *ip; ip++ ){
*ip = *(ip+1);
if( !*ip ) break;
}
Invalidate();
}
r = TRUE;
}
else if( m_WLine ){
if( m_fLastCP ){
if( m_CRCount ) m_CRCount--;
m_WLine--;
if( m_WLine >= (m_ScreenLineMax - 1) ){
m_DTop = m_WLine - m_ScreenLineMax + 1;
m_Y = (m_WLine - m_DTop) * m_FontYW;
m_RY = (m_RLine - m_DTop) * m_FontYW;
}
else {
m_Y -= m_FontYW;
}
int *ip = m_pBase[m_WLine];
m_X = 0;
for( ; *ip; ip++ ){
m_X += CharWidth(*ip);
m_WCol++;
}
if( m_WCol ){
ip--;
m_X -= CharWidth(*ip);
m_WCol--;
*ip = 0;
}
Invalidate();
SetScrollBar();
}
else {
MoveCursor(VK_LEFT);
DeleteChar(TRUE);
}
}
SetCursorPos();
FollowRP();
Cursor(TRUE);
return r;
}
//---------------------------------------------------------------------------
void __fastcall CDump::Invalidate(void)
{
if( m_pPaintBox ) m_pPaintBox->Invalidate();
}
//---------------------------------------------------------------------------
void __fastcall CDump::Paint(void)
{
if( !m_hWnd ) return;
Cursor(FALSE);
TColor cBack = m_fWindow ? m_Color[0].c : m_Color[4].c;
if( m_pPanel && (m_Color[0].c != m_Color[4].c) ){
m_pPanel->Color = cBack;
}
m_pCanvas->Brush->Color = cBack;
int i;
for( i = 0; i < m_ScreenLineMax; i++ ){
int n = i + m_DTop;
TRect rc;
rc.Left = 0; rc.Right = m_ScreenXW;
rc.Top = i * m_FontYW;
rc.Bottom = rc.Top + m_FontYW;
m_pCanvas->FillRect(rc);
if( (n <= m_MLine) && (n < m_StgLineMax) ){
int *ip = m_pBase[n];
int x = 0;
while(*ip){
if( (*ip & 0x0000ffff) != '\r' ){
x = DrawChar(x, rc.Top, *ip++, TRUE);
}
else {
ip++;
}
}
}
}
Cursor(TRUE);
}
//---------------------------------------------------------------------------
static int __fastcall GetCharLength(int *ip)
{
int n = 0;
for( ; *ip; ip++ ) n++;
return n;
}
//---------------------------------------------------------------------------
int __fastcall CDump::GetCharCount(BOOL fTX)
{
int line;
int *ip;
if( fTX ){
if( m_WLine < m_RLine ) return 0;
if( m_WLine == m_RLine ) return m_WCol - m_RCol;
line = m_RLine;
ip = m_pBase[line++] + m_RCol;
}
else {
if( !m_WLine ) return m_WCol;
line = 0;
ip = m_pBase[line++];
}
int n = GetCharLength(ip);
while( m_WLine >= line ){
ip = m_pBase[line++];
n += GetCharLength(ip);
}
return n;
}
//---------------------------------------------------------------------------
int __fastcall CDump::GetChar(BOOL fDraw)
{
int r;
if( m_fSelText ){
if( m_RLine > m_SLine ) return -1;
if( (m_RLine == m_SLine) && (m_RCol >= m_SCol) ) return -1;
}
if( (m_WLine > m_RLine) || (m_WCol > m_RCol) ){
int *ip = m_pBase[m_RLine] + m_RCol;
r = *ip;
m_RCol++;
if( !r ){
m_RX = 0;
m_RCol = 0;
m_RLine++;
if( m_RLine >= m_StgLineMax ) m_RLine--;
r = -1;
}
else { // Color change
m_RY = (m_RLine - m_DTop) * m_FontYW;
r &= 0x0000ffff;
*ip = r | (2<<16);
m_RX = DrawChar(m_RX, m_RY, *ip, m_fWindow && fDraw);
}
}
else {
r = -1;
}
return r;
}
//---------------------------------------------------------------------------
int __fastcall CDump::IsWord(void)
{
int r = TRUE;
if( m_fSelText ){
if( m_RLine > m_SLine ) return TRUE;
if( (m_RLine == m_SLine) && (m_RCol >= m_SCol) ) return TRUE;
}
if( m_WLine > m_RLine ){
return TRUE;
}
else if( (m_WLine == m_RLine) || (m_WCol > m_RCol) ){
int *ip = m_pBase[m_RLine] + m_RCol;
r = *ip;
if( !r ){
r = TRUE;
}
else if( (r & 0x0000ff00) == 0x0100 ){
r = TRUE;
}
else {
r = FALSE;
int d;
for( ; *ip; ip++ ){
d = *ip & 0x0000ffff;
if( (d == ' ') || (d == '\r') ) r = TRUE;
}
}
}
return r;
}
//---------------------------------------------------------------------------
int __fastcall CDump::GetCharNB(void)
{
int r;
if( (m_WLine > m_RLine) || (m_WCol > m_RCol) ){
int *ip = m_pBase[m_RLine] + m_RCol;
if( *ip ){
r = *ip & 0x0000ffff;
}
else {
r = -1;
}
}
else {
r = -1;
}
return r;
}
//---------------------------------------------------------------------------
static int __fastcall JisType(int c)
{
if( c <= 0x0100 ){
return 0;
}
else if( c < 0x8140 ){
return -1;
}
else if( c == 0x815b ){ // <20>[
return 3;
}
else if( (c >= 0x8395) && (c <= 0x8396) ){ // <20><>
return 4;
}
else if( (c >= 0x824f) && (c <= 0x8258) ){
return 6; // suuji
}
else if( (c >= 0x829f) && (c <= 0x82f2) ){ // hiragana
return 2;
}
else if( (c >= 0x8340) && (c <= 0x8396) ){ // katakana
return 3;
}
else if( c >= 0x8840 ){ // kanji
return 4;
}
else if( c <= 0x82ff ){
return 5; // kugiri
}
else {
return 1;
}
}
//---------------------------------------------------------------------------
BOOL __fastcall CDump::IsSpace(int c, int ci)
{
c &= 0x0000ffff;
if( c == ' ' ) return TRUE;
if( ci >= 0x8140 ){ // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Shift-JIS<49>̏ꍇ
c = JisType(c);
if( (c == 5)||(c == -1) ) return TRUE;
return (c != JisType(ci));
}
else { // <20><><EFBFBD>񂪉p<F182AA89><70><EFBFBD>̏ꍇ
if( c == '/' ) return FALSE;
if( c >= 0x100 ) return TRUE;
return !isalnum(c);
}
}
//---------------------------------------------------------------------------
BOOL __fastcall CDump::ClearAllSelect(BOOL fPaint)
{
BOOL f = FALSE;
int i;
int *ip;
for( i = 0; i < m_StgLineMax; i++ ){
ip = m_pBase[i];
for( ; *ip; ip++ ){
if( *ip & 0x80000000 ){
f = TRUE;
*ip &= 0x7fffffff;
}
}
}
if( fPaint && f ){
Invalidate();
}
m_fSelText = FALSE;
return f;
}
//---------------------------------------------------------------------------
BOOL __fastcall CDump::GetWindowCallsign(AnsiString &as)
{
AnsiString MyCall = ClipCall(sys.m_CallSign.c_str());
as = "";
int line;
for( line = m_WLine; line >= 0; line-- ){
int *bp = m_pBase[line];
int *ip = bp;
if( (*ip & 0xffff0000)==0x00020000 ){ // <20><><EFBFBD>M<EFBFBD><4D><EFBFBD><EFBFBD>
break;
}
int n = 0;
char bf[256];
for( ; *ip; ip++ ){
int c = *ip & 0x0000fff;
if( (c == ' ') || (c == '\r') ){
bf[n] = 0;
if( (n >= 3) && IsCall(bf) && strcmpi(ClipCall(bf), MyCall.c_str()) ){
jstrupr(bf);
as = bf;
}
n = 0;
}
else if( (c >= 0x100) || (!isalpha(c) && !isdigit(c) && (c != '/')) ){
n = 0;
}
else {
bf[n++] = char(c);
if( n >= 250 ) n = 0;
}
}
if( !as.IsEmpty() ) break;
}
return !as.IsEmpty();
}
//---------------------------------------------------------------------------
BOOL __fastcall CDump::IsWindowText(LPCSTR pText)
{
int line;
for( line = m_WLine; line >= m_FLine; line-- ){
int *bp = m_pBase[line];
int *ip = bp;
if( (*ip & 0xffff0000)==0x00020000 ){ // <20><><EFBFBD>M<EFBFBD><4D><EFBFBD><EFBFBD>
break;
}
AnsiString as;
WriteLine(as, line);
if( strstr(as.c_str(), pText) ) return TRUE;
}
return FALSE;
}
//---------------------------------------------------------------------------
void __fastcall CDump::GetWindowText(AnsiString &as)
{
as = "";
for( int i = 0; i <= m_MLine; i++ ){
WriteLine(as, i);
}
}
//---------------------------------------------------------------------------
int __fastcall CDump::GetWindowText(AnsiString &as, int SX, int SY)
{
m_SMX = SX;
as = "";
int line = SY/m_FontYW + m_DTop;
if( line > m_WLine ) return FALSE;
m_SML = line;
int *bp = m_pBase[line];
int *ip = bp;
int x;
for( x = 0; *ip; ip++ ){
x += CharWidth(*ip);
if( x >= SX ) break;
}
if( !*ip ) return FALSE;
int ci = *ip & 0x0000ffff;
if( m_fRTTY ){
if( ci == ' ' ) return FALSE;
}
else if( m_pFont->Charset != SHIFTJIS_CHARSET ){
if( IsSpace(ci, 'A') ) return FALSE;
}
else if( IsSpace(ci, ci) ){
return FALSE;
}
/* <20>X<EFBFBD>y<EFBFBD>[<5B>X<EFBFBD><58><EFBFBD>T<EFBFBD><54> */
for( ip--; ip >= bp; ip-- ){
if( IsSpace(*ip, ci) ){
ip++;
break;
}
}
if( ip < bp ) ip = bp;
/* <20>X<EFBFBD>y<EFBFBD>[<5B>X<EFBFBD>܂ŃR<C583>s<EFBFBD>[ */
int c;
for( ; *ip; ip++ ){
if( IsSpace(*ip, ci) ) break;
c = *ip & 0x0000ffff;
if( c >= 0x0100 ){
as += char(c>>8);
as += char(c);
}
else {
as += char(c);
}
*ip |= 0x80000000;
}
return (ci > 0x0100) ? JisType(ci)+1 : 1;
}
//---------------------------------------------------------------------------
void __fastcall CDump::SwapLTR(void)
{
if( (m_SML < 0) || (m_SML > m_WLine) ) return;
CRTTY rtty;
int *bp = m_pBase[m_SML];
int *ip = bp;
int x;
for( x = 0; *ip; ip++ ){
x += CharWidth(*ip);
if( x >= m_SMX ) break;
}
if( !*ip ) return;
int ci = *ip & 0x0000ffff;
if( ci == ' ' ) return;
/* <20>X<EFBFBD>y<EFBFBD>[<5B>X<EFBFBD><58><EFBFBD>T<EFBFBD><54> */
for( ip--; ip >= bp; ip-- ){
if( (*ip & 0x0000ffff) == ' ' ){
ip++;
break;
}
}
if( ip < bp ) ip = bp;
/* <20>X<EFBFBD>y<EFBFBD>[<5B>X<EFBFBD>܂ŃR<C583>s<EFBFBD>[ */
int c;
for( ; *ip; ip++ ){
if( (*ip & 0x0000ffff) == ' ' ) break;
c = *ip & 0x0000ffff;
if( (c >= 0x20) && (c <= 0x7f) ){
c = rtty.InvShift(char(c));
*ip = (*ip & 0xffff0000) | c;
}
*ip |= 0x80000000;
}
Invalidate();
}
//---------------------------------------------------------------------------
void __fastcall CDump::SetCursorPos(void)
{
if( !m_fActive ) return;
if( m_CursorType == csCARET ){
SetCaretPos(m_X, m_Y);
SetCompositionWindowPos(FALSE);
}
}
//---------------------------------------------------------------------------
void __fastcall CDump::DrawCursor(int x, int y, int sw)
{
TRect rc;
rc.Left = x; rc.Top = y + m_FontYW - 2;
rc.Right = x + m_FontXW; rc.Bottom = y + m_FontYW;
m_pCanvas->Brush->Color = sw ? m_CursorColor : m_Color[0].c;
m_pCanvas->FillRect(rc);
}
//---------------------------------------------------------------------------
void __fastcall CDump::SetCursorType(int type)
{
Cursor(FALSE);
m_CursorType = type;
Cursor(TRUE);
}
//---------------------------------------------------------------------------
void __fastcall CDump::Cursor(int sw)
{
if( sw && !m_fWindow ) return;
switch(m_CursorType){
case csCARET: // <20>L<EFBFBD><4C><EFBFBD><EFBFBD><EFBFBD>b<EFBFBD>g<EFBFBD><67><EFBFBD>g<EFBFBD><67><EFBFBD><EFBFBD><EFBFBD>J<EFBFBD>[<5B>\<5C><>
if( sw ){
if( !m_fActive ) return;
if( !m_Cursor ){
m_Cursor++;
ShowCaret(m_hWnd);
}
}
else {
if( m_Cursor ){
m_Cursor--;
HideCaret(m_hWnd);
}
}
break;
case csSTATIC: // <20>`<60><><EFBFBD>J<EFBFBD>[<5B>\<5C><>
if( sw ){
DrawCursor(m_X, m_Y, TRUE);
}
else {
DrawCursor(m_X, m_Y, FALSE);
}
}
}
//---------------------------------------------------------------------------
void __fastcall CDump::CreateCaret(void)
{
if( m_fActive ) return;
m_fActive = TRUE;
if( m_CursorType == csCARET ){
::CreateCaret(m_hWnd, 0, 2, m_FontYW);
::SetCaretPos(m_X, m_Y);
::ShowCaret(m_hWnd);
m_Cursor = TRUE;
SetCompositionWindowPos(TRUE);
}
}
//---------------------------------------------------------------------------
void __fastcall CDump::DestroyCaret(void)
{
if( !m_fActive ) return;
m_fActive = FALSE;
if( m_CursorType == csCARET ){
m_Cursor = 0;
::DestroyCaret();
}
}
//---------------------------------------------------------------------------
void __fastcall CDump::SetCompositionWindowPos(BOOL fFont)
{
if( !m_fActive ) return;
HIMC hIMC;
COMPOSITIONFORM Composition;
if( (hIMC = ::ImmGetContext(m_hWnd))!=NULL ){
if( fFont ){
::ImmSetCompositionFont(hIMC, &m_LogFont);
}
Composition.dwStyle = CFS_POINT;
Composition.ptCurrentPos.x = m_X;
Composition.ptCurrentPos.y = m_Y;
::ImmSetCompositionWindow(hIMC, &Composition);
::ImmReleaseContext(m_hWnd, hIMC);
}
}
//---------------------------------------------------------------------------
void __fastcall CDump::ShowCtrl(BOOL f)
{
m_fShowCtrlCode = f;
if( m_pPaintBox ) m_pPaintBox->Invalidate();
}
#pragma package(smart_init)