📄 memo.c
字号:
/******************************************************************************
*
* Copyright 2006 National ASIC Center, All right Reserved
*
* FILE NAME: Memo.c
* PROGRAMMER: ming.c
* Date of Creation: 2006/08/8
*
* DESCRIPTION:
* Single Line Editor
* NOTE:
*
* FUNCTIONS LIST:
* -----------------------------------------------------------------------------
*
* -----------------------------------------------------------------------------
*
* MODIFICATION HISTORY
* LastModify 2008/05/20
******************************************************************************/
#include "mingui.h"
//---------------------------------------------------------------------------
#define MARGIN_EDIT_LEFT 3
#define MARGIN_EDIT_TOP 3
#define MARGIN_EDIT_RIGHT 2
#define MARGIN_EDIT_BOTTOM 3
#define CARET_HEIGHT_OVERLAP 1
#define MEDIT_COL_SPACE 1
#define MEDIT_ROW_SPACE 2
#define LEN_MLEDIT_BUFFER 512
//---------------------------------------------------------------------------
typedef struct tag_multiedit
{ TRECT textArea;
int editPos; /* current edit position */
int startPos; /* start display position */
int pageTopLine; /* 编缉框中可见的第一行对应于整个文全的行号*/
int caretx,carety,caretheight;
int colspace,rowspace;
int bufferLen; /* length of buffer */
int dataEnd; /* data end position */
int hardLimit; /* hard limit */
char *buffer; /* buffer */
}TMultiEdit;
#define GetSysCharHeight(hWnd) SYS_FONT_HEIGHT
#define GetSysCharWidth(hWnd) SYS_FONT_WIDTH
#define GetSysCCharWidth(hWnd) (2*GetSysCharWidth(hWnd))
#define GetLineIndexByCarret(hWnd,pMLEditData) ( (pMLEditData->carety<=pMLEditData->textArea.top)?pMLEditData->pageTopLine:pMLEditData->pageTopLine + (pMLEditData->carety-pMLEditData->rowspace-pMLEditData->textArea.top)/GetSysCharHeight(hWnd) )
/* 1st:gb:a1-f7,big5:a1-f9 2nd:gb:a1-fe,big5:40-7e,a1-fe */
#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 )
//---------------------------------------------------------------------------
// box、startpos的坐标都是相对dc的坐标。
#define TB_ERASEBKGND 0x01 /*bit0: 是不擦除背景*/
#define TB_DRAWTEXT 0x02 /* bit1:是否写字*/
#define TB_MEASURE 0x04 /*bit2:是否返回画笔结束位置到startpos*/
static void TextBox(HDC dc,TRECT *box,TPOINT *startpos,LPCSTR lptext,int mode)
{ BYTE ch;
int disptext,hanzi_mached,linecount,hzkoffset,EndPosX,EndPosY,PenPosX,PenPosY,colspace,rowspace;
if(!lptext || !*lptext) return;
disptext=mode&TB_DRAWTEXT;
hanzi_mached=false;
colspace=GetColSpace(dc);
rowspace=GetRowSpace(dc);
PenPosX=startpos->x,PenPosY=startpos->y;
if(disptext) GroupOn(dc);
if(mode&TB_ERASEBKGND)
{ TPOINT endpos=*startpos;
TextBox(dc,box,&endpos,lptext,TB_MEASURE);
linecount=(endpos.y-startpos->y+rowspace)/(SYS_FONT_HEIGHT+rowspace);
if(linecount==1)
{ EraseBackground(dc,startpos->x,startpos->y,endpos.x-startpos->x,SYS_FONT_HEIGHT);
}
else if(linecount>=2)
{ EraseBackground(dc,startpos->x,startpos->y,box->right-startpos->x,SYS_FONT_HEIGHT);
if(linecount>2)
{ EraseBackground(dc,box->left,startpos->y+SYS_FONT_HEIGHT,box->right-box->left,endpos.y-startpos->y-SYS_FONT_HEIGHT-SYS_FONT_HEIGHT);
}
EraseBackground(dc,box->left,endpos.y-SYS_FONT_HEIGHT,endpos.x-box->left,SYS_FONT_HEIGHT);
}
}
while (1)
{ ch=*lptext++;
if(ch>0xa0)
{ if(hanzi_mached)
{ if(PenPosX+SYS_FONT_WIDTH+SYS_FONT_WIDTH>box->right)
{ PenPosX=box->left;
PenPosY=PenPosY+SYS_FONT_HEIGHT+rowspace;
if(PenPosY+SYS_FONT_HEIGHT>box->bottom) break;
}
if(disptext)
{ hzkoffset = ((*(BYTE *)(lptext-2) - 0xA1) * 94 + (ch - 0xA1)) * SYS_FONT_HEIGHT * ((SYS_FONT_WIDTH+SYS_FONT_WIDTH+7)>>3);
DrawFontMatrix(dc,PenPosX,PenPosY,SYS_FONT_WIDTH+SYS_FONT_WIDTH,SYS_FONT_HEIGHT,(BYTE *)&SYS_FONT_CHINESE[hzkoffset]) ;
}
PenPosX=PenPosX+SYS_FONT_WIDTH+SYS_FONT_WIDTH+colspace;
}
hanzi_mached=!hanzi_mached;
}
else
{ if(ch==0)break;
hanzi_mached=false;
if(ch=='\r' || ch=='\n')
{ PenPosX=box->left;
PenPosY=PenPosY+SYS_FONT_HEIGHT+rowspace;
if(PenPosY+SYS_FONT_HEIGHT<=box->bottom)
{ if(ch=='\r' && *(lptext+1)=='\n') lptext++;
}else break;
}
else
{ if(PenPosX+SYS_FONT_WIDTH>box->right)
{ PenPosX=box->left;
PenPosY=PenPosY+SYS_FONT_HEIGHT+rowspace;
if(PenPosY+SYS_FONT_HEIGHT>box->bottom)break;
}
if(disptext)
{ hzkoffset=SYS_FONT_HEIGHT*((SYS_FONT_WIDTH+7)>>3)*ch;
DrawFontMatrix(dc,PenPosX,PenPosY,SYS_FONT_WIDTH,SYS_FONT_HEIGHT,(BYTE *)&SYS_FONT_ENGLISH[hzkoffset]) ;
}
PenPosX=PenPosX+SYS_FONT_WIDTH+colspace;
}
}
}
if(PenPosX>box->left)
{ EndPosX=PenPosX;
EndPosY=PenPosY+SYS_FONT_HEIGHT;
}
else
{ EndPosX=box->right;
EndPosY=PenPosY-rowspace;
}
if(disptext)
{ linecount=(EndPosY-startpos->y+rowspace)/(SYS_FONT_HEIGHT+rowspace);
if(linecount==1)
{ GroupOff(dc,startpos->x,startpos->y,EndPosX-startpos->x,SYS_FONT_HEIGHT);
}
else if(linecount>=2)
{ GroupOff(dc,startpos->x,startpos->y,box->right-startpos->x,SYS_FONT_HEIGHT);
if(linecount>2)
{ GroupOn(dc);
GroupOff(dc,box->left,startpos->y+SYS_FONT_HEIGHT,box->right-box->left,EndPosY-startpos->y-SYS_FONT_HEIGHT-SYS_FONT_HEIGHT);
}
GroupOn(dc);
GroupOff(dc,box->left,EndPosY-SYS_FONT_HEIGHT,EndPosX-box->left,SYS_FONT_HEIGHT);
}
}
if(mode&TB_MEASURE)
{ startpos->x=EndPosX;
startpos->y=EndPosY;
}
}
void TextBoxGroupOff(HDC dc,TRECT *box,TPOINT *startpos,TPOINT *endpos1,TPOINT *endpos2)
{ TPOINT *endpos=(endpos2->y>endpos1->y || (endpos2->y==endpos1->y && endpos2->x>endpos1->x))?endpos2:endpos1;
int rowspace=GetRowSpace(dc);
int linecount=(endpos->y - startpos->y + rowspace)/(SYS_FONT_HEIGHT+rowspace);
if(linecount==1)
{ GroupOff(dc,startpos->x,startpos->y,endpos->x-startpos->x,SYS_FONT_HEIGHT);
}
else if(linecount>=2)
{ GroupOff(dc,startpos->x,startpos->y,box->right-startpos->x,SYS_FONT_HEIGHT);
if(linecount>2)
{ GroupOn(dc);
GroupOff(dc,box->left,startpos->y+SYS_FONT_HEIGHT,box->right-box->left,endpos->y-startpos->y-SYS_FONT_HEIGHT-SYS_FONT_HEIGHT);
}
GroupOn(dc);
GroupOff(dc,box->left,endpos->y-SYS_FONT_HEIGHT,endpos->x-box->left,SYS_FONT_HEIGHT);
}
}
/* 输入鼠标位置curpos,根据框内文本,重新定格curpos,同时取得所在行信息,并返回curpos指向的文本位置.
*/
int BoxLocateCursor(TMultiEdit *pEdit,int x,int y,int *cx,int *cy,int *linepos,int *linelen)
{ BYTE ch;
bool hanzi_mached=false;
LPCSTR pline,pedit,lptext=pEdit->buffer+pEdit->startPos;
int PenPosX,PenPosY,lineindex=0,linesize=0,nx=pEdit->textArea.left,ny=pEdit->textArea.top;
pline=pedit=lptext;
if(lptext && *lptext)
{ y=y-((y-pEdit->textArea.top)%(SYS_FONT_HEIGHT+pEdit->rowspace));
PenPosX=pEdit->textArea.left;
PenPosY=pEdit->textArea.top;
while (1)
{ ch=*lptext++;
if(ch>0xa0)
{ if(hanzi_mached)
{ if(PenPosX+SYS_FONT_WIDTH+SYS_FONT_WIDTH>pEdit->textArea.right)
{ PenPosX=pEdit->textArea.left;
PenPosY=PenPosY+SYS_FONT_HEIGHT+pEdit->rowspace;
if(PenPosY+SYS_FONT_HEIGHT<=pEdit->textArea.bottom)
{ if(PenPosY>y)break;
else {pedit=pline=lptext-2;linesize=0;nx=pEdit->textArea.left;ny=PenPosY;}
}
else break;
}
linesize+=2;
PenPosX=PenPosX+SYS_FONT_WIDTH+SYS_FONT_WIDTH+pEdit->colspace;
if(PenPosX-SYS_FONT_WIDTH-pEdit->colspace<=x)
{ pedit=lptext;
nx=PenPosX;
}
}
hanzi_mached=!hanzi_mached;
}
else
{ if(ch==0)break;
hanzi_mached=false;
if(ch=='\r' || ch=='\n')
{ PenPosX=pEdit->textArea.left;
PenPosY=PenPosY+SYS_FONT_HEIGHT+pEdit->rowspace;
if(PenPosY+SYS_FONT_HEIGHT<=pEdit->textArea.bottom)
{ if(ch=='\r' && *(lptext+1)=='\n') lptext++;
if(PenPosY>y)break;
else {pedit=pline=lptext;linesize=0;nx=pEdit->textArea.left;ny=PenPosY;}
}else break;
}
else
{ if(PenPosX+SYS_FONT_WIDTH>pEdit->textArea.right)
{ PenPosX=pEdit->textArea.left;
PenPosY=PenPosY+SYS_FONT_HEIGHT+pEdit->rowspace;
if(PenPosY+SYS_FONT_HEIGHT<=pEdit->textArea.bottom)
{ if(PenPosY>y)break;
else {pedit=pline=lptext-1;linesize=0;nx=pEdit->textArea.left;ny=PenPosY;}
}
else break;
}
PenPosX=PenPosX+SYS_FONT_WIDTH+pEdit->colspace;
linesize++;
if(PenPosX-(SYS_FONT_WIDTH>>1)-pEdit->colspace<=x)
{ pedit=lptext;
nx=PenPosX;
}
}
}
}
}
if(linepos) *linepos=(int)(pline-pEdit->buffer);
if(linelen) *linelen=linesize;
if(cx)*cx=nx;
if(cy)*cy=ny;
return (int)(pedit-pEdit->buffer);
}
/*根据行号取得文本行首批针,行首偏移,行长度*/
LPCSTR MemoGetLineInfo(TMultiEdit * pEdit,int linenum,int *linepos,int *linelen,int *linewidth)
{ BYTE ch;
bool hanzi_mached=false;
int PenPosX,PenPosY,lineindex=0,linesize=0;
LPCSTR pline=pEdit->buffer,lptext=pEdit->buffer;
if(!lptext || linenum<0)return NULL;
PenPosX=pEdit->textArea.left;
PenPosY=pEdit->textArea.top;
while (1)
{ ch=*lptext++;
if(ch>0xa0)
{ if(hanzi_mached)
{ if(PenPosX+SYS_FONT_WIDTH+SYS_FONT_WIDTH>pEdit->textArea.right)
{ if(++lineindex>linenum)break;
else{pline=lptext-2;linesize=0;}
PenPosX=pEdit->textArea.left;
PenPosY=PenPosY+SYS_FONT_HEIGHT+pEdit->rowspace;
}
linesize+=2;
PenPosX=PenPosX+SYS_FONT_WIDTH+SYS_FONT_WIDTH+pEdit->colspace;
}
hanzi_mached=!hanzi_mached;
}
else
{ if(ch==0)break;
hanzi_mached=false;
if(ch=='\r' || ch=='\n')
{ if(++lineindex>linenum)break;
else{pline=lptext;linesize=0;}
PenPosX=pEdit->textArea.left;
PenPosY=PenPosY+SYS_FONT_HEIGHT+pEdit->rowspace;
if(ch=='\r' && *(lptext+1)=='\n') lptext++;
}
else
{ if(PenPosX+SYS_FONT_WIDTH>pEdit->textArea.right)
{ if(++lineindex>linenum)break;
else{pline=lptext-1;linesize=0;}
PenPosX=pEdit->textArea.left;
PenPosY=PenPosY+SYS_FONT_HEIGHT+pEdit->rowspace;
}
PenPosX=PenPosX+SYS_FONT_WIDTH+pEdit->colspace;
linesize++;
}
}
}
if(linepos) *linepos=(int)(pline-pEdit->buffer);
if(linelen) *linelen=linesize;
if(linewidth) *linewidth=PenPosX-pEdit->textArea.left;
return (lineindex>=linenum)?pline:NULL;
}
int Memo_GetLineCount(HWND hWnd)
{ BYTE ch;
bool hanzi_mached=false;
int linecount=1;
TMultiEdit *pEdit=(TMultiEdit *)WndClsBuf(hWnd);
int PenPosX=pEdit->textArea.left;
int PenPosY=pEdit->textArea.top;
LPCSTR lptext=pEdit->buffer;
while (1)
{ ch=*lptext++;
if(ch>0xa0)
{ if(hanzi_mached)
{ if(PenPosX+SYS_FONT_WIDTH+SYS_FONT_WIDTH>pEdit->textArea.right)
{ PenPosX=pEdit->textArea.left;
PenPosY=PenPosY+SYS_FONT_HEIGHT+pEdit->rowspace;
linecount++;
}
PenPosX=PenPosX+SYS_FONT_WIDTH+SYS_FONT_WIDTH+pEdit->colspace;
}
hanzi_mached=!hanzi_mached;
}
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -