📄 cimeex.cpp
字号:
#include "stdafx.h"
#include "cIMEex.h"
#include "./interface/cFont.h"
#include "./interface/cEditbox.h"
cIMEex::cIMEex()
{
m_wFontIdx = 0;
m_pStrBuf = NULL;
m_pLineDesc = NULL;
m_InsertPos.nLine = 0;
m_InsertPos.nIndex = 0;
m_nCurTotalLen = 0;
m_nCurTotalLine = 1;
m_nMaxTotalLen = 128; //ÀÓÀÇ·Î
m_nMaxTotalLine = 1;
m_bCompositing = FALSE;
m_bMultiLine = FALSE;
m_bEnterAllow = TRUE;
m_nLimitWidth = 1024; //È¸éÆøÀ¸·Î ±³Ã¼
m_pParentEdit = NULL;
SetValidCheckMethod( VCM_DEFAULT );
}
cIMEex::~cIMEex()
{
}
void cIMEex::Init( int nMaxBufSize, int nPixelWidth, BOOL bMultiLine, int nMaxLine )
{
m_nMaxTotalLen = nMaxBufSize;
m_nLimitWidth = nPixelWidth;
m_bMultiLine = bMultiLine;
if( m_bMultiLine )
{
m_nMaxTotalLine = nMaxLine;
}
else
{
m_nMaxTotalLine = 1;
}
m_bChanged = FALSE;
m_pStrBuf = new char[nMaxBufSize+1];
ZeroMemory( m_pStrBuf, nMaxBufSize+1 );
m_pLineDesc = new sLineDesc[MAX_LINE]; //·¡ÇÎÇÒ ÇÑÄ ´õ...
ZeroMemory( m_pLineDesc, MAX_LINE * sizeof(sLineDesc) );
SetValidCheckMethod( VCM_DEFAULT );
}
void cIMEex::Release()
{
if( m_pStrBuf )
{
delete[] m_pStrBuf;
m_pStrBuf = NULL;
}
if( m_pLineDesc )
{
delete[] m_pLineDesc;
m_pLineDesc = NULL;
}
}
BOOL cIMEex::Insert( char* str ) //Çѹ®ÀÚÀÇ °æ¿ì
{
m_bChanged = TRUE;
if( m_bCompositing )
DeleteBefore();
int nLen = strlen( str );
if( nLen == 0 ) return FALSE;
if( m_nCurTotalLen + nLen > m_nMaxTotalLen )
return FALSE;
int nInsertIndex = GetInsertIndex();
char* p = GetInsertBufPtr();
memmove( p + nLen, p, m_nCurTotalLen - nInsertIndex );
m_nCurTotalLen += nLen;
memcpy( p, str, nLen );
m_InsertPos.nIndex += nLen;
m_pLineDesc[m_InsertPos.nLine].nLen += nLen;
for( int i = m_InsertPos.nLine + 1 ; i < m_nCurTotalLine ; ++ i )
{
m_pLineDesc[i].nStartIndex += nLen;
}
if( !Wrap( m_InsertPos.nLine ) )
{
DeleteBefore();
return FALSE;
}
return TRUE;
}
BOOL cIMEex::Wrap( int nStartLine )
{
if( m_bMultiLine == FALSE ) return TRUE;
LONG lExtent = CFONT_OBJ->GetTextExtentEx( m_wFontIdx,
m_pStrBuf + m_pLineDesc[nStartLine].nStartIndex,
m_pLineDesc[nStartLine].nLen );
int nWrapNum = 0;
int nStartIndex = m_pLineDesc[nStartLine].nStartIndex;
int nWrapIndex = m_pLineDesc[nStartLine].nLen;
char* p;
int nMoveNum;
////////////////////////
// ±ÛÀÚ°¡ ÆøÀ» ³Ñ¾î°¥ ¶§
if( lExtent > m_nLimitWidth )
{
// if( m_bMultiLine == FALSE || m_nCurTotalLine >= m_nMaxTotalLine )
if( m_bMultiLine == FALSE || m_nCurTotalLine > m_nMaxTotalLine )
return FALSE; //·¡ÇÎ ÇÒ¼ö ¾ø´Ù.
while( lExtent > m_nLimitWidth ) //·¡ÇÎÇÒ ±ÛÀÚ ¼ö¸¦ Á¤ÇÑ´Ù.
{
p = m_pStrBuf + nStartIndex + nWrapIndex;
// nMoveNum = IsDBCSLeadByte( *(p-1) ) ? 2 : 1;
nMoveNum = IsDBCSLeadByte( *CharPrev( m_pStrBuf, p ) ) ? 2 : 1;
nWrapNum += nMoveNum;
nWrapIndex -= nMoveNum;
if( m_InsertPos.nIndex > nWrapIndex )
{
m_InsertPos.nIndex = nWrapNum;
++m_InsertPos.nLine;
}
lExtent = CFONT_OBJ->GetTextExtentEx( m_wFontIdx,
m_pStrBuf + m_pLineDesc[nStartLine].nStartIndex,
nWrapIndex );
}
if( m_pLineDesc[nStartLine].nEndKind != EK_WRAP )
{
//¶óÀÎ »ðÀÔÇÏ°í ¼¼ÆÃ
for( int i = m_nCurTotalLine ; i > nStartLine ; --i )
{
m_pLineDesc[i] = m_pLineDesc[i-1];
}
m_pLineDesc[nStartLine].nLen -= nWrapNum;
m_pLineDesc[nStartLine].nEndKind = EK_WRAP;
m_pLineDesc[nStartLine+1].nStartIndex = nStartIndex + nWrapIndex ;
m_pLineDesc[nStartLine+1].nLen = nWrapNum;
m_nCurTotalLine++;
return TRUE;
}
else
{
m_pLineDesc[nStartLine].nLen -= nWrapNum;
m_pLineDesc[nStartLine+1].nStartIndex -= nWrapNum;
m_pLineDesc[nStartLine+1].nLen += nWrapNum;
return Wrap( nStartLine + 1 );
//´Ù½Ã ·¡ÇνÃÀÛ.
}
}
////////////////////////
// ±ÛÀÚ°¡ Æøº¸´Ù ÀÛÀ» ¶§
else
{
if( m_pLineDesc[nStartLine].nEndKind != EK_WRAP )
return TRUE; //·¡ÇÎÇÒ ÇÊ¿ä¾ø´Ù
while( 1 ) //ÇÑľ¿ ¾ÕÀ¸·Î °¡º¸±â
{
if( m_pLineDesc[nStartLine+1].nLen <= -nWrapNum ) //±×ÁÙÀÇ ´ÙÀ½±îÁö¸¸.
break;
p = m_pStrBuf + nStartIndex + nWrapIndex;
nMoveNum = IsDBCSLeadByte( *p ) ? 2 : 1;
nWrapNum -= nMoveNum;
nWrapIndex += nMoveNum;
lExtent = CFONT_OBJ->GetTextExtentEx( m_wFontIdx,
m_pStrBuf + m_pLineDesc[nStartLine].nStartIndex,
nWrapIndex );
if( lExtent > m_nLimitWidth )
{
nWrapNum += nMoveNum;
nWrapIndex -= nMoveNum;
break;
}
}
if( nWrapNum == 0 ) return TRUE;
m_pLineDesc[nStartLine].nLen -= nWrapNum;
m_pLineDesc[nStartLine+1].nStartIndex -= nWrapNum;
m_pLineDesc[nStartLine+1].nLen += nWrapNum;
if( m_pLineDesc[nStartLine+1].nLen <=0 ) //³¡ÀÌ ·¦ÇÎÀϸ®°¡ ¾ø´Ù?
{
--m_nCurTotalLine;
m_pLineDesc[nStartLine].nEndKind = m_pLineDesc[nStartLine+1].nEndKind;
for( int i = nStartLine+1 ; i < m_nCurTotalLine ; ++i )
{
m_pLineDesc[i] = m_pLineDesc[i+1];
}
return TRUE;
}
return Wrap( nStartLine + 1 );
}
}
//ÇöÀç ¶óÀÎÀÇ ³¡À» Enter¼Ó¼ºÀ» ÁÖ°í ´ÙÀ½ ¶óÀÎÀ» Ãß°¡ÇÑ´Ù.(À¯Àú°¡ ¿£Å͸¦ ´·¶À»¶§)
BOOL cIMEex::Enter()
{
if( m_bEnterAllow == FALSE ) return FALSE;
m_bChanged = TRUE;
if( m_bMultiLine == FALSE || m_nMaxTotalLine <= m_nCurTotalLine ) return FALSE;
int nBreakLen = m_pLineDesc[m_InsertPos.nLine].nLen - m_InsertPos.nIndex;
int nStartIndex = m_pLineDesc[m_InsertPos.nLine].nStartIndex + m_InsertPos.nIndex;
m_pLineDesc[m_InsertPos.nLine].nLen = m_InsertPos.nIndex;
m_pLineDesc[m_InsertPos.nLine].nEndKind = EK_ENTER;
m_InsertPos.nIndex = 0;
++m_InsertPos.nLine;
for( int i = m_nCurTotalLine ; i >= m_InsertPos.nLine ; --i )
{
m_pLineDesc[i] = m_pLineDesc[i-1];
}
m_pLineDesc[m_InsertPos.nLine].nLen = nBreakLen;
m_pLineDesc[m_InsertPos.nLine].nStartIndex = nStartIndex;
++m_nCurTotalLine;
return TRUE;
}
BOOL cIMEex::CaretMoveLeft()
{
m_bChanged = TRUE;
int nInsertIndex = GetInsertIndex();
if( nInsertIndex <= 0 ) return FALSE;
if( m_InsertPos.nIndex <= 0 ) //Á¦ÀÏ ¾ÕÀ̸é ÀüÁÙ ¸ÇµÚ·Î À̵¿
{
--m_InsertPos.nLine;
m_InsertPos.nIndex = m_pLineDesc[m_InsertPos.nLine].nLen;
if( m_pLineDesc[m_InsertPos.nLine].nEndKind == EK_WRAP )
CaretMoveLeft();
}
else
{
char* p = GetInsertBufPtr();
// int nMoveNum = IsDBCSLeadByte( *(p-1) ) ? 2 : 1;
int nMoveNum = IsDBCSLeadByte( *CharPrev( m_pStrBuf, p ) ) ? 2 : 1;
m_InsertPos.nIndex -= nMoveNum;
}
return TRUE;
}
BOOL cIMEex::CaretMoveRight()
{
m_bChanged = TRUE;
int nInsertIndex = GetInsertIndex();
if( nInsertIndex >= m_nCurTotalLen ) return FALSE;
if( m_InsertPos.nIndex >= m_pLineDesc[m_InsertPos.nLine].nLen ) //Á¦ÀÏ µÚ¸é ´ÙÀ½ÁÙ ¸Ç¾ÕÀ¸·Î À̵¿
{
++m_InsertPos.nLine;
m_InsertPos.nIndex = 0;
if( m_pLineDesc[m_InsertPos.nLine].nEndKind == EK_WRAP )
CaretMoveRight();
}
else
{
char* p = GetInsertBufPtr();
int nMoveNum = IsDBCSLeadByte( *p ) ? 2 : 1;
m_InsertPos.nIndex += nMoveNum;
}
return TRUE;
}
//±ÛÀÚ ÆøÀ» °è»êÇÏ¿© Up Down...À¸·Î ¹Ù²Ù±â
BOOL cIMEex::CaretMoveUp()
{
m_bChanged = TRUE;
if( m_InsertPos.nLine <= 0 ) return FALSE;
--m_InsertPos.nLine;
if( m_InsertPos.nIndex >= m_pLineDesc[m_InsertPos.nLine].nLen )
{
m_InsertPos.nIndex = m_pLineDesc[m_InsertPos.nLine].nLen;
}
else if( m_InsertPos.nIndex != 0 ) //¸Ç¾ÕÀÌ ¾Æ´Ò¶§
{
char* p = GetInsertBufPtr();
// if( IsDBCSLeadByte( *p ) && IsDBCSLeadByte( *(p-1) ) ) //ÇѱÛÁß°£
if( p != CharNext( CharPrev( m_pStrBuf, p ) ) )
{
--m_InsertPos.nIndex;
}
}
return TRUE;
}
BOOL cIMEex::CaretMoveDown()
{
m_bChanged = TRUE;
if( m_InsertPos.nLine >= m_nCurTotalLine - 1 ) return FALSE;
++m_InsertPos.nLine;
if( m_InsertPos.nIndex >= m_pLineDesc[m_InsertPos.nLine].nLen )
{
m_InsertPos.nIndex = m_pLineDesc[m_InsertPos.nLine].nLen;
}
else if( m_InsertPos.nIndex != 0 ) //¸Ç¾ÕÀÌ ¾Æ´Ò¶§
{
char* p = GetInsertBufPtr();
// if( IsDBCSLeadByte( *p ) && IsDBCSLeadByte( *(p-1) ) ) //ÇѱÛÁß°£
if( p != CharNext( CharPrev( m_pStrBuf, p ) ) )
{
--m_InsertPos.nIndex;
}
}
return TRUE;
}
BOOL cIMEex::CaretMoveHome()
{
m_bChanged = TRUE;
m_InsertPos.nIndex = 0;
return TRUE;
}
BOOL cIMEex::CaretMoveEnd()
{
m_bChanged = TRUE;
m_InsertPos.nIndex = m_pLineDesc[m_InsertPos.nLine].nLen;
return TRUE;
}
BOOL cIMEex::CaretMoveFirst()
{
m_bChanged = TRUE; //for scroll and so on
m_InsertPos.nIndex = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -