📄 textbox.c
字号:
switch (msg) {
case DFM_CREATE_WINDOW:
wnd->HScrollBox = wnd->VScrollBox = 1;
DfClearTextPointers(wnd);
break;
case DFM_ADDTEXT:
return AddTextMsg(wnd, (char *) p1);
case DFM_DELETETEXT:
DeleteTextMsg(wnd, (int) p1);
return TRUE;
case DFM_INSERTTEXT:
InsertTextMsg(wnd, (char *) p1, (int) p2);
return TRUE;
case DFM_SETTEXT:
SetTextMsg(wnd, (char *) p1);
return TRUE;
case DFM_CLEARTEXT:
ClearTextMsg(wnd);
break;
case DFM_KEYBOARD:
if (DfWindowMoving || DfWindowSizing)
break;
if (KeyboardMsg(wnd, p1))
return TRUE;
break;
case DFM_LEFT_BUTTON:
if (DfWindowSizing || DfWindowMoving)
return FALSE;
if (LeftButtonMsg(wnd, p1, p2))
return TRUE;
break;
case MOUSE_MOVED:
if (MouseMovedMsg(wnd, p1, p2))
return TRUE;
break;
case DFM_BUTTON_RELEASED:
ButtonReleasedMsg(wnd);
break;
case DFM_SCROLL:
return ScrollMsg(wnd, p1);
case DFM_HORIZSCROLL:
return HorizScrollMsg(wnd, p1);
case DFM_SCROLLPAGE:
ScrollPageMsg(wnd, p1);
return TRUE;
case DFM_HORIZPAGE:
HorizScrollPageMsg(wnd, p1);
return TRUE;
case DFM_SCROLLDOC:
ScrollDocMsg(wnd, p1);
return TRUE;
case DFM_PAINT:
if (DfIsVisible(wnd))
{
PaintMsg(wnd, p1, p2);
return FALSE;
}
break;
case DFM_CLOSE_WINDOW:
CloseWindowMsg(wnd);
break;
default:
break;
}
return DfBaseWndProc(DF_TEXTBOX, wnd, msg, p1, p2);
}
/* ------ compute the vertical scroll box position from
the text pointers --------- */
static int ComputeVScrollBox(DFWINDOW wnd)
{
int pagelen = wnd->wlines - DfClientHeight(wnd);
int barlen = DfClientHeight(wnd)-2;
int lines_tick;
int vscrollbox;
if (pagelen < 1 || barlen < 1)
vscrollbox = 1;
else {
if (pagelen > barlen)
lines_tick = pagelen / barlen;
else
lines_tick = barlen / pagelen;
vscrollbox = 1 + (wnd->wtop / lines_tick);
if (vscrollbox > DfClientHeight(wnd)-2 ||
wnd->wtop + DfClientHeight(wnd) >= wnd->wlines)
vscrollbox = DfClientHeight(wnd)-2;
}
return vscrollbox;
}
/* ---- compute top text line from scroll box position ---- */
static void ComputeWindowTop(DFWINDOW wnd)
{
int pagelen = wnd->wlines - DfClientHeight(wnd);
if (wnd->VScrollBox == 0)
wnd->wtop = 0;
else if (wnd->VScrollBox == DfClientHeight(wnd)-2)
wnd->wtop = pagelen;
else {
int barlen = DfClientHeight(wnd)-2;
int lines_tick;
if (pagelen > barlen)
lines_tick = barlen ? (pagelen / barlen) : 0;
else
lines_tick = pagelen ? (barlen / pagelen) : 0;
wnd->wtop = (wnd->VScrollBox-1) * lines_tick;
if (wnd->wtop + DfClientHeight(wnd) > wnd->wlines)
wnd->wtop = pagelen;
}
if (wnd->wtop < 0)
wnd->wtop = 0;
}
/* ------ compute the horizontal scroll box position from
the text pointers --------- */
static int ComputeHScrollBox(DFWINDOW wnd)
{
int pagewidth = wnd->textwidth - DfClientWidth(wnd);
int barlen = DfClientWidth(wnd)-2;
int chars_tick;
int hscrollbox;
if (pagewidth < 1 || barlen < 1)
hscrollbox = 1;
else {
if (pagewidth > barlen)
chars_tick = barlen ? (pagewidth / barlen) : 0;
else
chars_tick = pagewidth ? (barlen / pagewidth) : 0;
hscrollbox = 1 + (chars_tick ? (wnd->wleft / chars_tick) : 0);
if (hscrollbox > DfClientWidth(wnd)-2 ||
wnd->wleft + DfClientWidth(wnd) >= wnd->textwidth)
hscrollbox = DfClientWidth(wnd)-2;
}
return hscrollbox;
}
/* ---- compute left column from scroll box position ---- */
static void ComputeWindowLeft(DFWINDOW wnd)
{
int pagewidth = wnd->textwidth - DfClientWidth(wnd);
if (wnd->HScrollBox == 0)
wnd->wleft = 0;
else if (wnd->HScrollBox == DfClientWidth(wnd)-2)
wnd->wleft = pagewidth;
else {
int barlen = DfClientWidth(wnd)-2;
int chars_tick;
if (pagewidth > barlen)
chars_tick = pagewidth / barlen;
else
chars_tick = barlen / pagewidth;
wnd->wleft = (wnd->HScrollBox-1) * chars_tick;
if (wnd->wleft + DfClientWidth(wnd) > wnd->textwidth)
wnd->wleft = pagewidth;
}
if (wnd->wleft < 0)
wnd->wleft = 0;
}
/* ----- get the text to a specified line ----- */
static char *GetTextLine(DFWINDOW wnd, int selection)
{
char *line;
int len = 0;
char *cp, *cp1;
cp = cp1 = DfTextLine(wnd, selection);
while (*cp && *cp != '\n') {
len++;
cp++;
}
line = DfMalloc(len+7);
memmove(line, cp1, len);
line[len] = '\0';
return line;
}
/* ------- write a line of text to a textbox window ------- */
void DfWriteTextLine(DFWINDOW wnd, DFRECT *rcc, int y, BOOL reverse)
{
int len = 0;
int dif = 0;
char line[200];
DFRECT rc;
char *lp, *svlp;
int lnlen;
int i;
BOOL trunc = FALSE;
/* ------ make sure y is inside the window ----- */
if (y < wnd->wtop || y >= wnd->wtop+DfClientHeight(wnd))
return;
/* ---- build the retangle DfWithin which can write ---- */
if (rcc == NULL) {
rc = DfRelativeWindowRect(wnd, DfWindowRect(wnd));
if (DfTestAttribute(wnd, DF_HASBORDER) &&
DfRectRight(rc) >= DfWindowWidth(wnd)-1)
DfRectRight(rc) = DfWindowWidth(wnd)-2;
}
else
rc = *rcc;
/* ----- make sure rectangle is DfWithin window ------ */
if (DfRectLeft(rc) >= DfWindowWidth(wnd)-1)
return;
if (DfRectRight(rc) == 0)
return;
rc = DfAdjustRectangle(wnd, rc);
if (y-wnd->wtop<DfRectTop(rc) || y-wnd->wtop>DfRectBottom(rc))
return;
/* --- get the text and length of the text line --- */
lp = svlp = GetTextLine(wnd, y);
if (svlp == NULL)
return;
lnlen = DfLineLength(lp);
/* -------- insert block DfColor change controls ------- */
if (DfTextBlockMarked(wnd)) {
int bbl = wnd->BlkBegLine;
int bel = wnd->BlkEndLine;
int bbc = wnd->BlkBegCol;
int bec = wnd->BlkEndCol;
int by = y;
/* ----- put lowest marker first ----- */
if (bbl > bel) {
swap(bbl, bel);
swap(bbc, bec);
}
if (bbl == bel && bbc > bec)
swap(bbc, bec);
if (by >= bbl && by <= bel) {
/* ------ the block includes this line ----- */
int blkbeg = 0;
int blkend = lnlen;
if (!(by > bbl && by < bel)) {
/* --- the entire line is not in the block -- */
if (by == bbl)
/* ---- the block begins on this line --- */
blkbeg = bbc;
if (by == bel)
/* ---- the block ends on this line ---- */
blkend = bec;
}
if (blkend == 0 && lnlen == 0) {
strcpy(lp, " ");
blkend++;
}
/* ----- insert the reset DfColor token ----- */
memmove(lp+blkend+1,lp+blkend,strlen(lp+blkend)+1);
lp[blkend] = DF_RESETCOLOR;
/* ----- insert the change DfColor token ----- */
memmove(lp+blkbeg+3,lp+blkbeg,strlen(lp+blkbeg)+1);
lp[blkbeg] = DF_CHANGECOLOR;
/* ----- insert the DfColor tokens ----- */
DfSetReverseColor(wnd);
lp[blkbeg+1] = DfForeground | 0x80;
lp[blkbeg+2] = DfBackground | 0x80;
lnlen += 4;
}
}
/* - make sure left margin doesn't overlap DfColor change - */
for (i = 0; i < wnd->wleft+3; i++) {
if (*(lp+i) == '\0')
break;
if (*(lp + i) == DF_RESETCOLOR)
break;
}
if (*(lp+i) && i < wnd->wleft+3) {
if (wnd->wleft+4 > lnlen)
trunc = TRUE;
else
lp += 4;
}
else {
/* --- it does, shift the DfColor change over --- */
for (i = 0; i < wnd->wleft; i++) {
if (*(lp+i) == '\0')
break;
if (*(lp + i) == DF_CHANGECOLOR) {
*(lp+wnd->wleft+2) = *(lp+i+2);
*(lp+wnd->wleft+1) = *(lp+i+1);
*(lp+wnd->wleft) = *(lp+i);
break;
}
}
}
/* ------ build the line to display -------- */
if (!trunc) {
if (lnlen < wnd->wleft)
lnlen = 0;
else
lp += wnd->wleft;
if (lnlen > DfRectLeft(rc)) {
/* ---- the line exceeds the rectangle ---- */
int ct = DfRectLeft(rc);
char *initlp = lp;
/* --- point to end of clipped line --- */
while (ct) {
if (*lp == DF_CHANGECOLOR)
lp += 3;
else if (*lp == DF_RESETCOLOR)
lp++;
else
lp++, --ct;
}
if (DfRectLeft(rc)) {
char *lpp = lp;
while (*lpp) {
if (*lpp==DF_CHANGECOLOR)
break;
if (*lpp==DF_RESETCOLOR) {
lpp = lp;
while (lpp >= initlp) {
if (*lpp == DF_CHANGECOLOR) {
lp -= 3;
memmove(lp,lpp,3);
break;
}
--lpp;
}
break;
}
lpp++;
}
}
lnlen = DfLineLength(lp);
len = min(lnlen, DfRectWidth(rc));
dif = strlen(lp) - lnlen;
len += dif;
if (len > 0)
strncpy(line, lp, len);
}
}
/* -------- pad the line --------- */
while (len < DfRectWidth(rc)+dif)
line[len++] = ' ';
line[len] = '\0';
dif = 0;
/* ------ establish the line's main DfColor ----- */
if (reverse) {
char *cp = line;
DfSetReverseColor(wnd);
while ((cp = strchr(cp, DF_CHANGECOLOR)) != NULL) {
cp += 2;
*cp++ = DfBackground | 0x80;
}
if (*line == DF_CHANGECOLOR)
dif = 3;
}
else
DfSetStandardColor(wnd);
/* ------- display the line -------- */
DfWriteLine(wnd, line+dif,
DfRectLeft(rc)+DfBorderAdj(wnd),
y-wnd->wtop+DfTopBorderAdj(wnd), FALSE);
free(svlp);
}
void DfMarkTextBlock(DFWINDOW wnd, int BegLine, int BegCol,
int EndLine, int EndCol)
{
wnd->BlkBegLine = BegLine;
wnd->BlkEndLine = EndLine;
wnd->BlkBegCol = BegCol;
wnd->BlkEndCol = EndCol;
}
/* ----- clear and initialize text line pointer array ----- */
void DfClearTextPointers(DFWINDOW wnd)
{
wnd->TextPointers = DfRealloc(wnd->TextPointers, sizeof(int));
*(wnd->TextPointers) = 0;
}
#define INITLINES 100
/* ---- build array of pointers to text lines ---- */
void DfBuildTextPointers(DFWINDOW wnd)
{
char *cp = wnd->text, *cp1;
int incrs = INITLINES;
unsigned int off;
wnd->textwidth = wnd->wlines = 0;
while (*cp) {
if (incrs == INITLINES) {
incrs = 0;
wnd->TextPointers = DfRealloc(wnd->TextPointers,
(wnd->wlines + INITLINES) * sizeof(int));
}
off = (unsigned int) ((unsigned int)cp - (unsigned int)wnd->text);
*((wnd->TextPointers) + wnd->wlines) = off;
wnd->wlines++;
incrs++;
cp1 = cp;
while (*cp && *cp != '\n')
cp++;
wnd->textwidth = max(wnd->textwidth, (int)(cp - cp1));
if (*cp)
cp++;
}
}
static void MoveScrollBox(DFWINDOW wnd, int vscrollbox)
{
DfForeground = DfFrameForeground(wnd);
DfBackground = DfFrameBackground(wnd);
DfWPutch(wnd, DF_SCROLLBARCHAR, DfWindowWidth(wnd)-1,
wnd->VScrollBox+1);
DfWPutch(wnd, DF_SCROLLBOXCHAR, DfWindowWidth(wnd)-1,
vscrollbox+1);
wnd->VScrollBox = vscrollbox;
}
int DfTextLineNumber(DFWINDOW wnd, char *lp)
{
int lineno;
char *cp;
for (lineno = 0; lineno < wnd->wlines; lineno++) {
cp = wnd->text + *((wnd->TextPointers) + lineno);
if (cp == lp)
return lineno;
if (cp > lp)
break;
}
return lineno-1;
}
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -