Files
MiniGUI/src/control/edit.c
T

2472 lines
71 KiB
C

///////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT NOTICE
//
// The following open source license statement does not apply to any
// entity in the Exception List published by FMSoft.
//
// For more information, please visit:
//
// https://www.fmsoft.cn/exception-list
//
//////////////////////////////////////////////////////////////////////////////
/*
* This file is part of MiniGUI, a mature cross-platform windowing
* and Graphics User Interface (GUI) support system for embedded systems
* and smart IoT devices.
*
* Copyright (C) 2002~2018, Beijing FMSoft Technologies Co., Ltd.
* Copyright (C) 1998~2002, 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 3 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, see <http://www.gnu.org/licenses/>.
*
* Or,
*
* As this program is a library, any link to this program must follow
* GNU General Public License version 3 (GPLv3). If you cannot accept
* GPLv3, you need to be licensed from FMSoft.
*
* If you have got a commercial license of this program, please use it
* under the terms and conditions of the commercial license.
*
* For more information about the commercial license, please refer to
* <http://www.minigui.com/blog/minigui-licensing-policy/>.
*/
/*
** edit.c: the Single Line Edit Control module.
**
** Create date: 1999/8/26
**
** TODO:
** * Replace
** * Undo.
**/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "common.h"
#ifdef _MGCTRL_SLEDIT
#include "minigui.h"
#include "gdi.h"
#include "window.h"
#include "ctrl/ctrlhelper.h"
#include "ctrl/edit.h"
#include "cliprect.h"
#include "internals.h"
#include "ctrlclass.h"
#include "clipboard.h"
#include "text.h"
#include "edit_impl.h"
static void set_line_width (HWND hWnd, PSLEDITDATA sled);
static void mySetCaretPos (HWND hWnd, PSLEDITDATA sled, int x);
static LRESULT SLEditCtrlProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
static void sledit_refresh_caret (HWND hWnd, PSLEDITDATA sled, BOOL bInited);
static BOOL make_charpos_visible (HWND hWnd, PSLEDITDATA sled, int charPos, int *cx);
/*
* for bug 4894, when select text don't hide caret, because this will close
* the ime window. by humingming 2010.8.17
*/
/*#define check_caret() \
if(sled->selStart != sled->selEnd) \
HideCaret(hWnd); \
else \
ShowCaret(hWnd);
*/
#define check_caret() ShowCaret(hWnd);
#define shift_one_char_r(pos) \
{ \
int len = CHLENNEXT((sled->content.string + sled->pos), (sled->content.txtlen - sled->pos)); \
sled->pos += len; \
}
#define shift_one_char_l(pos) \
{ \
int len = CHLENPREV((const char* )(sled->content.string),(const char* )(sled->content.string + sled->pos) ); \
sled->pos -= len; \
}
#define PASSWORD_REPLACEMENT '*'
BOOL RegisterSLEditControl (void)
{
WNDCLASS WndClass;
WndClass.spClassName = CTRL_SLEDIT;
WndClass.dwStyle = WS_NONE;
WndClass.dwExStyle = WS_EX_NONE;
WndClass.hCursor = GetSystemCursor (IDC_IBEAM);
#ifdef _MGSCHEMA_COMPOSITING
WndClass.dwBkColor = GetWindowElementAttr (HWND_NULL, WE_BGC_WINDOW);
#else
WndClass.iBkColor =
GetWindowElementPixelEx (HWND_NULL, HDC_SCREEN, WE_BGC_WINDOW);
#endif
WndClass.WinProc = SLEditCtrlProc;
if (gui_AddNewControlClass (&WndClass) != ERR_OK)
return FALSE;
WndClass.spClassName = CTRL_EDIT;
return gui_AddNewControlClass (&WndClass) == ERR_OK;
}
/* -------------------------------------------------------------------------- */
static void setup_dc (HWND hWnd, SLEDITDATA *sled, HDC hdc, BOOL bSel)
{
DWORD dwStyle = GetWindowStyle (hWnd);
if (!bSel) {
SetBkMode (hdc, BM_TRANSPARENT);
if (dwStyle & WS_DISABLED)
SetTextColor (hdc,
GetWindowElementPixelEx (hWnd, hdc, WE_FGC_DISABLED_ITEM));
else
SetTextColor (hdc,
GetWindowElementPixelEx (hWnd, hdc, WE_FGC_WINDOW));
SetBkColor (hdc, GetWindowBkColor (hWnd));
}
else {
SetBkMode (hdc, BM_OPAQUE);
if (dwStyle & WS_DISABLED)
SetTextColor (hdc,
GetWindowElementPixelEx (hWnd, hdc, WE_FGC_DISABLED_ITEM));
else
SetTextColor (hdc,
GetWindowElementPixelEx (hWnd, hdc, WE_FGC_SELECTED_ITEM));
if (sled->status & EST_FOCUSED)
SetBkColor (hdc,
GetWindowElementPixelEx (hWnd, hdc, WE_BGC_SELECTED_ITEM));
else
SetBkColor (hdc,
GetWindowElementPixelEx (hWnd, hdc, WE_BGC_SELECTED_LOSTFOCUS));
}
}
/* -------------------------------------------------------------------------- */
static int sledit_settext (PSLEDITDATA sled, const char *newtext)
{
int len, txtlen;
txtlen = strlen (newtext);
len = (txtlen <= 0) ? sled->nBlockSize : txtlen;
if (sled->hardLimit >= 0 && txtlen > sled->hardLimit) {
return -1;
}
/* free the old text */
if (sled->content.string)
testr_free (&sled->content);
if (!testr_alloc (&sled->content, len, sled->nBlockSize))
return -1;
if (newtext && txtlen > 0)
testr_setstr (&sled->content, newtext, txtlen);
else
sled->content.txtlen = 0;
return 0;
}
static void get_content_width (HWND hWnd, PSLEDITDATA sled)
{
GetClientRect (hWnd, &sled->rcVis);
sled->rcVis.left += sled->leftMargin;
sled->rcVis.top += sled->topMargin;
sled->rcVis.right -= sled->rightMargin;
sled->rcVis.bottom -= sled->bottomMargin;
sled->nVisW = sled->rcVis.right - sled->rcVis.left;
}
static void recalcSize (HWND hWnd, PSLEDITDATA sled, BOOL bInited)
{
get_content_width (hWnd, sled);
sled->nContX = 0;
sled->nContW = sled->rcVis.right - sled->rcVis.left;
set_line_width (hWnd, sled);
sled->starty = sled->topMargin + ( sled->rcVis.bottom -
sled->rcVis.top - GetWindowFont (hWnd)->size - 1 ) / 2;
sledit_refresh_caret (hWnd, sled, bInited);
}
static int sledit_init (HWND hWnd, PSLEDITDATA sled)
{
PCONTROL pCtrl;
if (!sled)
return -1;
pCtrl = gui_Control(hWnd);
pCtrl->dwAddData2 = (DWORD)sled;
sled->status = 0;
sled->editPos = 0;
sled->selStart = 0;
sled->selEnd = 0;
sled->leftMargin = MARGIN_EDIT_LEFT;
sled->topMargin = MARGIN_EDIT_TOP;
sled->rightMargin = MARGIN_EDIT_RIGHT;
sled->bottomMargin = MARGIN_EDIT_BOTTOM;
sled->passwdChar = PASSWORD_REPLACEMENT;
sled->changed = FALSE;
sled->bShowCaret = FALSE;
sled->nBlockSize = DEF_LINE_BLOCK_SIZE;
sled->hardLimit = -1;
if (pCtrl->dwStyle & ES_TIP) {
sled->tiptext = FixStrAlloc (DEF_TIP_LEN + 1);
sled->tiptext[0] = 0;
}
else
sled->tiptext = NULL;
sled->content.string = NULL;
sled->content.buffsize = 0;
sled->content.txtlen = 0;
sledit_settext (sled, pCtrl->spCaption);
if (pCtrl->dwStyle & ES_PASSWORD) {
pCtrl->pLogFont = GetSystemFont (SYSLOGFONT_DEFAULT);
}
CreateCaret (hWnd, NULL, 1, pCtrl->pLogFont->size);
recalcSize (hWnd, sled, TRUE);
return 0;
}
static void sledit_destroy (HWND hWnd, PSLEDITDATA sled)
{
DestroyCaret (hWnd);
if ( (GetWindowStyle(hWnd) & ES_TIP) && sled->tiptext)
FreeFixStr (sled->tiptext);
testr_free (&sled->content);
}
static inline BOOL sleContentToVisible (PSLEDITDATA sled, int *x)
{
if (x)
*x -= sled->nContX;
else
return -1;
if (*x < 0 || *x > sled->nVisW)
return -1;
return 0;
}
static inline BOOL sleVisibleToWindow (PSLEDITDATA sled, int *x)
{
if (x)
*x += sled->leftMargin;
return TRUE;
}
static inline void sleContentToWindow (PSLEDITDATA sled, int *x)
{
sleContentToVisible (sled, x);
sleVisibleToWindow (sled, x);
}
static inline void sleWindowToContent (PSLEDITDATA sled, int *x)
{
*x -= sled->leftMargin;
*x += sled->nContX;
}
/* sets the current caret position in the virtual content window */
static void mySetCaretPos (HWND hWnd, PSLEDITDATA sled, int x)
{
if (sleContentToVisible(sled, &x) < 0) {
HideCaret (hWnd);
} else {
sleVisibleToWindow (sled, &x);
SetCaretPos (hWnd, x, sled->starty);
ActiveCaret (hWnd);
/* fix bug 4349: CENTER style does not work when startup*/
if (sled->status & EST_FOCUSED) {
ShowCaret (hWnd);
}
}
}
static int get_caretpos_x(HWND hWnd)
{
PCONTROL pWin = (PCONTROL)hWnd;
if (!pWin->pCaretInfo)
return FALSE;
return pWin->pCaretInfo->x;
}
static void slePaint (HWND hWnd, HDC hdc, PSLEDITDATA sled)
{
char* dispBuffer, *passwdBuffer = NULL;
DWORD dwStyle = GetWindowStyle(hWnd);
StrBuffer *content = &sled->content;
int starty = sled->starty;
int outw = 0;
int startx;
//FIXME, normal case of ES_TIP?
if (dwStyle & ES_TIP && content->txtlen <= 0 &&
GetFocus(GetParent(hWnd)) != hWnd) {
setup_dc (hWnd, sled, hdc, FALSE);
TextOut (hdc, sled->leftMargin, starty,
sled->tiptext);
return;
}
if (dwStyle & ES_PASSWORD) {
dispBuffer = FixStrAlloc (content->txtlen);
memset (dispBuffer, sled->passwdChar, content->txtlen);
passwdBuffer = dispBuffer;
}
else {
dispBuffer = (char*)content->string;
}
if (dwStyle & ES_BASELINE) {
SetPenColor (hdc,
GetWindowElementPixelEx (hWnd, hdc, WE_FGC_WINDOW));
#ifdef _PHONE_WINDOW_STYLE
MoveTo (hdc, sled->leftMargin, sled->rcVis.bottom);
LineTo (hdc, sled->rcVis.right, sled->rcVis.bottom);
#else
DrawHDotLine (hdc,
sled->leftMargin,
sled->rcVis.bottom,
sled->rcVis.right - sled->rcVis.left);
#endif
}
ClipRectIntersect (hdc, &sled->rcVis);
if (sled->selStart != sled->selEnd) {//select chars
startx = sled->startx;
sleContentToWindow (sled, &startx);
/* draw first normal chars */
if (sled->selStart > 0) {
setup_dc (hWnd, sled, hdc, FALSE);
outw += TextOutLen (hdc, startx, starty,
dispBuffer, sled->selStart);
dispBuffer += sled->selStart;
}
/* draw selected chars */
setup_dc (hWnd, sled, hdc, TRUE);
outw += TextOutLen (hdc, startx + outw, starty, dispBuffer,
sled->selEnd - sled->selStart);
dispBuffer += sled->selEnd - sled->selStart;
/* draw others */
if (sled->selEnd < content->txtlen) {
setup_dc (hWnd, sled, hdc, FALSE);
outw += TextOutLen (hdc, startx + outw, starty, dispBuffer,
content->txtlen - sled->selEnd);
}
}
else {
setup_dc (hWnd, sled, hdc, FALSE);
startx = sled->startx;
sleContentToWindow (sled, &startx);
outw += TextOutLen (hdc, startx, starty, dispBuffer, content->txtlen);
}
if (dwStyle & ES_PASSWORD)
FreeFixStr (passwdBuffer);
}
static int sleSetSel (HWND hWnd, PSLEDITDATA sled, int sel_start, int sel_end)
{
if (sled->content.txtlen <= 0)
return -1;
if (sel_start < 0)
sel_start = 0;
if (sel_end < 0)
sel_end = sled->content.txtlen;
if (sel_start == sel_end)
return -1;
sled->selStart = sel_start;
sled->selEnd = sel_end;
/* houhh 20101129, set cart position to sled->selEnd. */
if (sled->selEnd >= sled->selStart) {
int cx = 0;
make_charpos_visible (hWnd, sled, sled->selEnd, &cx);
mySetCaretPos (hWnd, sled, cx);
}
/*
* for bug 4894, when select text don't hide caret, because this will close
* the ime window. by humingming 2010.8.17
*/
//HideCaret(hWnd);
InvalidateRect(hWnd, NULL, TRUE);
return sled->selEnd - sled->selStart;
}
/*
* set caret position according to the new desired x coordinate.
*/
static void set_caret_pos (HWND hWnd, PSLEDITDATA sled, int x, BOOL bSel)
{
int out_chars;
HDC hdc;
SIZE txtsize;
hdc = GetClientDC (hWnd);
sleWindowToContent (sled, &x);
if (x - sled->startx <= 0) {
out_chars = 0;
txtsize.cx = 0;
}
else {
/* DK [10/05/07] for fix bug4542: Replace content of edit to a same length
* string which is made up of '*' character when the edit control include
* ES_PASSWORD style, for take the right content width. */
if ((GetWindowStyle(hWnd) & ES_PASSWORD)) {
int sled_width = x - sled->startx;
int max_char_len = 0;
GetTextExtent(hdc, "*", 1, &txtsize);
max_char_len = sled_width / txtsize.cx;
out_chars = sled->content.txtlen > max_char_len ?
max_char_len : sled->content.txtlen;
txtsize.cx *= out_chars;
}
else {
const char* sled_string = (const char*)sled->content.string;
out_chars = GetTextExtentPoint (hdc, sled_string,
sled->content.txtlen,
x - sled->startx,
NULL, NULL, NULL, &txtsize);
}
}
if (!bSel) {
sled->editPos = out_chars;
sled->selStart = sled->selEnd = sled->editPos;
//mySetCaretPos (hWnd, sled, txtsize.cx + sled->startx);
}
else {
if (out_chars > sled->editPos) {
sled->selStart = sled->editPos;
sled->selEnd = out_chars;
}
else {
sled->selEnd = sled->editPos;
sled->selStart = out_chars;
}
}
/* move caret with select end. */
if (sled->editPos == sled->selStart)
make_charpos_visible (hWnd, sled, sled->selEnd, NULL);
else
make_charpos_visible (hWnd, sled, sled->selStart, NULL);
mySetCaretPos (hWnd, sled, txtsize.cx + sled->startx);
ReleaseDC (hdc);
}
static BOOL make_pos_visible (HWND hWnd, PSLEDITDATA sled, int x)
{
if (x - sled->nContX > sled->nVisW) {
sled->nContX = x - sled->nVisW;
return TRUE;
}
else if (x < sled->nContX) {
sled->nContX = x;
return TRUE;
}
return FALSE;
}
static BOOL
make_charpos_visible (HWND hWnd, PSLEDITDATA sled, int charPos, int *cx)
{
SIZE txtsize;
HDC hdc;
if (charPos <= 0)
txtsize.cx = 0;
else {
char* string = (char*)sled->content.string;
int dwStyle = GetWindowStyle(hWnd);
hdc = GetClientDC (hWnd);
if (dwStyle & ES_PASSWORD) {
string = FixStrAlloc (sled->content.txtlen);
memset (string, sled->passwdChar, sled->content.txtlen);
}
GetTextExtent (hdc, (const char*)string,
charPos, &txtsize);
if (dwStyle & ES_PASSWORD)
FreeFixStr (string);
ReleaseDC (hdc);
}
if (cx)
*cx = sled->startx + txtsize.cx;
return make_pos_visible (hWnd, sled, sled->startx + txtsize.cx);
}
static void
calc_content_width(HWND hWnd, PSLEDITDATA sled, int charPos, int *cx)
{
SIZE txtsize;
HDC hdc;
if (charPos <= 0)
txtsize.cx = 0;
else {
hdc = GetClientDC (hWnd);
GetTextExtent (hdc, (const char*)sled->content.string,
charPos, &txtsize);
ReleaseDC (hdc);
}
if (cx)
*cx = txtsize.cx;
}
static void
calc_charpos_cx (HWND hWnd, PSLEDITDATA sled, int charPos, int *cx)
{
SIZE txtsize;
HDC hdc;
if (charPos <= 0)
txtsize.cx = 0;
else {
hdc = GetClientDC (hWnd);
GetTextExtent (hdc, (const char*)sled->content.string,
charPos, &txtsize);
ReleaseDC (hdc);
}
if (cx)
*cx = sled->startx + txtsize.cx;
}
/*
* set caret position according to the current edit position.
*/
static BOOL edtSetCaretPos (HWND hWnd, PSLEDITDATA sled)
{
BOOL bRefresh;
int cx;
bRefresh = make_charpos_visible (hWnd, sled, sled->editPos, &cx);
mySetCaretPos (hWnd, sled, cx);
if (bRefresh) {
InvalidateRect (hWnd, NULL, TRUE);
}
return bRefresh;
}
static void set_edit_caret_pos(HWND hWnd, PSLEDITDATA sled)
{
int cx;
make_charpos_visible (hWnd, sled, sled->editPos, &cx);
mySetCaretPos (hWnd, sled, cx);
}
static int sleMouseMove (HWND hWnd, PSLEDITDATA sled, LPARAM lParam)
{
int selStart, selEnd;
int mouseX, mouseY;
RECT rcClient;
mouseX = LOSWORD(lParam);
mouseY = HISWORD(lParam);
ScreenToClient(hWnd, &mouseX, &mouseY);
GetClientRect(hWnd, &rcClient);
selStart = sled->selStart;
selEnd = sled->selEnd;
if (mouseX < 0) {
mouseX = 0;
if (sled->selStart > 0) {
shift_one_char_l (selStart);
make_charpos_visible (hWnd, sled, sled->selStart, NULL);
}
else {
return -1;
}
}
if (mouseX > RECTW(rcClient)) {
mouseX = RECTW(rcClient) - 1;
if (sled->selEnd < sled->content.txtlen) {
shift_one_char_r (selEnd);
make_charpos_visible (hWnd, sled, sled->selEnd, NULL);
}
else {
return -1;
}
}
set_caret_pos (hWnd, sled, mouseX, TRUE);
check_caret();
if (selStart != sled->selStart || selEnd != sled->selEnd)
InvalidateRect(hWnd, NULL, TRUE);
return 0;
}
static void set_line_width (HWND hWnd, PSLEDITDATA sled)
{
SIZE txtsize;
HDC hdc;
DWORD dwStyle = GetWindowStyle(hWnd);
int old_w = sled->nContW;
hdc = GetClientDC (hWnd);
SelectFont (hdc, GetWindowFont(hWnd));
GetTextExtent(hdc, (const char*)(sled->content.string),
sled->content.txtlen, &txtsize);
ReleaseDC (hdc);
if (txtsize.cx > sled->nVisW)
sled->nContW = txtsize.cx;
else
sled->nContW = sled->nVisW;
if (dwStyle & ES_RIGHT) {
sled->nContX += (sled->nContW - old_w);
}
else if (dwStyle & ES_CENTER) {
sled->nContX += (sled->nContW - old_w) >> 1;
}
if (sled->nContX + sled->nVisW > sled->nContW) {
sled->nContX = sled->nContW - sled->nVisW;
}
else if (sled->nContX < 0)
sled->nContX = 0;
if (sled->nContW > sled->nVisW)
sled->startx = 0;
else if (dwStyle & ES_RIGHT) {
sled->startx = sled->nVisW - txtsize.cx;
}
else if (dwStyle & ES_CENTER) {
sled->startx = (sled->nVisW - txtsize.cx) >> 1;
}
else {
sled->startx = 0;
}
}
static inline void edtChangeCont (HWND hWnd, PSLEDITDATA sled)
{
set_line_width (hWnd, sled);
}
/* check input validity for password style */
static void check_valid_passwd (char *newtext)
{
char *ptmp = newtext;
while (*ptmp) {
if (!isprint(*ptmp))
*ptmp = PASSWORD_REPLACEMENT;
ptmp ++;
}
}
static int
sleInsertText (HWND hWnd, PSLEDITDATA sled, char *newtext, int inserting)
{
int deleted;
unsigned char *pIns, *content = sled->content.string;
if ( (GetWindowStyle(hWnd) & ES_PASSWORD) && newtext && inserting > 0 ) {
check_valid_passwd (newtext);
}
//delete the seleted
if(sled->selStart != sled->selEnd) {
deleted = sled->selEnd - sled->selStart;
memmove (content + sled->selStart, content + sled->selEnd,
sled->content.txtlen - sled->selEnd);
sled->content.txtlen -= deleted;
sled->editPos = sled->selStart;
sled->selEnd = sled->selStart;
ShowCaret(hWnd);
if (!newtext)
inserting = 0;
}
if ( !(sled->status & EST_REPLACE) && inserting > 0
&& sled->hardLimit >= 0
&& ((sled->content.txtlen + inserting) > sled->hardLimit)) {
Ping ();
NotifyParent (hWnd, GetDlgCtrlID(hWnd), EN_MAXTEXT);
inserting = sled->hardLimit - sled->content.txtlen;
return 0;
}
else if ( (sled->status & EST_REPLACE) && inserting > 0
&& sled->hardLimit >= 0
&& (sled->editPos + inserting > sled->hardLimit) ) {
Ping ();
NotifyParent (hWnd, GetDlgCtrlID(hWnd), EN_MAXTEXT);
inserting = sled->hardLimit - sled->editPos;
}
if (inserting > 0) {
content = testr_realloc (&sled->content, sled->content.txtlen +
inserting);
pIns = content + sled->editPos;
if ( !(sled->status & EST_REPLACE) )
memmove (pIns + inserting, pIns,
sled->content.txtlen+1 - sled->editPos);
memcpy (pIns, newtext, inserting);
}
else if (inserting < 0) {
pIns = content + sled->editPos;
memmove (pIns + inserting, pIns,
sled->content.txtlen+1 - sled->editPos);
content = testr_realloc (&sled->content, sled->content.txtlen +
inserting);
}
if (inserting <= 0 || !(sled->status & EST_REPLACE))
sled->content.txtlen += inserting;
else {
int add_len = inserting - sled->content.txtlen + sled->editPos;
if (add_len > 0) {
sled->content.txtlen += add_len;
sled->content.string[sled->content.txtlen] = '\0';
}
}
sled->editPos += inserting;
sled->selStart = sled->selEnd = sled->editPos;
//FIXME
edtChangeCont (hWnd, sled);
InvalidateRect (hWnd, NULL, TRUE);
if (!edtSetCaretPos (hWnd, sled)) {
InvalidateRect (hWnd, NULL, TRUE);
}
sled->changed = TRUE;
NotifyParent (hWnd, GetDlgCtrlID(hWnd), EN_CHANGE);
return 0;
}
static int
sleInsertText_refresh (HWND hWnd,
PSLEDITDATA sled, char *newtext, int inserting)
{
int deleted;
unsigned char *pIns, *content = sled->content.string;
if ( (GetWindowStyle(hWnd) & ES_PASSWORD) && newtext && inserting > 0 ) {
check_valid_passwd (newtext);
}
//delete the seleted
if(sled->selStart != sled->selEnd) {
deleted = sled->selEnd - sled->selStart;
memmove (content + sled->selStart, content + sled->selEnd,
sled->content.txtlen - sled->selEnd);
sled->content.txtlen -= deleted;
sled->editPos = sled->selStart;
sled->selEnd = sled->selStart;
ShowCaret(hWnd);
if (!newtext)
inserting = 0;
}
if ( !(sled->status & EST_REPLACE) && inserting > 0 && sled->hardLimit >= 0
&& ((sled->content.txtlen + inserting) > sled->hardLimit)) {
Ping ();
NotifyParent (hWnd, GetDlgCtrlID(hWnd), EN_MAXTEXT);
inserting = sled->hardLimit - sled->content.txtlen;
//return 0;
}
else if ( (sled->status & EST_REPLACE) && inserting > 0
&& sled->hardLimit >= 0
&& (sled->editPos + inserting > sled->hardLimit) ) {
Ping ();
NotifyParent (hWnd, GetDlgCtrlID(hWnd), EN_MAXTEXT);
inserting = sled->hardLimit - sled->editPos;
}
if (inserting > 0) {
content = testr_realloc (&sled->content, sled->content.txtlen +
inserting);
pIns = content + sled->editPos;
if ( !(sled->status & EST_REPLACE) )
memmove (pIns + inserting, pIns,
sled->content.txtlen+1 - sled->editPos);
memcpy (pIns, newtext, inserting);
}
else if (inserting < 0) {
pIns = content + sled->editPos;
memmove (pIns + inserting, pIns,
sled->content.txtlen+1 - sled->editPos);
content = testr_realloc (&sled->content, sled->content.txtlen +
inserting);
}
if (inserting <= 0 || !(sled->status & EST_REPLACE))
sled->content.txtlen += inserting;
else {
int add_len = inserting - sled->content.txtlen + sled->editPos;
if (add_len > 0) {
sled->content.txtlen += add_len;
sled->content.string[sled->content.txtlen] = '\0';
}
}
sled->editPos += inserting;
sled->selStart = sled->selEnd = sled->editPos;
//FIXME
edtChangeCont (hWnd, sled);
return 0;
}
static int sleCaseText (char* txt, BOOL bupper)
{
char *str;
char (*tocase)(char);
if (NULL == txt)
return -1;
if (bupper)
tocase = (char(*)(char))toupper;
else
tocase = (char(*)(char))tolower;
str = txt;
while (*str != '\0') {
str[0] = tocase(str[0]);
str ++;
}
return 0;
}
#ifdef _MGHAVE_CLIPBOARD
static int sleInsertCbText (HWND hWnd, PSLEDITDATA sled)
{
int inserting;
unsigned char *txtBuffer;
if (GetWindowStyle(hWnd) & ES_READONLY) {
return 0;
}
inserting = GetClipBoardDataLen (CBNAME_TEXT);
txtBuffer = ALLOCATE_LOCAL (inserting);
GetClipBoardData (CBNAME_TEXT, txtBuffer, inserting);
txtBuffer[inserting]=0;
if (GetWindowStyle(hWnd) & ES_UPPERCASE)
sleCaseText((char *)txtBuffer, TRUE);
else if (GetWindowStyle(hWnd) & ES_LOWERCASE)
sleCaseText((char *)txtBuffer, FALSE);
sleInsertText (hWnd, sled, (char *)txtBuffer, inserting);
DEALLOCATE_LOCAL(txtBuffer);
return 0;
}
#endif
static void esright_backspace_refresh(HWND hWnd, PSLEDITDATA sled, int del)
{
RECT scroll_rc, refresh_rc;
int sel_start_x, sel_end_x;
int old_caret_x, cur_caret_x;
int scroll_len;
int old_editpos_x, cur_editpos_x;
scroll_rc.top = sled->rcVis.top;
scroll_rc.bottom = sled->rcVis.bottom;
if (sled->nContW <= sled->nVisW){
if (sled->selStart != sled->selEnd){
calc_charpos_cx(hWnd, sled, sled->selStart, &sel_start_x);
calc_charpos_cx(hWnd, sled, sled->selEnd, &sel_end_x);
if (sled->selStart < sled->selEnd){
scroll_rc.right = sel_end_x + 1;
}
else{
scroll_rc.right = sel_start_x + 1;
}
scroll_rc.left = sled->rcVis.left;
sleInsertText_refresh (hWnd, sled, NULL, del);
scroll_len = abs(sel_start_x - sel_end_x);
ScrollWindow(hWnd, scroll_len, 0, &scroll_rc, NULL);
edtSetCaretPos (hWnd, sled);
}
else{
calc_charpos_cx(hWnd, sled, sled->editPos, &old_editpos_x);
scroll_rc.left = sled->rcVis.left;
calc_charpos_cx(hWnd, sled, sled->editPos + del, &cur_editpos_x);
sleInsertText_refresh (hWnd, sled, NULL, del);
edtSetCaretPos (hWnd, sled);
scroll_rc.right = old_editpos_x + 1;
scroll_len = abs(cur_editpos_x - old_editpos_x);
ScrollWindow(hWnd, scroll_len, 0, &scroll_rc, NULL);
}
}
else{
if (sled->nContX <= 0){//left scroll window while the head of text is in the sled->rcVis
if (sled->selStart != sled->selEnd){
refresh_rc.top = sled->rcVis.top;
refresh_rc.bottom = sled->rcVis.bottom;
refresh_rc.right = sled->rcVis.right;
scroll_rc.right = sled->rcVis.right;
calc_charpos_cx(hWnd, sled, sled->selStart, &sel_start_x);
calc_charpos_cx(hWnd, sled, sled->selEnd, &sel_end_x);
if (sled->selStart < sled->selEnd){
scroll_rc.left = sel_start_x + 1;
}
else{
scroll_rc.left = sel_end_x + 1;
}
sleInsertText_refresh (hWnd, sled, NULL, del);
edtSetCaretPos (hWnd, sled);
scroll_len = abs(sel_start_x - sel_end_x);
refresh_rc.left = refresh_rc.right - scroll_len;
ScrollWindow(hWnd, -scroll_len, 0, &scroll_rc, NULL);
InvalidateRect(hWnd, &refresh_rc, TRUE);
if (sled->nContW <= sled->nVisW){
InvalidateRect(hWnd, NULL, TRUE);
}
}
else{
refresh_rc.top = sled->rcVis.top;
refresh_rc.bottom = sled->rcVis.bottom;
refresh_rc.right = sled->rcVis.right;
scroll_rc.right = sled->rcVis.right;
old_caret_x = get_caretpos_x(hWnd);
sleInsertText_refresh (hWnd, sled, NULL, del);
edtSetCaretPos (hWnd, sled);
cur_caret_x = get_caretpos_x(hWnd);
scroll_rc.left = cur_caret_x;
scroll_len = abs(cur_caret_x - old_caret_x);
refresh_rc.left = refresh_rc.right - scroll_len;
ScrollWindow(hWnd, -scroll_len, 0, &scroll_rc, NULL);
InvalidateRect(hWnd, &refresh_rc, TRUE);
if (sled->nContW <= sled->nVisW){
InvalidateRect(hWnd, NULL, TRUE);
}
}
}
else{//right scroll window while sled->nContX > 0
if (sled->selStart != sled->selEnd){
refresh_rc.top = sled->rcVis.top;
refresh_rc.bottom = sled->rcVis.bottom;
refresh_rc.left = sled->rcVis.left;
calc_charpos_cx(hWnd, sled, sled->selStart, &sel_start_x);
calc_charpos_cx(hWnd, sled, sled->selEnd, &sel_end_x);
if (sled->selStart < sled->selEnd){
scroll_rc.right = sel_end_x + 1 - sled->nContX;
}
else{
scroll_rc.right = sel_start_x + 1 - sled->nContX;
}
scroll_rc.left = sled->rcVis.left;
sleInsertText_refresh (hWnd, sled, NULL, del);
scroll_len = abs(sel_start_x - sel_end_x);
refresh_rc.right = refresh_rc.left + scroll_len;
ScrollWindow(hWnd, scroll_len, 0, &scroll_rc, NULL);
edtSetCaretPos (hWnd, sled);
InvalidateRect(hWnd, &refresh_rc, TRUE);
if (sled->nContW <= sled->nVisW){
InvalidateRect(hWnd, NULL, TRUE);
}
if (sled->nContX <= 0){
InvalidateRect(hWnd, NULL, TRUE);
}
}
else{
int old_ncontw;
refresh_rc.top = sled->rcVis.top;
refresh_rc.bottom = sled->rcVis.bottom;
refresh_rc.left = sled->rcVis.left;
scroll_rc.left = sled->rcVis.left;
old_ncontw = sled->nContW;
sleInsertText_refresh (hWnd, sled, NULL, del);
edtSetCaretPos (hWnd, sled);
cur_caret_x = get_caretpos_x(hWnd);
scroll_rc.right = cur_caret_x;
scroll_len = abs(sled->nContW - old_ncontw);
refresh_rc.right = refresh_rc.left + abs(scroll_len);
ScrollWindow(hWnd, scroll_len, 0, &scroll_rc, NULL);
InvalidateRect(hWnd, &refresh_rc, TRUE);
if (sled->nContW <= sled->nVisW){
InvalidateRect(hWnd, NULL, TRUE);
}
if (sled->nContX <= 0){
InvalidateRect(hWnd, NULL, TRUE);
}
}
}
}
sled->changed = TRUE;
NotifyParent (hWnd, GetDlgCtrlID(hWnd), EN_CHANGE);
}
static void esright_del_refresh(HWND hWnd, PSLEDITDATA sled, int del)
{
RECT scroll_rc, refresh_rc;
int sel_start_x, sel_end_x;
int old_caret_x, cur_caret_x;
int scroll_len;
int old_editpos_x, cur_editpos_x;
scroll_rc.top = sled->rcVis.top;
scroll_rc.bottom = sled->rcVis.bottom;
if (sled->nContW <= sled->nVisW){
if (sled->selStart != sled->selEnd){
calc_charpos_cx(hWnd, sled, sled->selStart, &sel_start_x);
calc_charpos_cx(hWnd, sled, sled->selEnd, &sel_end_x);
if (sled->selStart < sled->selEnd){
scroll_rc.right = sel_end_x + 1;
}
else{
scroll_rc.right = sel_start_x + 1;
}
scroll_rc.left = sled->rcVis.left;
sleInsertText_refresh (hWnd, sled, NULL, del);
scroll_len = abs(sel_start_x - sel_end_x);
ScrollWindow(hWnd, scroll_len, 0, &scroll_rc, NULL);
edtSetCaretPos (hWnd, sled);
}
else{
old_caret_x = get_caretpos_x(hWnd);
scroll_rc.left = sled->rcVis.left;
sleInsertText_refresh (hWnd, sled, NULL, del);
edtSetCaretPos (hWnd, sled);
cur_caret_x = get_caretpos_x(hWnd);
scroll_rc.right = cur_caret_x;
scroll_len = cur_caret_x - old_caret_x;
ScrollWindow(hWnd, scroll_len, 0, &scroll_rc, NULL);
}
}
else{
if (sled->nContX <=0){//left scroll window while the head of text is in the sled->rcVis
if (sled->selStart != sled->selEnd){
refresh_rc.top = sled->rcVis.top;
refresh_rc.bottom = sled->rcVis.bottom;
refresh_rc.right = sled->rcVis.right;
scroll_rc.right = sled->rcVis.right;
calc_charpos_cx(hWnd, sled, sled->selStart, &sel_start_x);
calc_charpos_cx(hWnd, sled, sled->selEnd, &sel_end_x);
if (sled->selStart < sled->selEnd){
scroll_rc.left = sel_start_x + 1;
}
else{
scroll_rc.left = sel_end_x + 1;
}
sleInsertText_refresh (hWnd, sled, NULL, del);
edtSetCaretPos (hWnd, sled);
scroll_len = abs(sel_start_x - sel_end_x);
refresh_rc.left = refresh_rc.right - scroll_len;
ScrollWindow(hWnd, -scroll_len, 0, &scroll_rc, NULL);
InvalidateRect(hWnd, &refresh_rc, TRUE);
if (sled->nContW <= sled->nVisW){
InvalidateRect(hWnd, NULL, TRUE);
}
}
else{
refresh_rc.top = sled->rcVis.top;
refresh_rc.bottom = sled->rcVis.bottom;
refresh_rc.right = sled->rcVis.right;
scroll_rc.right = sled->rcVis.right;
scroll_rc.left = get_caretpos_x(hWnd);
calc_charpos_cx(hWnd, sled, sled->editPos, &old_editpos_x);
sleInsertText_refresh (hWnd, sled, NULL, del);
calc_charpos_cx(hWnd, sled, sled->editPos, &cur_editpos_x);
edtSetCaretPos (hWnd, sled);
scroll_len = old_editpos_x - cur_editpos_x;
refresh_rc.left = refresh_rc.right - scroll_len;
ScrollWindow(hWnd, -scroll_len, 0, &scroll_rc, NULL);
InvalidateRect(hWnd, &refresh_rc, TRUE);
if (sled->nContW <= sled->nVisW){
InvalidateRect(hWnd, NULL, TRUE);
}
}
}
else{//right scroll window while sled->nContX > 0
if (sled->selStart != sled->selEnd){
refresh_rc.top = sled->rcVis.top;
refresh_rc.bottom = sled->rcVis.bottom;
refresh_rc.left = sled->rcVis.left;
calc_charpos_cx(hWnd, sled, sled->selStart, &sel_start_x);
calc_charpos_cx(hWnd, sled, sled->selEnd, &sel_end_x);
if (sled->selStart < sled->selEnd){
scroll_rc.right = sel_end_x + 1 - sled->nContX;
}
else{
scroll_rc.right = sel_start_x + 1 - sled->nContX;
}
scroll_rc.left = sled->rcVis.left;
sleInsertText_refresh (hWnd, sled, NULL, del);
scroll_len = abs(sel_start_x - sel_end_x);
refresh_rc.right = refresh_rc.left + scroll_len;
ScrollWindow(hWnd, scroll_len, 0, &scroll_rc, NULL);
edtSetCaretPos (hWnd, sled);
InvalidateRect(hWnd, &refresh_rc, TRUE);
if (scroll_len >= sled->nVisW){
InvalidateRect(hWnd, NULL, TRUE);
}
if (sled->nContW <= sled->nVisW){
InvalidateRect(hWnd, NULL, TRUE);
}
if (sled->nContX <= 0){
InvalidateRect(hWnd, NULL, TRUE);
}
}
else{
refresh_rc.top = sled->rcVis.top;
refresh_rc.bottom = sled->rcVis.bottom;
refresh_rc.left = sled->rcVis.left;
old_caret_x = get_caretpos_x(hWnd);
scroll_rc.left = sled->rcVis.left;
sleInsertText_refresh (hWnd, sled, NULL, del);
edtSetCaretPos (hWnd, sled);
cur_caret_x = get_caretpos_x(hWnd);
scroll_rc.right = cur_caret_x;
scroll_len = cur_caret_x - old_caret_x;
refresh_rc.right = refresh_rc.left + abs(scroll_len);
ScrollWindow(hWnd, scroll_len, 0, &scroll_rc, NULL);
InvalidateRect(hWnd, &refresh_rc, TRUE);
if (sled->nContW <= sled->nVisW){
InvalidateRect(hWnd, NULL, TRUE);
}
if (sled->nContX <= 0){
InvalidateRect(hWnd, NULL, TRUE);
}
}
}
}
sled->changed = TRUE;
NotifyParent (hWnd, GetDlgCtrlID(hWnd), EN_CHANGE);
}
static void esleft_del_refresh(HWND hWnd, PSLEDITDATA sled, int del)
{
int old_nContX = sled->nContX;
RECT scroll_rc, del_rc, refresh_rc;
int txtlen_x;
int sel_start_x, sel_end_x;
int old_caret_x, cur_caret_x;
int scroll_len;
scroll_rc.top = sled->rcVis.top;
scroll_rc.bottom = sled->rcVis.bottom;
del_rc.bottom = sled->rcVis.bottom;
del_rc.top = sled->rcVis.top;
refresh_rc.top = sled->rcVis.top;
refresh_rc.bottom = sled->rcVis.bottom;
if (sled->selStart != sled->selEnd){
if (sled->selStart < sled->selEnd){
calc_charpos_cx(hWnd, sled, sled->selEnd, &sel_end_x);
scroll_rc.left = sel_end_x;
}
else{
calc_charpos_cx(hWnd, sled, sled->selStart, &sel_start_x);
scroll_rc.left = sel_start_x;
}
scroll_rc.right = sled->rcVis.right;
}
else{
calc_charpos_cx(hWnd, sled, sled->editPos, &scroll_rc.left);
scroll_rc.left = scroll_rc.left - old_nContX;
scroll_rc.right = sled->rcVis.right;
}
old_caret_x = get_caretpos_x(hWnd);
calc_charpos_cx(hWnd, sled, sled->content.txtlen, &txtlen_x);
sleInsertText_refresh (hWnd, sled, NULL, del);
calc_charpos_cx(hWnd, sled, sled->editPos, &del_rc.left);
del_rc.left = del_rc.left - old_nContX;
del_rc.right = scroll_rc.left;
scroll_len = del_rc.left - scroll_rc.left;
if (abs(sel_start_x - sel_end_x) >= sled->nVisW){
InvalidateRect(hWnd, NULL, TRUE);
}
else{
if ((old_nContX > 0) && ((txtlen_x - old_nContX) <= sled->rcVis.right)){
cur_caret_x = get_caretpos_x(hWnd);
if (cur_caret_x != old_caret_x){
scroll_len = cur_caret_x - old_caret_x;
scroll_rc.left = sled->rcVis.left;
scroll_rc.right = old_caret_x;
ScrollWindow(hWnd, scroll_len, 0, &scroll_rc, NULL);
refresh_rc.left = old_caret_x;
refresh_rc.right = cur_caret_x;
InvalidateRect(hWnd, &refresh_rc, TRUE);
}
else if (sled->selStart != sled->selEnd) {
scroll_len = sel_start_x - sel_end_x;
scroll_rc.left = sled->rcVis.left;
scroll_rc.right = old_caret_x;
ScrollWindow(hWnd, scroll_len, 0, &scroll_rc, NULL);
refresh_rc.left = old_caret_x;
refresh_rc.right = cur_caret_x;
InvalidateRect(hWnd, &refresh_rc, TRUE);
}
else{
InvalidateRect(hWnd, NULL, TRUE);
}
}
else{
int rl;
InvalidateRect(hWnd, &del_rc, TRUE);
ScrollWindow(hWnd, scroll_len, 0, &scroll_rc, NULL);
calc_charpos_cx(hWnd, sled, sled->content.txtlen, &rl);
if (((sled->nContW - sled->nContX) == sled->nVisW) && (old_nContX > 0)){
InvalidateRect(hWnd, NULL, TRUE);
}
else if (rl < sled->nVisW){
refresh_rc.left = rl;
refresh_rc.right = sled->rcVis.right;
InvalidateRect(hWnd, &refresh_rc, TRUE);
}
else{
refresh_rc.left = sled->rcVis.right - abs(scroll_len);
refresh_rc.right = sled->rcVis.right;
InvalidateRect(hWnd, &refresh_rc, TRUE);
}
}
}
}
static int sleKeyDown (HWND hWnd, WPARAM wParam, LPARAM lParam)
{
BOOL bChange = FALSE;
DWORD dwStyle = GetWindowStyle (hWnd);
PCONTROL pCtrl = gui_Control(hWnd);
PSLEDITDATA sled = (PSLEDITDATA) (pCtrl->dwAddData2);
switch (LOWORD (wParam)) {
case SCANCODE_KEYPADENTER:
case SCANCODE_ENTER:
NotifyParent (hWnd, pCtrl->id, EN_ENTER);
return 0;
case SCANCODE_HOME:
{
BOOL refresh = FALSE;
if(lParam & KS_SHIFT) {
make_pos_visible (hWnd, sled, sled->startx);
sled->selStart = 0;
sled->selEnd = sled->editPos;
check_caret();
//InvalidateRect (hWnd, NULL, TRUE);
InvalidateRect (hWnd, &sled->rcVis, TRUE);
NotifyParent (hWnd, pCtrl->id, EN_SELCHANGED);
return 0;
}
if (sled->selStart != sled->selEnd) {
ShowCaret(hWnd);
refresh = TRUE;
}
sled->editPos = 0;
sled->selStart = sled->selEnd = 0;
if (!edtSetCaretPos (hWnd, sled) && refresh)
//InvalidateRect (hWnd, NULL, TRUE);
InvalidateRect (hWnd, &sled->rcVis, TRUE);
return 0;
}
case SCANCODE_END:
{
BOOL refresh = FALSE;
if(lParam & KS_SHIFT) {
sled->selStart = sled->editPos;
sled->selEnd = sled->content.txtlen;
check_caret();
make_charpos_visible (hWnd, sled, sled->selEnd, NULL);
InvalidateRect(hWnd, NULL, TRUE);
NotifyParent (hWnd, pCtrl->id, EN_SELCHANGED);
return 0;
}
if (sled->selStart != sled->selEnd) {
ShowCaret(hWnd);
refresh = TRUE;
}
sled->editPos = sled->content.txtlen;
sled->selStart = sled->selEnd = sled->editPos;
if (!edtSetCaretPos (hWnd, sled) && refresh)
InvalidateRect (hWnd, NULL, TRUE);
return 0;
}
case SCANCODE_CURSORBLOCKLEFT:
{
BOOL refresh = FALSE;
if(lParam & KS_SHIFT) {
if (sled->selStart == sled->selEnd) {
sled->selStart = sled->selEnd = sled->editPos;
}
if (sled->selStart < sled->editPos ||
sled->selStart == sled->selEnd) {
if (sled->selStart > 0)
shift_one_char_l(selStart);
}
else {
shift_one_char_l(selEnd);
}
check_caret ();
make_charpos_visible (hWnd, sled, sled->selStart, NULL);
InvalidateRect (hWnd, NULL, TRUE);
NotifyParent (hWnd, pCtrl->id, EN_SELCHANGED);
return 0;
}
if (sled->selStart != sled->selEnd) {
if (sled->editPos != sled->selEnd)
sled->editPos = sled->selEnd;
else
sled->editPos = sled->selStart;
}
if (sled->editPos > 0) {
shift_one_char_l (editPos);
}
if (sled->selStart != sled->selEnd) {
ShowCaret (hWnd);
ActiveCaret (hWnd);
refresh = TRUE;
}
sled->selStart = sled->selEnd = sled->editPos;
if (!edtSetCaretPos (hWnd, sled) && refresh) {
InvalidateRect (hWnd, NULL, TRUE);
}
return 0;
}
case SCANCODE_CURSORBLOCKRIGHT:
{
BOOL refresh = FALSE;
if(lParam & KS_SHIFT) {
if(sled->selStart == sled->selEnd)
sled->selStart = sled->selEnd = sled->editPos;
if (sled->selStart == sled->selEnd ||
sled->selEnd > sled->editPos) {
if (sled->selEnd < sled->content.txtlen)
shift_one_char_r (selEnd);
}
else {
shift_one_char_r (selStart);
}
check_caret ();
make_charpos_visible (hWnd, sled, sled->selEnd, NULL);
InvalidateRect (hWnd, NULL, TRUE);
NotifyParent (hWnd, pCtrl->id, EN_SELCHANGED);
return 0;
}
if (sled->selStart != sled->selEnd) {
if (sled->editPos != sled->selEnd)
sled->editPos = sled->selEnd;
else
sled->editPos = sled->selStart;
}
if (sled->editPos < sled->content.txtlen) {
shift_one_char_r (editPos);
}
if (sled->selStart != sled->selEnd) {
ShowCaret (hWnd);
ActiveCaret (hWnd);
refresh = TRUE;
}
sled->selStart = sled->selEnd = sled->editPos;
if (!edtSetCaretPos (hWnd, sled) && refresh)
InvalidateRect (hWnd, NULL, TRUE);
}
return 0;
case SCANCODE_REMOVE:
{
int del;
int oldpos = sled->editPos;
if ((dwStyle & ES_READONLY))
return 0;
if (sled->editPos == sled->content.txtlen
&& sled->selStart == sled->selEnd)
return 0;
if (sled->selStart == sled->selEnd &&
sled->editPos < sled->content.txtlen) {
shift_one_char_r(editPos);
}
del = oldpos - sled->editPos;
if (dwStyle & ES_LEFT) {
esleft_del_refresh(hWnd, sled, del);
if (!edtSetCaretPos (hWnd, sled)) {
InvalidateRect (hWnd, NULL, TRUE);
}
sled->changed = TRUE;
NotifyParent (hWnd, GetDlgCtrlID(hWnd), EN_CHANGE);
}
else if (dwStyle & ES_RIGHT) {
esright_del_refresh(hWnd, sled, del);
//sleInsertText (hWnd, sled, NULL, del);
}
else if (dwStyle & ES_CENTER) {
sleInsertText (hWnd, sled, NULL, del);
}
else {
sleInsertText (hWnd, sled, NULL, del);
}
}
break;
case SCANCODE_BACKSPACE:
{
int del;
if (dwStyle & ES_READONLY)
return 0;
if (sled->editPos == 0 && sled->selStart == sled->selEnd)
return 0;
del = - CHLENPREV( sled->content.string,
(sled->content.string + sled->editPos) );
sleInsertText (hWnd, sled, NULL, del);
}
break;
case SCANCODE_A:
{
if (lParam & KS_CTRL) {
sleSetSel (hWnd, sled, 0, sled->content.txtlen);
}
return 0;
}
#ifdef _MGHAVE_CLIPBOARD
case SCANCODE_C:
case SCANCODE_X:
{
if ((lParam & KS_CTRL) && (sled->selEnd - sled->selStart > 0)) {
SetClipBoardData (CBNAME_TEXT, sled->content.string + sled->selStart,
sled->selEnd - sled->selStart, CBOP_NORMAL);
if (wParam == SCANCODE_X && !(GetWindowStyle(hWnd) & ES_READONLY)) {
sleInsertText (hWnd, sled, NULL, 0);
}
}
return 0;
}
case SCANCODE_V:
{
if (!(lParam & KS_CTRL))
return 0;
return sleInsertCbText (hWnd, sled);
}
#endif /* _MGHAVE_CLIPBOARD */
case SCANCODE_INSERT:
sled->status ^= EST_REPLACE;
break;
default:
break;
} //end switch
if (bChange){
sled->changed = TRUE;
NotifyParent (hWnd, pCtrl->id, EN_CHANGE);
}
return 0;
}
static void
esright_input_char_refresh (HWND hWnd,
PSLEDITDATA sled, char *charBuffer, int chars)
{
RECT scroll_rc;
int scroll_len;
int old_ncontw, cur_ncontw;
int cur_caret_x;
if (sled->selStart != sled->selEnd) {
sleInsertText (hWnd, sled, (char* )charBuffer, chars);
}
else {//left scroll window
scroll_rc.top = sled->rcVis.top;
scroll_rc.bottom = sled->rcVis.bottom;
calc_content_width(hWnd, sled, sled->content.txtlen, &old_ncontw);
sleInsertText_refresh (hWnd, sled, (char* )charBuffer, chars);
calc_content_width(hWnd, sled, sled->content.txtlen, &cur_ncontw);
scroll_len = abs(old_ncontw- cur_ncontw);
cur_caret_x = get_caretpos_x(hWnd);
scroll_rc.left = sled->rcVis.left;
scroll_rc.right = cur_caret_x;
ScrollWindow(hWnd, -scroll_len, 0, &scroll_rc, NULL);
UpdateInvalidClient(hWnd, TRUE);
edtSetCaretPos (hWnd, sled);
sled->changed = TRUE;
NotifyParent (hWnd, GetDlgCtrlID(hWnd), EN_CHANGE);
}
}
static void
esleft_input_char_refresh (HWND hWnd,
PSLEDITDATA sled, char *charBuffer, int chars)
{
int old_caretpos_x;
int old_sel_start, old_sel_end;
int old_sel_start_x, old_sel_end_x, cur_sel_start_x;
RECT scroll_rc, refresh_rc;
int scroll_len;
int old_edit_pos_x, cur_edit_pos_x;
int old_nContX;
//char_size is width of input chars; sel_size is width of the selected area
int char_size, sel_size;
int txtlen_x;
old_sel_start = sled->selStart;
old_sel_end = sled->selEnd;
old_caretpos_x = get_caretpos_x(hWnd);
calc_charpos_cx(hWnd, sled, sled->editPos, &old_edit_pos_x);
calc_charpos_cx(hWnd, sled, sled->content.txtlen, &txtlen_x);
old_nContX= sled->nContX;
calc_charpos_cx(hWnd, sled, old_sel_start, &old_sel_start_x);
calc_charpos_cx(hWnd, sled, old_sel_end, &old_sel_end_x);
old_sel_start_x = old_sel_start_x - sled->nContX;
old_sel_end_x = old_sel_end_x - sled->nContX;
sleInsertText_refresh (hWnd, sled, (char* )charBuffer, chars);
calc_charpos_cx(hWnd, sled, sled->editPos, &cur_edit_pos_x);
calc_charpos_cx(hWnd, sled, old_sel_start, &cur_sel_start_x);
/* Not used var
int cur_caretpos_x, cur_ncontx;
cur_ncontx = sled->nContX;
cur_caretpos_x = get_caretpos_x(hWnd);
*/
char_size = cur_edit_pos_x - cur_sel_start_x;
sel_size = abs(old_sel_start_x - old_sel_end_x);
scroll_rc.top = sled->rcVis.top;
scroll_rc.bottom = sled->rcVis.bottom;
refresh_rc.top = sled->rcVis.top;
refresh_rc.bottom = sled->rcVis.bottom;
if (char_size >= sled->nVisW){
InvalidateRect(hWnd, NULL, TRUE);
}
else{
if (old_sel_start != old_sel_end){
if (sel_size >= sled->nVisW){
InvalidateRect(hWnd, NULL, TRUE);
}
else{
if (char_size < sel_size){
//right scroll window
if ((old_nContX > 0)
&& ((txtlen_x - old_nContX) <= sled->rcVis.right)) {
scroll_len = sel_size - char_size;
scroll_rc.left = sled->rcVis.left;
scroll_rc.right = old_sel_start_x < old_sel_end_x
? old_sel_start_x : old_sel_end_x;
ScrollWindow(hWnd, scroll_len, 0, &scroll_rc, NULL);
refresh_rc.left = scroll_rc.right;
refresh_rc.right = refresh_rc.left + sel_size + scroll_len;
InvalidateRect(hWnd, &refresh_rc, TRUE);
}
else{//left scroll window
scroll_len = -(sel_size - char_size);
scroll_rc.left = old_sel_start_x < old_sel_end_x
? old_sel_end_x : old_sel_start_x;
scroll_rc.right = sled->rcVis.right;
ScrollWindow(hWnd, scroll_len, 0, &scroll_rc, NULL);
refresh_rc.left = scroll_rc.left - sel_size;
refresh_rc.right = scroll_rc.left;
InvalidateRect(hWnd, &refresh_rc, TRUE);
}
}
else{//when char_size > sel_size right scroll window
scroll_len = char_size - sel_size;
scroll_rc.left = old_sel_start_x < old_sel_end_x
? old_sel_end_x : old_sel_start_x;
scroll_rc.right = sled->rcVis.right;
ScrollWindow(hWnd, scroll_len, 0, &scroll_rc, NULL);
refresh_rc.left = scroll_rc.left - sel_size;
refresh_rc.right = refresh_rc.left + char_size + 1;
InvalidateRect(hWnd, &refresh_rc, TRUE);
}
}
}
else{
int right;
char_size = cur_edit_pos_x - old_edit_pos_x;
calc_charpos_cx(hWnd, sled, sled->content.txtlen, &right);
if (old_caretpos_x < sled->rcVis.right){//right scroll window
scroll_len = cur_edit_pos_x - old_edit_pos_x;
if ((sled->rcVis.right - old_caretpos_x) < scroll_len){//
scroll_len = -(scroll_len - (sled->rcVis.right- old_caretpos_x));
scroll_rc.left = sled->rcVis.left;
scroll_rc.right = old_caretpos_x;
ScrollWindow(hWnd, scroll_len, 0, &scroll_rc, NULL);
refresh_rc.left = sled->rcVis.right - char_size;
refresh_rc.right = sled->rcVis.right;
InvalidateRect(hWnd, &refresh_rc, TRUE);
}
else{
scroll_rc.left = old_caretpos_x;
scroll_rc.right = (right < sled->rcVis.right)
? right+1 : sled->rcVis.right;
ScrollWindow(hWnd, scroll_len, 0, &scroll_rc, NULL);
refresh_rc.left = sled->rcVis.right - char_size;
refresh_rc.right = sled->rcVis.right;
InvalidateRect(hWnd, &refresh_rc, TRUE);
}
}
else{//left scroll window
scroll_len = old_edit_pos_x - cur_edit_pos_x;
ScrollWindow(hWnd, scroll_len, 0, &sled->rcVis, NULL);
refresh_rc.left = sled->rcVis.right - char_size;
refresh_rc.right = sled->rcVis.right;
InvalidateRect(hWnd, &refresh_rc, TRUE);
}
if (((sled->nContW - sled->nContX) == sled->nVisW)
&& (old_nContX > 0)){
InvalidateRect(hWnd, NULL, TRUE);
}
}
}
}
static void sledit_refresh_caret (HWND hWnd, PSLEDITDATA sled, BOOL bInited)
{
DWORD dwStyle = GetWindowStyle(hWnd);
SIZE txtsize;
int outchar;
HDC hdc;
if (!sled)
return;
hdc= GetClientDC (hWnd);
outchar = GetTextExtentPoint (hdc, (const char*)sled->content.string,
sled->content.txtlen,
0,
NULL, NULL, NULL, &txtsize);
ReleaseDC (hdc);
if (bInited) {
if (dwStyle & ES_RIGHT)
sled->editPos = outchar;
else if (dwStyle & ES_CENTER)
sled->editPos = outchar/2;
else
sled->editPos = 0;
}
if (!edtSetCaretPos (hWnd, sled)) {
InvalidateRect (hWnd, NULL, TRUE);
}
}
static int sledit_reset_text (HWND hWnd, PSLEDITDATA sled, char* str)
{
DWORD dwStyle = GetWindowStyle(hWnd);
char* buffer = str;
if (!sled || !buffer)
return -1;
if (dwStyle & ES_PASSWORD) {
buffer = strdup (buffer);
check_valid_passwd (buffer);
}
//we must retain the status of this control, it include is ETS_FOCUS state, that
//tell this control whether the caret is need
//sled->status = 0;
sled->selStart = 0;
sled->selEnd = 0;
if (sled->content.string) {
free (sled->content.string);
sled->content.string = NULL;
sled->content.buffsize = 0;
sled->content.txtlen = 0;
}
sledit_settext (sled, buffer);
recalcSize (hWnd, sled, TRUE);
if (dwStyle & ES_PASSWORD) { free (buffer);
}
//sledit_refresh_caret (hWnd, sled, TRUE);
sled->changed = TRUE;
NotifyParent (hWnd, GetDlgCtrlID(hWnd), EN_UPDATE);
return 0;
}
static int
sledit_insert_text (HWND hWnd, PSLEDITDATA sled, const char* newtext, int len)
{
int i, realen = strlen (newtext);
char* tempstr;
char* newbuffer;
DWORD dwStyle = GetWindowStyle(hWnd);
if (len > realen)
len = realen;
if (!newtext || len <= 0)
return -1;
if (dwStyle & ES_READONLY) {
return 0;
}
tempstr = (char*) malloc(realen+1);
for (i = 0; i < len && newtext[i] != '\0'; i ++)
{
if (dwStyle & ES_UPPERCASE) {
tempstr[i] = toupper (newtext[i]);
}
else if (dwStyle & ES_LOWERCASE) {
tempstr[i] = tolower (newtext[i]);
}
else
tempstr[i] = newtext[i];
}
newbuffer = tempstr;
sleInsertText (hWnd, sled, (char* )newbuffer, len);
free(tempstr);
return 0;
}
static LRESULT
SLEditCtrlProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
DWORD dwStyle;
HDC hdc;
PSLEDITDATA sled = NULL;
PMAINWIN pWin = (PMAINWIN)hWnd;
RECT rcCaret;
dwStyle = GetWindowStyle(hWnd);
if (message != MSG_CREATE)
sled = (PSLEDITDATA) GetWindowAdditionalData2 (hWnd);
switch (message) {
case MSG_CREATE:
if ( !(sled = calloc (1, sizeof (SLEDITDATA))) )
return -1;
if (sledit_init (hWnd, sled) < 0)
return -1;
break;
case MSG_DESTROY:
sledit_destroy (hWnd, sled);
free (sled);
break;
case MSG_PAINT:
{
hdc = BeginPaint (hWnd);
slePaint (hWnd, hdc, sled);
EndPaint (hWnd, hdc);
if (sled->bShowCaret)
ShowCaret (hWnd);
else
HideCaret (hWnd);
return 0;
}
case MSG_SIZECHANGED:
recalcSize (hWnd, sled, FALSE);
return 0;
case MSG_FONTCHANGING:
if (dwStyle & ES_PASSWORD)
return -1;
return 0;
case MSG_FONTCHANGED:
{
sled->starty = sled->topMargin + (sled->rcVis.bottom
- sled->rcVis.top - GetWindowFont(hWnd)->size - 1)/2;
DestroyCaret (hWnd);
CreateCaret (hWnd, NULL, 1, GetWindowFont (hWnd)->size);
recalcSize (hWnd, sled, FALSE);
return 0;
}
case MSG_SETCURSOR:
if (dwStyle & WS_DISABLED) {
SetCursor (GetSystemCursor (IDC_ARROW));
return 0;
}
break;
case MSG_KILLFOCUS:
if (sled->status & EST_FOCUSED) {
BOOL refresh = FALSE;
sled->status &= ~EST_FOCUSED;
//HideCaret (hWnd);
if (pWin->pCaretInfo) {
sled->bShowCaret = FALSE;
SetRect (&rcCaret, pWin->pCaretInfo->x, pWin->pCaretInfo->y,
pWin->pCaretInfo->x + pWin->pCaretInfo->nWidth,
pWin->pCaretInfo->y + pWin->pCaretInfo->nHeight);
InvalidateRect (hWnd, &rcCaret, FALSE);
}
if ( sled->selStart != sled->selEnd
|| (dwStyle & ES_TIP && sled->content.txtlen <= 0)) {
refresh = TRUE;
}
if (sled->selStart != sled->selEnd && !(dwStyle & ES_NOHIDESEL))
{
sled->selStart = sled->selEnd = sled->editPos;
}
if (refresh)
InvalidateRect (hWnd, NULL, TRUE);
NotifyParent (hWnd, GetDlgCtrlID(hWnd), EN_KILLFOCUS);
if (sled->changed){
sled->changed = FALSE;
NotifyParent (hWnd, GetDlgCtrlID(hWnd), EN_CONTCHANGED);
}
}
break;
case MSG_SETFOCUS:
if (sled->status & EST_FOCUSED)
break;
sled->status |= EST_FOCUSED;
/*[humingming/2010/10/19]:bug 5158:
* don't draw the caret here, should in MSG_PAINT. */
ActiveCaret (hWnd);
//ShowCaret(hWnd);
if (pWin->pCaretInfo) {
sled->bShowCaret = TRUE;
SetRect (&rcCaret, pWin->pCaretInfo->x, pWin->pCaretInfo->y,
pWin->pCaretInfo->x + pWin->pCaretInfo->nWidth,
pWin->pCaretInfo->y + pWin->pCaretInfo->nHeight);
InvalidateRect (hWnd, &rcCaret, FALSE);
}
if (dwStyle & ES_AUTOSELECT) {
if (sleSetSel (hWnd, sled, 0,
sled->content.txtlen) <= 0 && dwStyle & ES_TIP)
InvalidateRect (hWnd, NULL, TRUE);
if (lParam == 1)
sled->status |= EST_TMP;
}
else if ( (dwStyle & ES_NOHIDESEL && sled->selStart != sled->selEnd)
|| (dwStyle & ES_TIP && sled->content.txtlen <= 0)) {
InvalidateRect (hWnd, NULL, TRUE);
}
NotifyParent (hWnd, GetDlgCtrlID(hWnd), EN_SETFOCUS);
break;
case MSG_ENABLE:
if ( (!(dwStyle & WS_DISABLED) && !wParam)
|| ((dwStyle & WS_DISABLED) && wParam) ) {
if (wParam)
ExcludeWindowStyle(hWnd,WS_DISABLED);
else
IncludeWindowStyle(hWnd,WS_DISABLED);
InvalidateRect (hWnd, NULL, TRUE);
}
return 0;
case MSG_GETTEXTLENGTH:
return sled->content.txtlen;
case MSG_GETTEXT:
{
char* buffer = (char*)lParam;
int len;
len = MIN ((int)wParam, sled->content.txtlen);
memcpy (buffer, sled->content.string, len);
buffer [len] = '\0';
return len;
}
case MSG_SETTEXT:
return sledit_reset_text (hWnd, sled, (char*)lParam);
case MSG_KEYDOWN:
{
return sleKeyDown (hWnd, wParam, lParam);
}
case MSG_UTF8CHAR:
_ERR_PRINTF ("CONTROL>EDIT: MSG_UTF8CHAR is not implemented.\n");
break;
case MSG_CHAR:
{
unsigned char charBuffer [4];
int chars;
if (dwStyle & ES_READONLY)
return 0;
charBuffer [0] = FIRSTBYTE (wParam);
charBuffer [1] = SECONDBYTE (wParam);
charBuffer [2] = THIRDBYTE (wParam);
charBuffer [3] = FOURTHBYTE (wParam);
if (charBuffer [3]) {
chars = 4;
}
else if (charBuffer [2]) {
chars = 3;
}
else if (charBuffer [1]) {
chars = 2;
}
else {
chars = 1;
if (dwStyle & ES_UPPERCASE) {
charBuffer [0] = toupper (charBuffer[0]);
}
else if (dwStyle & ES_LOWERCASE) {
charBuffer [0] = tolower (charBuffer[0]);
}
}
if (chars == 1 && (charBuffer[0] == '\b' || charBuffer[0] == 0x7F)) {
// ASCII BS or DEL
int del;
if (sled->editPos == 0 && sled->selStart == sled->selEnd)
return 0;
del = -CHLENPREV((const char *)(sled->content.string),
(sled->content.string + sled->editPos) );
if (dwStyle & ES_LEFT) {
esleft_del_refresh(hWnd, sled, del);
set_edit_caret_pos(hWnd, sled);
sled->changed = TRUE;
NotifyParent (hWnd, GetDlgCtrlID(hWnd), EN_CHANGE);
}
else if (dwStyle & ES_RIGHT) {
esright_backspace_refresh(hWnd, sled, del);
}
else if (dwStyle & ES_CENTER) {
sleInsertText (hWnd, sled, NULL, del);
}
else {
sleInsertText (hWnd, sled, NULL, del);
}
}
else if (chars == 1 && charBuffer [0] < 0x20) {
// ignore all other ASCII control characters.
return 0;
}
else {
if (dwStyle & ES_LEFT) {
esleft_input_char_refresh(hWnd, sled, (char*)charBuffer, chars);
set_edit_caret_pos(hWnd, sled);
sled->changed = TRUE;
NotifyParent (hWnd, GetDlgCtrlID(hWnd), EN_CHANGE);
}
else if (dwStyle & ES_RIGHT) {
esright_input_char_refresh(hWnd, sled, (char*)charBuffer, chars);
}
else if (dwStyle & ES_CENTER) {
sleInsertText (hWnd, sled, (char* )charBuffer, chars);
}
else {
sleInsertText (hWnd, sled, (char* )charBuffer, chars);
}
}
return 0;
}
case MSG_LBUTTONDBLCLK:
sleSetSel (hWnd, sled, 0, sled->content.txtlen);
NotifyParent (hWnd, GetDlgCtrlID(hWnd), EN_DBLCLK);
break;
case MSG_LBUTTONDOWN:
{
if ( sled->status & EST_TMP) {
sled->status &= ~EST_TMP;
break;
}
if (HISWORD(lParam) < sled->rcVis.top
|| HISWORD(lParam) > sled->rcVis.bottom)
break;
set_caret_pos (hWnd, sled, LOSWORD(lParam), FALSE);
ActiveCaret (hWnd);
ShowCaret(hWnd);
SetCapture(hWnd);
InvalidateRect(hWnd, NULL, TRUE);
break;
}
case MSG_NCLBUTTONUP:
case MSG_LBUTTONUP:
if (GetCapture() == hWnd)
ReleaseCapture();
NotifyParent (hWnd, GetDlgCtrlID(hWnd), EN_CLICKED);
if (sled->selStart != sled->selEnd)
NotifyParent (hWnd, GetDlgCtrlID(hWnd), EN_SELCHANGED);
break;
case MSG_MOUSEMOVE:
{
if (GetCapture () == hWnd)
sleMouseMove (hWnd, sled, lParam);
return 0;
}
case MSG_GETDLGCODE:
return DLGC_WANTCHARS| DLGC_HASSETSEL| DLGC_WANTARROWS| DLGC_WANTENTER;
case MSG_DOESNEEDIME:
if (dwStyle & ES_READONLY)
return IME_WINDOW_TYPE_READONLY;
else if (dwStyle & ES_PASSWORD)
return IME_WINDOW_TYPE_PASSWORD;
else
return IME_WINDOW_TYPE_EDITABLE;
case EM_GETCARETPOS:
case EM_GETSELPOS:
{
int nr_chars, pos;
int* line_pos = (int *)wParam;
int* char_pos = (int *)lParam;
if (message == EM_GETSELPOS)
pos = (sled->editPos == sled->selStart)
? sled->selEnd : sled->selStart;
else
pos = sled->editPos;
nr_chars = GetTextMCharInfo (GetWindowFont (hWnd),
(const char* )(sled->content.string), pos, NULL);
if (line_pos) *line_pos = 0;
if (char_pos) *char_pos = nr_chars;
return pos;
}
case EM_SETCARETPOS:
case EM_SETSEL:
{
int char_pos = (int)lParam;
int nr_chars, pos;
int *pos_chars;
if (char_pos < 0)
return -1;
pos_chars = ALLOCATE_LOCAL (sled->content.txtlen * sizeof(int));
nr_chars = GetTextMCharInfo (GetWindowFont (hWnd),
(const char* )sled->content.string, sled->content.txtlen, pos_chars);
if (char_pos > nr_chars) {
DEALLOCATE_LOCAL (pos_chars);
return -1;
}
if (char_pos == nr_chars)
pos = sled->content.txtlen;
else
pos = pos_chars[char_pos];
DEALLOCATE_LOCAL (pos_chars);
if (message == EM_SETCARETPOS) {
sled->editPos = pos;
sled->selStart = sled->selEnd = 0;
edtSetCaretPos (hWnd, sled);
return sled->editPos;
}
else {
int start, end;
if (sled->editPos < pos) {
start = sled->editPos;
end = pos;
}
else {
start = pos;
end = sled->editPos;
}
return sleSetSel (hWnd, sled, start, end);
}
}
case EM_INSERTTEXT:
{
return sledit_insert_text (hWnd, sled, (const char*)lParam, wParam);
}
case EM_SETREADONLY:
if (wParam)
IncludeWindowStyle (hWnd, ES_READONLY);
else
ExcludeWindowStyle (hWnd, ES_READONLY);
return 0;
case EM_SETPASSWORDCHAR:
if (sled->passwdChar != (int)wParam) {
sled->passwdChar = (int)wParam;
if (dwStyle & ES_PASSWORD) {
InvalidateRect (hWnd, NULL, TRUE);
}
}
return 0;
case EM_GETPASSWORDCHAR:
{
if (lParam)
*((int*)lParam) = sled->passwdChar;
return 0;
}
case EM_GETMAXLIMIT:
return sled->hardLimit;
case EM_LIMITTEXT:
{
int newLimit = (int)wParam;
if (newLimit >= 0) {
if (sled->content.txtlen > newLimit) {
Ping ();
return -1;
}
else {
sled->hardLimit = newLimit;
return 0;
}
}
return -1;
}
case EM_GETTIPTEXT:
{
int len, tip_len;
char *buffer = (char *)lParam;
if (!(dwStyle & ES_TIP))
return -1;
tip_len = strlen (sled->tiptext);
if (!buffer)
return tip_len;
if (wParam >= 0)
len = (wParam > DEF_TIP_LEN) ? DEF_TIP_LEN : wParam;
else
len = DEF_TIP_LEN;
strncpy (buffer, sled->tiptext, len);
buffer[len] = '\0';
return tip_len;
}
case EM_SETTIPTEXT:
{
int len;
if (!(dwStyle & ES_TIP) || !lParam)
return -1;
if (wParam >= 0)
len = (wParam > DEF_TIP_LEN) ? DEF_TIP_LEN : wParam;
else
len = DEF_TIP_LEN;
strncpy (sled->tiptext, (char *)lParam, len);
sled->tiptext[len] = '\0';
if (sled->content.txtlen <= 0)
InvalidateRect (hWnd, NULL, TRUE);
return strlen(sled->tiptext);
}
case EM_GETSEL:
{
char *buffer = (char *)lParam;
int len;
if (!buffer || sled->selEnd - sled->selStart <= 0)
return 0;
if (wParam < 0)
len = sled->selEnd - sled->selStart;
else
len = MIN(sled->selEnd - sled->selStart, (int)wParam);
strncpy (buffer,
(const char*)(sled->content.string + sled->selStart), len);
return len;
}
case EM_INSERTCBTEXT:
{
#ifdef _CLIPBOAR_SUPPORT
return sleInsertCbText (hWnd, sled);
#endif
}
case EM_COPYTOCB:
case EM_CUTTOCB:
{
#ifdef _MGHAVE_CLIPBOARD
if (sled->selEnd - sled->selStart > 0) {
SetClipBoardData (CBNAME_TEXT,
sled->content.string + sled->selStart,
sled->selEnd - sled->selStart, CBOP_NORMAL);
if (message == EM_CUTTOCB
&& !(GetWindowStyle(hWnd) & ES_READONLY)) {
sleInsertText (hWnd, sled, NULL, 0);
}
return sled->selEnd - sled->selStart;
}
#endif
return 0;
}
default:
break;
} // end switch
return DefaultControlProc (hWnd, message, wParam, lParam);
}
#endif /* _MGCTRL_SLEDIT */