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

📄 textedit.c

📁 有了操作系统、TCP/IP协议栈、文件系统
💻 C
📖 第 1 页 / 共 5 页
字号:
        rc.left = 0;        rc.top = 0;        rc.right = scrolled_get_contwidth(ptescr);        rc.bottom = ptedata->nLineHeight;        i = 0;        while (1) {            if (i > 0) indent = 0;            DrawTextEx2 (hdc, pLine, txtlen, &rc, indent,                     TE_FORMAT | DT_WORDBREAK | DT_CALCRECT, &fl);            if (i == line)                break;            pLine += fl.nr_chars;            txtlen -= fl.nr_chars;            i++;        }        ln_chars = fl.nr_chars;    }    else {        pLine = string;        ln_chars = txtlen;    }    if (pLine[ln_chars-1] == txtdoc->lnsep) {        // add caret before line seperator        ln_chars --;        if (ln_chars > 0 && is_rn_sep((pLine + ln_chars - 1)) )            ln_chars --;    }    if (x - indent <= 0) {        out_chars = 0;        txtsize.cx = 0;    }    else        out_chars = GetTabbedTextExtentPoint (hdc, pLine, ln_chars,                         x - indent, NULL, NULL, NULL, &txtsize);    ReleaseDC (hdc);#if 0    printf ("pLine : %s\n", pLine);    printf ("lnchars : %d\n", ln_chars);    printf ("out chars : %d\n", out_chars);    printf ("caret x = %d\n", x);    printf ("txtsize.cx = %d\n", txtsize.cx);    printf ("h = %d\n", h);#endif    if (!bSel) {        txtdoc->insert.pos_lnOff = pLine - string + out_chars;        mySetCaretPos (hWnd, txtsize.cx + indent, h + ptedata->nLineAboveH);    }#ifdef _SELECT_SUPPORT    else {        txtdoc->selection.pos_lnOff = pLine - string + out_chars;        mySetSelPos (txtsize.cx + indent, h + ptedata->nLineAboveH);    }#endif    //scrolled_make_pos_visible (hWnd, ptescr, txtsize.cx + indent, h + ptedata->nLineHeight);    return 0;}/* calculates line number of a text node, for wrap mode */static int get_line_nr (HWND hWnd, PTEDATA ptedata, TextNode *node, int indent){    RECT rc;    PLOGFONT logfont = GetWindowFont(hWnd);    HDC hdc;    if (!node) {        fprintf (stderr, "Warning: pass NULL text node to get_line_nr\n");        return 0;    }    if (!BE_WRAP(hWnd))        return 1;    hdc = GetClientDC (hWnd);    SelectFont (hdc, logfont);    rc.left = 0;    rc.top = 0;    rc.right = scrolled_get_contwidth(ptescr);    rc.bottom = logfont->size;    if (ptedata->lnChar) {        char *content, chln = 0;        int outlen;        content = node->content.string;        outlen = node->content.txtlen;        if (outlen > 0 && content[outlen-1] == ptedata->txtdoc.lnsep) {            outlen --;            if (ptedata->txtdoc.lnsep == '\n' && content[outlen-1] == '\r')                outlen --;            outlen ++;            chln = content[outlen-1];            content[outlen-1] = ptedata->lnChar;        }        DrawTextEx (hdc, content, outlen, &rc, indent,                     TE_FORMAT | DT_WORDBREAK | DT_CALCRECT);        if (chln)            content[outlen-1] = chln;    }    else {        DrawTextEx (hdc, node->content.string, node->content.txtlen, &rc, indent,                     TE_FORMAT | DT_WORDBREAK | DT_CALCRECT);    }    ReleaseDC (hdc);    return (RECTH(rc)/logfont->size);}//TODOstatic int recalc_max_len (HWND hWnd ,PTEDATA ptedata){    list_t *me;    TextDoc *txtdoc = &ptedata->txtdoc;    SIZE txtsize;    TextNode *node;    HDC hdc;    ptedata->maxLen = 0;    ptedata->maxNode = NULL;    ptedata->secLen = 0;    ptedata->secNode = NULL;    hdc = GetClientDC (hWnd);    //SelectFont (hdc, GetWindowFont(hWnd));    list_for_each (me, &txtdoc->queue) {        node = list_entry (me, TextNode, list);        GetTabbedTextExtent(hdc, node->content.string,                         node->content.txtlen, &txtsize);        if (txtsize.cx > ptedata->maxLen || ptedata->maxLen == 0) {            ptedata->maxLen = txtsize.cx;            ptedata->maxNode = node;        }        else if (txtsize.cx >= ptedata->secLen) {            ptedata->secLen = txtsize.cx;            ptedata->secNode = node;        }    }    ReleaseDC (hdc);    return 0;}static intrevise_max_len (HWND hWnd, PTEDATA ptedata, TextNode *node, int textlen){    if (textlen > ptedata->maxLen) {        if (node != ptedata->maxNode) {            ptedata->secLen = ptedata->maxLen;            ptedata->secNode = ptedata->maxNode;        }        ptedata->maxLen = textlen;        ptedata->maxNode = node;    }    else if (textlen > ptedata->secLen) {        if (node != ptedata->maxNode) {            ptedata->secLen = textlen;            ptedata->secNode = node;            return 0; /* no need to reset content width */        }        else {            ptedata->maxLen = textlen;        }    }    else { //FIXME        if (node == ptedata->maxNode) {            recalc_max_len (hWnd, ptedata);            return 1;        }        else if (node == ptedata->secNode) {            recalc_max_len (hWnd, ptedata);            return 0;        }        return 0;    }    /* need to reset content width */    return 1;}/* set text node line width, for non wrap mode */static int set_line_width (HWND hWnd, PTEDATA ptedata, TextNode *node, int indent){    SIZE txtsize;    HDC hdc;    if (!node) {        fprintf (stderr, "Warning: pass NULL text node to set_line_width\n");        return -1;    }    if (BE_WRAP(hWnd))        return -1;    hdc = GetClientDC (hWnd);    SelectFont (hdc, GetWindowFont(hWnd));    GetTabbedTextExtent(hdc, node->content.string, node->content.txtlen, &txtsize);    ReleaseDC (hdc);    if (revise_max_len (hWnd, ptedata, node, txtsize.cx + indent) > 0)        scrolled_set_cont_width (hWnd, ptescr, ptedata->maxLen + 1);    return 0;}/*static int set_line_size (HWND hWnd, PTEDATA ptedata, TextNode *node){    int linenr = 1, indent;    if (!node)        return 0;    indent = teGetLineIndent (ptedata, node);    linenr = get_line_nr(hWnd, ptedata, node, indent);    set_line_width (hWnd, ptedata, node, indent);    return scrollview_set_item_height (hWnd, (HSVITEM)node->addData,                         ptedata->nLineHeight*linenr);}*//* * get_node_by_idx : Get node and y position by node index */static TextNode* get_node_by_idx (PTEDATA ptedata, int line, int *item_y){    TextDoc *txtdoc = &ptedata->txtdoc;    TextNode *node;    int nr = 0, ypos = 0;    if (line < 0)        return NULL;    node = FIRSTNODE(txtdoc);    while (node) {        if (nr == line)            break;        nr ++;        ypos += NODE_HEIGHT(node);        node = TXTNODE_NEXT(node);    }    if (nr != line)        return NULL;    if (item_y)        *item_y = ypos;    return node;}static void teNodeInit (TextDoc *txtdoc, TextNode* node, TextNode *prenode){    SVITEMINFO svii;    HWND hWnd = (HWND)txtdoc->fn_data;    PTEDATA ptedata = (PTEDATA)GetWindowAdditionalData2(hWnd);    int linenr = 1, indent;    HSVITEM preitem = 0;    if (!node) return;    indent = teGetLineIndent (ptedata, node);    linenr = get_line_nr(hWnd, ptedata, node, indent);    set_line_width (hWnd, ptedata, node, indent);    svii.nItemHeight = ptedata->nLineHeight * linenr;    svii.addData = (DWORD)node;    svii.nItem = -1;    if (prenode)        preitem = (HSVITEM)prenode->addData;    node->addData = (DWORD) scrollview_add_item (hWnd, &ptedata->svdata,                                 preitem, &svii, NULL);}static void teNodeDel (TextDoc *txtdoc, TextNode *node){    HWND hWnd = (HWND)txtdoc->fn_data;    PTEDATA ptedata = (PTEDATA)GetWindowAdditionalData2(hWnd);    scrollview_del_item (hWnd, &ptedata->svdata, 0, (HSVITEM)node->addData);}static void teNodeChange (TextDoc *txtdoc, BOOL bSel){    PTEDATA ptedata = (PTEDATA)GetWindowAdditionalData2((HWND)txtdoc->fn_data);    if (!bSel) {        ptedata->curItemY = scrollview_get_item_ypos (&ptedata->svdata,                                      (HSVITEM)txtdoc->insert.curNode->addData);    }#ifdef _SELECT_SUPPORT            else {        ptedata->selItemY = scrollview_get_item_ypos (&ptedata->svdata,                                      (HSVITEM)txtdoc->selection.curNode->addData);    }#endif        }static void teChangeCont (TextDoc *txtdoc, TextNode *node){    HWND hWnd = (HWND)txtdoc->fn_data;    PTEDATA ptedata = (PTEDATA)GetWindowAdditionalData2(hWnd);    int indent, linenr;    if (!node)        return;    indent = teGetLineIndent (ptedata, node);    linenr = get_line_nr(hWnd, ptedata, node, indent);    scrollview_set_item_height (hWnd, (HSVITEM)node->addData,                         ptedata->nLineHeight*linenr);    set_line_width (hWnd, ptedata, node, indent);}/* * textdoc_reset : resets or initializes the properties of a textdoc to  *                 default values */static int textdoc_reset (HWND hWnd, TextDoc *txtdoc){    txtdoc->lnsep = DEF_LINESEP;    txtdoc->nDefLineSize = DEF_LINE_BUFFER_SIZE;    txtdoc->nBlockSize = DEF_LINE_BLOCK_SIZE;    txtdoc->init_fn = teNodeInit;    txtdoc->change_fn = teNodeChange;    txtdoc->change_cont = teChangeCont;    txtdoc->del_fn = teNodeDel;    txtdoc->fn_data = (void*)hWnd;    return 0;}/* * teResetData : resets status data */static void teResetData (PTEDATA ptedata){    ptedata->des_caret_x = 0;    ptedata->curItemY = 0;#ifdef _SELECT_SUPPORT    ptedata->selItemY = 0;#endif    ptedata->maxNode = NULL;    ptedata->maxLen = 0;    ptedata->secNode = NULL;    ptedata->secLen = 0;    ptedata->flags = 0;}/* -------------------------------------------------------------------------- */#ifdef _SELECT_SUPPORTint textdoc_copy_to_cb (PTEDATA ptedata, char *buffer, int len, BOOL bCB){    TextDoc *txtdoc = &ptedata->txtdoc;    int pos_start, pos_end;    TextNode *node, *endnode;    TextMark *markStart, *markEnd;    int org_len = len;    if (!txtdoc->selection.curNode)        return 0;    markStart = get_start_mark (ptedata);    markEnd = (markStart == &txtdoc->insert) ?                           &txtdoc->selection : &txtdoc->insert;    node = markStart->curNode;    endnode = markEnd->curNode;    /* clear clipboard */    if (bCB)        SetClipBoardData (CBNAME_TEXT, NULL, 0, CBOP_NORMAL);    while (1) {        get_selection_points (ptedata, node, &pos_start, &pos_end);        if (bCB) {            SetClipBoardData (CBNAME_TEXT, node->content.string + pos_start,                        pos_end - pos_start, CBOP_APPEND);        }        else if (buffer) {            int output;            output = MIN(len, pos_end - pos_start);            strncpy (buffer, node->content.string + pos_start, output);            buffer += output;            len -= output;        }        else {            len += pos_end - pos_start;        }        if(node != endnode)            node = TXTNODE_NEXT (node);        else            break;    }    if (!bCB && !buffer && org_len == 0)        return len;    return org_len - len;}#endifstatic void te_make_caret_visible (HWND hWnd, PTEDATA ptedata, BOOL bSel){    POINT pt;    if (!bSel)        myGetCaretPos (&pt);#ifdef _SELECT_SUPPORT    else        myGetSelPos (&pt);#endif    if (pt.y > ptescr->nContY)        pt.y = (pt.y / ptedata->nLineHeight + 1) * ptedata->nLineHeight;    else        pt.y = (pt.y / ptedata->nLineHeight) * ptedata->nLineHeight;    scrolled_make_pos_visible (hWnd, ptescr, pt.x, pt.y);    if (!bSel) {        mySetCaretPos (hWnd, -1, -1);//FIXME        //ShowCaret (hWnd);    }}/* * teSetCaretPos : sets the caret position according to the current insertion  *                 point or sets the selection caret position according to the *                 current selection point of the text doc. * Description   : should be called after the current insert point or the  *                 selection point of the text document is changed */static void teSetCaretPos (HWND hWnd, PTEDATA ptedata){    TextDoc *txtdoc = &ptedata->txtdoc;    TextNode *node;    TextMark *mark;    int h, indent, endh;    HDC hdc;    hdc = GetClientDC (hWnd);    mark = GETMARK(txtdoc->selection.curNode);    node = mark->curNode;    SelectFont (hdc, GetWindowFont(hWnd));#ifdef _SELECT_SUPPORT    if (txtdoc->selection.curNode)        h = ptedata->selItemY;    else#endif        h = ptedata->curItemY;    indent = teGetLineIndent (ptedata, node);    if (BE_WRAP(hWnd)) {        RECT rc;        int w;        SIZE txtsize = {0, 0};        int txtlen, linenr, lineidx;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -