📄 medit.c
字号:
/*** $Id: medit.c,v 1.67 2003/09/04 02:40:36 weiym Exp $**** medit.c: the Multi-Line Edit control**** Copyright (C) 2003 Feynman Software.** Copyright (C) 1999 ~ 2002 Chen Lei and Wei Yongming.** ** Current maintainer: Chen Lei (leon@minigui.org).**** Create date: 1999/8/26*//*** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU General Public License as published by** the Free Software Foundation; either version 2 of the License, or** (at your option) any later version.**** This program 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 General Public License for more details.**** You should have received a copy of the GNU General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*//*** TODO:** * Selection.** * Undo.*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include "common.h"#include "minigui.h"#include "gdi.h"#include "window.h"#include "control.h"#include "cliprect.h"#include "internals.h"#include "ctrlclass.h"#ifdef _CTRL_MLEDIT#include "ctrlmisc.h"#include "medit.h"static int MLEditCtrlProc (HWND hWnd, int message, WPARAM wParam, LPARAM lParam);BOOL RegisterMLEditControl (void){ // This control class has two names: "medit" and "mledit" WNDCLASS WndClass; WndClass.spClassName = CTRL_MEDIT; WndClass.dwStyle = WS_NONE; WndClass.dwExStyle = WS_EX_NONE; WndClass.hCursor = GetSystemCursor (IDC_IBEAM); WndClass.iBkColor = PIXEL_lightwhite; WndClass.WinProc = MLEditCtrlProc; if (AddNewControlClass (&WndClass) != ERR_OK) return FALSE; WndClass.spClassName = CTRL_MLEDIT; WndClass.dwStyle = WS_NONE; WndClass.dwExStyle = WS_EX_NONE; WndClass.hCursor = GetSystemCursor (IDC_IBEAM); WndClass.iBkColor = PIXEL_lightwhite; WndClass.WinProc = MLEditCtrlProc; return AddNewControlClass (&WndClass) == ERR_OK;}#if 0void MLEditControlCleanup (void){ // do nothing return;}#endifstatic inline int edtGetOutWidth (HWND hWnd){ PMLEDITDATA pMLEditData =(PMLEDITDATA) GetWindowAdditionalData2(hWnd); RECT rc; GetClientRect(hWnd,&rc); return RECTW(rc) - pMLEditData->leftMargin - pMLEditData->rightMargin;}static int edtGetLineNO (const MLEDITDATA* 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 len){ int i; for(i=0;i<len;i++) { if(str[i]==10) return i; } return -1;}void MLEditEmptyBuffer(PMLEDITDATA pMLEditData){ PLINEDATA temp; PLINEDATA 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 linestatic int edtGetnextStartPos (HWND hWnd, PMLEDITDATA pMLEditData, int startPos){ int i = 0; if (!pMLEditData->dx_chars) return -1; if (pMLEditData->sz.cx - pMLEditData->dx_chars[startPos] <= edtGetOutWidth (hWnd)) return -1; for (i = startPos; i < pMLEditData->fit_chars+1; i++) { if (pMLEditData->dx_chars[i]-pMLEditData->dx_chars[startPos] >= edtGetOutWidth (hWnd)) return i-1; } return -1;}static void edtGetLineInfoEx (HWND hWnd, PMLEDITDATA pMLEditData, PLINEDATA pLineData){ HDC hdc = GetClientDC (hWnd); if (!pMLEditData) pMLEditData = (PMLEDITDATA) 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, PLINEDATA pLineData){ edtGetLineInfoEx (hWnd, NULL, pLineData);}static int edtGetStartDispPosAtEnd (HWND hWnd, PLINEDATA pLineData){ PMLEDITDATA pMLEditData =(PMLEDITDATA) 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, PMLEDITDATA pMLEditData, PLINEDATA 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, PMLEDITDATA pMLEditData, const char *spcaption, DWORD dwStyle){ char *caption=(char*)spcaption; int off1; int lineNO=0; int pace=0; int totallen=0; PLINEDATA pLineData; if (!(pMLEditData->head = malloc (sizeof (LINEDATA)))) { return ; } pMLEditData->head->previous = NULL; pLineData = pMLEditData->head; pMLEditData->wraplines = 0; totallen = strlen(caption); while ( (off1 = GetRETURNPos(caption, totallen)) != -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; pace = MIN (pLineData->dataEnd, LEN_MLEDIT_BUFFER) + 1; caption += pace; totallen -= pace; 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 (LINEDATA)); 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'; pace = MIN (off1,LEN_MLEDIT_BUFFER)+1; caption += pace; 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 (LINEDATA)); pLineData->next->previous = pLineData; pLineData->next->next = NULL; pLineData = pLineData->next; } if (pMLEditData->totalLimit > 0 && pMLEditData->curtotalLen < pMLEditData->totalLimit)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -