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

📄 ebmedit.c

📁 基于minigui开发的一套图形控件系统
💻 C
📖 第 1 页 / 共 5 页
字号:
// $Id: ebmedit.c,v 1.5 2005/10/17 07:50:14 tangjb Exp $

//

// medit.c: the Multi-Line Edit Control module.

//

// Copyright (C) 1999, 2000, Chen Lei

// Copyright (C) 1999, 2000, 2001, 2002, Wei Yongming.

// 

// Current maintainer: Chen Lei (chenlei@minigui.org).

//

/*

**  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.

*/



// Create date: 1999/8/26

//

// Modify records:

//

//  Who             When        Where       For What                Status

//-----------------------------------------------------------------------------

//  WEI Yongming    2000/02/24  Tsinghua    Add MPL License         Finished

//  leon            2000/11/07  BJ         	Optimize display        Finished

//  leon            2000/11/07  BJ          Fix bugs                Finished

//  leon            2000/11     BJ          Multi-Charset support   Finished

//  leon			2000/12/28  BJ          Fix bug                 

//											M$ like Scrolling		Finished 

//	leon			2001/04/08  BluePoint	autowrap support		Finished



// TODO:

//    * Selection.

//    * Undo.



#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <ctype.h>



#include <minigui/common.h>

#include <minigui/minigui.h>

#include <minigui/gdi.h>

#include <minigui/window.h>

#include <minigui/control.h>



#if 0

#include "cliprect.h"

#include "internals.h"

#include "ctrlclass.h"

#endif

#include "ctrlmisc.h"

#include "ebmedit.h"

#include "ebcontrol.h"

#include "ebedit.h"



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



BOOL RegisterEBMLEditControl (void)

{

    // This control class has two names: "medit" and "mledit"



    WNDCLASS WndClass;



    WndClass.spClassName = "ebmedit";

    WndClass.dwStyle     = WS_NONE;

    WndClass.dwExStyle   = WS_EX_NONE;

    WndClass.hCursor     = GetSystemCursor (IDC_IBEAM);

    WndClass.iBkColor    = PIXEL_lightwhite;

    WndClass.WinProc     = EBMLEditCtrlProc;



    if (AddNewControlClass (&WndClass) != ERR_OK)

        return FALSE;



    WndClass.spClassName = "ebmledit";

    WndClass.dwStyle     = WS_NONE;

    WndClass.dwExStyle   = WS_EX_NONE;

    WndClass.hCursor     = GetSystemCursor (IDC_IBEAM);

    WndClass.iBkColor    = PIXEL_lightwhite;

    WndClass.WinProc     = EBMLEditCtrlProc;



    return AddNewControlClass (&WndClass) == ERR_OK;

}





void EBMLEditControlCleanup (void)

{

    // do nothing

    UnregisterWindowClass ("ebmedit");

	UnregisterWindowClass ("ebmledit");

    return;

}





static inline int edtGetOutWidth (HWND hWnd)

{

	PEBMLEDITDATA pMLEditData =(PEBMLEDITDATA) GetWindowAdditionalData2(hWnd);

	RECT rc;

	GetClientRect(hWnd,&rc);



    return RECTW(rc) - pMLEditData->leftMargin - pMLEditData->rightMargin;

}



static int edtGetLineNO (const EBMLEDITDATA* pMLEditData, int x)

{

    int nline = 0;

	if(x>=0)

	{

	    nline = x / pMLEditData->lineHeight;

		if (nline <= pMLEditData->linesDisp)

   			return nline;

	}

	return -1;

}



int GetRETURNPos(char *str)

{

	int i;

	for(i=0;i<strlen(str);i++)

	{	

		if(str[i]==10)

			return i;

	}

	return -1;

}



void MLEditEmptyBuffer(PEBMLEDITDATA pMLEditData)

{

    PEBLINEDATA temp;

    PEBLINEDATA  pLineData;

    pLineData = pMLEditData->head;

    while(pLineData)

    {

        temp = pLineData->next;

        free(pLineData);

        pLineData = temp;

    }

    pMLEditData->head = NULL;

}



// get next wrap line start address according to startPos

// > 0 : next start position

// -1  : end of current line

static int edtGetnextStartPos (HWND hWnd, PEBMLEDITDATA pMLEditData, int startPos)

{

	int		i = 0;

	int		outwidth = edtGetOutWidth (hWnd);

	

	if (!pMLEditData->dx_chars) 

		return -1;



	if (pMLEditData->sz.cx - pMLEditData->dx_chars[startPos] <= outwidth)

		return -1;

	

	for (i = startPos; i < pMLEditData->fit_chars+1; i++) 

	{

		if (pMLEditData->dx_chars[i]-pMLEditData->dx_chars[startPos] >= outwidth)

			return i-1;

	}

	return -1;

}



