📄 test1.c
字号:
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);
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
// LOOK HERE
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
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -