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

📄 editbox.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 3 页
字号:
/* ------------- editbox.c ------------ */
#include "dflat.h"

#define EditBufLen(wnd) (DfIsMultiLine(wnd) ? DF_EDITLEN : DF_ENTRYLEN)
#define SetLinePointer(wnd, ln) (wnd->CurrLine = ln)
#define isWhite(c)     ((c)==' '||(c)=='\n')
/* ---------- local prototypes ----------- */
static void SaveDeletedText(DFWINDOW, char *, int);
static void Forward(DFWINDOW);
static void Backward(DFWINDOW);
static void End(DFWINDOW);
static void Home(DFWINDOW);
static void Downward(DFWINDOW);
static void Upward(DFWINDOW);
static void StickEnd(DFWINDOW);
static void NextWord(DFWINDOW);
static void PrevWord(DFWINDOW);
static void ModTextPointers(DFWINDOW, int, int);
static void SetAnchor(DFWINDOW, int, int);
/* -------- local variables -------- */
static BOOL KeyBoardMarking, ButtonDown;
static BOOL TextMarking;
static int ButtonX, ButtonY;
static int PrevY = -1;

/* ----------- DFM_CREATE_WINDOW Message ---------- */
static int CreateWindowMsg(DFWINDOW wnd)
{
    int rtn = DfBaseWndProc(DF_EDITBOX, wnd, DFM_CREATE_WINDOW, 0, 0);
    wnd->MaxTextLength = DF_MAXTEXTLEN+1;
    wnd->textlen = EditBufLen(wnd);
    wnd->InsertMode = TRUE;
	DfSendMessage(wnd, DFM_CLEARTEXT, 0, 0);
    return rtn;
}
/* ----------- DFM_SETTEXT Message ---------- */
static int SetTextMsg(DFWINDOW wnd, DF_PARAM p1)
{
    int rtn = FALSE;
    if (strlen((char *)p1) <= wnd->MaxTextLength)
        rtn = DfBaseWndProc(DF_EDITBOX, wnd, DFM_SETTEXT, p1, 0);
    return rtn;
}
/* ----------- DFM_CLEARTEXT Message ------------ */
static int ClearTextMsg(DFWINDOW wnd)
{
    int rtn = DfBaseWndProc(DF_EDITBOX, wnd, DFM_CLEARTEXT, 0, 0);
    unsigned blen = EditBufLen(wnd)+2;
    wnd->text = DfRealloc(wnd->text, blen);
    memset(wnd->text, 0, blen);
    wnd->wlines = 0;
    wnd->CurrLine = 0;
    wnd->CurrCol = 0;
    wnd->WndRow = 0;
    wnd->wleft = 0;
    wnd->wtop = 0;
    wnd->textwidth = 0;
    wnd->TextChanged = FALSE;
    return rtn;
}
/* ----------- DFM_ADDTEXT Message ---------- */
static int AddTextMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2)
{
    int rtn = FALSE;
    if (strlen((char *)p1)+wnd->textlen <= wnd->MaxTextLength) {
        rtn = DfBaseWndProc(DF_EDITBOX, wnd, DFM_ADDTEXT, p1, p2);
        if (rtn != FALSE)    {
            if (!DfIsMultiLine(wnd))    {
                wnd->CurrLine = 0;
                wnd->CurrCol = strlen((char *)p1);
                if (wnd->CurrCol >= DfClientWidth(wnd))    {
                    wnd->wleft = wnd->CurrCol-DfClientWidth(wnd);
                    wnd->CurrCol -= wnd->wleft;
                }
                wnd->BlkEndCol = wnd->CurrCol;
                DfSendMessage(wnd, DFM_KEYBOARD_CURSOR,
                                     DfWndCol, wnd->WndRow);
            }
        }
    }
    return rtn;
}
/* ----------- DFM_GETTEXT Message ---------- */
static int GetTextMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2)
{
    char *cp1 = (char *)p1;
    char *cp2 = wnd->text;
    if (cp2 != NULL)    {
        while (p2-- && *cp2 && *cp2 != '\n')
            *cp1++ = *cp2++;
        *cp1 = '\0';
        return TRUE;
    }
    return FALSE;
}
/* ----------- DFM_SETTEXTLENGTH Message ---------- */
static int SetTextLengthMsg(DFWINDOW wnd, unsigned int len)
{
    if (++len < DF_MAXTEXTLEN)    {
        wnd->MaxTextLength = len;
        if (len < wnd->textlen)    {
            wnd->text=DfRealloc(wnd->text, len+2);
            wnd->textlen = len;
            *((wnd->text)+len) = '\0';
            *((wnd->text)+len+1) = '\0';
            DfBuildTextPointers(wnd);
        }
        return TRUE;
    }
    return FALSE;
}
/* ----------- DFM_KEYBOARD_CURSOR Message ---------- */
static void KeyboardCursorMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2)
{
    wnd->CurrCol = (int)p1 + wnd->wleft;
    wnd->WndRow = (int)p2;
    wnd->CurrLine = (int)p2 + wnd->wtop;
    if (wnd == DfInFocus)	{
		if (DfCharInView(wnd, (int)p1, (int)p2))
	        DfSendMessage(NULL, DFM_SHOW_CURSOR,
				(wnd->InsertMode && !TextMarking), 0);
    	else
			DfSendMessage(NULL, DFM_HIDE_CURSOR, 0, 0);
	}
}
/* ----------- SIZE Message ---------- */
int SizeMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2)
{
    int rtn = DfBaseWndProc(DF_EDITBOX, wnd, DFM_DFM_SIZE, p1, p2);
    if (DfWndCol > DfClientWidth(wnd)-1)
        wnd->CurrCol = DfClientWidth(wnd)-1 + wnd->wleft;
    if (wnd->WndRow > DfClientHeight(wnd)-1)    {
        wnd->WndRow = DfClientHeight(wnd)-1;
        SetLinePointer(wnd, wnd->WndRow+wnd->wtop);
    }
    DfSendMessage(wnd, DFM_KEYBOARD_CURSOR, DfWndCol, wnd->WndRow);
    return rtn;
}
/* ----------- DFM_SCROLL Message ---------- */
static int ScrollMsg(DFWINDOW wnd, DF_PARAM p1)
{
    int rtn = FALSE;
    if (DfIsMultiLine(wnd))    {
        rtn = DfBaseWndProc(DF_EDITBOX,wnd,DFM_SCROLL,p1,0);
        if (rtn != FALSE)    {
            if (p1)    {
                /* -------- scrolling up --------- */
                if (wnd->WndRow == 0)    {
                    wnd->CurrLine++;
                    StickEnd(wnd);
                }
                else
                    --wnd->WndRow;
            }
            else    {
                /* -------- scrolling down --------- */
                if (wnd->WndRow == DfClientHeight(wnd)-1)    {
                    if (wnd->CurrLine > 0)
                        --wnd->CurrLine;
                    StickEnd(wnd);
                }
                else
                    wnd->WndRow++;
            }
            DfSendMessage(wnd,DFM_KEYBOARD_CURSOR,DfWndCol,wnd->WndRow);
        }
    }
    return rtn;
}
/* ----------- DFM_HORIZSCROLL Message ---------- */
static int HorizScrollMsg(DFWINDOW wnd, DF_PARAM p1)
{
    int rtn = FALSE;
    char *currchar = DfCurrChar;
    if (!(p1 &&
            wnd->CurrCol == wnd->wleft && *currchar == '\n'))  {
        rtn = DfBaseWndProc(DF_EDITBOX, wnd, DFM_HORIZSCROLL, p1, 0);
        if (rtn != FALSE)    {
            if (wnd->CurrCol < wnd->wleft)
                wnd->CurrCol++;
            else if (DfWndCol == DfClientWidth(wnd))
                --wnd->CurrCol;
            DfSendMessage(wnd,DFM_KEYBOARD_CURSOR,DfWndCol,wnd->WndRow);
        }
    }
    return rtn;
}
/* ----------- DFM_SCROLLPAGE Message ---------- */
static int ScrollPageMsg(DFWINDOW wnd, DF_PARAM p1)
{
    int rtn = FALSE;
    if (DfIsMultiLine(wnd))    {
        rtn = DfBaseWndProc(DF_EDITBOX, wnd, DFM_SCROLLPAGE, p1, 0);
        SetLinePointer(wnd, wnd->wtop+wnd->WndRow);
        StickEnd(wnd);
        DfSendMessage(wnd, DFM_KEYBOARD_CURSOR,DfWndCol, wnd->WndRow);
    }
    return rtn;
}
/* ----------- HORIZSCROLLPAGE Message ---------- */
static int HorizPageMsg(DFWINDOW wnd, DF_PARAM p1)
{
    int rtn = DfBaseWndProc(DF_EDITBOX, wnd, DFM_HORIZPAGE, p1, 0);
    if ((int) p1 == FALSE)    {
        if (wnd->CurrCol > wnd->wleft+DfClientWidth(wnd)-1)
            wnd->CurrCol = wnd->wleft+DfClientWidth(wnd)-1;
    }
    else if (wnd->CurrCol < wnd->wleft)
        wnd->CurrCol = wnd->wleft;
    DfSendMessage(wnd, DFM_KEYBOARD_CURSOR, DfWndCol, wnd->WndRow);
    return rtn;
}
/* ----- Extend the marked block to the new x,y position ---- */
static void ExtendBlock(DFWINDOW wnd, int x, int y)
{
    int bbl, bel;
    int ptop = min(wnd->BlkBegLine, wnd->BlkEndLine);
    int pbot = max(wnd->BlkBegLine, wnd->BlkEndLine);
    char *lp = DfTextLine(wnd, wnd->wtop+y);
    int len = (int) (strchr(lp, '\n') - lp);
    x = max(0, min(x, len));
    y = max(0, y);
    wnd->BlkEndCol = min(len, x+wnd->wleft);
    wnd->BlkEndLine = y+wnd->wtop;
    DfSendMessage(wnd, DFM_KEYBOARD_CURSOR, wnd->BlkEndCol, wnd->BlkEndLine);
    bbl = min(wnd->BlkBegLine, wnd->BlkEndLine);
    bel = max(wnd->BlkBegLine, wnd->BlkEndLine);
    while (ptop < bbl)    {
        DfWriteTextLine(wnd, NULL, ptop, FALSE);
        ptop++;
    }
    for (y = bbl; y <= bel; y++)
        DfWriteTextLine(wnd, NULL, y, FALSE);
    while (pbot > bel)    {
        DfWriteTextLine(wnd, NULL, pbot, FALSE);
        --pbot;
    }
}
/* ----------- DFM_LEFT_BUTTON Message ---------- */
static int LeftButtonMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2)
{
    int MouseX = (int) p1 - DfGetClientLeft(wnd);
    int MouseY = (int) p2 - DfGetClientTop(wnd);
    DFRECT rc = DfClientRect(wnd);
    char *lp;
    int len;
    if (KeyBoardMarking)
        return TRUE;
    if (DfWindowMoving || DfWindowSizing)
        return FALSE;
    if (DfIsMultiLine(wnd))    {
        if (TextMarking)    {
            if (!DfInsideRect(p1, p2, rc))    {
				int x = MouseX, y = MouseY;
				int dir;
				DFMESSAGE msg = 0;
                if ((int)p2 == DfGetTop(wnd))
					y++, dir = FALSE, msg = DFM_SCROLL;
                else if ((int)p2 == DfGetBottom(wnd))
					--y, dir = TRUE, msg = DFM_SCROLL;
                else if ((int)p1 == DfGetLeft(wnd))
					--x, dir = FALSE, msg = DFM_HORIZSCROLL;
                else if ((int)p1 == DfGetRight(wnd))
					x++, dir = TRUE, msg = DFM_HORIZSCROLL;
				if (msg != 0)	{
                    if (DfSendMessage(wnd, msg, dir, 0))
                        ExtendBlock(wnd, x, y);
	                DfSendMessage(wnd, DFM_PAINT, 0, 0);
				}
            }
            return TRUE;
        }
        if (!DfInsideRect(p1, p2, rc))
            return FALSE;
        if (DfTextBlockMarked(wnd))    {
            DfClearTextBlock(wnd);
            DfSendMessage(wnd, DFM_PAINT, 0, 0);
        }
        if (wnd->wlines)    {
            if (MouseY > wnd->wlines-1)
                return TRUE;
            lp = DfTextLine(wnd, MouseY+wnd->wtop);
            len = (int) (strchr(lp, '\n') - lp);
            MouseX = min(MouseX, len);
            if (MouseX < wnd->wleft)    {
                MouseX = 0;
                DfSendMessage(wnd, DFM_KEYBOARD, DF_HOME, 0);
            }
            ButtonDown = TRUE;
            ButtonX = MouseX;
            ButtonY = MouseY;
        }
        else
            MouseX = MouseY = 0;
        wnd->WndRow = MouseY;
        SetLinePointer(wnd, MouseY+wnd->wtop);
    }
    if (DfIsMultiLine(wnd) ||
        (!DfTextBlockMarked(wnd)
            && (int)(MouseX+wnd->wleft) < (int)strlen(wnd->text)))
        wnd->CurrCol = MouseX+wnd->wleft;
    DfSendMessage(wnd, DFM_KEYBOARD_CURSOR, DfWndCol, wnd->WndRow);
    return TRUE;
}
/* ----------- MOUSE_MOVED Message ---------- */
static int MouseMovedMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2)
{
    int MouseX = (int) p1 - DfGetClientLeft(wnd);
    int MouseY = (int) p2 - DfGetClientTop(wnd);
    DFRECT rc = DfClientRect(wnd);
    if (!DfInsideRect(p1, p2, rc))
        return FALSE;
    if (MouseY > wnd->wlines-1)
        return FALSE;
    if (ButtonDown)    {
        SetAnchor(wnd, ButtonX+wnd->wleft, ButtonY+wnd->wtop);
        TextMarking = TRUE;
		rc = DfWindowRect(wnd);
        DfSendMessage(NULL,DFM_MOUSE_TRAVEL,(DF_PARAM) &rc, 0);
        ButtonDown = FALSE;
    }
    if (TextMarking && !(DfWindowMoving || DfWindowSizing))    {
        ExtendBlock(wnd, MouseX, MouseY);
        return TRUE;
    }
    return FALSE;
}
static void StopMarking(DFWINDOW wnd)
{
    TextMarking = FALSE;
    if (wnd->BlkBegLine > wnd->BlkEndLine)    {
        swap(wnd->BlkBegLine, wnd->BlkEndLine);
        swap(wnd->BlkBegCol, wnd->BlkEndCol);
    }
    if (wnd->BlkBegLine == wnd->BlkEndLine &&
            wnd->BlkBegCol > wnd->BlkEndCol)
        swap(wnd->BlkBegCol, wnd->BlkEndCol);
}
/* ----------- BUTTON_RELEASED Message ---------- */
static int ButtonReleasedMsg(DFWINDOW wnd)
{
    if (DfIsMultiLine(wnd))    {
        ButtonDown = FALSE;
        if (TextMarking && !(DfWindowMoving || DfWindowSizing))  {
            /* release the mouse ouside the edit box */
            DfSendMessage(NULL, DFM_MOUSE_TRAVEL, 0, 0);
            StopMarking(wnd);
            return TRUE;
        }
        else
            PrevY = -1;
    }
    return FALSE;
}
/* ---- Process text block keys for multiline text box ---- */
static void DoMultiLines(DFWINDOW wnd, int c, DF_PARAM p2)
{
    if (DfIsMultiLine(wnd) && !KeyBoardMarking)    {
        if ((int)p2 & (DF_LEFTSHIFT | DF_RIGHTSHIFT))    {
            switch (c)    {
                case DF_HOME:
                case DF_CTRL_HOME:
                case DF_CTRL_BS:
                case DF_PGUP:
                case DF_CTRL_PGUP:
                case DF_UP:
                case DF_BS:
                case DF_END:
                case DF_CTRL_END:
                case DF_PGDN:
                case DF_CTRL_PGDN:
                case DF_DN:

⌨️ 快捷键说明

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