📄 test1.c
字号:
return u;
}
//-------------------------------------------------------------------------
UNDO *undo_casechange(EDITDATA *p)
{
UNDO *x = undo_deletesel(p);
x->type = UNDO_CASECHANGE;
return x;
}
/**********************************************************************
* undo_insertsel gets the undo structure for an operation which pasts
**********************************************************************/
UNDO *undo_insertsel(EDITDATA *p, char *s)
{
UNDO *u = getundo(p, UNDO_INSERTSELECTION);
if (!u)
return u;
u->len = strlen(s);
return u;
}
/**********************************************************************
* undo_deletechar gets the undo structure for a character deletion
**********************************************************************/
UNDO *undo_deletechar(EDITDATA *p, int ch, int type)
{
UNDO *u = getundo(p, type);
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] = ch;
u->postselstart = p->selstartcharpos;
u->postselend = p->selendcharpos;
return u;
}
/**********************************************************************
* undo_deletechar gets the undo structure for typing over a character
**********************************************************************/
UNDO *undo_modifychar(EDITDATA *p)
{
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
// LOOK HERE this looks funny, it probably shouldn't be indented
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
// LOOK HERE
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
// LOOK HERE
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -