📄 edit.c
字号:
/******************************************************************************
*
* Copyright 2006 National ASIC Center, All right Reserved
*
* FILE NAME: Edit.c
* PROGRAMMER: ming.c
* Date of Creation: 2006/08/8
*
* DESCRIPTION:
* Single Line Editor
* NOTE:
*
* FUNCTIONS LIST:
* -----------------------------------------------------------------------------
*
* -----------------------------------------------------------------------------
*
* MODIFICATION HISTORY
* LastModify 2006/10/30
******************************************************************************/
#include "mingui.h"
//---------------------------------------------------------------------------
#define MARGIN_EDIT_LEFT 3
#define MARGIN_EDIT_RIGHT 3
#define SEDIT_COL_SPACE 1
#define CARET_HEIGHT_OVERLAP 1
#define LEN_SLEDIT_BUFFER 128
typedef struct tagSLEDITDATA
{ int bufferLen; /* length of buffer */
int dataEnd; /* data end position */
int editPos; /* current edit position */
int startPos; /* start display position */
int passwdChar; /* password character */
TRECT textArea; /* text display area */
int colspace;
int caretheight;
int caretx,carety;
int hardLimit; /* hard limit */
char *buffer; /* buffer */
} SLEDITDATA, *PSLEDITDATA;
#define GetSysCharHeight(hWnd) SYS_FONT_HEIGHT
#define GetSysCharWidth(hWnd) SYS_FONT_WIDTH
#define GetSysCCharWidth(hWnd) (2*GetSysCharWidth(hWnd))
#define EdtIsACCharBeforePosition(pstr,pos) ( (pos)>1 && *((BYTE *)(pstr)+pos-1)>0xA0 && *((BYTE *)(pstr)+pos-2)>0xA0 )
#define EdtIsACCharAtPosition(pstr,pos) ( *((BYTE *)(pstr)+pos)>0xA0 && *((BYTE *)(pstr)+pos+1)>0xA0 )
#define EditGetOutWidth(sEdtInfo) ( sEdtInfo->textArea.right - sEdtInfo->textArea.left )
static int EdtGetStartDispPosAtEnd(const HWND pCtrl, PSLEDITDATA pSLEditData,int *textwidth)
{ if( pSLEditData->dataEnd>0 )
{ int w,chars,nTextWidth=0;
int nOutWidth = EditGetOutWidth(pSLEditData);
int pos=pSLEditData->dataEnd;
const char* buffer = pSLEditData->buffer;
while(pos>=0)
{ if ((BYTE)buffer[pos-1] > 0xA0)
{ w=GetSysCCharWidth(pCtrl)+pSLEditData->colspace;
chars=2;
}
else
{ w=GetSysCharWidth(pCtrl)+pSLEditData->colspace;
chars=1;
}
if(nTextWidth+w > nOutWidth) break;
else {nTextWidth+=w;pos-=chars;}
}
*textwidth=nTextWidth;
return (pos>=0)?pos:0;
}
else
{ *textwidth=0;
return 0;
}
}
static int EdtGetDispLen (const HWND pCtrl)
{ int w,chars,nTextWidth=0;
PSLEDITDATA pSLEditData = (SLEDITDATA *)WndClsBuf(pCtrl);
int nOutWidth = EditGetOutWidth(pSLEditData);
int pos=pSLEditData->startPos;
const char* buffer = pSLEditData->buffer;
while(pos < pSLEditData->dataEnd)
{ if ((BYTE)buffer[pos] > 0xA0) /* st:gb:a1-f7,big5:a1-f9 */
{ w=GetSysCCharWidth(pCtrl);
chars=2;
}
else
{ w=GetSysCharWidth (pCtrl);
chars=1;
}
if(nTextWidth+w > nOutWidth) break;
else {nTextWidth+=(w+pSLEditData->colspace);pos+=chars;}
}
return pos-pSLEditData->startPos;
}
static int Edit_LocateCarret(const HWND pCtrl,int *x)
{ int w,chars,pos,x1,x2;
PSLEDITDATA pSLEditData = (SLEDITDATA *)WndClsBuf(pCtrl);
char* buffer;
if(*x<=pSLEditData->textArea.left)
{ *x=pSLEditData->textArea.left;
return pSLEditData->startPos;
}
else
{ x2=(*x < pSLEditData->textArea.right)? *x : pSLEditData->textArea.right;
x1=pSLEditData->textArea.left;
pos=pSLEditData->startPos;
buffer = pSLEditData->buffer;
}
while(pos < pSLEditData->dataEnd)
{ if ((BYTE)buffer[pos] > 0xA0) /* st:gb:a1-f7,big5:a1-f9 */
{ w=GetSysCCharWidth(pCtrl);
chars=2;
}
else
{ w=GetSysCharWidth (pCtrl);
chars=1;
}
if(x1+w > x2) break;
else {x1+=(w+pSLEditData->colspace);pos+=chars;}
}
*x=x1;
return pos;
}
void SLEdit_OnCreate(HWND hWnd)
{ int VerMargin=(crHeight(hWnd) - SYS_FONT_HEIGHT)/2;
PSLEDITDATA pSLEditData=(SLEDITDATA *)WndClsBuf(hWnd);
pSLEditData->bufferLen = LEN_SLEDIT_BUFFER;
pSLEditData->editPos = 0;
pSLEditData->startPos = 0;
pSLEditData->colspace = SEDIT_COL_SPACE;
pSLEditData->passwdChar = '*';
pSLEditData->textArea.top = ( crHeight(hWnd) - SYS_FONT_HEIGHT )/2;
pSLEditData->textArea.bottom = crHeight(hWnd) - pSLEditData->textArea.top;
pSLEditData->textArea.left = MARGIN_EDIT_LEFT;
pSLEditData->textArea.right = crWidth(hWnd) - MARGIN_EDIT_RIGHT;
pSLEditData->caretheight = GetSysCharHeight(hWnd)+CARET_HEIGHT_OVERLAP+CARET_HEIGHT_OVERLAP;
pSLEditData->carety = pSLEditData->textArea.top;
pSLEditData->caretx= pSLEditData->textArea.left;
pSLEditData->hardLimit = -1;
pSLEditData->buffer = WndGetText(hWnd);
pSLEditData->dataEnd = strlen(pSLEditData->buffer);
}
void SLEdit_Repaint(HWND hWnd)
{ int dispLen;
PSLEDITDATA pSLEditData=(SLEDITDATA *)WndClsBuf(hWnd);
HDC hdc=BeginPaint(hWnd);
SetColSpace(hdc,pSLEditData->colspace);
dispLen = EdtGetDispLen (hWnd);
if (dispLen > 0)
{ char *dispBuffer,botsave;
if (WndGetAttr(hWnd,ES_PASSWORD))
{ dispBuffer = (char *)GetMem(dispLen + 1);
memset (dispBuffer, '*', dispLen);
}
else
{ dispBuffer=pSLEditData->buffer + pSLEditData->startPos;
botsave=dispBuffer[dispLen];
}
dispBuffer [dispLen] = '\0';
((TWndCanvas *)hdc)->Mode |= FS_PLAIN;
if(WndGetAttr(hWnd,WS_DISABLED)) SetColor (hdc, CL_DARKGRAY);
else ((TWndCanvas *)hdc)->Foreground = WNDPTR(hWnd)->Foreground;
TextOut(hdc, pSLEditData->textArea.left, pSLEditData->textArea.top, dispBuffer);
if (WndGetAttr(hWnd,ES_PASSWORD))
{ FreeMem(dispBuffer);
}
else
{ dispBuffer[dispLen]=botsave;
}
}
EndPaint(hWnd);
}
void SLEdit_GetChar(HWND hWnd,BYTE LowByte,BYTE HighByte,int KeyDecodeDepth)
{ PSLEDITDATA pSLEditData= (SLEDITDATA *)WndClsBuf(hWnd);
int i, chars, inserting,newcaretx,scrollStep=0;
if (HighByte)
{ chars = 2;
}
else
{ if(LowByte<32) return;
chars = 1;
}
HideCaret(hWnd);
newcaretx=pSLEditData->caretx;
if(KeyDecodeDepth>1)
{ /*这里改变插入位置到前一个字符*/
if(pSLEditData->caretx<=pSLEditData->textArea.left)return;
pSLEditData->caretx -= (GetSysCharWidth(hWnd)+pSLEditData->colspace);
pSLEditData->editPos--;
}
if (WndGetAttr(hWnd,ES_REPLACE) || KeyDecodeDepth>1)
{ if (pSLEditData->dataEnd == pSLEditData->editPos)
{ inserting = chars;
}
else if (EdtIsACCharAtPosition(pSLEditData->buffer, pSLEditData->editPos))
{ inserting = (chars==2)? 0 : -1;
}
else
{ inserting = (chars==2)? 1 : 0;
}
}
else
{ inserting = chars;
}
// check space
if (pSLEditData->dataEnd + inserting > pSLEditData->bufferLen)
{ // Ping ();
CMD_NotifyParent(hWnd,EN_MAXTEXT);
return;
}
else if ((pSLEditData->hardLimit >= 0) && ((pSLEditData->dataEnd + inserting) > pSLEditData->hardLimit))
{ // Ping ();
CMD_NotifyParent(hWnd,EN_MAXTEXT);
return;
}
if (inserting == -1)
{ for (i = pSLEditData->editPos; i < pSLEditData->dataEnd-1; i++)
{ pSLEditData->buffer [i] = pSLEditData->buffer [i + 1];
}
}
else if (inserting > 0)
{ for (i = pSLEditData->dataEnd + inserting - 1; i > pSLEditData->editPos + inserting - 1; i--)
{ pSLEditData->buffer [i] = pSLEditData->buffer [i - inserting];
}
}
pSLEditData->buffer[pSLEditData->editPos] = LowByte;
if(HighByte)pSLEditData->buffer [pSLEditData->editPos+1] = HighByte;
if(inserting)
{ pSLEditData->dataEnd += inserting;
pSLEditData->buffer [pSLEditData->dataEnd] = '\0';
}
if(KeyDecodeDepth<=1) /*非键盘译码状态,输入字符后要改变光标位置*/
{ newcaretx += (chars*GetSysCharWidth(hWnd)+pSLEditData->colspace);
if (newcaretx > pSLEditData->textArea.right)
{ if (EdtIsACCharAtPosition(pSLEditData->buffer, pSLEditData->startPos))
{ scrollStep = 2;
newcaretx -= (2*GetSysCharWidth(hWnd)+pSLEditData->colspace);
}
else
{ if (HighByte)
{ if (EdtIsACCharAtPosition(pSLEditData->buffer, pSLEditData->startPos + 1))
{ scrollStep = 3;
newcaretx -= (3*GetSysCharWidth(hWnd)+2*pSLEditData->colspace);
}
else
{ scrollStep = 2;
newcaretx -= ((GetSysCharWidth(hWnd)+pSLEditData->colspace)<<1);
}
}
else
{ scrollStep = 1;
newcaretx -= (GetSysCharWidth(hWnd)+pSLEditData->colspace);
}
}
pSLEditData->startPos += scrollStep;
InvalidateClient(hWnd, &pSLEditData->textArea);
}
}
if(!scrollStep)
{ if(inserting)
{ TRECT InvRect=pSLEditData->textArea;
InvRect.left = pSLEditData->caretx;
InvalidateClient(hWnd, &InvRect);
}
else if(!WndGetAttr(hWnd,ES_PASSWORD))
{ char dummybottom;
int tw=chars*GetSysCharWidth(hWnd),th=GetSysCharHeight(hWnd);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -