📄 simedit.c
字号:
/*
** $Id: simedit.c,v 1.24 2004/07/22 09:36:44 snig Exp $
**
** simedit.c: the Simple Edit Control module.
**
** Copyright (C) 2003 Feynman Software.
** Copyright (C) 1999 ~ 2002 Wei Yongming.
**
** Current maintainer: Wei Yongming.
*/
/*
** 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:
*/
#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_SIMEDIT
#include "ctrlmisc.h"
#include "simedit.h"
#ifdef _FLAT_WINDOW_STYLE
#define WIDTH_EDIT_BORDER 1
#else
#define WIDTH_EDIT_BORDER 2
#endif
#define MARGIN_EDIT_LEFT 1
#define MARGIN_EDIT_TOP 1
#define MARGIN_EDIT_RIGHT 2
#define MARGIN_EDIT_BOTTOM 1
#define EST_FOCUSED 0x00000001L
#define EST_MODIFY 0x00000002L
#define EST_REPLACE 0x00000008L
#define EDIT_OP_NONE 0x00
#define EDIT_OP_DELETE 0x01
#define EDIT_OP_INSERT 0x02
#define EDIT_OP_REPLACE 0x03
static int SIMEditCtrlProc (HWND hWnd, int message, WPARAM wParam, LPARAM lParam);
BOOL RegisterSIMEditControl (void)
{
WNDCLASS WndClass;
WndClass.spClassName = CTRL_EDIT;
WndClass.dwStyle = WS_NONE;
WndClass.dwExStyle = WS_EX_NONE;
WndClass.hCursor = GetSystemCursor (IDC_IBEAM);
WndClass.iBkColor = GetWindowElementColor (BKC_EDIT_DEF);
WndClass.WinProc = SIMEditCtrlProc;
return AddNewControlClass (&WndClass) == ERR_OK;
}
#if 0
void SIMEditControlCleanup (void)
{
// do nothing
return;
}
#endif
static inline int edtGetOutWidth (const CONTROL* pCtrl)
{
return pCtrl->cr - pCtrl->cl
- ((PSIMEDITDATA)(pCtrl->dwAddData2))->leftMargin
- ((PSIMEDITDATA)(pCtrl->dwAddData2))->rightMargin;
}
static int edtGetStartDispPosAtEnd (const CONTROL* pCtrl,
PSIMEDITDATA simed)
{
int nOutWidth = edtGetOutWidth (pCtrl);
int endPos = simed->dataEnd;
int newStartPos = simed->startPos;
const char* buffer = simed->buffer;
while (TRUE) {
if ((endPos - newStartPos) * simed->charWidth < nOutWidth)
break;
if ((BYTE)buffer [newStartPos] > 0xA0) {
newStartPos ++;
if (newStartPos < simed->dataEnd) {
if ((BYTE)buffer [newStartPos] > 0xA0)
newStartPos ++;
}
}
else
newStartPos ++;
}
return newStartPos;
}
static int edtGetDispLen (const CONTROL* pCtrl)
{
int i, n = 0;
int nOutWidth = edtGetOutWidth (pCtrl);
int nTextWidth = 0;
PSIMEDITDATA simed = (PSIMEDITDATA)(pCtrl->dwAddData2);
const char* buffer = simed->buffer;
for (i = simed->startPos; i < simed->dataEnd; i++) {
if ((BYTE)buffer [i] > 0xA0) {
i++;
if (i < simed->dataEnd) {
if ((BYTE)buffer [i] > 0xA0) {
nTextWidth += simed->charWidth * 2;
n += 2;
}
else
i--;
}
else {
nTextWidth += simed->charWidth;
n++;
}
}
else {
nTextWidth += simed->charWidth;
n++;
}
if (nTextWidth > nOutWidth)
break;
}
return n;
}
static int edtGetOffset (const SIMEDITDATA* simed, int x)
{
int i;
int newOff = 0;
int nTextWidth = 0;
const char* buffer = simed->buffer;
x -= simed->leftMargin;
for (i = simed->startPos; i < simed->dataEnd; i++) {
if ((nTextWidth + (simed->charWidth >> 1)) >= x)
break;
if ((BYTE)buffer [i] > 0xA0) {
i++;
if (i < simed->dataEnd) {
if ((BYTE)buffer [i] > 0xA0) {
nTextWidth += simed->charWidth * 2;
newOff += 2;
}
else
i --;
}
else {
nTextWidth += simed->charWidth;
newOff ++;
}
}
else {
nTextWidth += simed->charWidth;
newOff ++;
}
}
return newOff;
}
static BOOL edtIsACCharBeforePosition (const char* string, int pos)
{
if (pos < 2)
return FALSE;
if ((BYTE)string [pos - 2] > 0xA0 && (BYTE)string [pos - 1] > 0xA0)
return TRUE;
return FALSE;
}
static BOOL edtIsACCharAtPosition (const char* string, int len, int pos)
{
if (pos > (len - 2))
return FALSE;
if ((BYTE)string [pos] > 0xA0 && (BYTE)string [pos + 1] > 0xA0)
return TRUE;
return FALSE;
}
static int SIMEditCtrlProc (HWND hWnd, int message, WPARAM wParam, LPARAM lParam)
{
PCONTROL pCtrl;
DWORD dwStyle;
HDC hdc;
PSIMEDITDATA simed;
pCtrl = Control(hWnd);
dwStyle = pCtrl->dwStyle;
switch (message)
{
case MSG_CREATE:
if (!(simed = calloc (1, sizeof (SIMEDITDATA)))) {
return -1;
}
simed->status = 0;
simed->bufferLen = LEN_SIMEDIT_BUFFER;
simed->buffer = calloc (LEN_SIMEDIT_BUFFER, sizeof (char));
if (simed->buffer == NULL) {
free (simed);
return -1;
}
if (!CreateCaret (hWnd, NULL, 1, GetSysFontHeight (SYSLOGFONT_FIXED))) {
free (simed->buffer);
free (simed);
return -1;
}
simed->editPos = 0;
simed->caretOff = 0;
simed->startPos = 0;
simed->passwdChar = '*';
simed->leftMargin = MARGIN_EDIT_LEFT;
simed->topMargin = MARGIN_EDIT_TOP;
simed->rightMargin = MARGIN_EDIT_RIGHT;
simed->bottomMargin = MARGIN_EDIT_BOTTOM;
simed->hardLimit = -1;
simed->dataEnd = strlen (pCtrl->spCaption);
memcpy (simed->buffer, pCtrl->spCaption, MIN (LEN_SIMEDIT_BUFFER, simed->dataEnd));
simed->dataEnd = MIN (LEN_SIMEDIT_BUFFER, simed->dataEnd);
pCtrl->dwAddData2 = (DWORD) simed;
pCtrl->pLogFont = GetSystemFont (SYSLOGFONT_FIXED);
simed->charWidth = GetSysFontMaxWidth (SYSLOGFONT_FIXED);
break;
case MSG_DESTROY:
simed = (PSIMEDITDATA) (pCtrl->dwAddData2);
DestroyCaret (hWnd);
free (simed->buffer);
free (simed);
break;
case MSG_ERASEBKGND:
EditOnEraseBackground (hWnd, (HDC)wParam, (const RECT*)lParam);
return 0;
case MSG_FONTCHANGING:
return -1;
case MSG_SETCURSOR:
if (dwStyle & WS_DISABLED) {
SetCursor (GetSystemCursor (IDC_ARROW));
return 0;
}
break;
case MSG_KILLFOCUS:
simed = (PSIMEDITDATA) (pCtrl->dwAddData2);
if (simed->status & EST_FOCUSED) {
simed->status &= ~EST_FOCUSED;
HideCaret (hWnd);
NotifyParent (hWnd, pCtrl->id, EN_KILLFOCUS);
}
break;
case MSG_SETFOCUS:
simed = (PSIMEDITDATA) (pCtrl->dwAddData2);
if (simed->status & EST_FOCUSED)
break;
simed->status |= EST_FOCUSED;
/* only implemented for ES_LEFT align format. */
SetCaretPos (hWnd, simed->caretOff * simed->charWidth + simed->leftMargin,
simed->topMargin);
ShowCaret (hWnd);
ActiveCaret (hWnd);
NotifyParent (hWnd, pCtrl->id, EN_SETFOCUS);
break;
case MSG_ENABLE:
if ( (!(dwStyle & WS_DISABLED) && !wParam)
|| ((dwStyle & WS_DISABLED) && wParam) ) {
if (wParam)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -