📄 test.c
字号:
si.fMask = SIF_TRACKPOS ;
GetScrollInfo(hwnd, SB_HORZ,&si) ;
p->leftshownindex = si.nTrackPos ;
if (end)
SetScrollPos(hwnd,SB_HORZ,si.nTrackPos,0) ;
SendUpdate(hwnd) ;
}
/**********************************************************************
* lfchars counts the number of times we switch from one line to another
* within a range of chars
**********************************************************************/
int lfchars(INTERNAL_CHAR *c,int start, int end)
{
int rv =0 ;
while (start < end) {
if (c[start].ch == '\n')
rv++ ;
start++ ;
}
return rv ;
}
/**********************************************************************
* Line from char takes a character pos and turns it into a line number
**********************************************************************/
int LineFromChar (EDITDATA *p, int pos)
{
int rv = 0 ;
INTERNAL_CHAR *ic = p->text ;
while (ic < p->text + p->textlen && pos) {
if (ic->ch == '\n')
rv ++;
pos-- ;
ic++ ;
}
return rv ;
}
/**********************************************************************
* SelLine is the Same as lineFromChar, but counts a partial (unterminated)
* line at the end of the buffer
**********************************************************************/
static int SelLine(EDITDATA *p, int pos)
{
int rv = LineFromChar(p,pos) ;
#ifdef OLD_EDIT_FORMAT
if (pos && p->text[pos-1].ch != '\n' && p->text[pos-1].ch != '\r')
#else
if (pos && p->text[pos-1].ch != '\n')
#endif
rv++ ;
return rv ;
}
/**********************************************************************
* Replace handles pasting. Will also cut a previous selection, if there
* was one
**********************************************************************/
void Replace(HWND hwnd, EDITDATA *p, char *s, int lens)
{
UNDO *u=0 ;
int i,temp ;
char *buf,*s1 ;
int len = 0,linepos ;
i = p->selendcharpos - p->selstartcharpos ;
u = undo_deletesel(p) ;
if (i > 0) {
len -= lfchars(p->text,p->selstartcharpos,p->selendcharpos) ;
SendMessage(GetParent(hwnd),EN_LINECHANGE,SelLine(p,p->selstartcharpos),len) ;
memcpy(p->text + p->selstartcharpos, p->text + p->selendcharpos, (p->textlen - p->selendcharpos + 1) * sizeof(INTERNAL_CHAR)) ;
p->textlen -= i ;
} else if (i < 0) {
temp = lfchars(p->text,p->selendcharpos,p->selstartcharpos) ;
SendMessage(GetParent(hwnd),EN_LINECHANGE,SelLine(p,p->selendcharpos),-temp) ;
VScrollPos(hwnd,-temp,FALSE) ;
len -= temp ;
memcpy(p->text + p->selendcharpos, p->text + p->selstartcharpos, (p->textlen - p->selstartcharpos + 1) * sizeof(INTERNAL_CHAR)) ;
p->selstartcharpos = p->selendcharpos ;
p->textlen += i ;
}
p->selendcharpos = p->selstartcharpos + lens ;
if (u) {
u->postselstart = u->postselend = p->selstartcharpos ;
}
if (p->selendcharpos -p->selstartcharpos+ p->textlen > p->textmaxlen) {
int adj = p->textlen + p->selendcharpos-p->selstartcharpos ;
buf = realloc(p->text,(adj + 1) * sizeof(INTERNAL_CHAR)) ;
if (!buf) {
p->selendcharpos = p->selstartcharpos ;
SendUpdate(hwnd) ;
p->sendchangeonpaint = TRUE ;
InvalidateRect(hwnd,0,0) ;
return;
}
p->text = buf ;
p->textmaxlen = adj ;
}
if (lens) {
u = undo_insertsel(p,s) ;
if (u) {
u->preselstart = u->preselend = p->selstartcharpos ;
u->postselstart = u->preselstart ;
u->postselend = u->preselstart + lens ;
}
}
temp = 0 ;
s1 = s ;
i = 0 ;
while (*s1 && i++ < lens)
if (*s1++ == '\n')
temp++ ;
SendMessage(GetParent(hwnd),EN_LINECHANGE,SelLine(p,p->selstartcharpos),temp) ;
memmove(p->selendcharpos+p->text,p->text + p->selstartcharpos, (p->textlen - p->selstartcharpos + 1) * sizeof(INTERNAL_CHAR)) ;
memset(p->selstartcharpos+p->text,0,(p->selendcharpos - p->selstartcharpos) * sizeof(INTERNAL_CHAR)) ;
i = 0 ;
while (*s && i < lens) {
if (*s == '\n')
len++ ;
p->text[p->selstartcharpos+i].ch = *s++ ;
p->text[p->selstartcharpos+i].color = p->defforeground ;
i++ ;
p->textlen++ ;
}
VScrollLen(hwnd,len,FALSE) ;
if (p->colorize)
FormatBufferFromScratch(p->text,p->selstartcharpos-1,p->selendcharpos+1,p->colorize) ;
SendUpdate(hwnd) ;
p->sendchangeonpaint = TRUE ;
InvalidateRect(hwnd,0,0) ;
}
/**********************************************************************
* GetLineOffset returns the line number, this time as an offset from
* the first line shown at the top of the window
**********************************************************************/
int GetLineOffset(HWND hwnd, EDITDATA *p, int chpos)
{
int pos = p->textshowncharpos ;
int line =0 ;
while (pos != chpos && pos < p->textlen) {
if (p->text[pos].ch == '\n')
line++ ;
pos++ ;
}
return line ;
}
/**********************************************************************
* drawline draws the current line and everything below it(by invalidating
* the selection)
**********************************************************************/
void drawline(HWND hwnd, EDITDATA *p,int chpos)
{
RECT r ;
int pos ;
if (p->selecting)
pos = p->selendcharpos ;
else
pos = p->selstartcharpos ;
ClientArea(hwnd,p,&r) ;
r.top = GetLineOffset(hwnd,p,pos)*p->txtFontHeight ;
SendUpdate(hwnd) ;
InvalidateRect(hwnd,&r,1) ;
MoveCaret(hwnd,p) ;
}
/**********************************************************************
* insertchar handles the functionality of inserting a character
* will also cut a previous selection
**********************************************************************/
void insertchar(HWND hwnd, EDITDATA *p, int ch)
{
int len = 0,temp ;
UNDO *u =0;
if (p->inserting) {
int i = p->selendcharpos - p->selstartcharpos ;
u = undo_deletesel(p) ;
if (i > 0) {
len -= lfchars(p->text,p->selstartcharpos,p->selendcharpos) ;
SendMessage(GetParent(hwnd),EN_LINECHANGE,SelLine(p,p->selstartcharpos),len) ;
memcpy(p->text + p->selstartcharpos, p->text + p->selendcharpos, (p->textlen - p->selendcharpos + 1) * sizeof(INTERNAL_CHAR)) ;
} else if (i < 0) {
temp = lfchars(p->text,p->selendcharpos,p->selstartcharpos) ;
SendMessage(GetParent(hwnd),EN_LINECHANGE,SelLine(p,p->selendcharpos),-temp) ;
VScrollPos(hwnd,-temp,FALSE) ;
len -= temp ;
memcpy(p->text + p->selendcharpos, p->text + p->selstartcharpos, (p->textlen - p->selendcharpos + 1) * sizeof(INTERNAL_CHAR)) ;
p->selstartcharpos = p->selendcharpos ;
}
p->selendcharpos = p->selstartcharpos ;
if (u) {
u->postselstart = u->postselend = p->selstartcharpos ;
}
if (ch == '\n') {
len++ ;
SendMessage(GetParent(hwnd),EN_LINECHANGE,SelLine(p,p->selstartcharpos),1) ;
}
if (2+ p->textlen >= p->textmaxlen) {
int adj = p->textmaxlen + 64 ;
INTERNAL_CHAR *buf = realloc(p->text,(adj + 1) * sizeof(INTERNAL_CHAR)) ;
if (!buf) {
SendUpdate(hwnd) ;
p->sendchangeonpaint = TRUE ;
InvalidateRect(hwnd,0,0) ;
return 0 ;
}
p->text = buf ;
p->textmaxlen = adj ;
}
u = undo_insertchar(p,ch) ;
memmove(p->text + p->selstartcharpos +1, p->text + p->selstartcharpos, (p->textlen -p->selstartcharpos+1)*sizeof(INTERNAL_CHAR)) ;
p->text[p->selstartcharpos].ch = ch ;
p->textlen++ ;
VScrollLen(hwnd,len,FALSE) ;
} else {
p->selendcharpos = p->selstartcharpos ;
#ifdef OLD_EDIT_FORMAT
if (p->text[p->selstartcharpos].ch == '\r' || p->text[p->selstartcharpos].ch == '\n')
p->selendcharpos = p->selstartcharpos++ ;
if (p->text[p->selstartcharpos].ch == '\r' || p->text[p->selstartcharpos].ch == '\n')
p->selendcharpos = p->selstartcharpos++ ;
#else
if (p->text[p->selstartcharpos].ch == '\n')
p->selendcharpos = p->selstartcharpos++ ;
#endif
u = undo_modifychar(p) ;
p->text[p->selstartcharpos].ch = ch ;
}
p->selendcharpos = ++p->selstartcharpos ;
if (u) {
u->postselstart = p->selstartcharpos ;
u->postselend = p->selendcharpos ;
}
p->sendchangeonpaint = TRUE ;
ScrollCaretIntoView(hwnd,p) ;
}
/**********************************************************************
* insertcr inserts a cr/lf pair
**********************************************************************/
void insertcr(HWND hwnd, EDITDATA *p)
{
RECT r,update ;
int totallines ;
int temp ;
drawline(hwnd,p,p->selstartcharpos);
if (p->selstartcharpos > p->selendcharpos) {
temp = -p->selstartcharpos ;
p->selstartcharpos = p->selendcharpos ;
} else {
temp = p->selendcharpos ;
p->selendcharpos = p->selstartcharpos ;
}
#ifdef OLD_EDIT_FORMAT
insertchar(hwnd,p,'\r') ;
#endif
insertchar(hwnd,p,'\n') ;
#ifdef OLD_EDIT_FORMAT
if (temp < 0) {
p->selstartcharpos = -temp+2 ;
} else {
p->selendcharpos = temp+2 ;
}
#else
if (temp < 0) {
p->selstartcharpos = -temp+1 ;
} else {
p->selendcharpos = temp+1 ;
}
#endif
// ClientArea(hwnd,p,&r) ;
// r.top = GetLineOffset(hwnd,p,p->selstartcharpos)*p->txtFontHeight ;
// ScrollWindowEx(hwnd,0,1*p->txtFontHeight,&r,0,0,&update,SW_ERASE) ;
VScrollLen(hwnd,1,FALSE) ;
VScrollPos(hwnd,1,FALSE) ;
}
/**********************************************************************
* inserttab inserts a tab, or types in a bunch of spaces to take
* us to the next tab position
**********************************************************************/
void inserttab(HWND hwnd, EDITDATA *p)
{
if (!(editFlags & TABS_AS_SPACES))
insertchar(hwnd,p,'\t') ;
else {
int pos = p->selstartcharpos, col=0,col2 ;
while (pos) {
if (p->text[pos].ch == '\n') {
pos++ ;
break ;
}
pos-- ;
}
while (pos != p->selstartcharpos) {
if (p->text[pos].ch == '\t') {
col = col + p->tabs ;
col /= p->tabs ;
col *= p->tabs ;
} else
col++ ;
pos++ ;
}
col2 = col +p->tabs ;
col2 /= p->tabs ;
col2 *= p->tabs ;
while(col < col2) {
insertchar(hwnd,p,' ') ;
col++ ;
}
}
}
/**********************************************************************
* tab to the current line position
**********************************************************************/
void insertcrtabs(HWND hwnd, EDITDATA *p)
{
int pos,n ;
int oldinsert = p->inserting ;
if (!p->colorize)
return ;
if (editFlags & AUTO_INDENT)
return ;
p->inserting = TRUE ;
pos = p->selstartcharpos-1 ;
while (1) {
while (pos && p->text[pos-1].ch != '\n')
pos -- ;
while (p->text[pos].ch && isspace(p->text[pos].ch) && p->text[pos].ch != '\n')
pos++ ;
if (p->text[pos].ch != '#')
break ;
while (pos && p->text[pos-1].ch != '\n')
pos -- ;
if (!pos)
break ;
pos-- ;
}
n = curcol(p,p->text,pos) ;
while (n >= p->tabs) {
inserttab(hwnd,p) ;
n-=p->tabs;
}
while (n--)
insertchar(hwnd,p,' ') ;
p->inserting = oldinsert ;
}
int spacedend(EDITDATA *p, int pos)
{
int rv = 0 ;
while (pos && p->text[pos-1].ch != '\n')
pos -- ;
rv = pos ;
while (p->text[pos].ch && isspace(p->text[pos].ch) && p->text[pos].ch != '\n')
pos++ ;
if (p->text[pos].ch == '}')
return rv ;
else
return 0 ;
}
int preprocline(EDITDATA *p, int pos)
{
int rv ;
while (pos && p->text[pos-1].ch != '\n')
pos -- ;
rv = pos ;
while (isspace(p->text[pos].ch))
pos ++ ;
if (p->text[pos].ch == '#')
return rv ;
else
return -1 ;
}
/**********************************************************************
* tab to the current line position
**********************************************************************/
void InsertEndTabs(HWND hwnd, EDITDATA *p, int newend)
{
int pos,n ;
int solpos, eospos ;
int lsolpos, leospos ;
int oldinsert = p->inserting ;
if (p->colorize != COLORIZE_C)
return ;
if (!newend)
return ;
if (editFlags & AUTO_FORMAT)
return ;
p->inserting = TRUE ;
leospos = pos = p->selstartcharpos-1 ;
while (isspace(p->text[leospos].ch) && p->text[leospos].ch != '\n')
leospos++ ;
if (lsolpos = spacedend(p,pos)) {
int indentlevel = 0 ;
eospos = 0 ;
pos-- ;
while (pos > 0) {
int pos1 = preprocline(p,pos) ;
if (pos1 != -1 )
pos = pos1 ;
else if (p->text[pos].color != commentColor)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -