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

📄 pureedit.c

📁 rtCell 实时微内核-具有下列功能: 1. 完全抢占的实时微内核结构
💻 C
字号:
/*
 *******************************************************************************
 *                      The real-time kernel "rtCell"                          *
 *              Copyright 2005 taowentao, allrights reserved.                  *
 * File : PureEdit.c                                                           *
 * By   : taowentao     2006-09-02  2007-05-20                                 *
 *******************************************************************************
 */

#if !defined(PUREEDIT_H)
#include "giCell\Wins\include\PureEdit.h"
#endif

#include <mem.h>
#include <string.h> 

/*
 *******************************************************************************
 *                                                                             *
 *******************************************************************************
 */

static COLOR editColor = GD_WHITE;
static COLOR selectColor = GD_BLUE;
static COLOR textColor[2] = {GD_BLACK, GD_WHITE};

/*
 *******************************************************************************
 *                                                                             *
 *******************************************************************************
 */

static void GetTextOrgByCursor(PEDIT* pEdit)
{
    int    xSize, ySize;
    POINT  pt;
    RECT   r = pEdit->pView->viewRect; 

    xSize = TextWidth(pEdit->pText);
    ySize = TextHeight(pEdit->pText);
    GetOrgFromAlign(xSize, ySize, &r, pEdit->textAlign, &pt);

    xSize = GetCharX(pt.x, pEdit->xCursor, pEdit->pText);
    if (xSize < (r.left+1)) {
        pt.x += (r.left - xSize + 2);
    } else if (xSize > (r.right-1)) {
        pt.x -= (xSize - r.right + 2);
    }
    
    pEdit->ptText = pt;
}

static void PEditPaint(VIEW *pView)
{
    PEDIT* pEdit;
    COLOR  clr;
    int    xSize, ySize;
    POINT  pt;
    RECT   r = pView->viewRect;

    pEdit = OBJ_FROM_VIEW(pView);
    FillRect(&r, pEdit->editColor);

    xSize = TextWidth(pEdit->pText);
    ySize = TextHeight(pEdit->pText);

    GetTextOrgByCursor(pEdit);
    pt = pEdit->ptText;
    if (pEdit->Status & CTRL_MOUSE_ENTER) clr = MOUSEENTERCOLOR;
    else clr = pEdit->textColor[0];
    DrawText(pt.x, pt.y, pEdit->pText, clr);
    
    if (pEdit->Status & CTRL_FOCUSSED) {
        int start, end;
        
        if (pEdit->selStart != pEdit->selEnd) {
            BYTE ch;

            if (pEdit->selStart > pEdit->selEnd) {
                start = pEdit->selEnd;
                end = pEdit->selStart;
            } else {
                start = pEdit->selStart;
                end =  pEdit->selEnd;
            }
        
            r.left = GetCharX(pt.x, start, pEdit->pText);
            r.right = GetCharX(pt.x, end, pEdit->pText);
            r.top = pt.y;
            r.bottom = r.top + ySize - 1;
            FillRect(&r, pEdit->selectColor);
            if (end < pEdit->textLength) {
                ch = pEdit->pText[end];
                pEdit->pText[end] = 0;
            }
            DrawText(r.left, r.top, pEdit->pText+start, pEdit->textColor[1]);
            if (end < pEdit->textLength) {
                pEdit->pText[end] = ch;
            }
        }
    
        if (pEdit->Status & CTRL_PEDIT_CURSOR) {
            xSize = GetCharX(pt.x, pEdit->xCursor, pEdit->pText);
            clr = GD_BLACK;
            if (pEdit->selStart != pEdit->selEnd) {
                if ((pEdit->xCursor >= start) &&
                    (pEdit->xCursor <= end)) {
                    clr = GD_WHITE;
                }
            } 
            DrawVLine(xSize-1, pt.y, pt.y+ySize-1, clr);
            DrawVLine(xSize, pt.y, pt.y+ySize-1, clr);
        }
    }
}

static void SetCursor(PEDIT *pEdit, int x)
{
    int   xSize, xCh, i, sLen;
    POINT pt;
    BYTE *s = pEdit->pText;

    xSize = TextWidth(pEdit->pText);
    GetTextOrgByCursor(pEdit);
    pt = pEdit->ptText;
    
    sLen = strlen(s);
    if (x <= pt.x) {
        pEdit->xCursor = 0;
    } else if (x >= (pt.x+xSize)) {
        pEdit->xCursor = sLen;
    } else {         
        for (i = 0, xSize = pt.x; i < sLen; i++) {
            xCh = CharWidth(*(s + i));
            if (x < (xSize + (xCh >> 1))) break;  
            xSize += xCh;
        }
        pEdit->xCursor = i;   
    }    
}

static CBOOL DelSelected(PEDIT *pEdit)
{
    int nCopy, start, end;

    if (pEdit->Status & CTRL_PEDIT_READOMLY)
        return (false);
    if (pEdit->selStart != pEdit->selEnd) {
        const BYTE *s = pEdit->pText;

        if (pEdit->selStart > pEdit->selEnd) {
            start = pEdit->selEnd;
            end = pEdit->selStart;
        } else {
            start = pEdit->selStart;
            end =  pEdit->selEnd; 
        }
        
        pEdit->xCursor = start;
        nCopy = pEdit->textLength-end;
        memmove(s + start, s + end, nCopy); 

        pEdit->selStart = 0; pEdit->selEnd = 0;
        return (true);
    } else {
        return (false);
    }
}

static void PEditAddChar(PEDIT *pEdit, BYTE ch)
{
    int   sLen, nCopy;
    BYTE *s;

    if (pEdit->Status & CTRL_PEDIT_READOMLY)
        return;

    DelSelected(pEdit);
    s = pEdit->pText;
    sLen = strlen(s);
            
    if (pEdit->Status & CTRL_PEDIT_INSERT) {
        if (sLen < (pEdit->textLength - 1)) {
            nCopy = pEdit->textLength - pEdit->xCursor - 1;
            memmove(s + pEdit->xCursor + 1, s + pEdit->xCursor, nCopy);
            *(s + pEdit->xCursor) = ch;
            if (pEdit->xCursor < (pEdit->textLength - 1))
                pEdit->xCursor++;
        }
    } else {
        *(s + pEdit->xCursor) = ch;
        if (pEdit->xCursor < (pEdit->textLength - 1))
            pEdit->xCursor++;
    }
}

static void PEditKeyDown(VMSG *pMsg)
{
    PEDIT  *pEdit;
    BYTE   *s;
    int     sLen, nCopy;
    KEY_INF ki;

    pEdit = OBJ_FROM_VIEW(pMsg->pView);
    ki.raw = pMsg->vParam;

    s = pEdit->pText;
    sLen = strlen(s);

    if (ki.inf.ctrl) {
        if ((ki.inf.scan == SCANCODE_C) || (ki.inf.scan == SCANCODE_X)) {
            if (pEdit->selStart != pEdit->selEnd) {
                int start, end; 

                if (pEdit->selStart > pEdit->selEnd) {
                    start = pEdit->selEnd;
                    end = pEdit->selStart;
                } else {
                    start = pEdit->selStart;
                    end =  pEdit->selEnd;
                }
                
                AddToClipBoard(pEdit->pText+start, end-start);
                if (ki.inf.scan == SCANCODE_X) DelSelected(pEdit);
            }
            return;
        } else if (ki.inf.scan == SCANCODE_V) {
            nCopy = GetClipBoardContentSize();
            if (nCopy > 0) {
                BYTE *scr = (BYTE *)GetClipBoardBuf(); 
                for (; nCopy > 0; scr ++, nCopy --)
                    PEditAddChar(pEdit, (*scr));
            }
            return;
        } else if (ki.inf.scan == SCANCODE_A) {
            pEdit->selStart = 0;
            pEdit->selEnd = sLen;
            pEdit->xCursor = sLen;
            return;
        }
    }
    
    switch (ki.inf.key) {
    case KEY_HOME:
        pEdit->xCursor = 0;
        pEdit->selStart = 0; pEdit->selEnd = 0;
        break;
    case KEY_END:
        pEdit->xCursor = sLen;
        pEdit->selStart = 0; pEdit->selEnd = 0;
        break;
    case KEY_RIGHT:
        pEdit->selStart = 0; pEdit->selEnd = 0;
        if (pEdit->xCursor < (pEdit->textLength - 1)) {
            if (pEdit->xCursor < sLen)
                pEdit->xCursor ++;
        }
        break;
    case KEY_LEFT:
        pEdit->selStart = 0; pEdit->selEnd = 0;
        if (pEdit->xCursor > 0)
            pEdit->xCursor--;
        break;
    case KEY_BACKSPACE:
        if (DelSelected(pEdit) == false) { 
            if ((sLen > 0) && (pEdit->xCursor > 0)) {
                nCopy = pEdit->textLength - pEdit->xCursor;
                strncpy(s + pEdit->xCursor - 1, s + pEdit->xCursor, nCopy);
                *(s + sLen - 1) = 0;
                pEdit->xCursor--;
            }
        }
        break;
    case KEY_DELETE:
        if (DelSelected(pEdit) == false) {  
            if ((sLen > 0) && (pEdit->xCursor < sLen)) {
                if (sLen > 1) {
                    nCopy = pEdit->textLength - pEdit->xCursor - 1;
                    strncpy(s + pEdit->xCursor, s + pEdit->xCursor + 1, nCopy);
                }
                *(s + sLen - 1) = 0;
            }
        }
        break;
	case KEY_INSERT:
        if (pEdit->Status & CTRL_PEDIT_INSERT)
            pEdit->Status &= (~CTRL_PEDIT_INSERT);
        else
            pEdit->Status |= CTRL_PEDIT_INSERT;
         break;
    case KEY_ENTER:
    case KEY_ESCAPE:
          break;
    default:
        if ((ki.inf.key >= 0x20) && (ki.inf.key <= 0x7f)) {
            PEditAddChar(pEdit, (BYTE)(ki.inf.key));
        }
        break;
    } 
}

static CBOOL _cdecl_ PEditViewProc(VMSG *pMsg)
{
    PEDIT  *pEdit = OBJ_FROM_VIEW(pMsg->pView);
    KEY_INF ki;
    MOUSE_INF mi;
    RECT    r;
    POINT   pt = pMsg->pt;
    
    switch (pMsg->MsgID) {
    case TIMERM_OUT:
        pEdit->Timer ++;
        if (pEdit->Timer >= CTRL_PEDIT_TIME) {
            pEdit->Timer = 0;
            if (pEdit->Status & CTRL_PEDIT_CURSOR)
                pEdit->Status &= (~CTRL_PEDIT_CURSOR);
            else
                pEdit->Status |= CTRL_PEDIT_CURSOR;

            GetTextOrgByCursor(pEdit);  
            r.left = GetCharX(pEdit->ptText.x, pEdit->xCursor, pEdit->pText)-1;
            r.right = r.left+1; r.top = pEdit->ptText.y;
            r.bottom = r.top+TextHeight(pEdit->pText)-1;            
            UpdateViewRect(pMsg->pView, &r);
        }
        return (true);
    case KEYM_KEY_DOWN:
        if (pEdit->Status & CTRL_FOCUSSED) {
            PEditKeyDown(pMsg);
            UpdateView(pMsg->pView);
            
            if (pEdit->pKeyDown != NULL) {
                ki.raw = pMsg->vParam;
                (*(pEdit->pKeyDown))(ki);
            }
        }

        return (true);
    case MSM_LB_DOWN:
        if ((pEdit->Status & CTRL_FOCUSSED)) {
            pEdit->Status |= CTRL_MOUSE_ENTER;

            r = pMsg->pView->viewRect;
            if (IsInRect(pt.x, pt.y, &r) == false) return (true);

            SetCursor(pEdit, pt.x);
            pEdit->selStart = pEdit->xCursor;
            pEdit->selEnd = pEdit->xCursor;
            pEdit->ptCatch = pt;
            pEdit->Status |= CTRL_MOUSE_CATCH;
            pEdit->Status |= CTRL_CATCH_MOVE;
            UpdateView(pMsg->pView);  
        }
        return (true);
    case MSM_LB_UP:
        if ((pEdit->Status & CTRL_MOUSE_CATCH) == 0) return (true);
        pEdit->Status &= ~(CTRL_MOUSE_CATCH);
        UpdateView(pMsg->pView);  
        return (true);
    case MSM_MS_MOVE:
        mi.raw = pMsg->vParam;
        if ((pEdit->Status & CTRL_MOUSE_CATCH) && (mi.inf.lbtn != 0)) {
            if (pEdit->Status & CTRL_CATCH_MOVE) {
                SetCursor(pEdit, pt.x);  
                pEdit->selEnd = pEdit->xCursor;
                UpdateView(pMsg->pView);  
            }
        } 
        return (true);
    case MSM_MS_ENTER:
        SetMouseCursor(TEXT);
        pEdit->Status |= CTRL_MOUSE_ENTER;
        UpdateView(pMsg->pView);
        return (true);
    default:
        return (CtrlViewProc(pMsg, PEditPaint, &(pEdit->Status)));
    }
}  

PEDIT* CreatePureEdit(int left, int top, int width, int height, VIEW* pParent,
	                  BYTE *pText, PKEYDOWN pKeyDown, CWORD Align, CWORD textLen)
{
    PEDIT *pEdit;
    VIEW  *pView;

    if (pParent == NULL) 
        return (NULL);

    pView = CreateControl(left, top, width, height, pParent, 0,
                          PEditViewProc, sizeof(PEDIT)+textLen+1);
    if (pView == NULL) return (NULL); 

    pEdit = OBJ_FROM_VIEW(pView);
    pEdit->pView = pView; 
    pEdit->textColor[0] = textColor[0];
    pEdit->textColor[1] = textColor[1];
    pEdit->pKeyDown = pKeyDown;
    pEdit->ptCatch.x = 0; pEdit->ptCatch.y = 0;
    pEdit->editColor = editColor;
    pEdit->selectColor = selectColor;
    pEdit->Status = CTRL_PEDIT_INSERT;
    pEdit->textAlign = Align;
    pEdit->textLength = textLen;
    pEdit->pText = ((BYTE *)(pEdit+1));
    memcpy(pEdit->pText, pText, pEdit->textLength);
    pEdit->pText[pEdit->textLength] = 0;  

    pEdit->selStart = 0;    pEdit->selEnd = 0;
    pEdit->Timer = 0;
    pEdit->xCursor = 0; 

    ShowView(pEdit->pView);

    return (pEdit);
}

const BYTE * GetPureEditText(PEDIT *pEdit)
{
    if (pEdit != NULL)
        return (pEdit->pText);
    else
        return (NULL);
}

void DeletePureEdit(PEDIT *pEdit)
{
    if (pEdit == NULL) return;
    DeleteView(pEdit->pView);
}

/*
 *******************************************************************************
 *                                                                             *
 *******************************************************************************
 */

⌨️ 快捷键说明

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