2914 lines
74 KiB
C
2914 lines
74 KiB
C
/*
|
|
* Edit control
|
|
*
|
|
* Copyright David W. Metcalfe, 1994
|
|
* Copyright William Magro, 1995, 1996
|
|
* Copyright Frans van Dorsselaer, 1996
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* UNDER CONSTRUCTION, please read EDIT.TODO
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "windows.h"
|
|
#include "win.h"
|
|
#include "local.h"
|
|
#include "stddebug.h"
|
|
#include "debug.h"
|
|
#include "xmalloc.h"
|
|
#include "callback.h"
|
|
|
|
#define BUFLIMIT_MULTI 65534 /* maximum text buffer length (not including '\0') */
|
|
#define BUFLIMIT_SINGLE 32766
|
|
#define BUFSTART_MULTI 1024 /* starting length for multi-line control */
|
|
#define BUFSTART_SINGLE 256 /* starting length for single line control */
|
|
#define GROWLENGTH 64 /* buffers grow by this much */
|
|
#define HSCROLL_FRACTION 3 /* scroll window by 1/3 width */
|
|
|
|
typedef enum
|
|
{
|
|
END_0 = 0,
|
|
END_DELIMIT,
|
|
END_NONE,
|
|
END_HARD,
|
|
END_SOFT,
|
|
} LINE_END;
|
|
|
|
typedef struct {
|
|
UINT offset;
|
|
UINT length;
|
|
LINE_END ending;
|
|
} LINEDEF;
|
|
|
|
typedef struct
|
|
{
|
|
UINT TextWidth; /* width of the widest line in pixels */
|
|
HLOCAL16 hBuf;
|
|
char *text;
|
|
HFONT hFont;
|
|
LINEDEF *LineDefs;
|
|
UINT XOffset; /* offset of the viewport in pixels */
|
|
UINT FirstVisibleLine;
|
|
UINT LineCount;
|
|
UINT LineHeight; /* height of a screen line in pixels */
|
|
UINT AveCharWidth; /* average character width in pixels */
|
|
UINT BufLimit;
|
|
UINT BufSize;
|
|
BOOL TextChanged;
|
|
BOOL Redraw;
|
|
UINT SelStart; /* offset of selection start, == SelEnd if no selection */
|
|
UINT SelEnd; /* offset of selection end == current caret position */
|
|
UINT NumTabStops;
|
|
LPINT16 TabStops;
|
|
EDITWORDBREAKPROC WordBreakProc;
|
|
char PasswordChar;
|
|
} EDITSTATE;
|
|
|
|
|
|
#define SWAP_UINT(x,y) do { UINT temp = (UINT)(x); (x) = (UINT)(y); (y) = temp; } while(0)
|
|
#define ORDER_UINT(x,y) do { if ((UINT)(y) < (UINT)(x)) SWAP_UINT((x),(y)); } while(0)
|
|
|
|
/* macros to access window styles */
|
|
#define IsMultiLine(wndPtr) ((wndPtr)->dwStyle & ES_MULTILINE)
|
|
#define IsVScrollBar(wndPtr) ((wndPtr)->dwStyle & WS_VSCROLL)
|
|
#define IsHScrollBar(wndPtr) ((wndPtr)->dwStyle & WS_HSCROLL)
|
|
#define IsReadOnly(wndPtr) ((wndPtr)->dwStyle & ES_READONLY)
|
|
#define IsWordWrap(wndPtr) (((wndPtr)->dwStyle & ES_AUTOHSCROLL) == 0)
|
|
#define IsPassword(wndPtr) ((wndPtr)->dwStyle & ES_PASSWORD)
|
|
#define IsLower(wndPtr) ((wndPtr)->dwStyle & ES_LOWERCASE)
|
|
#define IsUpper(wndPtr) ((wndPtr)->dwStyle & ES_UPPERCASE)
|
|
|
|
#define EDITSTATEPTR(wndPtr) (*(EDITSTATE **)((wndPtr)->wExtra))
|
|
|
|
#define EDIT_SEND_CTLCOLOR(wndPtr,hdc) \
|
|
(SendMessage32A((wndPtr)->parent->hwndSelf, WM_CTLCOLOREDIT, \
|
|
(WPARAM)(hdc), (LPARAM)(wndPtr)->hwndSelf ))
|
|
#define EDIT_NOTIFY_PARENT(wndPtr, wNotifyCode) \
|
|
(SendMessage32A((wndPtr)->parent->hwndSelf, WM_COMMAND, \
|
|
MAKEWPARAM((wndPtr)->wIDmenu, wNotifyCode), \
|
|
(LPARAM)(wndPtr)->hwndSelf ))
|
|
#define DPRINTF_EDIT_MSG(str) \
|
|
dprintf_edit(stddeb, \
|
|
"edit: " str ": hwnd=%04x, wParam=%04x, lParam=%08x\n", \
|
|
(UINT32)hwnd, (UINT32)wParam, (UINT32)lParam)
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* Declarations
|
|
*
|
|
* Files like these should really be kept in alphabetical order.
|
|
*
|
|
*/
|
|
LRESULT EditWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
|
|
|
static void EDIT_BuildLineDefs(WND *wndPtr);
|
|
static INT EDIT_CallWordBreakProc(WND *wndPtr, char *s, INT index, INT count, INT action);
|
|
static UINT EDIT_ColFromWndX(WND *wndPtr, UINT line, INT x);
|
|
static void EDIT_DelEnd(WND *wndPtr);
|
|
static void EDIT_DelLeft(WND *wndPtr);
|
|
static void EDIT_DelRight(WND *wndPtr);
|
|
static UINT EDIT_GetAveCharWidth(WND *wndPtr);
|
|
static UINT EDIT_GetLineHeight(WND *wndPtr);
|
|
static void EDIT_GetLineRect(WND *wndPtr, UINT line, UINT scol, UINT ecol, LPRECT16 rc);
|
|
static char * EDIT_GetPointer(WND *wndPtr);
|
|
static char * EDIT_GetPasswordPointer(WND *wndPtr);
|
|
static LRESULT EDIT_GetRect(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static BOOL EDIT_GetRedraw(WND *wndPtr);
|
|
static UINT EDIT_GetTextWidth(WND *wndPtr);
|
|
static UINT EDIT_GetVisibleLineCount(WND *wndPtr);
|
|
static UINT EDIT_GetWndWidth(WND *wndPtr);
|
|
static UINT EDIT_GetXOffset(WND *wndPtr);
|
|
static void EDIT_InvalidateText(WND *wndPtr, UINT start, UINT end);
|
|
static UINT EDIT_LineFromWndY(WND *wndPtr, INT y);
|
|
static BOOL EDIT_MakeFit(WND *wndPtr, UINT size);
|
|
static void EDIT_MoveBackward(WND *wndPtr, BOOL extend);
|
|
static void EDIT_MoveDownward(WND *wndPtr, BOOL extend);
|
|
static void EDIT_MoveEnd(WND *wndPtr, BOOL extend);
|
|
static void EDIT_MoveForward(WND *wndPtr, BOOL extend);
|
|
static void EDIT_MoveHome(WND *wndPtr, BOOL extend);
|
|
static void EDIT_MovePageDown(WND *wndPtr, BOOL extend);
|
|
static void EDIT_MovePageUp(WND *wndPtr, BOOL extend);
|
|
static void EDIT_MoveUpward(WND *wndPtr, BOOL extend);
|
|
static void EDIT_MoveWordBackward(WND *wndPtr, BOOL extend);
|
|
static void EDIT_MoveWordForward(WND *wndPtr, BOOL extend);
|
|
static void EDIT_PaintLine(WND *wndPtr, HDC hdc, UINT line, BOOL rev);
|
|
static UINT EDIT_PaintText(WND *wndPtr, HDC hdc, INT x, INT y, UINT line, UINT col, UINT count, BOOL rev);
|
|
static void EDIT_ReleasePointer(WND *wndPtr);
|
|
static LRESULT EDIT_ReplaceSel(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static void EDIT_ScrollIntoView(WND *wndPtr);
|
|
static INT EDIT_WndXFromCol(WND *wndPtr, UINT line, UINT col);
|
|
static INT EDIT_WndYFromLine(WND *wndPtr, UINT line);
|
|
static INT EDIT_WordBreakProc(char *s, INT index, INT count, INT action);
|
|
|
|
static LRESULT EDIT_EM_CanUndo(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_EmptyUndoBuffer(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_FmtLines(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_GetFirstVisibleLine(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_GetHandle(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_GetLine(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_GetLineCount(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_GetModify(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_GetPasswordChar(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_GetRect(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_GetSel(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_GetThumb(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_GetWordBreakProc(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_LimitText(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_LineFromChar(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_LineIndex(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_LineLength(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_LineScroll(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_ReplaceSel(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_Scroll(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_SetHandle(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_SetModify(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_SetPasswordChar(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_SetReadOnly(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_SetRect(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_SetRectNP(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_SetSel(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_SetTabStops(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_SetWordBreakProc(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_Undo(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
|
|
static LRESULT EDIT_WM_Char(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_Clear(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_Copy(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_Cut(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_Create(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_Destroy(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_Enable(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_EraseBkGnd(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_GetDlgCode(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_GetFont(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_GetText(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_GetTextLength(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_HScroll(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_KeyDown(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_KillFocus(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_LButtonDblClk(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_LButtonDown(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_LButtonUp(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_MouseMove(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_Paint(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_Paste(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_SetCursor(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_SetFocus(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_SetFont(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_SetRedraw(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_SetText(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_Size(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_VScroll(WND *wndPtr, WPARAM wParam, LPARAM lParam);
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* General shortcuts for variable names:
|
|
*
|
|
* UINT l; line
|
|
* UINT c; column
|
|
* UINT s; offset of selection start
|
|
* UINT e; offset of selection end
|
|
* UINT sl; line on which the selection starts
|
|
* UINT el; line on which the selection ends
|
|
* UINT sc; column on which the selection starts
|
|
* UINT ec; column on which the selection ends
|
|
* UINT li; line index (offset)
|
|
* UINT fv; first visible line
|
|
* UINT vlc; vissible line count
|
|
* UINT lc; line count
|
|
* UINT lh; line height (in pixels)
|
|
* UINT tw; text width (in pixels)
|
|
* UINT ww; window width (in pixels)
|
|
* UINT cw; character width (average, in pixels)
|
|
*
|
|
*/
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EditWndProc()
|
|
*
|
|
*/
|
|
LRESULT EditWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
LRESULT lResult = 0L;
|
|
WND *wndPtr = WIN_FindWndPtr(hwnd);
|
|
|
|
switch (msg) {
|
|
case EM_CANUNDO:
|
|
DPRINTF_EDIT_MSG("EM_CANUNDO");
|
|
lResult = EDIT_EM_CanUndo(wndPtr, wParam, lParam);
|
|
break;
|
|
case EM_EMPTYUNDOBUFFER:
|
|
DPRINTF_EDIT_MSG("EM_EMPTYUNDOBUFFER");
|
|
lResult = EDIT_EM_EmptyUndoBuffer(wndPtr, wParam, lParam);
|
|
break;
|
|
case EM_FMTLINES:
|
|
DPRINTF_EDIT_MSG("EM_FMTLINES");
|
|
lResult = EDIT_EM_FmtLines(wndPtr, wParam, lParam);
|
|
break;
|
|
case EM_GETFIRSTVISIBLELINE:
|
|
DPRINTF_EDIT_MSG("EM_GETFIRSTVISIBLELINE");
|
|
lResult = EDIT_EM_GetFirstVisibleLine(wndPtr, wParam, lParam);
|
|
break;
|
|
case EM_GETHANDLE:
|
|
DPRINTF_EDIT_MSG("EM_GETHANDLE");
|
|
lResult = EDIT_EM_GetHandle(wndPtr, wParam, lParam);
|
|
break;
|
|
case EM_GETLINE:
|
|
DPRINTF_EDIT_MSG("EM_GETLINE");
|
|
lResult = EDIT_EM_GetLine(wndPtr, wParam, lParam);
|
|
break;
|
|
case EM_GETLINECOUNT:
|
|
DPRINTF_EDIT_MSG("EM_GETLINECOUNT");
|
|
lResult = EDIT_EM_GetLineCount(wndPtr, wParam, lParam);
|
|
break;
|
|
case EM_GETMODIFY:
|
|
DPRINTF_EDIT_MSG("EM_GETMODIFY");
|
|
lResult = EDIT_EM_GetModify(wndPtr, wParam, lParam);
|
|
break;
|
|
case EM_GETPASSWORDCHAR:
|
|
DPRINTF_EDIT_MSG("EM_GETPASSWORDCHAR");
|
|
lResult = EDIT_EM_GetPasswordChar(wndPtr, wParam, lParam);
|
|
break;
|
|
case EM_GETRECT:
|
|
DPRINTF_EDIT_MSG("EM_GETRECT");
|
|
lResult = EDIT_EM_GetRect(wndPtr, wParam, lParam);
|
|
break;
|
|
case EM_GETSEL:
|
|
DPRINTF_EDIT_MSG("EM_GETSEL");
|
|
lResult = EDIT_EM_GetSel(wndPtr, wParam, lParam);
|
|
break;
|
|
case EM_GETTHUMB:
|
|
DPRINTF_EDIT_MSG("EM_GETTHUMB");
|
|
lResult = EDIT_EM_GetThumb(wndPtr, wParam, lParam);
|
|
break;
|
|
case EM_GETWORDBREAKPROC:
|
|
DPRINTF_EDIT_MSG("EM_GETWORDBREAKPROC");
|
|
lResult = EDIT_EM_GetWordBreakProc(wndPtr, wParam, lParam);
|
|
break;
|
|
case EM_LIMITTEXT:
|
|
DPRINTF_EDIT_MSG("EM_LIMITTEXT");
|
|
lResult = EDIT_EM_LimitText(wndPtr, wParam, lParam);
|
|
break;
|
|
case EM_LINEFROMCHAR:
|
|
DPRINTF_EDIT_MSG("EM_LINEFROMCHAR");
|
|
lResult = EDIT_EM_LineFromChar(wndPtr, wParam, lParam);
|
|
break;
|
|
case EM_LINEINDEX:
|
|
DPRINTF_EDIT_MSG("EM_LINEINDEX");
|
|
lResult = EDIT_EM_LineIndex(wndPtr, wParam, lParam);
|
|
break;
|
|
case EM_LINELENGTH:
|
|
DPRINTF_EDIT_MSG("EM_LINELENGTH");
|
|
lResult = EDIT_EM_LineLength(wndPtr, wParam, lParam);
|
|
break;
|
|
case EM_LINESCROLL:
|
|
DPRINTF_EDIT_MSG("EM_LINESCROLL");
|
|
lResult = EDIT_EM_LineScroll(wndPtr, wParam, lParam);
|
|
break;
|
|
case EM_REPLACESEL:
|
|
DPRINTF_EDIT_MSG("EM_REPLACESEL");
|
|
lResult = EDIT_EM_ReplaceSel(wndPtr, wParam, lParam);
|
|
break;
|
|
case EM_SCROLL:
|
|
DPRINTF_EDIT_MSG("EM_SCROLL");
|
|
lResult = EDIT_EM_Scroll(wndPtr, wParam, lParam);
|
|
break;
|
|
case EM_SETHANDLE:
|
|
DPRINTF_EDIT_MSG("EM_SETHANDLE");
|
|
lResult = EDIT_EM_SetHandle(wndPtr, wParam, lParam);
|
|
break;
|
|
case EM_SETMODIFY:
|
|
DPRINTF_EDIT_MSG("EM_SETMODIFY");
|
|
lResult = EDIT_EM_SetModify(wndPtr, wParam, lParam);
|
|
break;
|
|
case EM_SETPASSWORDCHAR:
|
|
DPRINTF_EDIT_MSG("EM_SETPASSWORDCHAR");
|
|
lResult = EDIT_EM_SetPasswordChar(wndPtr, wParam, lParam);
|
|
break;
|
|
case EM_SETREADONLY:
|
|
DPRINTF_EDIT_MSG("EM_SETREADONLY");
|
|
lResult = EDIT_EM_SetReadOnly(wndPtr, wParam, lParam);
|
|
break;
|
|
case EM_SETRECT:
|
|
DPRINTF_EDIT_MSG("EM_SETRECT");
|
|
lResult = EDIT_EM_SetRect(wndPtr, wParam, lParam);
|
|
break;
|
|
case EM_SETRECTNP:
|
|
DPRINTF_EDIT_MSG("EM_SETRECTNP");
|
|
lResult = EDIT_EM_SetRectNP(wndPtr, wParam, lParam);
|
|
break;
|
|
case EM_SETSEL:
|
|
DPRINTF_EDIT_MSG("EM_SETSEL");
|
|
lResult = EDIT_EM_SetSel(wndPtr, wParam, lParam);
|
|
break;
|
|
case EM_SETTABSTOPS:
|
|
DPRINTF_EDIT_MSG("EM_SETTABSTOPS");
|
|
lResult = EDIT_EM_SetTabStops(wndPtr, wParam, lParam);
|
|
break;
|
|
case EM_SETWORDBREAKPROC:
|
|
DPRINTF_EDIT_MSG("EM_SETWORDBREAKPROC");
|
|
lResult = EDIT_EM_SetWordBreakProc(wndPtr, wParam, lParam);
|
|
break;
|
|
case EM_UNDO:
|
|
case WM_UNDO:
|
|
DPRINTF_EDIT_MSG("EM_UNDO / WM_UNDO");
|
|
lResult = EDIT_EM_Undo(wndPtr, wParam, lParam);
|
|
break;
|
|
case WM_GETDLGCODE:
|
|
DPRINTF_EDIT_MSG("WM_GETDLGCODE");
|
|
lResult = EDIT_WM_GetDlgCode(wndPtr, wParam, lParam);
|
|
break;
|
|
case WM_CHAR:
|
|
DPRINTF_EDIT_MSG("WM_CHAR");
|
|
lResult = EDIT_WM_Char(wndPtr, wParam, lParam);
|
|
break;
|
|
case WM_CLEAR:
|
|
DPRINTF_EDIT_MSG("WM_CLEAR");
|
|
lResult = EDIT_WM_Clear(wndPtr, wParam, lParam);
|
|
break;
|
|
case WM_COPY:
|
|
DPRINTF_EDIT_MSG("WM_COPY");
|
|
lResult = EDIT_WM_Copy(wndPtr, wParam, lParam);
|
|
break;
|
|
case WM_CREATE:
|
|
DPRINTF_EDIT_MSG("WM_CREATE");
|
|
lResult = EDIT_WM_Create(wndPtr, wParam, lParam);
|
|
break;
|
|
case WM_CUT:
|
|
DPRINTF_EDIT_MSG("WM_CUT");
|
|
lResult = EDIT_WM_Cut(wndPtr, wParam, lParam);
|
|
break;
|
|
case WM_DESTROY:
|
|
DPRINTF_EDIT_MSG("WM_DESTROY");
|
|
lResult = EDIT_WM_Destroy(wndPtr, wParam, lParam);
|
|
break;
|
|
case WM_ENABLE:
|
|
DPRINTF_EDIT_MSG("WM_ENABLE");
|
|
lResult = EDIT_WM_Enable(wndPtr, wParam, lParam);
|
|
break;
|
|
case WM_ERASEBKGND:
|
|
DPRINTF_EDIT_MSG("WM_ERASEBKGND");
|
|
lResult = EDIT_WM_EraseBkGnd(wndPtr, wParam, lParam);
|
|
break;
|
|
case WM_GETFONT:
|
|
DPRINTF_EDIT_MSG("WM_GETFONT");
|
|
lResult = EDIT_WM_GetFont(wndPtr, wParam, lParam);
|
|
break;
|
|
case WM_GETTEXT:
|
|
DPRINTF_EDIT_MSG("WM_GETTEXT");
|
|
lResult = EDIT_WM_GetText(wndPtr, wParam, lParam);
|
|
break;
|
|
case WM_GETTEXTLENGTH:
|
|
DPRINTF_EDIT_MSG("WM_GETTEXTLENGTH");
|
|
lResult = EDIT_WM_GetTextLength(wndPtr, wParam, lParam);
|
|
break;
|
|
case WM_HSCROLL:
|
|
DPRINTF_EDIT_MSG("WM_HSCROLL");
|
|
lResult = EDIT_WM_HScroll(wndPtr, wParam, lParam);
|
|
break;
|
|
case WM_KEYDOWN:
|
|
DPRINTF_EDIT_MSG("WM_KEYDOWN");
|
|
lResult = EDIT_WM_KeyDown(wndPtr, wParam, lParam);
|
|
break;
|
|
case WM_KILLFOCUS:
|
|
DPRINTF_EDIT_MSG("WM_KILLFOCUS");
|
|
lResult = EDIT_WM_KillFocus(wndPtr, wParam, lParam);
|
|
break;
|
|
case WM_LBUTTONDBLCLK:
|
|
DPRINTF_EDIT_MSG("WM_LBUTTONDBLCLK");
|
|
lResult = EDIT_WM_LButtonDblClk(wndPtr, wParam, lParam);
|
|
break;
|
|
case WM_LBUTTONDOWN:
|
|
DPRINTF_EDIT_MSG("WM_LBUTTONDOWN");
|
|
lResult = EDIT_WM_LButtonDown(wndPtr, wParam, lParam);
|
|
break;
|
|
case WM_LBUTTONUP:
|
|
DPRINTF_EDIT_MSG("WM_LBUTTONUP");
|
|
lResult = EDIT_WM_LButtonUp(wndPtr, wParam, lParam);
|
|
break;
|
|
case WM_MOUSEMOVE:
|
|
/*
|
|
* DPRINTF_EDIT_MSG("WM_MOUSEMOVE");
|
|
*/
|
|
lResult = EDIT_WM_MouseMove(wndPtr, wParam, lParam);
|
|
break;
|
|
case WM_PAINT:
|
|
DPRINTF_EDIT_MSG("WM_PAINT");
|
|
lResult = EDIT_WM_Paint(wndPtr, wParam, lParam);
|
|
break;
|
|
case WM_PASTE:
|
|
DPRINTF_EDIT_MSG("WM_PASTE");
|
|
lResult = EDIT_WM_Paste(wndPtr, wParam, lParam);
|
|
break;
|
|
case WM_SETCURSOR:
|
|
/*
|
|
* DPRINTF_EDIT_MSG("WM_SETCURSOR");
|
|
*/
|
|
lResult = EDIT_WM_SetCursor(wndPtr, wParam, lParam);
|
|
break;
|
|
case WM_SETFOCUS:
|
|
DPRINTF_EDIT_MSG("WM_SETFOCUS");
|
|
lResult = EDIT_WM_SetFocus(wndPtr, wParam, lParam);
|
|
break;
|
|
case WM_SETFONT:
|
|
DPRINTF_EDIT_MSG("WM_SETFONT");
|
|
lResult = EDIT_WM_SetFont(wndPtr, wParam, lParam);
|
|
break;
|
|
case WM_SETREDRAW:
|
|
DPRINTF_EDIT_MSG("WM_SETREDRAW");
|
|
lResult = EDIT_WM_SetRedraw(wndPtr, wParam, lParam);
|
|
break;
|
|
case WM_SETTEXT:
|
|
DPRINTF_EDIT_MSG("WM_SETTEXT");
|
|
lResult = EDIT_WM_SetText(wndPtr, wParam, lParam);
|
|
break;
|
|
case WM_SIZE:
|
|
DPRINTF_EDIT_MSG("WM_SIZE");
|
|
lResult = EDIT_WM_Size(wndPtr, wParam, lParam);
|
|
break;
|
|
case WM_VSCROLL:
|
|
DPRINTF_EDIT_MSG("WM_VSCROLL");
|
|
lResult = EDIT_WM_VScroll(wndPtr, wParam, lParam);
|
|
break;
|
|
default:
|
|
if (msg >= WM_USER)
|
|
fprintf(stdnimp, "edit: undocumented message %d >= WM_USER, please report.\n", msg);
|
|
lResult = DefWindowProc16(hwnd, msg, wParam, lParam);
|
|
break;
|
|
}
|
|
EDIT_ReleasePointer(wndPtr);
|
|
return lResult;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_BuildLineDefs
|
|
*
|
|
* Build array of pointers to text lines.
|
|
* Lines can end with '\0' (last line), nothing (if it is too long),
|
|
* a delimiter (usually ' '), a soft return '\r\r\n' or a hard return '\r\n'
|
|
*
|
|
*/
|
|
static void EDIT_BuildLineDefs(WND *wndPtr)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
char *text = EDIT_GetPasswordPointer(wndPtr);
|
|
int ww = EDIT_GetWndWidth(wndPtr);
|
|
HDC32 hdc;
|
|
HFONT hFont;
|
|
HFONT oldFont = 0;
|
|
char *start, *cp;
|
|
int prev, next;
|
|
int width;
|
|
int length;
|
|
LINE_END ending;
|
|
|
|
hdc = GetDC32(wndPtr->hwndSelf);
|
|
hFont = (HFONT)EDIT_WM_GetFont(wndPtr, 0, 0L);
|
|
if (hFont)
|
|
oldFont = SelectObject(hdc, hFont);
|
|
|
|
if (!IsMultiLine(wndPtr)) {
|
|
es->LineCount = 1;
|
|
es->LineDefs = xrealloc(es->LineDefs, sizeof(LINEDEF));
|
|
es->LineDefs[0].offset = 0;
|
|
es->LineDefs[0].length = EDIT_WM_GetTextLength(wndPtr, 0, 0L);
|
|
es->LineDefs[0].ending = END_0;
|
|
es->TextWidth = LOWORD(GetTabbedTextExtent(hdc, text,
|
|
es->LineDefs[0].length,
|
|
es->NumTabStops, es->TabStops));
|
|
} else {
|
|
es->LineCount = 0;
|
|
start = text;
|
|
do {
|
|
if (!(cp = strstr(start, "\r\n"))) {
|
|
ending = END_0;
|
|
length = strlen(start);
|
|
} else if ((cp > start) && (*(cp - 1) == '\r')) {
|
|
ending = END_SOFT;
|
|
length = cp - start - 1;
|
|
} else {
|
|
ending = END_HARD;
|
|
length = cp - start;
|
|
}
|
|
width = LOWORD(GetTabbedTextExtent(hdc, start, length,
|
|
es->NumTabStops, es->TabStops));
|
|
|
|
if (IsWordWrap(wndPtr) && (width > ww)) {
|
|
next = 0;
|
|
do {
|
|
prev = next;
|
|
next = EDIT_CallWordBreakProc(wndPtr, start,
|
|
prev + 1, length, WB_RIGHT);
|
|
width = LOWORD(GetTabbedTextExtent(hdc, start, next,
|
|
es->NumTabStops, es->TabStops));
|
|
} while (width <= ww);
|
|
if (!prev) {
|
|
next = 0;
|
|
do {
|
|
prev = next;
|
|
next++;
|
|
width = LOWORD(GetTabbedTextExtent(hdc, start, next,
|
|
es->NumTabStops, es->TabStops));
|
|
} while (width <= ww);
|
|
if(!prev) prev = 1;
|
|
}
|
|
length = prev;
|
|
if (EDIT_CallWordBreakProc(wndPtr, start, length - 1,
|
|
length, WB_ISDELIMITER)) {
|
|
length--;
|
|
ending = END_DELIMIT;
|
|
} else
|
|
ending = END_NONE;
|
|
width = LOWORD(GetTabbedTextExtent(hdc, start, length,
|
|
es->NumTabStops, es->TabStops));
|
|
}
|
|
|
|
es->LineDefs = xrealloc(es->LineDefs, (es->LineCount + 1) * sizeof(LINEDEF));
|
|
es->LineDefs[es->LineCount].offset = start - text;
|
|
es->LineDefs[es->LineCount].length = length;
|
|
es->LineDefs[es->LineCount].ending = ending;
|
|
es->LineCount++;
|
|
es->TextWidth = MAX(es->TextWidth, width);
|
|
|
|
start += length;
|
|
switch (ending) {
|
|
case END_SOFT:
|
|
start += 3;
|
|
break;
|
|
case END_HARD:
|
|
start += 2;
|
|
break;
|
|
case END_DELIMIT:
|
|
start++;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
} while (*start || (ending == END_SOFT) || (ending == END_HARD));
|
|
}
|
|
if (hFont)
|
|
SelectObject(hdc, oldFont);
|
|
ReleaseDC32(wndPtr->hwndSelf, hdc);
|
|
|
|
free(text);
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_CallWordBreakProc
|
|
*
|
|
* Call appropriate WordBreakProc (internal or external).
|
|
*
|
|
*/
|
|
static INT EDIT_CallWordBreakProc(WND *wndPtr, char *s, INT index, INT count, INT action)
|
|
{
|
|
EDITWORDBREAKPROC wbp = (EDITWORDBREAKPROC)EDIT_EM_GetWordBreakProc(wndPtr, 0, 0L);
|
|
|
|
if (!wbp) return EDIT_WordBreakProc(s, index, count, action);
|
|
else
|
|
{
|
|
/* We need a SEGPTR here */
|
|
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
SEGPTR ptr = LOCAL_LockSegptr( wndPtr->hInstance, es->hBuf ) +
|
|
(UINT16)(s - EDIT_GetPointer(wndPtr));
|
|
INT ret = CallWordBreakProc( (FARPROC16)wbp, ptr,
|
|
index, count, action);
|
|
LOCAL_Unlock( wndPtr->hInstance, es->hBuf );
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_ColFromWndX
|
|
*
|
|
* Calculates, for a given line and X-coordinate on the screen, the column.
|
|
*
|
|
*/
|
|
static UINT EDIT_ColFromWndX(WND *wndPtr, UINT line, INT x)
|
|
{
|
|
UINT lc = (UINT)EDIT_EM_GetLineCount(wndPtr, 0, 0L);
|
|
UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, line, 0L);
|
|
UINT ll = (UINT)EDIT_EM_LineLength(wndPtr, li, 0L);
|
|
UINT i;
|
|
|
|
line = MAX(0, MIN(line, lc - 1));
|
|
for (i = 0 ; i < ll ; i++)
|
|
if (EDIT_WndXFromCol(wndPtr, line, i) >= x)
|
|
break;
|
|
return i;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_DelEnd
|
|
*
|
|
* Delete all characters on this line to right of cursor.
|
|
*
|
|
*/
|
|
static void EDIT_DelEnd(WND *wndPtr)
|
|
{
|
|
EDIT_EM_SetSel(wndPtr, 1, MAKELPARAM(-1, 0));
|
|
EDIT_MoveEnd(wndPtr, TRUE);
|
|
EDIT_WM_Clear(wndPtr, 0, 0L);
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_DelLeft
|
|
*
|
|
* Delete character to left of cursor.
|
|
*
|
|
*/
|
|
static void EDIT_DelLeft(WND *wndPtr)
|
|
{
|
|
EDIT_EM_SetSel(wndPtr, 1, MAKELPARAM(-1, 0));
|
|
EDIT_MoveBackward(wndPtr, TRUE);
|
|
EDIT_WM_Clear(wndPtr, 0, 0L);
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_DelRight
|
|
*
|
|
* Delete character to right of cursor.
|
|
*
|
|
*/
|
|
static void EDIT_DelRight(WND *wndPtr)
|
|
{
|
|
EDIT_EM_SetSel(wndPtr, 1, MAKELPARAM(-1, 0));
|
|
EDIT_MoveForward(wndPtr, TRUE);
|
|
EDIT_WM_Clear(wndPtr, 0, 0L);
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_GetAveCharWidth
|
|
*
|
|
*/
|
|
static UINT EDIT_GetAveCharWidth(WND *wndPtr)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
return es->AveCharWidth;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_GetLineHeight
|
|
*
|
|
*/
|
|
static UINT EDIT_GetLineHeight(WND *wndPtr)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
return es->LineHeight;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_GetLineRect
|
|
*
|
|
* Calculates the bounding rectangle for a line from a starting
|
|
* column to an ending column.
|
|
*
|
|
*/
|
|
static void EDIT_GetLineRect(WND *wndPtr, UINT line, UINT scol, UINT ecol, LPRECT16 rc)
|
|
{
|
|
rc->top = EDIT_WndYFromLine(wndPtr, line);
|
|
rc->bottom = rc->top + EDIT_GetLineHeight(wndPtr);
|
|
rc->left = EDIT_WndXFromCol(wndPtr, line, scol);
|
|
rc->right = ((INT)ecol == -1) ? EDIT_GetWndWidth(wndPtr) :
|
|
EDIT_WndXFromCol(wndPtr, line, ecol);
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_GetPointer
|
|
*
|
|
* This acts as a LOCAL_Lock(), but it locks only once. This way
|
|
* you can call it whenever you like, without unlocking.
|
|
*
|
|
*/
|
|
static char *EDIT_GetPointer(WND *wndPtr)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
if (!es->text && es->hBuf)
|
|
es->text = LOCAL_Lock(wndPtr->hInstance, es->hBuf);
|
|
return es->text;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_GetPasswordPointer
|
|
*
|
|
*
|
|
*/
|
|
static char *EDIT_GetPasswordPointer(WND *wndPtr)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
char *text = xstrdup(EDIT_GetPointer(wndPtr));
|
|
char *p;
|
|
|
|
if(es->PasswordChar) {
|
|
p = text;
|
|
while(*p != '\0') {
|
|
if(*p != '\r' && *p != '\n')
|
|
*p = es->PasswordChar;
|
|
p++;
|
|
}
|
|
}
|
|
return text;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_GetRect
|
|
*
|
|
* Beware: This is not the function called on EM_GETRECT.
|
|
* It expects a (LPRECT) in lParam, not a (SEGPTR).
|
|
* It is used internally, as if there were no pointer difficulties.
|
|
*
|
|
*/
|
|
static LRESULT EDIT_GetRect(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
GetClientRect16( wndPtr->hwndSelf, (LPRECT16)lParam );
|
|
return 0L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_GetRedraw
|
|
*
|
|
*/
|
|
static BOOL EDIT_GetRedraw(WND *wndPtr)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
return es->Redraw;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_GetTextWidth
|
|
*
|
|
*/
|
|
static UINT EDIT_GetTextWidth(WND *wndPtr)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
return es->TextWidth;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_GetVisibleLineCount
|
|
*
|
|
*/
|
|
static UINT EDIT_GetVisibleLineCount(WND *wndPtr)
|
|
{
|
|
RECT16 rc;
|
|
|
|
EDIT_GetRect(wndPtr, 0, (LPARAM)&rc);
|
|
return MAX(1, MAX(rc.bottom - rc.top, 0) / EDIT_GetLineHeight(wndPtr));
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_GetWndWidth
|
|
*
|
|
*/
|
|
static UINT EDIT_GetWndWidth(WND *wndPtr)
|
|
{
|
|
RECT16 rc;
|
|
|
|
EDIT_GetRect(wndPtr, 0, (LPARAM)&rc);
|
|
return rc.right - rc.left;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_GetXOffset
|
|
*
|
|
*/
|
|
static UINT EDIT_GetXOffset(WND *wndPtr)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
return es->XOffset;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_InvalidateText
|
|
*
|
|
* Invalidate the text from offset start upto, but not including,
|
|
* offset end. Useful for (re)painting the selection.
|
|
* Regions outside the linewidth are not invalidated.
|
|
* end == -1 means end == TextLength.
|
|
* start and end need not be ordered.
|
|
*
|
|
*/
|
|
static void EDIT_InvalidateText(WND *wndPtr, UINT start, UINT end)
|
|
{
|
|
UINT fv = (UINT)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L);
|
|
UINT vlc = EDIT_GetVisibleLineCount(wndPtr);
|
|
UINT sl;
|
|
UINT el;
|
|
UINT sc;
|
|
UINT ec;
|
|
RECT16 rcWnd;
|
|
RECT16 rcLine;
|
|
RECT16 rcUpdate;
|
|
UINT l;
|
|
|
|
if (end == start )
|
|
return;
|
|
|
|
if ((INT)end == -1)
|
|
end = (UINT)EDIT_WM_GetTextLength(wndPtr, 0, 0L);
|
|
ORDER_UINT(start, end);
|
|
sl = (UINT)EDIT_EM_LineFromChar(wndPtr, start, 0L);
|
|
el = (UINT)EDIT_EM_LineFromChar(wndPtr, end, 0L);
|
|
if ((el < fv) || (sl > fv + vlc))
|
|
return;
|
|
|
|
sc = start - (UINT)EDIT_EM_LineIndex(wndPtr, sl, 0L);
|
|
ec = end - (UINT)EDIT_EM_LineIndex(wndPtr, el, 0L);
|
|
if (sl < fv) {
|
|
sl = fv;
|
|
sc = 0;
|
|
}
|
|
if (el > fv + vlc) {
|
|
el = fv + vlc;
|
|
ec = (UINT)EDIT_EM_LineLength(wndPtr,
|
|
(UINT)EDIT_EM_LineIndex(wndPtr, el, 0L), 0L);
|
|
}
|
|
EDIT_GetRect(wndPtr, 0, (LPARAM)&rcWnd);
|
|
if (sl == el) {
|
|
EDIT_GetLineRect(wndPtr, sl, sc, ec, &rcLine);
|
|
if (IntersectRect16(&rcUpdate, &rcWnd, &rcLine))
|
|
InvalidateRect16( wndPtr->hwndSelf, &rcUpdate, FALSE );
|
|
} else {
|
|
EDIT_GetLineRect(wndPtr, sl, sc,
|
|
(UINT)EDIT_EM_LineLength(wndPtr,
|
|
(UINT)EDIT_EM_LineIndex(wndPtr, sl, 0L), 0L),
|
|
&rcLine);
|
|
if (IntersectRect16(&rcUpdate, &rcWnd, &rcLine))
|
|
InvalidateRect16( wndPtr->hwndSelf, &rcUpdate, FALSE );
|
|
for (l = sl + 1 ; l < el ; l++) {
|
|
EDIT_GetLineRect(wndPtr, l, 0,
|
|
(UINT)EDIT_EM_LineLength(wndPtr,
|
|
(UINT)EDIT_EM_LineIndex(wndPtr, l, 0L), 0L),
|
|
&rcLine);
|
|
if (IntersectRect16(&rcUpdate, &rcWnd, &rcLine))
|
|
InvalidateRect16(wndPtr->hwndSelf, &rcUpdate, FALSE);
|
|
}
|
|
EDIT_GetLineRect(wndPtr, el, 0, ec, &rcLine);
|
|
if (IntersectRect16(&rcUpdate, &rcWnd, &rcLine))
|
|
InvalidateRect16( wndPtr->hwndSelf, &rcUpdate, FALSE );
|
|
}
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_LineFromWndY
|
|
*
|
|
* Calculates, for a given Y-coordinate on the screen, the line.
|
|
*
|
|
*/
|
|
static UINT EDIT_LineFromWndY(WND *wndPtr, INT y)
|
|
{
|
|
UINT fv = (UINT)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L);
|
|
UINT lh = EDIT_GetLineHeight(wndPtr);
|
|
UINT lc = (UINT)EDIT_EM_GetLineCount(wndPtr, 0, 0L);
|
|
|
|
return MAX(0, MIN(lc - 1, y / lh + fv));
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_MakeFit
|
|
*
|
|
* Try to fit size + 1 bytes in the buffer. Constrain to limits.
|
|
*
|
|
*/
|
|
static BOOL EDIT_MakeFit(WND *wndPtr, UINT size)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
if (size <= es->BufSize)
|
|
return TRUE;
|
|
if (size > es->BufLimit)
|
|
return FALSE;
|
|
size = ((size / GROWLENGTH) + 1) * GROWLENGTH;
|
|
if (size > es->BufLimit)
|
|
size = es->BufLimit;
|
|
|
|
dprintf_edit(stddeb, "edit: EDIT_MakeFit: trying to ReAlloc to %d+1\n", size);
|
|
|
|
if (LOCAL_ReAlloc(wndPtr->hInstance, es->hBuf, size + 1, LMEM_MOVEABLE)) {
|
|
es->BufSize = MIN(LOCAL_Size(wndPtr->hInstance, es->hBuf) - 1, es->BufLimit);
|
|
return TRUE;
|
|
} else
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_MoveBackward
|
|
*
|
|
*/
|
|
static void EDIT_MoveBackward(WND *wndPtr, BOOL extend)
|
|
{
|
|
UINT s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
UINT l = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L);
|
|
UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L);
|
|
|
|
if (e - li == 0) {
|
|
if (l) {
|
|
li = (UINT)EDIT_EM_LineIndex(wndPtr, l - 1, 0L);
|
|
e = li + (UINT)EDIT_EM_LineLength(wndPtr, li, 0L);
|
|
}
|
|
} else
|
|
e--;
|
|
if (!extend)
|
|
s = e;
|
|
EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e));
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_MoveDownward
|
|
*
|
|
*/
|
|
static void EDIT_MoveDownward(WND *wndPtr, BOOL extend)
|
|
{
|
|
UINT s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
UINT l = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L);
|
|
UINT lc = (UINT)EDIT_EM_GetLineCount(wndPtr, e, 0L);
|
|
UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L);
|
|
INT x;
|
|
|
|
if (l < lc - 1) {
|
|
x = EDIT_WndXFromCol(wndPtr, l, e - li);
|
|
l++;
|
|
e = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L) +
|
|
EDIT_ColFromWndX(wndPtr, l, x);
|
|
}
|
|
if (!extend)
|
|
s = e;
|
|
EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e));
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_MoveEnd
|
|
*
|
|
*/
|
|
static void EDIT_MoveEnd(WND *wndPtr, BOOL extend)
|
|
{
|
|
UINT s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
UINT l = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L);
|
|
UINT ll = (UINT)EDIT_EM_LineLength(wndPtr, e, 0L);
|
|
UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L);
|
|
|
|
e = li + ll;
|
|
if (!extend)
|
|
s = e;
|
|
EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e));
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_MoveForward
|
|
*
|
|
*/
|
|
static void EDIT_MoveForward(WND *wndPtr, BOOL extend)
|
|
{
|
|
UINT s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
UINT l = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L);
|
|
UINT lc = (UINT)EDIT_EM_GetLineCount(wndPtr, e, 0L);
|
|
UINT ll = (UINT)EDIT_EM_LineLength(wndPtr, e, 0L);
|
|
UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L);
|
|
|
|
if (e - li == ll) {
|
|
if (l != lc - 1)
|
|
e = (UINT)EDIT_EM_LineIndex(wndPtr, l + 1, 0L);
|
|
} else
|
|
e++;
|
|
if (!extend)
|
|
s = e;
|
|
EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e));
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_MoveHome
|
|
*
|
|
* Home key: move to beginning of line.
|
|
*
|
|
*/
|
|
static void EDIT_MoveHome(WND *wndPtr, BOOL extend)
|
|
{
|
|
UINT s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
UINT l = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L);
|
|
UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L);
|
|
|
|
e = li;
|
|
if (!extend)
|
|
s = e;
|
|
EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e));
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_MovePageDown
|
|
*
|
|
*/
|
|
static void EDIT_MovePageDown(WND *wndPtr, BOOL extend)
|
|
{
|
|
UINT s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
UINT l = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L);
|
|
UINT lc = (UINT)EDIT_EM_GetLineCount(wndPtr, e, 0L);
|
|
UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L);
|
|
INT x;
|
|
|
|
if (l < lc - 1) {
|
|
x = EDIT_WndXFromCol(wndPtr, l, e - li);
|
|
l = MIN(lc - 1, l + EDIT_GetVisibleLineCount(wndPtr));
|
|
e = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L) +
|
|
EDIT_ColFromWndX(wndPtr, l, x);
|
|
}
|
|
if (!extend)
|
|
s = e;
|
|
EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e));
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_MovePageUp
|
|
*
|
|
*/
|
|
static void EDIT_MovePageUp(WND *wndPtr, BOOL extend)
|
|
{
|
|
UINT s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
UINT l = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L);
|
|
UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L);
|
|
INT x;
|
|
|
|
if (l) {
|
|
x = EDIT_WndXFromCol(wndPtr, l, e - li);
|
|
l = MAX(0, l - EDIT_GetVisibleLineCount(wndPtr));
|
|
e = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L) +
|
|
EDIT_ColFromWndX(wndPtr, l, x);
|
|
}
|
|
if (!extend)
|
|
s = e;
|
|
EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e));
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_MoveUpward
|
|
*
|
|
*/
|
|
static void EDIT_MoveUpward(WND *wndPtr, BOOL extend)
|
|
{
|
|
UINT s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
UINT l = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L);
|
|
UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L);
|
|
INT x;
|
|
|
|
if (l) {
|
|
x = EDIT_WndXFromCol(wndPtr, l, e - li);
|
|
l--;
|
|
e = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L) +
|
|
EDIT_ColFromWndX(wndPtr, l, x);
|
|
}
|
|
if (!extend)
|
|
s = e;
|
|
EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e));
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_MoveWordBackward
|
|
*
|
|
*/
|
|
static void EDIT_MoveWordBackward(WND *wndPtr, BOOL extend)
|
|
{
|
|
UINT s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
UINT l = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L);
|
|
UINT ll = (UINT)EDIT_EM_LineLength(wndPtr, e, 0L);
|
|
UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L);
|
|
char *text;
|
|
|
|
if (e - li == 0) {
|
|
if (l) {
|
|
li = (UINT)EDIT_EM_LineIndex(wndPtr, l - 1, 0L);
|
|
e = li + (UINT)EDIT_EM_LineLength(wndPtr, li, 0L);
|
|
}
|
|
} else {
|
|
text = EDIT_GetPointer(wndPtr);
|
|
e = li + (UINT)EDIT_CallWordBreakProc(wndPtr,
|
|
text + li, e - li, ll, WB_LEFT);
|
|
}
|
|
if (!extend)
|
|
s = e;
|
|
EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e));
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_MoveWordForward
|
|
*
|
|
*/
|
|
static void EDIT_MoveWordForward(WND *wndPtr, BOOL extend)
|
|
{
|
|
UINT s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
UINT l = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L);
|
|
UINT lc = (UINT)EDIT_EM_GetLineCount(wndPtr, e, 0L);
|
|
UINT ll = (UINT)EDIT_EM_LineLength(wndPtr, e, 0L);
|
|
UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L);
|
|
char *text;
|
|
|
|
if (e - li == ll) {
|
|
if (l != lc - 1)
|
|
e = (UINT)EDIT_EM_LineIndex(wndPtr, l + 1, 0L);
|
|
} else {
|
|
text = EDIT_GetPointer(wndPtr);
|
|
e = li + (UINT)EDIT_CallWordBreakProc(wndPtr,
|
|
text + li, e - li + 1, ll, WB_RIGHT);
|
|
}
|
|
if (!extend)
|
|
s = e;
|
|
EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e));
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_PaintLine
|
|
*
|
|
*/
|
|
static void EDIT_PaintLine(WND *wndPtr, HDC hdc, UINT line, BOOL rev)
|
|
{
|
|
UINT fv = (UINT)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L);
|
|
UINT vlc = EDIT_GetVisibleLineCount(wndPtr);
|
|
UINT lc = (UINT)EDIT_EM_GetLineCount(wndPtr, 0, 0L);
|
|
UINT li;
|
|
UINT ll;
|
|
UINT s;
|
|
UINT e;
|
|
INT x;
|
|
INT y;
|
|
|
|
if ((line < fv) || (line > fv + vlc) || (line >= lc))
|
|
return;
|
|
|
|
dprintf_edit(stddeb, "edit: EDIT_PaintLine: line=%d\n", line);
|
|
|
|
x = EDIT_WndXFromCol(wndPtr, line, 0);
|
|
y = EDIT_WndYFromLine(wndPtr, line);
|
|
li = (UINT)EDIT_EM_LineIndex(wndPtr, line, 0L);
|
|
ll = (UINT)EDIT_EM_LineLength(wndPtr, li, 0L);
|
|
s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
ORDER_UINT(s, e);
|
|
s = MIN(li + ll, MAX(li, s));
|
|
e = MIN(li + ll, MAX(li, e));
|
|
if (rev && (s != e) &&
|
|
((GetFocus32() == wndPtr->hwndSelf) ||
|
|
(wndPtr->dwStyle & ES_NOHIDESEL))) {
|
|
x += EDIT_PaintText(wndPtr, hdc, x, y, line, 0, s - li, FALSE);
|
|
x += EDIT_PaintText(wndPtr, hdc, x, y, line, s - li, e - s, TRUE);
|
|
x += EDIT_PaintText(wndPtr, hdc, x, y, line, e - li, li + ll - e, FALSE);
|
|
} else
|
|
x += EDIT_PaintText(wndPtr, hdc, x, y, line, 0, ll, FALSE);
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_PaintText
|
|
*
|
|
*/
|
|
static UINT EDIT_PaintText(WND *wndPtr, HDC hdc, INT x, INT y, UINT line, UINT col, UINT count, BOOL rev)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
COLORREF BkColor;
|
|
COLORREF TextColor;
|
|
UINT ret;
|
|
char *text;
|
|
UINT li;
|
|
UINT xoff;
|
|
|
|
if (!count)
|
|
return 0;
|
|
BkColor = GetBkColor(hdc);
|
|
TextColor = GetTextColor(hdc);
|
|
if (rev) {
|
|
SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
|
|
SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
|
|
}
|
|
text = EDIT_GetPasswordPointer(wndPtr);
|
|
li = (UINT)EDIT_EM_LineIndex(wndPtr, line, 0L);
|
|
xoff = EDIT_GetXOffset(wndPtr);
|
|
ret = LOWORD(TabbedTextOut(hdc, x, y, text + li + col, count,
|
|
es->NumTabStops, es->TabStops, -xoff));
|
|
free(text);
|
|
if (rev) {
|
|
SetBkColor(hdc, BkColor);
|
|
SetTextColor(hdc, TextColor);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_ReleasePointer
|
|
*
|
|
* This is the only helper function that can be called with es = NULL.
|
|
* It is called at the end of EditWndProc() to unlock the buffer.
|
|
*
|
|
*/
|
|
static void EDIT_ReleasePointer(WND *wndPtr)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
if (!es)
|
|
return;
|
|
if (es->text && es->hBuf)
|
|
LOCAL_Unlock(wndPtr->hInstance, es->hBuf);
|
|
es->text = NULL;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_ReplaceSel
|
|
*
|
|
* Beware: This is not the function called on EM_REPLACESEL.
|
|
* It expects a (char *) in lParam, not a (SEGPTR).
|
|
* It is used internally, as if there were no pointer difficulties.
|
|
*
|
|
*/
|
|
static LRESULT EDIT_ReplaceSel(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
const char *str = (char *)lParam;
|
|
int strl = strlen(str);
|
|
UINT tl = (UINT)EDIT_WM_GetTextLength(wndPtr, 0, 0L);
|
|
UINT s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
int i;
|
|
char *p;
|
|
char *text;
|
|
BOOL redraw;
|
|
|
|
ORDER_UINT(s,e);
|
|
if (!EDIT_MakeFit(wndPtr, tl - (e - s) + strl)) {
|
|
EDIT_NOTIFY_PARENT(wndPtr, EN_MAXTEXT);
|
|
return 0L;
|
|
}
|
|
redraw = EDIT_GetRedraw(wndPtr);
|
|
EDIT_WM_SetRedraw(wndPtr, FALSE, 0L);
|
|
EDIT_WM_Clear(wndPtr, 0, 0L);
|
|
tl = EDIT_WM_GetTextLength(wndPtr, 0, 0L);
|
|
e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
text = EDIT_GetPointer(wndPtr);
|
|
for (p = text + tl ; p >= text + e ; p--)
|
|
p[strl] = p[0];
|
|
for (i = 0 , p = text + e ; i < strl ; i++)
|
|
p[i] = str[i];
|
|
if(IsUpper(wndPtr))
|
|
AnsiUpperBuff(p, strl);
|
|
else if(IsLower(wndPtr))
|
|
AnsiLowerBuff(p, strl);
|
|
EDIT_BuildLineDefs(wndPtr);
|
|
e += strl;
|
|
EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(e, e));
|
|
EDIT_EM_SetModify(wndPtr, TRUE, 0L);
|
|
EDIT_NOTIFY_PARENT(wndPtr, EN_UPDATE);
|
|
EDIT_WM_SetRedraw(wndPtr, redraw, 0L);
|
|
if (redraw) {
|
|
InvalidateRect32( wndPtr->hwndSelf, NULL, TRUE );
|
|
EDIT_NOTIFY_PARENT(wndPtr, EN_CHANGE);
|
|
}
|
|
return 0L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_ScrollIntoView
|
|
*
|
|
* Makes sure the caret is visible.
|
|
*
|
|
*/
|
|
static void EDIT_ScrollIntoView(WND *wndPtr)
|
|
{
|
|
UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
UINT l = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L);
|
|
UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L);
|
|
UINT fv = (UINT)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L);
|
|
UINT vlc = EDIT_GetVisibleLineCount(wndPtr);
|
|
UINT ww = EDIT_GetWndWidth(wndPtr);
|
|
UINT cw = EDIT_GetAveCharWidth(wndPtr);
|
|
INT x = EDIT_WndXFromCol(wndPtr, l, e - li);
|
|
int dy = 0;
|
|
int dx = 0;
|
|
|
|
if (l >= fv + vlc)
|
|
dy = l - vlc + 1 - fv;
|
|
if (l < fv)
|
|
dy = l - fv;
|
|
if (x < 0)
|
|
dx = x - ww / HSCROLL_FRACTION / cw * cw;
|
|
if (x > ww)
|
|
dx = x - (HSCROLL_FRACTION - 1) * ww / HSCROLL_FRACTION / cw * cw;
|
|
if (dy || dx) {
|
|
EDIT_EM_LineScroll(wndPtr, 0, MAKELPARAM(dy, dx));
|
|
if (dy)
|
|
EDIT_NOTIFY_PARENT(wndPtr, EN_VSCROLL);
|
|
if (dx)
|
|
EDIT_NOTIFY_PARENT(wndPtr, EN_HSCROLL);
|
|
}
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_WndXFromCol
|
|
*
|
|
* Calculates, for a given line and column, the X-coordinate on the screen.
|
|
*
|
|
*/
|
|
static INT EDIT_WndXFromCol(WND *wndPtr, UINT line, UINT col)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
char *text = EDIT_GetPasswordPointer(wndPtr);
|
|
INT ret;
|
|
HDC32 hdc;
|
|
HFONT hFont;
|
|
HFONT oldFont = 0;
|
|
UINT lc = (UINT)EDIT_EM_GetLineCount(wndPtr, 0, 0L);
|
|
UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, line, 0L);
|
|
UINT ll = (UINT)EDIT_EM_LineLength(wndPtr, li, 0L);
|
|
UINT xoff = EDIT_GetXOffset(wndPtr);
|
|
|
|
hdc = GetDC32(wndPtr->hwndSelf);
|
|
hFont = (HFONT)EDIT_WM_GetFont(wndPtr, 0, 0L);
|
|
if (hFont)
|
|
oldFont = SelectObject(hdc, hFont);
|
|
line = MAX(0, MIN(line, lc - 1));
|
|
col = MIN(col, ll);
|
|
ret = LOWORD(GetTabbedTextExtent(hdc,
|
|
text + li, col,
|
|
es->NumTabStops, es->TabStops)) - xoff;
|
|
if (hFont)
|
|
SelectObject(hdc, oldFont);
|
|
ReleaseDC32(wndPtr->hwndSelf, hdc);
|
|
free(text);
|
|
return ret;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_WndYFromLine
|
|
*
|
|
* Calculates, for a given line, the Y-coordinate on the screen.
|
|
*
|
|
*/
|
|
static INT EDIT_WndYFromLine(WND *wndPtr, UINT line)
|
|
{
|
|
UINT fv = (UINT)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L);
|
|
UINT lh = EDIT_GetLineHeight(wndPtr);
|
|
|
|
return (line - fv) * lh;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_WordBreakProc
|
|
*
|
|
* Find the beginning of words.
|
|
* Note: unlike the specs for a WordBreakProc, this function only
|
|
* allows to be called without linebreaks between s[0] upto
|
|
* s[count - 1]. Remember it is only called
|
|
* internally, so we can decide this for ourselves.
|
|
*
|
|
*/
|
|
static INT EDIT_WordBreakProc(char *s, INT index, INT count, INT action)
|
|
{
|
|
INT ret = 0;
|
|
|
|
dprintf_edit(stddeb, "edit: EDIT_WordBreakProc: s=%p, index=%d"
|
|
", count=%d, action=%d\n", s, index, count, action);
|
|
|
|
switch (action) {
|
|
case WB_LEFT:
|
|
if (!count)
|
|
break;
|
|
if (index)
|
|
index--;
|
|
if (s[index] == ' ') {
|
|
while (index && (s[index] == ' '))
|
|
index--;
|
|
if (index) {
|
|
while (index && (s[index] != ' '))
|
|
index--;
|
|
if (s[index] == ' ')
|
|
index++;
|
|
}
|
|
} else {
|
|
while (index && (s[index] != ' '))
|
|
index--;
|
|
if (s[index] == ' ')
|
|
index++;
|
|
}
|
|
ret = index;
|
|
break;
|
|
case WB_RIGHT:
|
|
if (!count)
|
|
break;
|
|
if (index)
|
|
index--;
|
|
if (s[index] == ' ')
|
|
while ((index < count) && (s[index] == ' ')) index++;
|
|
else {
|
|
while (s[index] && (s[index] != ' ') && (index < count))
|
|
index++;
|
|
while ((s[index] == ' ') && (index < count)) index++;
|
|
}
|
|
ret = index;
|
|
break;
|
|
case WB_ISDELIMITER:
|
|
ret = (s[index] == ' ');
|
|
break;
|
|
default:
|
|
fprintf(stderr, "edit: EDIT_WordBreakProc: unknown action code, please report !\n");
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_CANUNDO
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_CanUndo(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
return 0L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_EMPTYUNDOBUFFER
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_EmptyUndoBuffer(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
return 0L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_FMTLINES
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_FmtLines(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
fprintf(stdnimp, "edit: EM_FMTLINES: message not implemented.\n");
|
|
return wParam ? -1L : 0L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_GETFIRSTVISIBLELINE
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_GetFirstVisibleLine(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
return (LRESULT)es->FirstVisibleLine;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_GETHANDLE
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_GetHandle(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
return (LRESULT)es->hBuf;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_GETLINE
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_GetLine(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
char *text;
|
|
char *src;
|
|
char *dst;
|
|
UINT len;
|
|
UINT i;
|
|
UINT lc = (UINT)EDIT_EM_GetLineCount(wndPtr, 0, 0L);
|
|
|
|
if (!IsMultiLine(wndPtr))
|
|
wParam = 0;
|
|
if ((UINT)wParam >= lc)
|
|
return 0L;
|
|
text = EDIT_GetPointer(wndPtr);
|
|
src = text + (UINT)EDIT_EM_LineIndex(wndPtr, wParam, 0L);
|
|
dst = (char *)PTR_SEG_TO_LIN(lParam);
|
|
len = MIN(*(WORD *)dst, (UINT)EDIT_EM_LineLength(wndPtr, wParam, 0L));
|
|
for (i = 0 ; i < len ; i++) {
|
|
*dst = *src;
|
|
src++;
|
|
dst++;
|
|
}
|
|
return (LRESULT)len;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_GETLINECOUNT
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_GetLineCount(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
return (LRESULT)es->LineCount;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_GETMODIFY
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_GetModify(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
return (LRESULT)es->TextChanged;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_GETPASSWORDCHAR
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_GetPasswordChar(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
return (LRESULT)es->PasswordChar;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_GETRECT
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_GetRect(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
return EDIT_GetRect(wndPtr, wParam, (LPARAM)PTR_SEG_TO_LIN(lParam));
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_GETSEL
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_GetSel(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
return MAKELONG(es->SelStart, es->SelEnd);
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_GETTHUMB
|
|
*
|
|
* FIXME: undocumented: is this right ?
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_GetThumb(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
return MAKELONG(EDIT_WM_VScroll(wndPtr, EM_GETTHUMB, 0L),
|
|
EDIT_WM_HScroll(wndPtr, EM_GETTHUMB, 0L));
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_GETWORDBREAKPROC
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_GetWordBreakProc(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
return (LRESULT)es->WordBreakProc;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_LIMITTEXT
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_LimitText(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
if (IsMultiLine(wndPtr)) {
|
|
if (wParam)
|
|
es->BufLimit = MIN((UINT)wParam, BUFLIMIT_MULTI);
|
|
else
|
|
es->BufLimit = BUFLIMIT_MULTI;
|
|
} else {
|
|
if (wParam)
|
|
es->BufLimit = MIN((UINT)wParam, BUFLIMIT_SINGLE);
|
|
else
|
|
es->BufLimit = BUFLIMIT_SINGLE;
|
|
}
|
|
return 0L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_LINEFROMCHAR
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_LineFromChar(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
UINT l;
|
|
|
|
if (!IsMultiLine(wndPtr))
|
|
return 0L;
|
|
if ((INT)wParam == -1)
|
|
wParam = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
l = (UINT)EDIT_EM_GetLineCount(wndPtr, 0, 0L) - 1;
|
|
while ((UINT)EDIT_EM_LineIndex(wndPtr, l, 0L) > (UINT)wParam)
|
|
l--;
|
|
return (LRESULT)l;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_LINEINDEX
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_LineIndex(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
UINT e;
|
|
UINT l;
|
|
UINT lc = (UINT)EDIT_EM_GetLineCount(wndPtr, 0, 0L);
|
|
|
|
if ((INT)wParam == -1) {
|
|
e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
l = lc - 1;
|
|
while (es->LineDefs[l].offset > e)
|
|
l--;
|
|
return (LRESULT)es->LineDefs[l].offset;
|
|
}
|
|
if ((UINT)wParam >= lc)
|
|
return -1L;
|
|
return (LRESULT)es->LineDefs[(UINT)wParam].offset;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_LINELENGTH
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_LineLength(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
UINT s;
|
|
UINT e;
|
|
UINT sl;
|
|
UINT el;
|
|
|
|
if (!IsMultiLine(wndPtr))
|
|
return (LRESULT)es->LineDefs[0].length;
|
|
if ((INT)wParam == -1) {
|
|
s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
sl = (UINT)EDIT_EM_LineFromChar(wndPtr, s, 0L);
|
|
el = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L);
|
|
return (LRESULT)(s - es->LineDefs[sl].offset +
|
|
es->LineDefs[el].offset +
|
|
es->LineDefs[el].length - e);
|
|
}
|
|
return (LRESULT)es->LineDefs[(UINT)EDIT_EM_LineFromChar(wndPtr, wParam, 0L)].length;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_LINESCROLL
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_LineScroll(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
UINT lc = (UINT)EDIT_EM_GetLineCount(wndPtr, 0, 0L);
|
|
UINT fv = (UINT)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L);
|
|
UINT nfv = MAX(0, fv + (INT)LOWORD(lParam));
|
|
UINT xoff = EDIT_GetXOffset(wndPtr);
|
|
UINT nxoff = MAX(0, xoff + (INT)HIWORD(lParam));
|
|
UINT tw = EDIT_GetTextWidth(wndPtr);
|
|
INT dx;
|
|
INT dy;
|
|
POINT16 pos;
|
|
|
|
if (nfv >= lc)
|
|
nfv = lc - 1;
|
|
|
|
if (nxoff >= tw)
|
|
nxoff = tw;
|
|
dx = xoff - nxoff;
|
|
dy = EDIT_WndYFromLine(wndPtr, fv) - EDIT_WndYFromLine(wndPtr, nfv);
|
|
if (dx || dy) {
|
|
if (wndPtr->hwndSelf == GetFocus32())
|
|
HideCaret(wndPtr->hwndSelf);
|
|
if (EDIT_GetRedraw(wndPtr))
|
|
ScrollWindow(wndPtr->hwndSelf, dx, dy, NULL, NULL);
|
|
es->FirstVisibleLine = nfv;
|
|
es->XOffset = nxoff;
|
|
if (IsVScrollBar(wndPtr))
|
|
SetScrollPos32(wndPtr->hwndSelf, SB_VERT,
|
|
EDIT_WM_VScroll(wndPtr, EM_GETTHUMB, 0L), TRUE);
|
|
if (IsHScrollBar(wndPtr))
|
|
SetScrollPos32(wndPtr->hwndSelf, SB_HORZ,
|
|
EDIT_WM_HScroll(wndPtr, EM_GETTHUMB, 0L), TRUE);
|
|
if (wndPtr->hwndSelf == GetFocus32()) {
|
|
GetCaretPos16(&pos);
|
|
SetCaretPos(pos.x + dx, pos.y + dy);
|
|
ShowCaret(wndPtr->hwndSelf);
|
|
}
|
|
}
|
|
return -1L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_REPLACESEL
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_ReplaceSel(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
return (LRESULT)EDIT_ReplaceSel(wndPtr, wParam,
|
|
(LPARAM)(char *)PTR_SEG_TO_LIN(lParam));
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_SCROLL
|
|
*
|
|
* FIXME: undocumented message.
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_Scroll(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
fprintf(stdnimp, "edit: EM_SCROLL: message not implemented (undocumented), please report.\n");
|
|
return 0L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_SETHANDLE
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_SetHandle(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
if (IsMultiLine(wndPtr)) {
|
|
EDIT_ReleasePointer(wndPtr);
|
|
/*
|
|
* old buffer is freed by caller
|
|
*/
|
|
es->hBuf = (HLOCAL16)wParam;
|
|
es->BufSize = LOCAL_Size(wndPtr->hInstance, es->hBuf) - 1;
|
|
es->LineCount = 0;
|
|
es->FirstVisibleLine = 0;
|
|
es->SelStart = es->SelEnd = 0;
|
|
EDIT_EM_EmptyUndoBuffer(wndPtr, 0, 0L);
|
|
EDIT_EM_SetModify(wndPtr, FALSE, 0L);
|
|
EDIT_BuildLineDefs(wndPtr);
|
|
if (EDIT_GetRedraw(wndPtr))
|
|
InvalidateRect32( wndPtr->hwndSelf, NULL, TRUE );
|
|
EDIT_ScrollIntoView(wndPtr);
|
|
}
|
|
return 0L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_SETMODIFY
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_SetModify(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
es->TextChanged = (BOOL)wParam;
|
|
return 0L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_SETPASSWORDCHAR
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_SetPasswordChar(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
es->PasswordChar = (char)wParam;
|
|
return 0L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_SETREADONLY
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_SetReadOnly(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
if ((BOOL)wParam)
|
|
wndPtr->dwStyle |= ES_READONLY;
|
|
else
|
|
wndPtr->dwStyle &= ~(DWORD)ES_READONLY;
|
|
return 0L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_SETRECT
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_SetRect(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
fprintf(stdnimp,"edit: EM_SETRECT: message not implemented, please report.\n");
|
|
return 0L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_SETRECTNP
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_SetRectNP(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
fprintf(stdnimp,"edit: EM_SETRECTNP: message not implemented, please report.\n");
|
|
return 0L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_SETSEL
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_SetSel(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
UINT ns = LOWORD(lParam);
|
|
UINT ne = HIWORD(lParam);
|
|
UINT s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
UINT el;
|
|
UINT eli;
|
|
UINT tl = (UINT)EDIT_WM_GetTextLength(wndPtr, 0, 0L);
|
|
|
|
if ((INT)ns == -1) {
|
|
ns = e;
|
|
ne = e;
|
|
}
|
|
else {
|
|
ns = MIN(ns, tl);
|
|
ne = MIN(ne, tl);
|
|
}
|
|
es->SelStart = ns;
|
|
es->SelEnd = ne;
|
|
if (wndPtr->hwndSelf == GetFocus32()) {
|
|
el = (UINT)EDIT_EM_LineFromChar(wndPtr, ne, 0L);
|
|
eli = (UINT)EDIT_EM_LineIndex(wndPtr, el, 0L);
|
|
SetCaretPos(EDIT_WndXFromCol(wndPtr, el, ne - eli),
|
|
EDIT_WndYFromLine(wndPtr, el));
|
|
}
|
|
if (!wParam)
|
|
EDIT_ScrollIntoView(wndPtr);
|
|
if (EDIT_GetRedraw(wndPtr)) {
|
|
ORDER_UINT(s, e);
|
|
ORDER_UINT(s, ns);
|
|
ORDER_UINT(s, ne);
|
|
ORDER_UINT(e, ns);
|
|
ORDER_UINT(e, ne);
|
|
ORDER_UINT(ns, ne);
|
|
if (e != ns) {
|
|
EDIT_InvalidateText(wndPtr, s, e);
|
|
EDIT_InvalidateText(wndPtr, ns, ne);
|
|
} else
|
|
EDIT_InvalidateText(wndPtr, s, ne);
|
|
}
|
|
return -1L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_SETTABSTOPS
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_SetTabStops(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
if (!IsMultiLine(wndPtr))
|
|
return 0L;
|
|
if (es->TabStops)
|
|
free(es->TabStops);
|
|
es->NumTabStops = (UINT)wParam;
|
|
if (!wParam)
|
|
es->TabStops = NULL;
|
|
else {
|
|
es->TabStops = (LPINT16)xmalloc(wParam * sizeof(INT16));
|
|
memcpy(es->TabStops, (LPINT16)PTR_SEG_TO_LIN(lParam),
|
|
(UINT)wParam * sizeof(INT16));
|
|
}
|
|
return 1L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_SETWORDBREAKPROC
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_SetWordBreakProc(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
es->WordBreakProc = (EDITWORDBREAKPROC)lParam;
|
|
return 0L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_UNDO
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_Undo(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
return 0L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_CHAR
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_Char(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
char str[2];
|
|
unsigned char c = (unsigned char)wParam;
|
|
|
|
switch (c) {
|
|
case '\r':
|
|
case '\n':
|
|
if (IsMultiLine(wndPtr)) {
|
|
if (IsReadOnly(wndPtr)) {
|
|
EDIT_MoveHome(wndPtr, FALSE);
|
|
EDIT_MoveDownward(wndPtr, FALSE);
|
|
} else
|
|
EDIT_ReplaceSel(wndPtr, 0, (LPARAM)"\r\n");
|
|
}
|
|
break;
|
|
case '\t':
|
|
if (IsMultiLine(wndPtr) && !IsReadOnly(wndPtr))
|
|
EDIT_ReplaceSel(wndPtr, 0, (LPARAM)"\t");
|
|
break;
|
|
default:
|
|
if (!IsReadOnly(wndPtr) && (c >= ' ') && (c != 127)) {
|
|
str[0] = c;
|
|
str[1] = '\0';
|
|
EDIT_ReplaceSel(wndPtr, 0, (LPARAM)str);
|
|
}
|
|
break;
|
|
}
|
|
return 0L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_CLEAR
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_Clear(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
UINT s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
char *text;
|
|
BOOL redraw;
|
|
|
|
if (s != e) {
|
|
redraw = EDIT_GetRedraw(wndPtr);
|
|
EDIT_WM_SetRedraw(wndPtr, FALSE, 0L);
|
|
ORDER_UINT(s, e);
|
|
text = EDIT_GetPointer(wndPtr);
|
|
strcpy(text + s, text + e);
|
|
EDIT_BuildLineDefs(wndPtr);
|
|
EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, s));
|
|
EDIT_EM_SetModify(wndPtr, TRUE, 0L);
|
|
EDIT_NOTIFY_PARENT(wndPtr, EN_UPDATE);
|
|
EDIT_WM_SetRedraw(wndPtr, redraw, 0L);
|
|
if (redraw) {
|
|
InvalidateRect32( wndPtr->hwndSelf, NULL, TRUE );
|
|
EDIT_NOTIFY_PARENT(wndPtr, EN_CHANGE);
|
|
}
|
|
}
|
|
return -1L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_COPY
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_Copy(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
UINT s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
HGLOBAL16 hdst;
|
|
char *text;
|
|
char *dst;
|
|
char *src;
|
|
int i;
|
|
|
|
if (e == s)
|
|
return -1L;
|
|
ORDER_UINT(s, e);
|
|
hdst = GlobalAlloc16(GMEM_MOVEABLE, (DWORD)(e - s + 1));
|
|
dst = GlobalLock16(hdst);
|
|
text = EDIT_GetPointer(wndPtr);
|
|
src = text + s;
|
|
for (i = 0 ; i < e - s ; i++)
|
|
*dst++ = *src++;
|
|
*dst = '\0';
|
|
GlobalUnlock16(hdst);
|
|
OpenClipboard(wndPtr->hwndSelf);
|
|
EmptyClipboard();
|
|
SetClipboardData(CF_TEXT, hdst);
|
|
CloseClipboard();
|
|
return -1L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_CREATE
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_Create(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
CREATESTRUCT16 *cs = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam);
|
|
EDITSTATE *es;
|
|
char *text;
|
|
|
|
es = xmalloc(sizeof(EDITSTATE));
|
|
memset(es, 0, sizeof(EDITSTATE));
|
|
*(EDITSTATE **)wndPtr->wExtra = es;
|
|
|
|
if (cs->style & WS_VSCROLL)
|
|
cs->style |= ES_AUTOVSCROLL;
|
|
if (cs->style & WS_HSCROLL)
|
|
cs->style |= ES_AUTOHSCROLL;
|
|
|
|
/* remove the WS_CAPTION style if it has been set - this is really a */
|
|
/* pseudo option made from a combination of WS_BORDER and WS_DLGFRAME */
|
|
if ((cs->style & WS_BORDER) && (cs->style & WS_DLGFRAME))
|
|
cs->style ^= WS_DLGFRAME;
|
|
|
|
if (IsMultiLine(wndPtr)) {
|
|
es->BufSize = BUFSTART_MULTI;
|
|
es->BufLimit = BUFLIMIT_MULTI;
|
|
es->PasswordChar = '\0';
|
|
} else {
|
|
es->BufSize = BUFSTART_SINGLE;
|
|
es->BufLimit = BUFLIMIT_SINGLE;
|
|
es->PasswordChar = (cs->style & ES_PASSWORD) ? '*' : '\0';
|
|
}
|
|
if (!LOCAL_HeapSize(wndPtr->hInstance)) {
|
|
if (!LocalInit(wndPtr->hInstance, 0,
|
|
GlobalSize16(wndPtr->hInstance))) {
|
|
fprintf(stderr, "edit: WM_CREATE: could not initialize local heap\n");
|
|
return -1L;
|
|
}
|
|
dprintf_edit(stddeb, "edit: WM_CREATE: local heap initialized\n");
|
|
}
|
|
if (!(es->hBuf = LOCAL_Alloc(wndPtr->hInstance, LMEM_MOVEABLE, es->BufSize + 1))) {
|
|
fprintf(stderr, "edit: WM_CREATE: unable to allocate buffer\n");
|
|
return -1L;
|
|
}
|
|
es->BufSize = LOCAL_Size(wndPtr->hInstance, es->hBuf) - 1;
|
|
text = EDIT_GetPointer(wndPtr);
|
|
*text = '\0';
|
|
EDIT_BuildLineDefs(wndPtr);
|
|
EDIT_WM_SetFont(wndPtr, 0, 0L);
|
|
if (cs->lpszName && *(char *)PTR_SEG_TO_LIN(cs->lpszName) != '\0')
|
|
EDIT_EM_ReplaceSel(wndPtr, FALSE, (LPARAM)cs->lpszName);
|
|
EDIT_WM_SetRedraw(wndPtr, TRUE, 0L);
|
|
return 0L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_CUT
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_Cut(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
EDIT_WM_Copy(wndPtr, 0, 0L);
|
|
EDIT_WM_Clear(wndPtr, 0, 0L);
|
|
return -1L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_DESTROY
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_Destroy(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
free(es->LineDefs);
|
|
if (es->TabStops)
|
|
free(es->TabStops);
|
|
EDIT_ReleasePointer(wndPtr);
|
|
LOCAL_Free(wndPtr->hInstance, es->hBuf);
|
|
free(es);
|
|
*(EDITSTATE **)&wndPtr->wExtra = NULL;
|
|
return 0L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_ENABLE
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_Enable(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
EDIT_InvalidateText(wndPtr, 0, -1);
|
|
return 0L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_ERASEBKGND
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_EraseBkGnd(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
HBRUSH hBrush;
|
|
RECT16 rc;
|
|
|
|
hBrush = (HBRUSH)EDIT_SEND_CTLCOLOR(wndPtr, wParam);
|
|
if (!hBrush)
|
|
hBrush = (HBRUSH)GetStockObject(WHITE_BRUSH);
|
|
|
|
GetClientRect16(wndPtr->hwndSelf, &rc);
|
|
IntersectClipRect((HDC)wParam, rc.left, rc.top, rc.right, rc.bottom);
|
|
GetClipBox16((HDC)wParam, &rc);
|
|
/*
|
|
* FIXME: specs say that we should UnrealizeObject() the brush,
|
|
* but the specs of UnrealizeObject() say that we shouldn't
|
|
* unrealize a stock object. The default brush that
|
|
* DefWndProc() returns is ... a stock object.
|
|
*/
|
|
FillRect16((HDC)wParam, &rc, hBrush);
|
|
return -1L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_GETDLGCODE
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_GetDlgCode(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
return DLGC_HASSETSEL | DLGC_WANTCHARS | DLGC_WANTARROWS;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_GETFONT
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_GetFont(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
return (LRESULT)es->hFont;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_GETTEXT
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_GetText(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
char *text = EDIT_GetPointer(wndPtr);
|
|
int len;
|
|
LRESULT lResult = 0L;
|
|
|
|
len = strlen(text);
|
|
if ((UINT)wParam > len) {
|
|
strcpy((char *)PTR_SEG_TO_LIN(lParam), text);
|
|
lResult = (LRESULT)len ;
|
|
}
|
|
return lResult;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_GETTEXTLENGTH
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_GetTextLength(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
char *text = EDIT_GetPointer(wndPtr);
|
|
|
|
return (LRESULT)strlen(text);
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_HSCROLL
|
|
*
|
|
* FIXME: scrollbar code itself is broken, so this one is a hack.
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_HScroll(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
UINT ww = EDIT_GetWndWidth(wndPtr);
|
|
UINT tw = EDIT_GetTextWidth(wndPtr);
|
|
UINT cw = EDIT_GetAveCharWidth(wndPtr);
|
|
UINT xoff = EDIT_GetXOffset(wndPtr);
|
|
INT dx = 0;
|
|
BOOL not = TRUE;
|
|
LRESULT ret = 0L;
|
|
|
|
switch (wParam) {
|
|
case SB_LINELEFT:
|
|
dx = -cw;
|
|
break;
|
|
case SB_LINERIGHT:
|
|
dx = cw;
|
|
break;
|
|
case SB_PAGELEFT:
|
|
dx = -ww / HSCROLL_FRACTION / cw * cw;
|
|
break;
|
|
case SB_PAGERIGHT:
|
|
dx = ww / HSCROLL_FRACTION / cw * cw;
|
|
break;
|
|
case SB_LEFT:
|
|
dx = -xoff;
|
|
break;
|
|
case SB_RIGHT:
|
|
dx = tw - xoff;
|
|
break;
|
|
case SB_THUMBTRACK:
|
|
/*
|
|
* not = FALSE;
|
|
*/
|
|
case SB_THUMBPOSITION:
|
|
dx = LOWORD(lParam) * tw / 100 - xoff;
|
|
break;
|
|
/* The next two are undocumented ! */
|
|
case EM_GETTHUMB:
|
|
ret = tw ? MAKELONG(xoff * 100 / tw, 0) : 0;
|
|
break;
|
|
case EM_LINESCROLL:
|
|
dx = LOWORD(lParam);
|
|
break;
|
|
case SB_ENDSCROLL:
|
|
default:
|
|
break;
|
|
}
|
|
if (dx) {
|
|
EDIT_EM_LineScroll(wndPtr, 0, MAKELPARAM(0, dx));
|
|
if (not)
|
|
EDIT_NOTIFY_PARENT(wndPtr, EN_HSCROLL);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_KEYDOWN
|
|
*
|
|
* Handling of special keys that don't produce a WM_CHAR
|
|
* (i.e. non-printable keys) & Backspace & Delete
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_KeyDown(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
UINT s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
BOOL shift;
|
|
BOOL control;
|
|
|
|
if (GetKeyState(VK_MENU) & 0x8000)
|
|
return 0L;
|
|
|
|
shift = GetKeyState(VK_SHIFT) & 0x8000;
|
|
control = GetKeyState(VK_CONTROL) & 0x8000;
|
|
|
|
switch (wParam) {
|
|
case VK_LEFT:
|
|
case VK_UP:
|
|
if (IsMultiLine(wndPtr) && (wParam == VK_UP))
|
|
EDIT_MoveUpward(wndPtr, shift);
|
|
else
|
|
if (control)
|
|
EDIT_MoveWordBackward(wndPtr, shift);
|
|
else
|
|
EDIT_MoveBackward(wndPtr, shift);
|
|
break;
|
|
case VK_RIGHT:
|
|
case VK_DOWN:
|
|
if (IsMultiLine(wndPtr) && (wParam == VK_DOWN))
|
|
EDIT_MoveDownward(wndPtr, shift);
|
|
else if (control)
|
|
EDIT_MoveWordForward(wndPtr, shift);
|
|
else
|
|
EDIT_MoveForward(wndPtr, shift);
|
|
break;
|
|
case VK_HOME:
|
|
EDIT_MoveHome(wndPtr, shift);
|
|
break;
|
|
case VK_END:
|
|
EDIT_MoveEnd(wndPtr, shift);
|
|
break;
|
|
case VK_PRIOR:
|
|
if (IsMultiLine(wndPtr))
|
|
EDIT_MovePageUp(wndPtr, shift);
|
|
break;
|
|
case VK_NEXT:
|
|
if (IsMultiLine(wndPtr))
|
|
EDIT_MovePageDown(wndPtr, shift);
|
|
break;
|
|
case VK_BACK:
|
|
if (!IsReadOnly(wndPtr) && !control)
|
|
if (e != s)
|
|
EDIT_WM_Clear(wndPtr, 0, 0L);
|
|
else
|
|
EDIT_DelLeft(wndPtr);
|
|
break;
|
|
case VK_DELETE:
|
|
if (!IsReadOnly(wndPtr) && !(shift && control))
|
|
if (e != s) {
|
|
if (shift)
|
|
EDIT_WM_Cut(wndPtr, 0, 0L);
|
|
else
|
|
EDIT_WM_Clear(wndPtr, 0, 0L);
|
|
} else {
|
|
if (shift)
|
|
EDIT_DelLeft(wndPtr);
|
|
else if (control)
|
|
EDIT_DelEnd(wndPtr);
|
|
else
|
|
EDIT_DelRight(wndPtr);
|
|
}
|
|
break;
|
|
case VK_INSERT:
|
|
if (shift) {
|
|
if (!IsReadOnly(wndPtr))
|
|
EDIT_WM_Paste(wndPtr, 0, 0L);
|
|
} else if (control)
|
|
EDIT_WM_Copy(wndPtr, 0, 0L);
|
|
break;
|
|
}
|
|
return 0L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_KILLFOCUS
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_KillFocus(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
UINT s;
|
|
UINT e;
|
|
|
|
DestroyCaret();
|
|
if(!(wndPtr->dwStyle & ES_NOHIDESEL)) {
|
|
s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
EDIT_InvalidateText(wndPtr, s, e);
|
|
}
|
|
EDIT_NOTIFY_PARENT(wndPtr, EN_KILLFOCUS);
|
|
return 0L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_LBUTTONDBLCLK
|
|
*
|
|
* The caret position has been set on the WM_LBUTTONDOWN message
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_LButtonDblClk(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
UINT s;
|
|
UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
UINT l = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L);
|
|
UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L);
|
|
UINT ll = (UINT)EDIT_EM_LineLength(wndPtr, e, 0L);
|
|
char *text = EDIT_GetPointer(wndPtr);
|
|
|
|
s = li + EDIT_CallWordBreakProc (wndPtr, text + li, e - li, ll, WB_LEFT);
|
|
e = li + EDIT_CallWordBreakProc(wndPtr, text + li, e - li, ll, WB_RIGHT);
|
|
EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e));
|
|
return 0L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_LBUTTONDOWN
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_LButtonDown(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
INT x = (INT)LOWORD(lParam);
|
|
INT y = (INT)HIWORD(lParam);
|
|
UINT l = EDIT_LineFromWndY(wndPtr, y);
|
|
UINT c;
|
|
UINT s;
|
|
UINT e;
|
|
UINT fv = (UINT)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L);
|
|
UINT vlc = EDIT_GetVisibleLineCount(wndPtr);
|
|
UINT li;
|
|
|
|
SetFocus32(wndPtr->hwndSelf);
|
|
SetCapture32(wndPtr->hwndSelf);
|
|
l = MIN(fv + vlc - 1, MAX(fv, l));
|
|
x = MIN(EDIT_GetWndWidth(wndPtr), MAX(0, x));
|
|
c = EDIT_ColFromWndX(wndPtr, l, x);
|
|
li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L);
|
|
e = li + c;
|
|
if (GetKeyState(VK_SHIFT) & 0x8000)
|
|
s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
else
|
|
s = e;
|
|
EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e));
|
|
return 0L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_LBUTTONUP
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_LButtonUp(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
if (GetCapture32() == wndPtr->hwndSelf)
|
|
ReleaseCapture();
|
|
return 0L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_MOUSEMOVE
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_MouseMove(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
INT x;
|
|
INT y;
|
|
UINT l;
|
|
UINT c;
|
|
UINT s;
|
|
UINT fv;
|
|
UINT vlc;
|
|
UINT li;
|
|
|
|
if (GetCapture32() == wndPtr->hwndSelf) {
|
|
x = (INT)LOWORD(lParam);
|
|
y = (INT)HIWORD(lParam);
|
|
fv = (UINT)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L);
|
|
vlc = EDIT_GetVisibleLineCount(wndPtr);
|
|
l = EDIT_LineFromWndY(wndPtr, y);
|
|
l = MIN(fv + vlc - 1, MAX(fv, l));
|
|
x = MIN(EDIT_GetWndWidth(wndPtr), MAX(0, x));
|
|
c = EDIT_ColFromWndX(wndPtr, l, x);
|
|
s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L);
|
|
EDIT_EM_SetSel(wndPtr, 1, MAKELPARAM(s, li + c));
|
|
}
|
|
return 0L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_PAINT
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_Paint(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
PAINTSTRUCT16 ps;
|
|
UINT i;
|
|
UINT fv = (UINT)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L);
|
|
UINT vlc = EDIT_GetVisibleLineCount(wndPtr);
|
|
UINT lc = (UINT)EDIT_EM_GetLineCount(wndPtr, 0, 0L);
|
|
HDC16 hdc;
|
|
HFONT hFont;
|
|
HFONT oldFont = 0;
|
|
RECT16 rc;
|
|
RECT16 rcLine;
|
|
RECT16 rcRgn;
|
|
BOOL rev = IsWindowEnabled(wndPtr->hwndSelf) &&
|
|
((GetFocus32() == wndPtr->hwndSelf) ||
|
|
(wndPtr->dwStyle & ES_NOHIDESEL));
|
|
|
|
hdc = BeginPaint16(wndPtr->hwndSelf, &ps);
|
|
GetClientRect16(wndPtr->hwndSelf, &rc);
|
|
IntersectClipRect(hdc, rc.left, rc.top, rc.right, rc.bottom);
|
|
hFont = EDIT_WM_GetFont(wndPtr, 0, 0L);
|
|
if (hFont)
|
|
oldFont = SelectObject(hdc, hFont);
|
|
EDIT_SEND_CTLCOLOR(wndPtr, hdc);
|
|
if (!IsWindowEnabled(wndPtr->hwndSelf))
|
|
SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT));
|
|
GetClipBox16(hdc, &rcRgn);
|
|
for (i = fv ; i <= MIN(fv + vlc, fv + lc - 1) ; i++ ) {
|
|
EDIT_GetLineRect(wndPtr, i, 0, -1, &rcLine);
|
|
if (IntersectRect16(&rc, &rcRgn, &rcLine))
|
|
EDIT_PaintLine(wndPtr, hdc, i, rev);
|
|
}
|
|
if (hFont)
|
|
SelectObject(hdc, oldFont);
|
|
EndPaint16(wndPtr->hwndSelf, &ps);
|
|
return 0L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_PASTE
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_Paste(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
HGLOBAL16 hsrc;
|
|
char *src;
|
|
|
|
OpenClipboard(wndPtr->hwndSelf);
|
|
if ((hsrc = GetClipboardData(CF_TEXT))) {
|
|
src = (char *)GlobalLock16(hsrc);
|
|
EDIT_ReplaceSel(wndPtr, 0, (LPARAM)src);
|
|
GlobalUnlock16(hsrc);
|
|
}
|
|
CloseClipboard();
|
|
return -1L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_SETCURSOR
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_SetCursor(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
if (LOWORD(lParam) == HTCLIENT) {
|
|
SetCursor(LoadCursor16(0, IDC_IBEAM));
|
|
return -1L;
|
|
} else
|
|
return 0L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_SETFOCUS
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_SetFocus(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
UINT s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L));
|
|
|
|
CreateCaret(wndPtr->hwndSelf, 0, 2, EDIT_GetLineHeight(wndPtr));
|
|
EDIT_EM_SetSel(wndPtr, 1, MAKELPARAM(s, e));
|
|
if(!(wndPtr->dwStyle & ES_NOHIDESEL))
|
|
EDIT_InvalidateText(wndPtr, s, e);
|
|
ShowCaret(wndPtr->hwndSelf);
|
|
EDIT_NOTIFY_PARENT(wndPtr, EN_SETFOCUS);
|
|
return 0L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_SETFONT
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_SetFont(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
TEXTMETRIC16 tm;
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
LPARAM sel = EDIT_EM_GetSel(wndPtr, 0, 0L);
|
|
HDC32 hdc;
|
|
HFONT oldFont = 0;
|
|
|
|
es->hFont = (HFONT)wParam;
|
|
hdc = GetDC32(wndPtr->hwndSelf);
|
|
if (es->hFont)
|
|
oldFont = SelectObject(hdc, es->hFont);
|
|
GetTextMetrics16(hdc, &tm);
|
|
es->LineHeight = HIWORD(GetTextExtent(hdc, "X", 1));
|
|
es->AveCharWidth = tm.tmAveCharWidth;
|
|
if (es->hFont)
|
|
SelectObject(hdc, oldFont);
|
|
ReleaseDC32(wndPtr->hwndSelf, hdc);
|
|
EDIT_BuildLineDefs(wndPtr);
|
|
if ((BOOL)lParam && EDIT_GetRedraw(wndPtr))
|
|
InvalidateRect32( wndPtr->hwndSelf, NULL, TRUE );
|
|
if (wndPtr->hwndSelf == GetFocus32()) {
|
|
DestroyCaret();
|
|
CreateCaret(wndPtr->hwndSelf, 0, 2, EDIT_GetLineHeight(wndPtr));
|
|
EDIT_EM_SetSel(wndPtr, 1, sel);
|
|
ShowCaret(wndPtr->hwndSelf);
|
|
}
|
|
return 0L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_SETREDRAW
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_SetRedraw(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
es->Redraw = (BOOL)wParam;
|
|
return 0L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_SETTEXT
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_SetText(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
EDIT_EM_SetSel(wndPtr, 1, MAKELPARAM(0, -1));
|
|
EDIT_WM_Clear(wndPtr, 0, 0L);
|
|
if (lParam)
|
|
EDIT_EM_ReplaceSel(wndPtr, 0, lParam);
|
|
EDIT_EM_EmptyUndoBuffer(wndPtr, 0, 0L);
|
|
EDIT_EM_SetModify(wndPtr, TRUE, 0L);
|
|
EDIT_ScrollIntoView(wndPtr);
|
|
return 0L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_SIZE
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_Size(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
if (EDIT_GetRedraw(wndPtr) &&
|
|
((wParam == SIZE_MAXIMIZED) ||
|
|
(wParam == SIZE_RESTORED))) {
|
|
if (IsMultiLine(wndPtr) && IsWordWrap(wndPtr))
|
|
EDIT_BuildLineDefs(wndPtr);
|
|
InvalidateRect32( wndPtr->hwndSelf, NULL, TRUE );
|
|
}
|
|
return 0L;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_VSCROLL
|
|
*
|
|
* FIXME: scrollbar code itself is broken, so this one is a hack.
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_VScroll(WND *wndPtr, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
UINT lc = (UINT)EDIT_EM_GetLineCount(wndPtr, 0, 0L);
|
|
UINT fv = (UINT)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L);
|
|
UINT vlc = EDIT_GetVisibleLineCount(wndPtr);
|
|
INT dy = 0;
|
|
BOOL not = TRUE;
|
|
LRESULT ret = 0L;
|
|
|
|
switch (wParam) {
|
|
case SB_LINEUP:
|
|
dy = -1;
|
|
break;
|
|
case SB_LINEDOWN:
|
|
dy = 1;
|
|
break;
|
|
case SB_PAGEUP:
|
|
dy = -vlc;
|
|
break;
|
|
case SB_PAGEDOWN:
|
|
dy = vlc;
|
|
break;
|
|
case SB_TOP:
|
|
dy = -fv;
|
|
break;
|
|
case SB_BOTTOM:
|
|
dy = lc - 1 - fv;
|
|
break;
|
|
case SB_THUMBTRACK:
|
|
/*
|
|
* not = FALSE;
|
|
*/
|
|
case SB_THUMBPOSITION:
|
|
dy = LOWORD(lParam) * (lc - 1) / 100 - fv;
|
|
break;
|
|
/* The next two are undocumented ! */
|
|
case EM_GETTHUMB:
|
|
ret = (lc > 1) ? MAKELONG(fv * 100 / (lc - 1), 0) : 0L;
|
|
break;
|
|
case EM_LINESCROLL:
|
|
dy = LOWORD(lParam);
|
|
break;
|
|
case SB_ENDSCROLL:
|
|
default:
|
|
break;
|
|
}
|
|
if (dy) {
|
|
EDIT_EM_LineScroll(wndPtr, 0, MAKELPARAM(dy, 0));
|
|
if (not)
|
|
EDIT_NOTIFY_PARENT(wndPtr, EN_VSCROLL);
|
|
}
|
|
return ret;
|
|
}
|