static void edtGetLineInfoEx (HWND hWnd, PEBMLEDITDATA pMLEditData, PEBLINEDATA pLineData)

{

	HDC	hdc = GetClientDC (hWnd);

	

	if (!pMLEditData) 

		pMLEditData = (PEBMLEDITDATA) GetWindowAdditionalData2(hWnd);



#if 0

    if (pMLEditData->logfont)

        SelectFont (hdc, pMLEditData->logfont);

#endif



	GetTextExtentPoint (hdc,

				   		pLineData->buffer, 

						pLineData->dataEnd,  

						GetMaxFontWidth(hdc)*LEN_MLEDIT_BUFFER,//自动换行时,最大的宽度应该为控件的宽度?????

				        &(pMLEditData->fit_chars), 

						pMLEditData->pos_chars, 

						pMLEditData->dx_chars, 

						&(pMLEditData->sz));

	

	ReleaseDC (hdc);



	if (pMLEditData->pos_chars)

		pMLEditData->pos_chars[pMLEditData->fit_chars] = pLineData->dataEnd;

	if (pMLEditData->dx_chars)

		pMLEditData->dx_chars[pMLEditData->fit_chars] = pMLEditData->sz.cx;

}



static void edtGetLineInfo (HWND hWnd, PEBLINEDATA pLineData)

{

	edtGetLineInfoEx (hWnd, NULL, pLineData);

}



static int edtGetStartDispPosAtEnd (HWND hWnd,

            PEBLINEDATA pLineData)

{

	PEBMLEDITDATA pMLEditData =(PEBMLEDITDATA) GetWindowAdditionalData2(hWnd);

	int			i = 0;

	int 		dist = MAX_IMPOSSIBLE;

	int 		newdist = 0;

	

	edtGetLineInfo (hWnd, pLineData);



	if (pMLEditData->sz.cx <= edtGetOutWidth (hWnd)) 

		return 0;

	

	for (i = 0; i < pMLEditData->fit_chars-1; i++) 

	{

		newdist = (pMLEditData->sz.cx - edtGetOutWidth (hWnd)) - pMLEditData->dx_chars[i];

		if (newdist >= 0 && newdist < dist) 

		{

			dist = newdist;

			if (dist == 0) 

				return i; 

		}

		else 

			return i; 

	}

	return 0;

}



void calcLineInfo(HWND hWnd, PEBMLEDITDATA pMLEditData, PEBLINEDATA pLineData)

{

	int i;

		

	edtGetLineInfoEx (hWnd, pMLEditData, pLineData);



	for ( i=0,pLineData->nwrapline=1,pLineData->wrapStartPos[0]=0; 

		 (i = edtGetnextStartPos(hWnd, pMLEditData,i)) > 0; 

		  pLineData->nwrapline++ )

	{

		pLineData->wrapStartPos[pLineData->nwrapline] = i;

	}

	pLineData->wrapStartPos[pLineData->nwrapline] = pMLEditData->fit_chars;

}



void MLEditInitBuffer (HWND hWnd, PEBMLEDITDATA pMLEditData, const char *spcaption, DWORD dwStyle)

{

	char *caption=(char*)spcaption; 

    int off1;

	int lineNO=0;

	PEBLINEDATA  pLineData;



	if (!(pMLEditData->head = calloc (1, sizeof (EBLINEDATA)))) {

		return ;

	}

	pMLEditData->head->previous = NULL;

	pLineData = pMLEditData->head;	

	pMLEditData->wraplines = 0;

	

	while ( (off1 = GetRETURNPos(caption)) != -1)

	{

		int off;

		off1 = MIN (off1, LEN_MLEDIT_BUFFER);

		if ((char)caption[off1-1] == '\r')

			off = off1-1;

		else

			off = off1;

		

		if ((pMLEditData->curtotalLen + MIN (off,LEN_MLEDIT_BUFFER) >= pMLEditData->totalLimit)

			&& pMLEditData->totalLimit != -1)

		{			

			pLineData->dataEnd = pMLEditData->totalLimit-pMLEditData->curtotalLen;

			caption += MIN (pLineData->dataEnd, LEN_MLEDIT_BUFFER) + 1;



			if (pLineData->dataEnd-2 > 0 && (char)caption[pLineData->dataEnd-2] == '\r')

				pLineData->dataEnd -= 2;

			else if (pLineData->dataEnd-1 > 0 && (char)caption[pLineData->dataEnd-1] == '\n')

				pLineData->dataEnd --;



			memcpy(pLineData->buffer,caption, pLineData->dataEnd);

			pLineData->buffer[pLineData->dataEnd] = '\0';

			pLineData->lineNO  = lineNO++;

			pMLEditData->curtotalLen += pLineData->dataEnd;

			

			if (!pLineData->dataEnd)

			{

				pLineData->nwrapline = 1;

				pLineData->wrapStartPos[0] = 0;

				pLineData->wrapStartPos[1] = 0;

			} else

				calcLineInfo (hWnd, pMLEditData, pLineData);



			pMLEditData->wraplines += pLineData->nwrapline;

			pLineData->lineNO  = lineNO++;	



			if (pMLEditData->curtotalLen == pMLEditData->totalLimit)

			{

				pLineData->next = NULL;

				break;

			} else if (pMLEditData->curtotalLen + 1 < pMLEditData->totalLimit)

				pMLEditData->curtotalLen ++;

			pLineData->next    = malloc (sizeof (EBLINEDATA));

			pLineData->next->previous = pLineData; 

			pLineData->next->next = NULL;

			pLineData = pLineData->next;

			break;

		}

		

		memcpy(pLineData->buffer,caption, off1);

		if (pLineData->buffer[off1-1] == '\r')

			pLineData->buffer[off1-1] = '\0';

		else

			pLineData->buffer[off1] = '\0';

		

		caption += MIN (off1,LEN_MLEDIT_BUFFER)+1;

		

		pLineData->lineNO  = lineNO++;	

		pLineData->dataEnd = strlen(pLineData->buffer); 

		if (!pLineData->dataEnd)

		{

			pLineData->nwrapline = 1;

			pLineData->wrapStartPos[0] = 0;

			pLineData->wrapStartPos[1] = 0;

		}

		else

			calcLineInfo (hWnd, pMLEditData, pLineData);



		pMLEditData->wraplines += pLineData->nwrapline;



		pMLEditData->curtotalLen += pLineData->dataEnd;

		if (pMLEditData->curtotalLen == pMLEditData->totalLimit)

		{

			pLineData->next = NULL;

			break;

		} else if (pMLEditData->curtotalLen + 1 < pMLEditData->totalLimit)

			pMLEditData->curtotalLen ++;



		pLineData->next = malloc(sizeof (EBLINEDATA));

		pLineData->next->previous = pLineData; 

		pLineData->next->next = NULL;

		pLineData = pLineData->next;

	}

	

	if (pMLEditData->totalLimit > 0 && pMLEditData->curtotalLen < pMLEditData->totalLimit)

	{

		int off=0;

		off1 = MIN(strlen(caption), LEN_MLEDIT_BUFFER);

		if (off1 && (char)caption[off1-1] == '\r')

			off = off1-1;

		else

			off = off1;		

		if (pMLEditData->curtotalLen + MIN (off,LEN_MLEDIT_BUFFER) >= pMLEditData->totalLimit)

		{

			pLineData->dataEnd = pMLEditData->totalLimit-pMLEditData->curtotalLen;

			if (pLineData->dataEnd-2 > 0 && (char)caption[pLineData->dataEnd-2] == '\r')

				pLineData->dataEnd -= 2;

			else if (pLineData->dataEnd-1 > 0 && (char)caption[pLineData->dataEnd-1] == '\n')

				pLineData->dataEnd --;



			memcpy(pLineData->buffer,caption, pLineData->dataEnd);

			pLineData->buffer[pLineData->dataEnd] = '\0';



		}

		else 

		{

			memcpy(pLineData->buffer, caption, off1);

			if (off1 && pLineData->buffer[off1-1] == '\r')

				pLineData->buffer[off1-1] = '\0';

			else

				pLineData->buffer[off1] = '\0';

			pLineData->dataEnd 	= strlen(pLineData->buffer); 

			pLineData->next    	= NULL; 



		}

		

		pMLEditData->curtotalLen += pLineData->dataEnd;

		if (pMLEditData->curtotalLen == pMLEditData->totalLimit-1)

			pMLEditData->curtotalLen = pMLEditData->totalLimit;

		if (!pLineData->dataEnd)

		{

			pLineData->nwrapline = 1;

			pLineData->wrapStartPos[0] = 0;

			pLineData->wrapStartPos[1] = 0;

		} 

		else

	  		calcLineInfo (hWnd, pMLEditData, pLineData);



		pMLEditData->wraplines += pLineData->nwrapline;

		pLineData->lineNO = lineNO++;

	}

	pMLEditData->lines = lineNO; 



	if (dwStyle & EES_AUTOWRAP)

		pMLEditData->linesDisp = MIN(pMLEditData->wraplines, pMLEditData->MaxlinesDisp);

⌨️ 快捷键说明

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