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

📄 edit.c

📁 TN-kernel内核针对LPC系列ARM7处理器和S3C44B0X重新定制好的源代码包。内含Nano-X GUI。
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * Copyright (C) 1999, 2000, Wei Yongming.
 * Portions Copyright (c) 2000 Greg Haerr <greg@censoft.com>
 *
 * Edit control for Microwindows win32 api.
 */

/*
**  This library is free software; you can redistribute it and/or
**  modify it under the terms of the GNU Library General Public
**  License as published by the Free Software Foundation; either
**  version 2 of the License, or (at your option) any later version.
**
**  This library is distributed in the hope that it will be useful,
**  but WITHOUT ANY WARRANTY; without even the implied warranty of
**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
**  Library General Public License for more details.
**
**  You should have received a copy of the GNU Library General Public
**  License along with this library; if not, write to the Free
**  Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
**  MA 02111-1307, USA
*/

/*
**  Alternatively, the contents of this file may be used under the terms
**  of the Mozilla Public License (the "MPL License") in which case the
**  provisions of the MPL License are applicable instead of those above.
*/

/* Note:
**  Although there was a version by Zhao Jianghua, this version of
**  EDIT control is written by Wei Yongming from scratch.
**
** Create date: 1999/8/26
**
** Modify records:
**
**  Who             When        Where       For What                Status
**-----------------------------------------------------------------------------
**  WEI Yongming    2000/02/24  Tsinghua    Add MPL License         Finished
**  Kevin Tseng     2000/05/30  gv          port to microwin        ported
**  Greg Haerr      2000/06/16  Utah        3d look, bug fixes      Finished
**  Kevin Tseng     2000/06/22  gv          port to mw-nanox        ported
**
** TODO:
**    * Selection.
**    * Undo.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MWINCLUDECOLORS
#include "windows.h"        /* windef.h, winuser.h */
#include "wintools.h"
#include "device.h"         /* GdGetTextSize */

#if HAVE_HZK_SUPPORT || HAVE_BIG5_SUPPORT
#define USE_BIG5
#define DEFAULT_FONT        SYSTEM_FIXED_FONT
#else
#define DEFAULT_FONT        DEFAULT_GUI_FONT
#endif

#define WIDTH_EDIT_BORDER       2
#define MARGIN_EDIT_LEFT        1
#define MARGIN_EDIT_TOP         1
#define MARGIN_EDIT_RIGHT       2
#define MARGIN_EDIT_BOTTOM      1

#define LEN_SLEDIT_BUFFER       3000
#define LEN_SLEDIT_UNDOBUFFER   1024

#define EST_FOCUSED     0x00000001L
#define EST_MODIFY      0x00000002L
#define EST_READONLY    0x00000004L
#define EST_REPLACE     0x00000008L

#define EDIT_OP_NONE    0x00
#define EDIT_OP_DELETE  0x01
#define EDIT_OP_INSERT  0x02
#define EDIT_OP_REPLACE 0x03

typedef struct tagSLEDITDATA {
    HFONT   hFont;          /* hFont used */
    int     bufferLen;      /* length of buffer */

    int     dataEnd;        /* data end position */
    int     editPos;        /* current edit position */
    int     caretOff;       /* caret offset in box */
    int     startPos;       /* start display position */

    int     selStart;       /* selection start position */
    int     selEnd;         /* selection end position */

    int     passwdChar;     /* password character */

    int     leftMargin;     /* left margin */
    int     topMargin;      /* top margin */
    int     rightMargin;    /* right margin */
    int     bottomMargin;   /* bottom margin */

    int     hardLimit;      /* hard limit */

    int     lastOp;         /* last operation */
    int     lastPos;        /* last operation position */
    int     affectedLen;    /* affected len of last operation */
    int     undoBufferLen;  /* undo buffer len */
    char    undoBuffer [LEN_SLEDIT_UNDOBUFFER];        /* Undo buffer; */
    char    buffer [LEN_SLEDIT_BUFFER];                /* buffer */
} SLEDITDATA, *PSLEDITDATA;

static LRESULT CALLBACK
SLEditCtrlProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

static int GetSysCharHeight (HWND hwnd)
{
#ifndef USE_BIG5
        HDC                 hdc;
            int xw, xh, xb;

            hdc = GetDC(hwnd);
        SelectObject(hdc, GetStockObject(DEFAULT_FONT));
        GdSetFont(hdc->font->pfont);
            GdGetTextSize(hdc->font->pfont,"X",1, &xw,&xh,&xb,MWTF_ASCII);
            ReleaseDC(hwnd,hdc);

        return xh;
#else
        return 12;
#endif
}

static int GetSysCharWidth (HWND hwnd)
{
#ifndef USE_BIG5
        HDC                 hdc;
            int xw, xh, xb;

            hdc = GetDC(hwnd);
        SelectObject(hdc, GetStockObject(DEFAULT_FONT));
        GdSetFont(hdc->font->pfont);
            GdGetTextSize(hdc->font->pfont,"X",1, &xw,&xh,&xb,MWTF_ASCII);
            ReleaseDC(hwnd,hdc);

        return xw;
#else
        return 6;
#endif
}

static int GetSysCCharWidth (HWND hwnd)
{
        return (2*GetSysCharWidth(hwnd));
}

int WINAPI MwRegisterEditControl(HINSTANCE hInstance)
{
        WNDCLASS        wc;

        wc.style        = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_GLOBALCLASS;
        wc.lpfnWndProc        = (WNDPROC)SLEditCtrlProc;
        wc.cbClsExtra        = 0;
        wc.cbWndExtra        = 0;
        wc.hInstance        = hInstance;
        wc.hIcon        = NULL;
        wc.hCursor        = 0; /*LoadCursor(NULL, IDC_ARROW);*/
        wc.hbrBackground= GetStockObject(WHITE_BRUSH);
        wc.lpszMenuName        = NULL;
        wc.lpszClassName= "EDIT";

        return RegisterClass(&wc);
}

static int edtGetOutWidth (const HWND pCtrl)
{
    return pCtrl->clirect.right - pCtrl->clirect.left
            - ((PSLEDITDATA)(pCtrl->userdata2))->leftMargin
            - ((PSLEDITDATA)(pCtrl->userdata2))->rightMargin;
}

static int edtGetStartDispPosAtEnd (const HWND pCtrl, PSLEDITDATA pSLEditData)
{
    int         nOutWidth = edtGetOutWidth (pCtrl);
    int         endPos  = pSLEditData->dataEnd;
    int         newStartPos = pSLEditData->startPos;
    const char* buffer = pSLEditData->buffer;

    while (TRUE) {
        if ((endPos - newStartPos) * GetSysCharWidth (pCtrl) < nOutWidth)
            break;

        /* FIXME: #ifdef GB2312?*/
        if ((BYTE)buffer [newStartPos] > 0xA0)        /* 1st:gb:a1-f7,big5:a1-f9 */
        {
            newStartPos ++;
            if (newStartPos < pSLEditData->dataEnd)
            {
#ifndef USE_BIG5
                if ((BYTE)buffer [newStartPos] > 0xA0)
#else        /* 2nd:gb:a1-fe,big5:40-7e,a1-fe */
                if ( ((BYTE)buffer [newStartPos] >= 0x40 && (BYTE)buffer[newStartPos] <= 0x7e) ||
                     ((BYTE)buffer [newStartPos] >= 0xa1 && (BYTE)buffer[newStartPos] <= 0xfe))
#endif
                    newStartPos ++;
            }
        }
        else
            newStartPos ++;
    }

    return newStartPos;
}

static int edtGetDispLen (const HWND pCtrl)
{
    int i, n = 0;
    int nOutWidth = edtGetOutWidth (pCtrl);
    int nTextWidth = 0;
    PSLEDITDATA pSLEditData = (PSLEDITDATA)(pCtrl->userdata2);
    const char* buffer = pSLEditData->buffer;

    for (i = pSLEditData->startPos; i < pSLEditData->dataEnd; i++) {
        /* FIXME #ifdef GB2312?*/
        if ((BYTE)buffer [i] > 0xA0)        /* st:gb:a1-f7,big5:a1-f9 */
        {
            i++;
            if (i < pSLEditData->dataEnd)
            {
#ifndef USE_BIG5
                if ((BYTE)buffer [i] > 0xA0)        /* 2nd:gb:a1-fe,big5:40-7e,a1-fe */
#else        /* 2nd:gb:a1-fe,big5:40-7e,a1-fe */
                if ( ((BYTE)buffer [i] >= 0x40 && (BYTE)buffer[i] <= 0x7e) ||
                     ((BYTE)buffer [i] >= 0xa1 && (BYTE)buffer[i] <= 0xfe))
#endif
                {
                    nTextWidth += GetSysCCharWidth (pCtrl);
                    n += 2;
                }
                else
                    i--;
            }
            else
            {
                nTextWidth += GetSysCharWidth (pCtrl);
                n++;
            }
        }
        else
        {
            nTextWidth += GetSysCharWidth (pCtrl);
            n++;
        }

        if (nTextWidth > nOutWidth)
            break;
    }

    return n;
}

static int edtGetOffset (HWND hwnd,const SLEDITDATA* pSLEditData, int x)
{
    int i;
    int newOff = 0;
    int nTextWidth = 0;
    const char* buffer = pSLEditData->buffer;

    x -= pSLEditData->leftMargin;
    for (i = pSLEditData->startPos; i < pSLEditData->dataEnd; i++) {
        if ((nTextWidth + (GetSysCharWidth(hwnd) >> 1)) >= x)
            break;

        /* FIXME #ifdef GB2312?*/
        if ((BYTE)buffer [i] > 0xA0)        /* 1st:gb:a1-f7,big5:a1-f9 */
        {
            i++;
            if (i < pSLEditData->dataEnd)
            {
#ifndef USE_BIG5
                if ((BYTE)buffer [i] > 0xA0)        /* 2nd:gb:a1-fe,big5:40-7e,a1-fe */
#else        /* 2nd:gb:a1-fe,big5:40-7e,a1-fe */
                if ( ((BYTE)buffer [i] >= 0x40 && (BYTE)buffer[i] <= 0x7e) ||
                     ((BYTE)buffer [i] >= 0xa1 && (BYTE)buffer[i] <= 0xfe))
#endif
                {
                    nTextWidth += GetSysCCharWidth (hwnd);
                    newOff += 2;
                }
                else
                    i --;
            }
            else
            {
                nTextWidth += GetSysCharWidth (hwnd);
                newOff ++;
            }
        }
        else
        {
            nTextWidth += GetSysCharWidth (hwnd);
            newOff ++;
        }

    }

    return newOff;
}

static BOOL edtIsACCharBeforePosition (const char* string, int pos)
{
    if (pos < 2)
        return FALSE;

/* 1st:gb:a1-f7,big5:a1-f9  2nd:gb:a1-fe,big5:40-7e,a1-fe */
#ifndef USE_BIG5
    /* FIXME #ifdef GB2312?*/
    if ((BYTE)string [pos - 2] > 0xA0 && (BYTE)string [pos - 1] > 0xA0)
        return TRUE;
#else
    if ((BYTE)string [pos - 2] > 0xA0)
    {
        if ( ((BYTE)string [pos - 1] >= 0x40 && (BYTE)string[pos - 1] <= 0x7e) ||
             ((BYTE)string [pos - 1] >= 0xa1 && (BYTE)string[pos - 1] <= 0xfe))
            return TRUE;
    }
#endif

    return FALSE;
}

static BOOL edtIsACCharAtPosition (const char* string, int len, int pos)
{
    if (pos > (len - 2))
        return FALSE;

/* 1st:gb:a1-f7,big5:a1-f9  2nd:gb:a1-fe,big5:40-7e,a1-fe */
#ifndef USE_BIG5
    if ((BYTE)string [pos] > 0xA0 && (BYTE)string [pos + 1] > 0xA0)
        return TRUE;
#else
    if ((BYTE)string [pos] > 0xA0)
    {
        if ( ((BYTE)string [pos + 1] >= 0x40 && (BYTE)string [pos + 1] <= 0x7e) ||
             ((BYTE)string [pos + 1] >= 0xa1 && (BYTE)string [pos + 1] <= 0xfe)) {
            /*fprintf(stderr,"true\n");
            fflush(stderr);*/
            return TRUE;
        }
    }
#endif

    return FALSE;
}

LRESULT CALLBACK
SLEditCtrlProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HWND        pCtrl;
    DWORD       dwStyle;
    HDC         hdc;
    PSLEDITDATA pSLEditData;
    RECT        rc;

    pCtrl       = hWnd;
    dwStyle     = pCtrl->style;

    switch (message)
    {
        case WM_CREATE:
            if (!(pSLEditData = GdMalloc (sizeof (SLEDITDATA))))
            {
            //    fprintf (stderr, "EDIT: malloc error!\n");
                return -1;
            }

            pSLEditData->hFont              = GetStockObject(DEFAULT_FONT);

            pSLEditData->bufferLen      = LEN_SLEDIT_BUFFER;
            pSLEditData->editPos        = 0;
            pSLEditData->caretOff       = 0;
            pSLEditData->startPos       = 0;

            pSLEditData->selStart       = 0;
            pSLEditData->selEnd         = 0;
            pSLEditData->passwdChar     = '*';
            pSLEditData->leftMargin     = MARGIN_EDIT_LEFT;
            pSLEditData->topMargin      = MARGIN_EDIT_TOP;
            pSLEditData->rightMargin    = MARGIN_EDIT_RIGHT;
            pSLEditData->bottomMargin   = MARGIN_EDIT_BOTTOM;

⌨️ 快捷键说明

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