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

📄 medit.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
 * Copyright (C) 1999, 2000, Wei Yongming.
 * Portions Copyright (c) 2000 Greg Haerr <greg@censoft.com>
 *
 * Multi Line 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/08/30  gv          port to microwin        ported
**
**
** TODO:
**    * Selection.
**    * Undo.
*/

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

#define USE_BIG5

#define WIDTH_MEDIT_BORDER       2
#define MARGIN_MEDIT_LEFT        1
#define MARGIN_MEDIT_TOP         1
#define MARGIN_MEDIT_RIGHT       2
#define MARGIN_MEDIT_BOTTOM      1

#define LEN_MLEDIT_BUFFER       3000
#define LEN_MLEDIT_UNDOBUFFER   1024

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

#define MEDIT_OP_NONE    0x00
#define MEDIT_OP_DELETE  0x01
#define MEDIT_OP_INSERT  0x02
#define MEDIT_OP_REPLACE 0x03

typedef struct tagLINEDATA {
	int     lineNO;	                  /* 行号 */
	int     dataEnd; 
	struct  tagLINEDATA *previous;    /* 前一行 */
	struct  tagLINEDATA *next;        /* 后一行 */
	char    buffer[LEN_MLEDIT_BUFFER+1];
}LINEDATA;
typedef    LINEDATA*     PLINEDATA;

#define ATTENG 0	/* english */
#define ATTCHL 1	/* chinese left(1st) byte */
#define ATTCHR 2	/* chinese right(2nd) byte */
static char attr[LEN_MLEDIT_BUFFER];

typedef struct tagMLEDITDATA {
    int     totalLen;      /* length of buffer,可能没有用 */

    int     editPos;        /* current edit position */
    int     caretPos;       /* caret offset in box */
    int     editLine;		/* current eidt line */
    int     dispPos;        /* 开始显示的位置 */
    int     StartlineDisp;  /* start line displayed */
    int     EndlineDisp;    /* end line displayed */
    int     linesDisp;      /* 需要显示的行数 */
    int     lines;		    /* 总的行数` */
    int     MaxlinesDisp;    /* 最大显示的行数. */
							
    int     selStartPos;    /* selection start position */
    int     selStartLine;   /* selection start line */
    int     selEndPos;      /* selection end position */
    int     selEndLine;     /* selection end line */
    
    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     lastLine;       /* last operation line */
    int     affectedLen;    /* affected len of last operation */
    int     undoBufferLen;  /* undo buffer len */
    char    undoBuffer [LEN_MLEDIT_UNDOBUFFER];
                            /* Undo buffer; */
    PLINEDATA   head;       /* buffer */
    PLINEDATA   tail;       /* 可能不需要 */
}MLEDITDATA;
typedef MLEDITDATA* PMLEDITDATA;

BOOL RegisterMLEditControl (void);

int MLEditCtrlProc (HWND hWnd, int message, WPARAM wParam, LPARAM lParam);

#define PIXEL_invalid (-1)
extern HWND sg_hCaretWnd;
extern HWND rootwp;

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));
}
char* GetWindowCaption (HWND hWnd)
{
    return hWnd->szTitle;
}

DWORD GetWindowAdditionalData (HWND hWnd)
{
        return hWnd->userdata;
}

DWORD SetWindowAdditionalData (HWND hWnd, DWORD newData)
{
    DWORD    oldOne = 0L;

    oldOne = hWnd->userdata;
    hWnd->userdata = newData;
    
    return oldOne;
}

DWORD GetWindowAdditionalData2 (HWND hWnd)
{
        return hWnd->userdata2;
}

DWORD SetWindowAdditionalData2 (HWND hWnd, DWORD newData)
{
    DWORD    oldOne = 0L;

    oldOne = hWnd->userdata2;
    hWnd->userdata2 = newData;
    
    return oldOne;
}

DWORD GetWindowStyle (HWND hWnd)
{
        return hWnd->style;
}

BOOL ExcludeWindowStyle (HWND hWnd, DWORD dwStyle)
{
    	if (hWnd == rootwp/*HWND_DESKTOP*/)
        	return FALSE;

        hWnd->style &= ~dwStyle;
        return TRUE;
}

BOOL IncludeWindowStyle (HWND hWnd, DWORD dwStyle)
{

    	if (hWnd == rootwp/*HWND_DESKTOP*/)
        	return FALSE;

        hWnd->style |= dwStyle;
        return TRUE;
}

int WINAPI MwRegisterMEditControl(HINSTANCE hInstance)
{
	WNDCLASS	wc;

	wc.style	= CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_GLOBALCLASS;
	wc.lpfnWndProc	= (WNDPROC)MLEditCtrlProc;
	wc.cbClsExtra	= 0;
	wc.cbWndExtra	= 0;
	wc.hInstance	= hInstance;
	wc.hIcon	= NULL;
	wc.hCursor	= 0; 
	wc.hbrBackground= GetStockObject(WHITE_BRUSH);
	wc.lpszMenuName	= NULL;
	wc.lpszClassName= "MEDIT";

	return RegisterClass(&wc);
}

static inline int edtGetOutWidth (HWND hWnd)
{
	PMLEDITDATA pMLEditData =(PMLEDITDATA) GetWindowAdditionalData2(hWnd);
	RECT rc;
	GetClientRect(hWnd,&rc);
    return rc.right - rc.left 
            - pMLEditData->leftMargin
            - pMLEditData->rightMargin;
}

static int edtGetStartDispPosAtEnd (HWND hWnd,
            PLINEDATA pLineData)
{
    int         nOutWidth = edtGetOutWidth (hWnd);
    int         endPos  = pLineData->dataEnd;
    PMLEDITDATA pMLEditData =(PMLEDITDATA) GetWindowAdditionalData2(hWnd);
    int         newStartPos = pMLEditData->dispPos;
    const char* buffer = pLineData->buffer;

    if(endPos < newStartPos)
		return 0;
    while (TRUE) 
    {
        if ((endPos - newStartPos) * GetSysCharWidth (hWnd) < nOutWidth)
            break;
        
        /* 1st:gb:a1-f7,big5:a1-f9 */
        if ((BYTE)buffer [newStartPos] > 0xA0)
	{
            newStartPos ++;
            if (newStartPos < pLineData->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 (HWND hWnd,PLINEDATA pLineData)
{
    int i, n = 0;
    int nOutWidth = edtGetOutWidth (hWnd);
    int nTextWidth = 0;
    PMLEDITDATA pMLEditData =(PMLEDITDATA) GetWindowAdditionalData2(hWnd);
    const char* buffer = pLineData->buffer;
    
    if(buffer[0]==0||pLineData->dataEnd<pMLEditData->dispPos)
		return 0;
	
    for (i = pMLEditData->dispPos; i < pLineData->dataEnd; i++) 
    {
        /* 1st:gb:a1-f7,big5:a1-f9 */
        if ((BYTE)buffer [i] > 0xA0)
   	{
            i++;
            if (i < pLineData->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);
                    n += 2;
                }
                else
                    i--;
            }
            else 
	    {
                nTextWidth += GetSysCharWidth (hWnd);
                n++;
            }
        }
        else 
	{
            nTextWidth += GetSysCharWidth (hWnd);
            n++;
        }

        if (nTextWidth > nOutWidth)
            break;
    }

    return n;
}

static int edtGetOffset (HWND hwnd,const MLEDITDATA* pMLEditData, PLINEDATA pLineData, int x)
{
    int i;
    int newOff = 0;
    int nTextWidth = 0;
    const char* buffer = pLineData->buffer;

    if(pLineData->dataEnd<pMLEditData->dispPos)
		return pLineData->dataEnd;

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

        /* 1st:gb:a1-f7,big5:a1-f9 */
        if ((BYTE)buffer [i] > 0xA0)
	{
            i++;

   	    if (nTextWidth + GetSysCCharWidth(hwnd)/2 >= x)
		break;

            if (i < pLineData->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 int edtGetLineNO (HWND hwnd,const MLEDITDATA* pMLEditData, int x)
{
    int nline = 0;
	if(x>=0)
	{
	    nline = x / GetSysCharHeight(hwnd);
		if (nline <= pMLEditData->linesDisp)
   			return nline;
	}
	return -1;
}

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;

⌨️ 快捷键说明

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