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

📄 newedit.c

📁 microwindows最新源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * NEW "EDIT control" for Microwindows win32 api. * * Copyright (C) 2003, Gabriele Brugnoni * <gabrielebrugnoni@dveprojects.com> * DVE Prog. El. - Varese, Italy * * Based on microwindows edit.c *  Copyright (C) 1999, 2000, Wei Yongming. *  Portions Copyright (c) 2000 Greg Haerr <greg@censoft.com> * *//* Note:**** Create date: 2003/09/02**** Modify records:****  Who             When        Where       For What                Status**-----------------------------------------------------------------------------**** TODO:**    * BIG5 font and cinese support**    * Multiline.**    * UNICODE ??.*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#define MWINCLUDECOLORS#include "windows.h"		/* windef.h, winuser.h */#include "wintern.h"#include "wintools.h"#include "device.h"		/* GdGetTextSize */#include "intl.h"// NOTE: #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       256#define LEN_SLEDIT_ADDBUFFER    256#define LEN_SLEDIT_REMOVEBUFFER 1024	// if great than this, realloc#define LEN_SLEDIT_UNDOBUFFER   1024#define EST_FOCUSED     	0x00000001L#define EST_MODIFY      	0x00000002L#define EST_READONLY    	0x00000004L#define EST_REPLACE     	0x00000008L#define EST_CTRL		0x00000010L#define EST_SHIFT		0x00000020L#define EST_SELSCROLLLEFT	0x00000040L#define EST_SELSCROLLRIGHT	0x00000080L#define EDIT_OP_NONE    	0x00#define EDIT_OP_DELETE  	0x01#define EDIT_OP_INSERT  	0x02#define EDIT_OP_REPLACE 	0x03//  Timers#define IDTM_SELSCROLLLEFT	0x101#define IDTM_SELSCROLLRIGHT	0x102#define TM_SELSCROLL		60	// timeout for scrollingchar mwDefEditCaretSize = 1;char mwDefEditCaretSizeIns = 3;typedef unsigned short EDITCHAR;#define SZEDITCHAR	sizeof(EDITCHAR)/* * Edit structure */typedef struct tagSLEDITDATA {	HFONT hFont;		/* hFont used */	int bufferLen;		/* length of buffer */	int dataEnd;		/* data end position */	int editPos;		/* current edit position */	int caretX;		/* caret X position in box */	int caretRow;		/* caret Y position in box */	int scrollX;		/* X scrolling offset */	int scrollRow;		/* Y scrolling offset */	int epX, epY;		/* coordinates of edit position */	int epFirstIdx;		/* index of the first character in line with editPos */	int epLineCount;	/* count of characters in line with editPos */	int epLineOX;		/* X origin of current line. Typically > 0 when right aligned */	int epLineAlign;	/* Alignement of current line. 0 = left align, 1 = right align */	int selStart;		/* selection start position */	int selEnd;		/* selection end position */	int selCenter;		/* selection cursor center */	int passwdChar;		/* password character */	int charHeight;		/* height of 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 */	EDITCHAR undoBuffer[LEN_SLEDIT_UNDOBUFFER];	/* Undo buffer; */	EDITCHAR *buffer;	/* buffer */	int cLines;		/* count of allocated (visible) lines info */} SLEDITDATA, *PSLEDITDATA;//  For future implementation of unicode...#define edit_memcpy		memcpy#define memcpy_fromedit		memcpy#define neTextOut		TextOutW#define neIsWord(c)		( (c) > 32 && (((c) > 127) || isalpha(c) || isdigit(c)) )// Drawing attributes#define NEDRAW_ENTIRE			0x0001#define NEDRAW_ROW				0x0002#define NEDRAW_CALC_CURSOR		0x0004#define NEDRAW_CALC_EDITPOS		0x0008static int neGetTextHeight(HWND hWnd, HDC hdc);static int neGetTextWith(HWND hWnd, HDC hdc, PSLEDITDATA pSLEditData,			 const EDITCHAR * txt, int len);static int neCharPressed(HWND hWnd, WPARAM wParam, LPARAM lParam);static void neRecalcRows(HWND hwnd, PSLEDITDATA * ppData);static void neDrawAllText(HWND hWnd, HDC hdc, PSLEDITDATA pSLEditData,			  int action);//  Clipboard for cut and paste.static EDITCHAR *neClipboard = NULL;static int neClipboardSize = 0;/* *  Create new edit control */static intneCreate(HWND hwnd){	PSLEDITDATA pSLEditData;	HWND pCtrl = hwnd;	int len;	int charH;	int nl;	RECT rc;	GetClientRect(hwnd, &rc);	nl = (rc.bottom - rc.top + charH - 1) / charH;	if (!(pSLEditData = malloc(sizeof(SLEDITDATA)))) {		EPRINTF("EDIT: malloc error!\n");		return -1;	}	len = 1 + strlen(pCtrl->szTitle);	if (len < LEN_SLEDIT_BUFFER)		len = LEN_SLEDIT_BUFFER;	pCtrl->userdata2 = (DWORD) pSLEditData;	pCtrl->userdata = 0;#ifdef USE_BIG5	pSLEditData->hFont = CreateFont(12,					0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,					FF_DONTCARE | DEFAULT_PITCH,					"HZXFONT");#else	pSLEditData->hFont = GetStockObject(DEFAULT_FONT);#endif	pSLEditData->bufferLen = len;	pSLEditData->editPos = 0;	pSLEditData->caretX = 0;	pSLEditData->caretRow = 0;	pSLEditData->scrollX = 0;	pSLEditData->scrollRow = 0;	pSLEditData->epFirstIdx = 0;	pSLEditData->epLineCount = 0;	pSLEditData->epLineOX = 0;	pSLEditData->epLineAlign = 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;	pSLEditData->hardLimit = -1;	pSLEditData->buffer =		(EDITCHAR *) malloc(SZEDITCHAR * pSLEditData->bufferLen);	/* undo information */	pSLEditData->lastOp = EDIT_OP_NONE;	pSLEditData->lastPos = 0;	pSLEditData->affectedLen = 0;	pSLEditData->undoBufferLen = LEN_SLEDIT_UNDOBUFFER;	pSLEditData->undoBuffer[0] = '\0';	//edit_memcpy ( pSLEditData->buffer, pCtrl->szTitle, len );	pSLEditData->dataEnd = GdConvertEncoding(pCtrl->szTitle,						 mwTextCoding,						 strlen(pCtrl->szTitle),						 pSLEditData->buffer,						 MWTF_UC16);	pSLEditData->charHeight = neGetTextHeight(hwnd, NULL);	neRecalcRows(hwnd, &pSLEditData);	return 0;}static voidneRecalcRows(HWND hwnd, PSLEDITDATA * ppData){	PSLEDITDATA pSLEditData;	PSLEDITDATA pCurData = *ppData;	RECT rc;	int nl;	int charH;	charH = neGetTextHeight(hwnd, NULL);	GetClientRect(hwnd, &rc);	nl = (rc.bottom - rc.top + charH - 1) / charH;	pSLEditData = (PSLEDITDATA) malloc(sizeof(SLEDITDATA));	if (pSLEditData == NULL)		return;	*pSLEditData = *pCurData;	pSLEditData->charHeight = charH;	pSLEditData->cLines = nl;	*ppData = pSLEditData;	hwnd->userdata2 = (DWORD) pSLEditData;	free(pCurData);}/* *  Destroy an edit control */static voidneDestroy(HWND hwnd){	PSLEDITDATA pSLEditData = (PSLEDITDATA) (hwnd->userdata2);	free(pSLEditData->buffer);	free(pSLEditData);	hwnd->userdata2 = 0;	DestroyCaret();}/* *  Reallocate the buffer with the new size */static BOOLneReallocateBuffer(PSLEDITDATA pSLEditData, int len){	EDITCHAR *newbuff;	if (len < pSLEditData->dataEnd)		len = pSLEditData->dataEnd;	newbuff = (EDITCHAR *) malloc(len * SZEDITCHAR);	if (newbuff == NULL) {		EPRINTF("Unable to allocate buffer for EDIT control.\n");		return FALSE;	}	memcpy(newbuff, pSLEditData->buffer, len * SZEDITCHAR);	free(pSLEditData->buffer);	pSLEditData->bufferLen = len;	pSLEditData->buffer = newbuff;	return TRUE;}/* *  Check if it should reduce allocated buffer */static voidneCheckBufferSize(HWND hWnd, PSLEDITDATA pSLEditData){	if ((pSLEditData->bufferLen - pSLEditData->dataEnd) >	    LEN_SLEDIT_REMOVEBUFFER)		neReallocateBuffer(pSLEditData,				   pSLEditData->dataEnd +				   LEN_SLEDIT_ADDBUFFER);}/* *  Increment dataEnd and check if buffer should reallocated */static BOOLneIncDataEnd(PSLEDITDATA pSLEditData, int delta){	if ((pSLEditData->hardLimit >= 0) &&	    (pSLEditData->dataEnd + delta >= pSLEditData->hardLimit))		return FALSE;	pSLEditData->dataEnd += delta;	if (pSLEditData->dataEnd > pSLEditData->bufferLen) {		if (!neReallocateBuffer(pSLEditData,					pSLEditData->bufferLen +					LEN_SLEDIT_ADDBUFFER)) {			pSLEditData->dataEnd -= delta;			return FALSE;		}	}	return TRUE;}/* *  Copy selection to clipboard */static BOOLneCopyToCliboard(HWND hWnd, PSLEDITDATA pSLEditData){	if (pSLEditData->selStart < pSLEditData->selEnd) {		int count = pSLEditData->selEnd - pSLEditData->selStart;		if (count + pSLEditData->selStart > pSLEditData->dataEnd)			count = pSLEditData->dataEnd - pSLEditData->selStart;		if (count > 0) {			if (neClipboard != NULL)				free(neClipboard);			neClipboard = (EDITCHAR *) malloc(count * SZEDITCHAR);			if (neClipboard == NULL)				return FALSE;			memcpy(neClipboard,			       pSLEditData->buffer + pSLEditData->selStart,			       count * SZEDITCHAR);			neClipboardSize = count;			return TRUE;		}	}	return FALSE;}static voidneUpdateCaretPos(HWND hWnd){	PSLEDITDATA pSLEditData = (PSLEDITDATA) (hWnd->userdata2);	SetCaretPos(pSLEditData->caretX,		    pSLEditData->topMargin +		    pSLEditData->caretRow * pSLEditData->charHeight);}/* *  Parse WM_SETTEXT command */static BOOLneSetText(HWND hWnd, const char *text){	//DWORD dwStyle = hWnd->style;	PSLEDITDATA pSLEditData = (PSLEDITDATA) (hWnd->userdata2);	int len;	//FIXME: consider UTF8	len = strlen(text);	if (pSLEditData->hardLimit >= 0)		len = min(len, pSLEditData->hardLimit);	if (len > pSLEditData->bufferLen) {		if (!neReallocateBuffer(pSLEditData, len))			return FALSE;	}	pSLEditData->dataEnd = GdConvertEncoding(text, mwTextCoding,						 len, pSLEditData->buffer,						 MWTF_UC16);	//edit_memcpy ( pSLEditData->buffer, text, len );	neCheckBufferSize(hWnd, pSLEditData);	pSLEditData->editPos = 0;	pSLEditData->scrollX = 0;	pSLEditData->caretX = 0;	pSLEditData->scrollRow = 0;	pSLEditData->caretRow = 0;	if ((hWnd->userdata & EST_FOCUSED))		neUpdateCaretPos(hWnd);	InvalidateRect(hWnd, NULL, FALSE);	return TRUE;}/* *  Set FONT */static voidneSetFont(HWND hWnd, HFONT hFont, BOOL bRedraw){	PSLEDITDATA pSLEditData = (PSLEDITDATA) (hWnd->userdata2);	pSLEditData->hFont = (HFONT) hFont;	neRecalcRows(hWnd, &pSLEditData);	ShowWindow(hWnd, SW_HIDE);	ShowWindow(hWnd, SW_SHOWNA);	if (bRedraw)		InvalidateRect(hWnd, NULL, TRUE);}/* *  Calculate the password chr with */static intneGetPasswdCharWith(HDC hdc, EDITCHAR pwdChar){	int xw, xh, xb;	GdSetFont(hdc->font->pfont);	GdGetTextSize(hdc->font->pfont, &pwdChar, 1,		      &xw, &xh, &xb, MWTF_UC16);	return xw;}/* * Get height of character */static intneGetTextHeight(HWND hWnd, HDC hdc){	int xw, xh, xb;	BOOL bRelDC = FALSE;	if (hdc == NULL)		hdc = GetDC(hWnd), bRelDC = TRUE;	SelectObject(hdc, ((PSLEDITDATA) (hWnd->userdata2))->hFont);	GdSetFont(hdc->font->pfont);	GdGetTextSize(hdc->font->pfont, "X", 1, &xw, &xh, &xb, MWTF_ASCII);	if (bRelDC)		ReleaseDC(hWnd, hdc);	return xh;}/* *  Calculate a string with */static intneGetTextWith(HWND hWnd, HDC hdc, PSLEDITDATA pSLEditData,	      const EDITCHAR * txt, int len){	int xw, xh, xb;	DWORD dwStyle = hWnd->style;	BOOL bRelDC = FALSE;	if (dwStyle & dwStyle & ES_PASSWORD)		return len * neGetPasswdCharWith(hdc,						 pSLEditData->passwdChar);	if (hdc == NULL)		hdc = GetDC(hWnd), bRelDC = TRUE;	SelectObject(hdc, pSLEditData->hFont);	GdSetFont(hdc->font->pfont);	GdGetTextSize(hdc->font->pfont, txt, len, &xw, &xh, &xb, MWTF_UC16);	if (bRelDC)		ReleaseDC(hWnd, hdc);	return xw;}/* *  Calculate client area width */static intedtGetOutWidth(const HWND pCtrl){	return pCtrl->clirect.right - pCtrl->clirect.left		- ((PSLEDITDATA) (pCtrl->userdata2))->leftMargin		- ((PSLEDITDATA) (pCtrl->userdata2))->rightMargin;}/* *  Output a string in a PASSWORD EDIT */static voidneTextOutPwd(HDC hdc, int x, int y, EDITCHAR pwdChar, int len){	int i, xs;	xs = neGetPasswdCharWith(hdc, pwdChar);	for (i = 0; i < len; i++) {		neTextOut(hdc, x, y, &pwdChar, 1);		x += xs;	}}/* *  Determine the index position based on coords *  When exit, the pPoint is set to the position *  that the caret should be moved on. */static intneIndexFromPos(HWND hWnd, POINT * pPoint){	PSLEDITDATA pSLEditData = (PSLEDITDATA) (hWnd->userdata2);	HDC hdc = GetDC(hWnd);	int i, txts;	SelectObject(hdc, pSLEditData->hFont);	pPoint->x -= pSLEditData->leftMargin + 2;	pPoint->y -= pSLEditData->topMargin;	for (i = 0, txts = 0; i <= pSLEditData->dataEnd; i++) {		txts = neGetTextWith(hWnd, hdc, pSLEditData,				     pSLEditData->buffer, i);		if (txts >= (pPoint->x + pSLEditData->scrollX))			break;	}	if (i > pSLEditData->dataEnd)		i = pSLEditData->dataEnd;	pPoint->x = txts - pSLEditData->scrollX + pSLEditData->leftMargin;	ReleaseDC(hWnd, hdc);	return i;}/* *  Check if scroll pos should be changed. *  Return nonzero if the entire window should be redrawn */static BOOLneRecalcScrollPos(HWND hWnd, HDC hdc, PSLEDITDATA pSLEditData,		  BOOL checkNewline){	int xs;	int lastscrollX;	int lastscrollR;	int pfirst, palign;	lastscrollX = pSLEditData->scrollX;	lastscrollR = pSLEditData->scrollRow;	xs = edtGetOutWidth(hWnd);	pfirst = pSLEditData->epFirstIdx;	palign = pSLEditData->epLineAlign;	neDrawAllText(hWnd, hdc, pSLEditData, NEDRAW_CALC_CURSOR);	if (pSLEditData->epX < pSLEditData->scrollX)		pSLEditData->scrollX = pSLEditData->epX;	else if ((pSLEditData->epX - pSLEditData->scrollX -		  (pSLEditData->epLineAlign ? 2 : 0)) > xs) {		int scrollStep =			(pSLEditData->epX - pSLEditData->scrollX) - xs;		if ((pSLEditData->editPos < pSLEditData->dataEnd)		    && (scrollStep < (xs / 2))		    && !(hWnd->			 userdata & (EST_SELSCROLLLEFT | EST_SELSCROLLRIGHT))			)			scrollStep = xs / 2;		pSLEditData->scrollX += scrollStep;	}

⌨️ 快捷键说明

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