⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 textbox.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:
    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 + -