📄 test.c
字号:
{
UNDO *u = getundo(p,UNDO_MODIFY) ;
if (!u)
return u ;
if (u->max <= u->len) {
char *temp = realloc(u->data,u->max + 64) ;
if (!temp)
return 0 ;
u->data = temp ;
u->max += 64 ;
}
memmove(u->data+1,u->data,u->len++) ;
u->data[0] = p->text[p->selstartcharpos].ch ;
return u ;
}
/**********************************************************************
* undo_deletechar gets the undo structure for inserting a character
**********************************************************************/
UNDO *undo_insertchar(EDITDATA *p, int ch)
{
UNDO *u = getundo(p,UNDO_INSERT) ;
if (!u)
return u ;
u->len++ ;
return u ;
}
UNDO * undo_deleteindent(EDITDATA *p)
{
return getundo(p,UNDO_DELETEINDENT) ;
}
UNDO * undo_insertindent(EDITDATA *p)
{
return getundo(p,UNDO_INSERTINDENT) ;
}
/**********************************************************************
* ClientArea gets the client area. We are leaving space at the bottom
* because it would be overlayed with the scroll bar
**********************************************************************/
void ClientArea(HWND hwnd, EDITDATA *p, RECT *r)
{
GetClientRect(hwnd,r) ;
// r->bottom -= GetSystemMetrics(SM_CYHSCROLL) ;
r->bottom -= r->bottom % p->txtFontHeight ;
}
/**********************************************************************
* posfromchar determines the screen position of a given offset in
* the buffer
**********************************************************************/
int posfromchar( HWND hwnd, EDITDATA *p, POINTL *point, int pos)
{
char buf[256],*x=buf ;
SIZE size ;
RECT r ;
HDC dc ;
int spos = p->textshowncharpos,xcol ;
int i = 0,j ;
point->x = point->y = 0 ;
if (spos > pos)
return 0;
while (spos+i < pos && spos+i < p->textlen) {
if (p->text[spos+i].ch == '\n') {
point->y += p->txtFontHeight ;
spos += i+1 ;
i = 0 ;
} else
i++ ;
}
i = 0 ;
xcol = 0 ;
while (spos+i < pos && spos+i < p->textlen) {
#ifdef OLD_EDIT_FORMAT
if (p->text[spos+i].ch == '\r' || p->text[spos+i].ch == '\n')
#else
if (p->text[spos+i].ch == '\n')
#endif
break;
if (p->text[spos+i].ch == '\t') {
xcol += p->tabs ;
xcol /= p->tabs ;
xcol *=p->tabs ;
} else
xcol++ ;
i++ ;
}
if (xcol >=p->leftshownindex)
point->x = (xcol - p->leftshownindex) * p->txtFontWidth ;
else
return 0 ;
ClientArea(hwnd,p,&r) ;
if (point->x >=r.right || point->y >= r.bottom)
return 0 ;
return 1 ;
}
/**********************************************************************
* charfrompos determines the buffer offset from the screen position
**********************************************************************/
int charfrompos(HWND hwnd, EDITDATA *p, POINTL *point)
{
RECT r ;
int row,col,xcol = 0 ;
int pos = p->textshowncharpos,i=0 ;
char buf[256],*x=buf ;
ClientArea(hwnd,p,&r) ;
if (point->x > r.right || point->y > r.bottom)
return 0 ;
row = point->y/ p->txtFontHeight ;
col = point->x / p->txtFontWidth ;
while (row && pos < p->textlen) {
if (p->text[pos].ch == '\n')
row-- ;
pos++ ;
}
if (pos == p->textlen)
return pos ;
while (pos +i < p->textlen && xcol < p->leftshownindex) {
#ifdef OLD_EDIT_FORMAT
if (p->text[pos+i].ch == '\r' || p->text[pos+i].ch == '\n')
#else
if (p->text[pos+i].ch == '\n')
#endif
return pos+i-1 ;
if (p->text[pos+i].ch == '\t') {
xcol += p->tabs ;
xcol /= p->tabs ;
xcol *=p->tabs ;
} else
xcol++ ;
i++ ;
}
pos += i ;
i = 0 ;
xcol = 0 ;
while (xcol < col && pos + i < p->textlen) {
#ifdef OLD_EDIT_FORMAT
if (p->text[pos+i].ch == '\r' || p->text[pos+i].ch == '\n')
#else
if (p->text[pos+i].ch == '\n')
#endif
break ;
if (p->text[pos+i].ch == '\t') {
xcol += p->tabs ;
xcol /= p->tabs ;
xcol *=p->tabs ;
} else
xcol++ ;
i++ ;
}
return pos + i /*-1*/ ;
}
/**********************************************************************
* vscrolllen sets the limits for the vertical scroll bar
**********************************************************************/
void VScrollLen(HWND hwnd, int count, int set)
{
int count1 = count ;
int base = 0 ;
if (!set) {
GetScrollRange(hwnd,SB_VERT,&base,&count1) ;
count1 += count ;
}
SetScrollRange(hwnd,SB_VERT,base,count1,TRUE) ;
}
/**********************************************************************
* vscrolllen sets the position for the vertical scroll bar
**********************************************************************/
void VScrollPos(HWND hwnd, int count ,int set)
{
int count1 = count ;
if (!set) {
count1 = GetScrollPos(hwnd, SB_VERT) ;
count1 += count ;
}
// ExtendedMessageBox("hi",0,"%d",count1) ;
SetScrollPos(hwnd,SB_VERT,count1,TRUE) ;
}
/**********************************************************************
* curcol finds the screen column number corresponding to a text position
* (zero based)
**********************************************************************/
int curcol(EDITDATA *p, INTERNAL_CHAR *text, int pos)
{
int rv = 0 ;
int opos = pos ;
#ifdef OLD_EDIT_FORMAT
while (pos && text[pos].ch != '\n') {
pos-- ;
}
if (text[pos].ch == '\n')
pos++ ;
#else
while (pos && text[pos-1].ch != '\n') {
pos-- ;
}
#endif
while (pos < opos) {
if (text[pos].ch == '\t') {
rv += p->tabs ;
rv = ( rv /p->tabs) * p->tabs ;
} else
rv++ ;
pos++ ;
}
return rv ;
}
void setcurcol(EDITDATA *p)
{
int pos ;
if (p->selstartcharpos != p->selendcharpos)
pos = p->selendcharpos ;
else
pos = p->selstartcharpos ;
p->updowncol = curcol(p,p->text,pos) ;
}
/**********************************************************************
* MoveCaret moves the caret to the position of the selection. IF
* the caret is offscreen, it gets hidden
**********************************************************************/
void MoveCaret(HWND hwnd, EDITDATA *p)
{
int x=0, y= 0 ;
POINTL pt ;
if (posfromchar(hwnd,p,&pt,p->selecting ? p->selendcharpos : p->selstartcharpos)) {
if (p->hasfocus) {
SetCaretPos(pt.x,pt.y) ;
ShowCaret(hwnd) ;
}
p->hiddenCaret = FALSE ;
} else {
if (!p->hiddenCaret && p->hasfocus)
HideCaret(hwnd) ;
p->hiddenCaret = TRUE ;
}
}
/**********************************************************************
* Scroll Left scrolls left or right, depending on the sign of 'cols'
**********************************************************************/
void scrollleft(HWND hwnd, EDITDATA *p, int cols)
{
p->leftshownindex += cols ;
if (p->leftshownindex < 0)
p->leftshownindex = 0 ;
SendUpdate(hwnd) ;
InvalidateRect(hwnd,0,0) ;
}
/**********************************************************************
* Scrollup scrolls up or down, depending on the sign of 'lines'
**********************************************************************/
void scrollup(HWND hwnd, EDITDATA *p, int lines)
{
RECT r,update ;
int totallines,movelines = lines ;
int pos = p->textshowncharpos,len = 0 ;
ClientArea(hwnd,p,&r) ;
totallines = r.bottom/p->txtFontHeight ;
if (lines < 0){
lines = - lines ;
while(lines && pos > 0) {
--pos ;
if (p->text[pos].ch == '\n') {
lines-- ;
len-- ;
}
}
while (pos) {
--pos;
if (p->text[pos].ch == '\n') {
pos++ ;
break ;
}
}
SendUpdate(hwnd) ;
if (lines >= totallines) {
InvalidateRect(hwnd,0,0) ;
} else {
if (-movelines - lines)
ScrollWindowEx(hwnd,0,(-movelines - lines) * p->txtFontHeight,&r,&r,0,&update,SW_INVALIDATE) ;
}
p->textshowncharpos = pos ;
} else {
while (lines && pos < p->textlen) {
if (p->text[pos].ch == '\n') {
lines-- ;
len++ ;
}
pos++ ;
}
SendUpdate(hwnd) ;
if (lines >= totallines) {
InvalidateRect(hwnd,0,0) ;
} else {
if (movelines - lines)
ScrollWindowEx(hwnd,0,-(movelines - lines) * p->txtFontHeight,&r,&r,0,&update,SW_INVALIDATE) ;
}
p->textshowncharpos = pos ;
}
SendUpdate(hwnd) ;
VScrollPos(hwnd,len,FALSE) ;
}
/**********************************************************************
* ScrollCaretIntoView moves the text in the window around in such a way
* that the caret is in the window.
**********************************************************************/
void ScrollCaretIntoView(HWND hwnd, EDITDATA *p)
{
POINTL pt ;
int lines,cols,colpos=0 ;
RECT r ;
int pos1,pos ;
if (!p->selecting)
pos1 = p->selstartcharpos ;
else
pos1 = p->selendcharpos ;
if (posfromchar(hwnd,p,&pt,pos1)) {
MoveCaret(hwnd,p) ;
return ;
}
ClientArea(hwnd,p,&r) ;
lines = r.bottom / p->txtFontHeight ;
cols = r.right/p->txtFontWidth ;
if (pos1 > p->textshowncharpos) {
int xlines =0;
pos = p->textshowncharpos ;
while (pos < pos1 && pos < p->textlen) {
if (p->text[pos].ch == '\n')
xlines++ ;
pos++ ;
}
if (xlines >= lines)
scrollup(hwnd,p,xlines-lines+1) ;
} else {
lines = 0 ;
if (pos1 != p->textshowncharpos) {
pos = p->textshowncharpos ;
while (pos >0 && pos != pos1) {
--pos ;
if (p->text[pos].ch == '\n')
lines++ ;
}
if (lines > 0)
scrollup(hwnd,p,-lines) ;
}
}
pos = pos1 ;
while (pos > 0 && p->text[pos-1].ch != '\n')
pos--;
while (pos != pos1) {
if (p->text[pos-1].ch == '\t')
colpos = ((colpos + p->tabs)/p->tabs) * p->tabs ;
else
colpos++ ;
pos++ ;
}
if (colpos < p->leftshownindex)
scrollleft(hwnd,p,colpos - p->leftshownindex - 10) ;
else if (colpos >= p->leftshownindex + cols)
scrollleft(hwnd,p,colpos - p->leftshownindex - cols+1) ;
MoveCaret(hwnd,p) ;
}
/**********************************************************************
* TrackVScroll handles tracking messages and updating the display when
* the user moves the vertical scroll bar
**********************************************************************/
void TrackVScroll(HWND hwnd, EDITDATA *p, int end)
{
SCROLLINFO si ;
int count ;
memset(&si,0,sizeof(si)) ;
si.cbSize = sizeof(si) ;
si.fMask = SIF_TRACKPOS ;
GetScrollInfo(hwnd, SB_VERT,&si) ;
count = SendMessage(hwnd,EM_LINEINDEX,si.nTrackPos,0) ;
p->textshowncharpos = count ;
// if (end)
SetScrollPos(hwnd,SB_VERT,si.nTrackPos,0) ;
SendUpdate(hwnd) ;
InvalidateRect(hwnd,0,0) ;
MoveCaret(hwnd,p) ;
}
/**********************************************************************
* TrackHScroll handles tracking messages and updating the display when
* the user moves the horizontal scroll bar
**********************************************************************/
void TrackHScroll(HWND hwnd, EDITDATA *p, int end)
{
SCROLLINFO si ;
int count ;
memset(&si,0,sizeof(si)) ;
si.cbSize = sizeof(si) ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -