📄 edit.c
字号:
/*
* Copyright (C) 1999, 2000, Wei Yongming.
* Portions Copyright (c) 2000 Greg Haerr <greg@censoft.com>
*
* 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/05/30 gv port to microwin ported
** Greg Haerr 2000/06/16 Utah 3d look, bug fixes Finished
** Kevin Tseng 2000/06/22 gv port to mw-nanox ported
**
** TODO:
** * Selection.
** * Undo.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.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
#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 3000
#define LEN_SLEDIT_UNDOBUFFER 1024
#define EST_FOCUSED 0x00000001L
#define EST_MODIFY 0x00000002L
#define EST_READONLY 0x00000004L
#define EST_REPLACE 0x00000008L
#define EDIT_OP_NONE 0x00
#define EDIT_OP_DELETE 0x01
#define EDIT_OP_INSERT 0x02
#define EDIT_OP_REPLACE 0x03
typedef struct tagSLEDITDATA {
HFONT hFont; /* hFont used */
int bufferLen; /* length of buffer */
int dataEnd; /* data end position */
int editPos; /* current edit position */
int caretOff; /* caret offset in box */
int startPos; /* start display position */
int selStart; /* selection start position */
int selEnd; /* selection end position */
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 affectedLen; /* affected len of last operation */
int undoBufferLen; /* undo buffer len */
char undoBuffer [LEN_SLEDIT_UNDOBUFFER]; /* Undo buffer; */
char buffer [LEN_SLEDIT_BUFFER]; /* buffer */
} SLEDITDATA, *PSLEDITDATA;
static LRESULT CALLBACK
SLEditCtrlProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
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));
}
int WINAPI MwRegisterEditControl(HINSTANCE hInstance)
{
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_GLOBALCLASS;
wc.lpfnWndProc = (WNDPROC)SLEditCtrlProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = 0; /*LoadCursor(NULL, IDC_ARROW);*/
wc.hbrBackground= GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName= "EDIT";
return RegisterClass(&wc);
}
static int edtGetOutWidth (const HWND pCtrl)
{
return pCtrl->clirect.right - pCtrl->clirect.left
- ((PSLEDITDATA)(pCtrl->userdata2))->leftMargin
- ((PSLEDITDATA)(pCtrl->userdata2))->rightMargin;
}
static int edtGetStartDispPosAtEnd (const HWND pCtrl, PSLEDITDATA pSLEditData)
{
int nOutWidth = edtGetOutWidth (pCtrl);
int endPos = pSLEditData->dataEnd;
int newStartPos = pSLEditData->startPos;
const char* buffer = pSLEditData->buffer;
while (TRUE) {
if ((endPos - newStartPos) * GetSysCharWidth (pCtrl) < nOutWidth)
break;
/* FIXME: #ifdef GB2312?*/
if ((BYTE)buffer [newStartPos] > 0xA0) /* 1st:gb:a1-f7,big5:a1-f9 */
{
newStartPos ++;
if (newStartPos < pSLEditData->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 (const HWND pCtrl)
{
int i, n = 0;
int nOutWidth = edtGetOutWidth (pCtrl);
int nTextWidth = 0;
PSLEDITDATA pSLEditData = (PSLEDITDATA)(pCtrl->userdata2);
const char* buffer = pSLEditData->buffer;
for (i = pSLEditData->startPos; i < pSLEditData->dataEnd; i++) {
/* FIXME #ifdef GB2312?*/
if ((BYTE)buffer [i] > 0xA0) /* st:gb:a1-f7,big5:a1-f9 */
{
i++;
if (i < pSLEditData->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 (pCtrl);
n += 2;
}
else
i--;
}
else
{
nTextWidth += GetSysCharWidth (pCtrl);
n++;
}
}
else
{
nTextWidth += GetSysCharWidth (pCtrl);
n++;
}
if (nTextWidth > nOutWidth)
break;
}
return n;
}
static int edtGetOffset (HWND hwnd,const SLEDITDATA* pSLEditData, int x)
{
int i;
int newOff = 0;
int nTextWidth = 0;
const char* buffer = pSLEditData->buffer;
x -= pSLEditData->leftMargin;
for (i = pSLEditData->startPos; i < pSLEditData->dataEnd; i++) {
if ((nTextWidth + (GetSysCharWidth(hwnd) >> 1)) >= x)
break;
/* FIXME #ifdef GB2312?*/
if ((BYTE)buffer [i] > 0xA0) /* 1st:gb:a1-f7,big5:a1-f9 */
{
i++;
if (i < pSLEditData->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 BOOL edtIsACCharBeforePosition (const char* string, int pos)
{
if (pos < 2)
return FALSE;
/* 1st:gb:a1-f7,big5:a1-f9 2nd:gb:a1-fe,big5:40-7e,a1-fe */
#ifndef USE_BIG5
/* FIXME #ifdef GB2312?*/
if ((BYTE)string [pos - 2] > 0xA0 && (BYTE)string [pos - 1] > 0xA0)
return TRUE;
#else
if ((BYTE)string [pos - 2] > 0xA0)
{
if ( ((BYTE)string [pos - 1] >= 0x40 && (BYTE)string[pos - 1] <= 0x7e) ||
((BYTE)string [pos - 1] >= 0xa1 && (BYTE)string[pos - 1] <= 0xfe))
return TRUE;
}
#endif
return FALSE;
}
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;
}
}
#endif
return FALSE;
}
LRESULT CALLBACK
SLEditCtrlProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HWND pCtrl;
DWORD dwStyle;
HDC hdc;
PSLEDITDATA pSLEditData;
RECT rc;
pCtrl = hWnd;
dwStyle = pCtrl->style;
switch (message)
{
case WM_CREATE:
if (!(pSLEditData = GdMalloc (sizeof (SLEDITDATA))))
{
// fprintf (stderr, "EDIT: malloc error!\n");
return -1;
}
pSLEditData->hFont = GetStockObject(DEFAULT_FONT);
pSLEditData->bufferLen = LEN_SLEDIT_BUFFER;
pSLEditData->editPos = 0;
pSLEditData->caretOff = 0;
pSLEditData->startPos = 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -