?? medit.c
字號:
/* * 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 */#if HAVE_HZK_SUPPORT || HAVE_BIG5_SUPPORT#define USE_BIG5#else#define DEFAULT_FONT DEFAULT_GUI_FONT#endif#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 0x03typedef 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)) {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -