3954 lines
100 KiB
C
3954 lines
100 KiB
C
/*
|
|
* Edit control
|
|
*
|
|
* Copyright David W. Metcalfe, 1994
|
|
* Copyright William Magro, 1995, 1996
|
|
* Copyright Frans van Dorsselaer, 1996, 1997
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* please read EDIT.TODO (and update it when you change things)
|
|
* It also contains a discussion about the 16 to 32 bit transition.
|
|
*
|
|
*/
|
|
|
|
|
|
#define NO_TRANSITION_TYPES /* This file is Win32-clean */
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "windows.h"
|
|
#include "win.h"
|
|
#include "local.h"
|
|
#include "resource.h"
|
|
#include "stddebug.h"
|
|
#include "debug.h"
|
|
#include "xmalloc.h"
|
|
/*
|
|
#include "callback.h"
|
|
*/
|
|
|
|
#define BUFLIMIT_MULTI 65534 /* maximum text buffer length (not including '\0') */
|
|
/* FIXME: BTW, new specs say 65535 (do you dare ???) */
|
|
#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 {
|
|
INT32 offset;
|
|
INT32 length;
|
|
LINE_END ending;
|
|
} LINEDEF;
|
|
|
|
typedef struct
|
|
{
|
|
HLOCAL16 hBuf16; /* For when a 16-bit multiline edit
|
|
* control gets a EM_GETHANDLE (which
|
|
* should return 16-bit local heap).
|
|
* From that point on we _have_ to keep
|
|
* using 16-bit local heap (apps rely
|
|
* on that ... bummer).
|
|
*/
|
|
HLOCAL32 hBuf32; /* Don't worry about 'LOCAL'. LOCAL32 is
|
|
* identical to GLOBAL32, which is
|
|
* essentially a HANDLE32 created with
|
|
* HeapAlloc(GetProcessHeap(), ...) plus
|
|
* a global32 (and thus local32)
|
|
* descriptor, which we can return upon
|
|
* EM_GETHANDLE32.
|
|
* It is 32-bit linear addressing, so
|
|
* everything is fine.
|
|
*/
|
|
LPSTR text; /* Depending on the fact that we are a
|
|
* 16 or 32 bit control, this is the
|
|
* pointer that we get after
|
|
* LocalLock32(hBuf23) (which is a typecast :-)
|
|
* or LOCAL_Lock(hBuf16).
|
|
* This is always a 32-bit linear pointer.
|
|
*/
|
|
HFONT32 hFont;
|
|
LINEDEF *LineDefs; /* Internal table for (soft) linebreaks */
|
|
INT32 TextWidth; /* width of the widest line in pixels */
|
|
INT32 XOffset; /* offset of the viewport in pixels */
|
|
INT32 FirstVisibleLine;
|
|
INT32 LineCount;
|
|
INT32 LineHeight; /* height of a screen line in pixels */
|
|
INT32 AveCharWidth; /* average character width in pixels */
|
|
INT32 BufLimit;
|
|
INT32 BufSize;
|
|
BOOL32 TextChanged;
|
|
INT32 UndoInsertLen;
|
|
INT32 UndoPos;
|
|
INT32 UndoBufSize;
|
|
HLOCAL32 hUndoBuf;
|
|
LPSTR UndoText;
|
|
BOOL32 Redraw;
|
|
INT32 SelStart; /* offset of selection start, == SelEnd if no selection */
|
|
INT32 SelEnd; /* offset of selection end == current caret position */
|
|
INT32 NumTabStops;
|
|
LPINT16 TabStops;
|
|
/*
|
|
* FIXME: The following should probably be a (VOID *) that is
|
|
* typecast to either 16- or 32-bit callback when used,
|
|
* depending on the type of edit control (16 or 32 bit).
|
|
*
|
|
* EDITWORDBREAKPROC WordBreakProc;
|
|
*
|
|
* For now: no more application specific wordbreaking.
|
|
* (Internal wordbreak function still works)
|
|
*/
|
|
CHAR PasswordChar;
|
|
INT32 LeftMargin;
|
|
INT32 RightMargin;
|
|
RECT32 FormatRect;
|
|
} EDITSTATE;
|
|
|
|
|
|
#define SWAP_INT32(x,y) do { INT32 temp = (INT32)(x); (x) = (INT32)(y); (y) = temp; } while(0)
|
|
#define ORDER_INT32(x,y) do { if ((INT32)(y) < (INT32)(x)) SWAP_INT32((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, \
|
|
(WPARAM32)(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_MSG16(str) \
|
|
dprintf_edit(stddeb, \
|
|
"edit: 16 bit : " str ": hwnd=%08x, wParam=%08x, lParam=%08x\n", \
|
|
(UINT32)hwnd, (UINT32)wParam, (UINT32)lParam)
|
|
#define DPRINTF_EDIT_MSG32(str) \
|
|
dprintf_edit(stddeb, \
|
|
"edit: 32 bit : " str ": hwnd=%08x, wParam=%08x, lParam=%08x\n", \
|
|
(UINT32)hwnd, (UINT32)wParam, (UINT32)lParam)
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* Declarations
|
|
*
|
|
* Files like these should really be kept in alphabetical order.
|
|
*
|
|
*/
|
|
LRESULT EditWndProc(HWND32 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam);
|
|
|
|
static void EDIT_BuildLineDefs(WND *wndPtr);
|
|
static INT32 EDIT_CallWordBreakProc(WND *wndPtr, LPSTR s, INT32 index, INT32 count, INT32 action);
|
|
static INT32 EDIT_ColFromWndX(WND *wndPtr, INT32 line, INT32 x);
|
|
static void EDIT_DelEnd(WND *wndPtr);
|
|
static void EDIT_DelLeft(WND *wndPtr);
|
|
static void EDIT_DelRight(WND *wndPtr);
|
|
static INT32 EDIT_GetAveCharWidth(WND *wndPtr);
|
|
static INT32 EDIT_GetLineHeight(WND *wndPtr);
|
|
static void EDIT_GetLineRect(WND *wndPtr, INT32 line, INT32 scol, INT32 ecol, LPRECT32 rc);
|
|
static LPSTR EDIT_GetPointer(WND *wndPtr);
|
|
static LPSTR EDIT_GetPasswordPointer(WND *wndPtr);
|
|
static BOOL32 EDIT_GetRedraw(WND *wndPtr);
|
|
static void EDIT_GetSel(WND *wndPtr, LPINT32 s, LPINT32 e);
|
|
static INT32 EDIT_GetTextWidth(WND *wndPtr);
|
|
static LPSTR EDIT_GetUndoPointer(WND *wndPtr);
|
|
static INT32 EDIT_GetVisibleLineCount(WND *wndPtr);
|
|
static INT32 EDIT_GetWndWidth(WND *wndPtr);
|
|
static INT32 EDIT_GetXOffset(WND *wndPtr);
|
|
static void EDIT_InvalidateText(WND *wndPtr, INT32 start, INT32 end);
|
|
static INT32 EDIT_LineFromWndY(WND *wndPtr, INT32 y);
|
|
static BOOL32 EDIT_MakeFit(WND *wndPtr, INT32 size);
|
|
static BOOL32 EDIT_MakeUndoFit(WND *wndPtr, INT32 size);
|
|
static void EDIT_MoveBackward(WND *wndPtr, BOOL32 extend);
|
|
static void EDIT_MoveDownward(WND *wndPtr, BOOL32 extend);
|
|
static void EDIT_MoveEnd(WND *wndPtr, BOOL32 extend);
|
|
static void EDIT_MoveForward(WND *wndPtr, BOOL32 extend);
|
|
static void EDIT_MoveHome(WND *wndPtr, BOOL32 extend);
|
|
static void EDIT_MovePageDown(WND *wndPtr, BOOL32 extend);
|
|
static void EDIT_MovePageUp(WND *wndPtr, BOOL32 extend);
|
|
static void EDIT_MoveUpward(WND *wndPtr, BOOL32 extend);
|
|
static void EDIT_MoveWordBackward(WND *wndPtr, BOOL32 extend);
|
|
static void EDIT_MoveWordForward(WND *wndPtr, BOOL32 extend);
|
|
static void EDIT_PaintLine(WND *wndPtr, HDC32 hdc, INT32 line, BOOL32 rev);
|
|
static INT32 EDIT_PaintText(WND *wndPtr, HDC32 hdc, INT32 x, INT32 y, INT32 line, INT32 col, INT32 count, BOOL32 rev);
|
|
static void EDIT_ReleasePointer(WND *wndPtr);
|
|
static void EDIT_ReleaseUndoPointer(WND *wndPtr);
|
|
static void EDIT_SetSel(WND *wndPtr, INT32 ns, INT32 ne);
|
|
static INT32 EDIT_WndXFromCol(WND *wndPtr, INT32 line, INT32 col);
|
|
static INT32 EDIT_WndYFromLine(WND *wndPtr, INT32 line);
|
|
static INT32 EDIT_WordBreakProc(LPSTR s, INT32 index, INT32 count, INT32 action);
|
|
|
|
static LRESULT EDIT_EM_CanUndo(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_CharFromPos(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_EmptyUndoBuffer(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_FmtLines(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_GetFirstVisibleLine(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_GetHandle(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_GetHandle16(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_GetLimitText(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_GetLine(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_GetLineCount(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_GetMargins(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_GetModify(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_GetPasswordChar(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_GetRect(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_GetRect16(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_GetSel(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_GetThumb(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_GetWordBreakProc(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_LineFromChar(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_LineIndex(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_LineLength(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_LineScroll(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_PosFromChar(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_ReplaceSel(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_Scroll(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_ScrollCaret(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_SetHandle(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_SetHandle16(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_SetLimitText(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_SetMargins(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_SetModify(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_SetPasswordChar(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_SetReadOnly(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_SetRect(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_SetRectNP(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_SetSel(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_SetSel16(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_SetTabStops(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_SetTabStops16(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_SetWordBreakProc(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_EM_Undo(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
|
|
static LRESULT EDIT_WM_Char(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_Clear(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_Command(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_ContextMenu(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_Copy(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_Cut(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_Create(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_Destroy(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_Enable(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_EraseBkGnd(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_GetDlgCode(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_GetFont(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_GetText(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_GetTextLength(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_HScroll(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_InitMenuPopup(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_KeyDown(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_KillFocus(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_LButtonDblClk(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_LButtonDown(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_LButtonUp(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_MouseMove(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_Paint(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_Paste(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_SetCursor(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_SetFocus(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_SetFont(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_SetRedraw(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_SetText(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_Size(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_SysKeyDown(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_Timer(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
static LRESULT EDIT_WM_VScroll(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* General shortcuts for variable names:
|
|
*
|
|
* INT32 l; line
|
|
* INT32 c; column
|
|
* INT32 s; offset of selection start
|
|
* INT32 e; offset of selection end
|
|
* INT32 sl; line on which the selection starts
|
|
* INT32 el; line on which the selection ends
|
|
* INT32 sc; column on which the selection starts
|
|
* INT32 ec; column on which the selection ends
|
|
* INT32 li; line index (offset)
|
|
* INT32 fv; first visible line
|
|
* INT32 vlc; vissible line count
|
|
* INT32 lc; line count
|
|
* INT32 lh; line height (in pixels)
|
|
* INT32 tw; text width (in pixels)
|
|
* INT32 ww; window width (in pixels)
|
|
* INT32 cw; character width (average, in pixels)
|
|
*
|
|
*/
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EditWndProc()
|
|
*
|
|
* The messages are in the order of the actual integer values
|
|
* (which can be found in include/windows.h)
|
|
* Whereever possible the 16 bit versions are converted to
|
|
* the 32 bit ones, so that we can 'fall through' to the
|
|
* helper functions. These are mostly 32 bit (with a few
|
|
* exceptions, clearly indicated by a '16' extension to their
|
|
* names).
|
|
*
|
|
*/
|
|
LRESULT EditWndProc(HWND32 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
LRESULT lResult = 0;
|
|
WND *wndPtr = WIN_FindWndPtr(hwnd);
|
|
|
|
if ((!EDITSTATEPTR(wndPtr)) && (msg != WM_CREATE))
|
|
return DefWindowProc32A(hwnd, msg, wParam, lParam);
|
|
|
|
switch (msg) {
|
|
case EM_GETSEL16:
|
|
DPRINTF_EDIT_MSG16("EM_GETSEL");
|
|
wParam = 0;
|
|
lParam = 0;
|
|
/* fall through */
|
|
case EM_GETSEL32:
|
|
DPRINTF_EDIT_MSG32("EM_GETSEL");
|
|
lResult = EDIT_EM_GetSel(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case EM_SETSEL16:
|
|
DPRINTF_EDIT_MSG16("EM_SETSEL");
|
|
lResult = EDIT_EM_SetSel16(wndPtr, wParam, lParam);
|
|
break;
|
|
case EM_SETSEL32:
|
|
DPRINTF_EDIT_MSG32("EM_SETSEL");
|
|
lResult = EDIT_EM_SetSel(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case EM_GETRECT16:
|
|
DPRINTF_EDIT_MSG16("EM_GETRECT");
|
|
lResult = EDIT_EM_GetRect16(wndPtr, wParam, lParam);
|
|
break;
|
|
case EM_GETRECT32:
|
|
DPRINTF_EDIT_MSG32("EM_GETRECT");
|
|
lResult = EDIT_EM_GetRect(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case EM_SETRECT16:
|
|
DPRINTF_EDIT_MSG16("EM_SETRECT");
|
|
/* fall through */
|
|
case EM_SETRECT32:
|
|
DPRINTF_EDIT_MSG32("EM_SETRECT");
|
|
lResult = EDIT_EM_SetRect(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case EM_SETRECTNP16:
|
|
DPRINTF_EDIT_MSG16("EM_SETRECTNP");
|
|
/* fall through */
|
|
case EM_SETRECTNP32:
|
|
DPRINTF_EDIT_MSG32("EM_SETRECTNP");
|
|
lResult = EDIT_EM_SetRectNP(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case EM_SCROLL16:
|
|
DPRINTF_EDIT_MSG16("EM_SCROLL");
|
|
/* fall through */
|
|
case EM_SCROLL32:
|
|
DPRINTF_EDIT_MSG32("EM_SCROLL");
|
|
lResult = EDIT_EM_Scroll(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case EM_LINESCROLL16:
|
|
DPRINTF_EDIT_MSG16("EM_LINESCROLL");
|
|
wParam = (WPARAM32)(INT32)(INT16)HIWORD(lParam);
|
|
lParam = (LPARAM)(INT32)(INT16)LOWORD(lParam);
|
|
/* fall through */
|
|
case EM_LINESCROLL32:
|
|
DPRINTF_EDIT_MSG32("EM_LINESCROLL");
|
|
lResult = EDIT_EM_LineScroll(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case EM_SCROLLCARET16:
|
|
DPRINTF_EDIT_MSG16("EM_SCROLLCARET");
|
|
/* fall through */
|
|
case EM_SCROLLCARET32:
|
|
DPRINTF_EDIT_MSG32("EM_SCROLLCARET");
|
|
lResult = EDIT_EM_ScrollCaret(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case EM_GETMODIFY16:
|
|
DPRINTF_EDIT_MSG16("EM_GETMODIFY");
|
|
/* fall through */
|
|
case EM_GETMODIFY32:
|
|
DPRINTF_EDIT_MSG32("EM_GETMODIFY");
|
|
lResult = EDIT_EM_GetModify(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case EM_SETMODIFY16:
|
|
DPRINTF_EDIT_MSG16("EM_SETMODIFY");
|
|
/* fall through */
|
|
case EM_SETMODIFY32:
|
|
DPRINTF_EDIT_MSG32("EM_SETMODIFY");
|
|
lResult = EDIT_EM_SetModify(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case EM_GETLINECOUNT16:
|
|
DPRINTF_EDIT_MSG16("EM_GETLINECOUNT");
|
|
/* fall through */
|
|
case EM_GETLINECOUNT32:
|
|
DPRINTF_EDIT_MSG32("EM_GETLINECOUNT");
|
|
lResult = EDIT_EM_GetLineCount(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case EM_LINEINDEX16:
|
|
DPRINTF_EDIT_MSG16("EM_LINEINDEX");
|
|
/* fall through */
|
|
case EM_LINEINDEX32:
|
|
DPRINTF_EDIT_MSG32("EM_LINEINDEX");
|
|
lResult = EDIT_EM_LineIndex(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case EM_SETHANDLE16:
|
|
DPRINTF_EDIT_MSG16("EM_SETHANDLE");
|
|
lResult = EDIT_EM_SetHandle16(wndPtr, wParam, lParam);
|
|
break;
|
|
case EM_SETHANDLE32:
|
|
DPRINTF_EDIT_MSG32("EM_SETHANDLE");
|
|
lResult = EDIT_EM_SetHandle(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case EM_GETHANDLE16:
|
|
DPRINTF_EDIT_MSG16("EM_GETHANDLE");
|
|
lResult = EDIT_EM_GetHandle16(wndPtr, wParam, lParam);
|
|
break;
|
|
case EM_GETHANDLE32:
|
|
DPRINTF_EDIT_MSG32("EM_GETHANDLE");
|
|
lResult = EDIT_EM_GetHandle(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case EM_GETTHUMB16:
|
|
DPRINTF_EDIT_MSG16("EM_GETTHUMB");
|
|
/* fall through */
|
|
case EM_GETTHUMB32:
|
|
DPRINTF_EDIT_MSG32("EM_GETTHUMB");
|
|
lResult = EDIT_EM_GetThumb(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
/* messages 0x00bf and 0x00c0 missing from specs */
|
|
|
|
case WM_USER+15:
|
|
DPRINTF_EDIT_MSG16("undocumented WM_USER+15, please report");
|
|
/* fall through */
|
|
case 0x00bf:
|
|
DPRINTF_EDIT_MSG32("undocumented 0x00bf, please report");
|
|
lResult = DefWindowProc32A(hwnd, msg, wParam, lParam);
|
|
break;
|
|
|
|
case WM_USER+16:
|
|
DPRINTF_EDIT_MSG16("undocumented WM_USER+16, please report");
|
|
/* fall through */
|
|
case 0x00c0:
|
|
DPRINTF_EDIT_MSG32("undocumented 0x00c0, please report");
|
|
lResult = DefWindowProc32A(hwnd, msg, wParam, lParam);
|
|
break;
|
|
|
|
case EM_LINELENGTH16:
|
|
DPRINTF_EDIT_MSG16("EM_LINELENGTH");
|
|
/* fall through */
|
|
case EM_LINELENGTH32:
|
|
DPRINTF_EDIT_MSG32("EM_LINELENGTH");
|
|
lResult = EDIT_EM_LineLength(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case EM_REPLACESEL16:
|
|
DPRINTF_EDIT_MSG16("EM_REPLACESEL");
|
|
lParam = (LPARAM)PTR_SEG_TO_LIN((SEGPTR)lParam);
|
|
/* fall through */
|
|
case EM_REPLACESEL32:
|
|
DPRINTF_EDIT_MSG32("EM_REPLACESEL");
|
|
lResult = EDIT_EM_ReplaceSel(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
/* message 0x00c3 missing from specs */
|
|
|
|
case WM_USER+19:
|
|
DPRINTF_EDIT_MSG16("undocumented WM_USER+19, please report");
|
|
/* fall through */
|
|
case 0x00c3:
|
|
DPRINTF_EDIT_MSG32("undocumented 0x00c3, please report");
|
|
lResult = DefWindowProc32A(hwnd, msg, wParam, lParam);
|
|
break;
|
|
|
|
case EM_GETLINE16:
|
|
DPRINTF_EDIT_MSG16("EM_GETLINE");
|
|
lParam = (LPARAM)PTR_SEG_TO_LIN((SEGPTR)lParam);
|
|
/* fall through */
|
|
case EM_GETLINE32:
|
|
DPRINTF_EDIT_MSG32("EM_GETLINE");
|
|
lResult = EDIT_EM_GetLine(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case EM_LIMITTEXT16:
|
|
DPRINTF_EDIT_MSG16("EM_LIMITTEXT");
|
|
/* fall through */
|
|
case EM_SETLIMITTEXT32:
|
|
DPRINTF_EDIT_MSG32("EM_SETLIMITTEXT");
|
|
lResult = EDIT_EM_SetLimitText(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case EM_CANUNDO16:
|
|
DPRINTF_EDIT_MSG16("EM_CANUNDO");
|
|
/* fall through */
|
|
case EM_CANUNDO32:
|
|
DPRINTF_EDIT_MSG32("EM_CANUNDO");
|
|
lResult = EDIT_EM_CanUndo(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case EM_UNDO16:
|
|
DPRINTF_EDIT_MSG16("EM_UNDO");
|
|
/* fall through */
|
|
case EM_UNDO32:
|
|
/* fall through */
|
|
case WM_UNDO:
|
|
DPRINTF_EDIT_MSG32("EM_UNDO / WM_UNDO");
|
|
lResult = EDIT_EM_Undo(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case EM_FMTLINES16:
|
|
DPRINTF_EDIT_MSG16("EM_FMTLINES");
|
|
/* fall through */
|
|
case EM_FMTLINES32:
|
|
DPRINTF_EDIT_MSG32("EM_FMTLINES");
|
|
lResult = EDIT_EM_FmtLines(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case EM_LINEFROMCHAR16:
|
|
DPRINTF_EDIT_MSG16("EM_LINEFROMCHAR");
|
|
/* fall through */
|
|
case EM_LINEFROMCHAR32:
|
|
DPRINTF_EDIT_MSG32("EM_LINEFROMCHAR");
|
|
lResult = EDIT_EM_LineFromChar(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
/* message 0x00ca missing from specs */
|
|
|
|
case WM_USER+26:
|
|
DPRINTF_EDIT_MSG16("undocumented WM_USER+26, please report");
|
|
/* fall through */
|
|
case 0x00ca:
|
|
DPRINTF_EDIT_MSG32("undocumented 0x00ca, please report");
|
|
lResult = DefWindowProc32A(hwnd, msg, wParam, lParam);
|
|
break;
|
|
|
|
case EM_SETTABSTOPS16:
|
|
DPRINTF_EDIT_MSG16("EM_SETTABSTOPS");
|
|
lResult = EDIT_EM_SetTabStops16(wndPtr, wParam, lParam);
|
|
break;
|
|
case EM_SETTABSTOPS32:
|
|
DPRINTF_EDIT_MSG32("EM_SETTABSTOPS");
|
|
lResult = EDIT_EM_SetTabStops(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case EM_SETPASSWORDCHAR16:
|
|
DPRINTF_EDIT_MSG16("EM_SETPASSWORDCHAR");
|
|
/* fall through */
|
|
case EM_SETPASSWORDCHAR32:
|
|
DPRINTF_EDIT_MSG32("EM_SETPASSWORDCHAR");
|
|
lResult = EDIT_EM_SetPasswordChar(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case EM_EMPTYUNDOBUFFER16:
|
|
DPRINTF_EDIT_MSG16("EM_EMPTYUNDOBUFFER");
|
|
/* fall through */
|
|
case EM_EMPTYUNDOBUFFER32:
|
|
DPRINTF_EDIT_MSG32("EM_EMPTYUNDOBUFFER");
|
|
lResult = EDIT_EM_EmptyUndoBuffer(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case EM_GETFIRSTVISIBLELINE16:
|
|
DPRINTF_EDIT_MSG16("EM_GETFIRSTVISIBLELINE");
|
|
/* fall through */
|
|
case EM_GETFIRSTVISIBLELINE32:
|
|
DPRINTF_EDIT_MSG32("EM_GETFIRSTVISIBLELINE");
|
|
lResult = EDIT_EM_GetFirstVisibleLine(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case EM_SETREADONLY16:
|
|
DPRINTF_EDIT_MSG16("EM_SETREADONLY");
|
|
/* fall through */
|
|
case EM_SETREADONLY32:
|
|
DPRINTF_EDIT_MSG32("EM_SETREADONLY");
|
|
lResult = EDIT_EM_SetReadOnly(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case EM_SETWORDBREAKPROC16:
|
|
DPRINTF_EDIT_MSG16("EM_SETWORDBREAKPROC");
|
|
/* fall through */
|
|
case EM_SETWORDBREAKPROC32:
|
|
DPRINTF_EDIT_MSG32("EM_SETWORDBREAKPROC");
|
|
lResult = EDIT_EM_SetWordBreakProc(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case EM_GETWORDBREAKPROC16:
|
|
DPRINTF_EDIT_MSG16("EM_GETWORDBREAKPROC");
|
|
/* fall through */
|
|
case EM_GETWORDBREAKPROC32:
|
|
DPRINTF_EDIT_MSG32("EM_GETWORDBREAKPROC");
|
|
lResult = EDIT_EM_GetWordBreakProc(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case EM_GETPASSWORDCHAR16:
|
|
DPRINTF_EDIT_MSG16("EM_GETPASSWORDCHAR");
|
|
/* fall through */
|
|
case EM_GETPASSWORDCHAR32:
|
|
DPRINTF_EDIT_MSG32("EM_GETPASSWORDCHAR");
|
|
lResult = EDIT_EM_GetPasswordChar(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
/* The following EM_xxx are new to win95 and don't exist for 16 bit */
|
|
|
|
case EM_SETMARGINS32:
|
|
DPRINTF_EDIT_MSG16("EM_SETMARGINS");
|
|
lResult = EDIT_EM_SetMargins(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case EM_GETMARGINS32:
|
|
DPRINTF_EDIT_MSG16("EM_GETMARGINS");
|
|
lResult = EDIT_EM_GetMargins(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case EM_GETLIMITTEXT32:
|
|
DPRINTF_EDIT_MSG16("EM_GETLIMITTEXT");
|
|
lResult = EDIT_EM_GetLimitText(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case EM_POSFROMCHAR32:
|
|
DPRINTF_EDIT_MSG16("EM_POSFROMCHAR");
|
|
lResult = EDIT_EM_PosFromChar(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case EM_CHARFROMPOS32:
|
|
DPRINTF_EDIT_MSG16("EM_CHARFROMPOS");
|
|
lResult = EDIT_EM_CharFromPos(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case WM_GETDLGCODE:
|
|
DPRINTF_EDIT_MSG32("WM_GETDLGCODE");
|
|
lResult = EDIT_WM_GetDlgCode(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case WM_CHAR:
|
|
DPRINTF_EDIT_MSG32("WM_CHAR");
|
|
lResult = EDIT_WM_Char(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case WM_CLEAR:
|
|
DPRINTF_EDIT_MSG32("WM_CLEAR");
|
|
lResult = EDIT_WM_Clear(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
DPRINTF_EDIT_MSG32("WM_COMMAND");
|
|
lResult = EDIT_WM_Command(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
/*
|
|
* FIXME: when this one is added to WINE, change RBUTTONUP to CONTEXTMENU
|
|
* Furthermore, coordinate conversion should no longer be required
|
|
*
|
|
* case WM_CONTEXTMENU:
|
|
*/
|
|
case WM_RBUTTONUP:
|
|
DPRINTF_EDIT_MSG32("WM_RBUTTONUP");
|
|
ClientToScreen16(wndPtr->hwndSelf, (LPPOINT16)&lParam);
|
|
lResult = EDIT_WM_ContextMenu(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case WM_COPY:
|
|
DPRINTF_EDIT_MSG32("WM_COPY");
|
|
lResult = EDIT_WM_Copy(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case WM_CREATE:
|
|
DPRINTF_EDIT_MSG32("WM_CREATE");
|
|
lResult = EDIT_WM_Create(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case WM_CUT:
|
|
DPRINTF_EDIT_MSG32("WM_CUT");
|
|
lResult = EDIT_WM_Cut(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
DPRINTF_EDIT_MSG32("WM_DESTROY");
|
|
lResult = EDIT_WM_Destroy(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case WM_ENABLE:
|
|
DPRINTF_EDIT_MSG32("WM_ENABLE");
|
|
lResult = EDIT_WM_Enable(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case WM_ERASEBKGND:
|
|
DPRINTF_EDIT_MSG32("WM_ERASEBKGND");
|
|
lResult = EDIT_WM_EraseBkGnd(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case WM_GETFONT:
|
|
DPRINTF_EDIT_MSG32("WM_GETFONT");
|
|
lResult = EDIT_WM_GetFont(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case WM_GETTEXT:
|
|
DPRINTF_EDIT_MSG32("WM_GETTEXT");
|
|
lResult = EDIT_WM_GetText(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case WM_GETTEXTLENGTH:
|
|
DPRINTF_EDIT_MSG32("WM_GETTEXTLENGTH");
|
|
lResult = EDIT_WM_GetTextLength(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case WM_HSCROLL:
|
|
DPRINTF_EDIT_MSG32("WM_HSCROLL");
|
|
lResult = EDIT_WM_HScroll(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case WM_INITMENUPOPUP:
|
|
DPRINTF_EDIT_MSG32("WM_INITMENUPOPUP");
|
|
lResult = EDIT_WM_InitMenuPopup(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case WM_KEYDOWN:
|
|
DPRINTF_EDIT_MSG32("WM_KEYDOWN");
|
|
lResult = EDIT_WM_KeyDown(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case WM_KILLFOCUS:
|
|
DPRINTF_EDIT_MSG32("WM_KILLFOCUS");
|
|
lResult = EDIT_WM_KillFocus(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case WM_LBUTTONDBLCLK:
|
|
DPRINTF_EDIT_MSG32("WM_LBUTTONDBLCLK");
|
|
lResult = EDIT_WM_LButtonDblClk(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case WM_LBUTTONDOWN:
|
|
DPRINTF_EDIT_MSG32("WM_LBUTTONDOWN");
|
|
lResult = EDIT_WM_LButtonDown(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case WM_LBUTTONUP:
|
|
DPRINTF_EDIT_MSG32("WM_LBUTTONUP");
|
|
lResult = EDIT_WM_LButtonUp(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case WM_MOUSEMOVE:
|
|
/*
|
|
* DPRINTF_EDIT_MSG32("WM_MOUSEMOVE");
|
|
*/
|
|
lResult = EDIT_WM_MouseMove(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case WM_PAINT:
|
|
DPRINTF_EDIT_MSG32("WM_PAINT");
|
|
lResult = EDIT_WM_Paint(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case WM_PASTE:
|
|
DPRINTF_EDIT_MSG32("WM_PASTE");
|
|
lResult = EDIT_WM_Paste(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case WM_SETCURSOR:
|
|
/*
|
|
* DPRINTF_EDIT_MSG32("WM_SETCURSOR");
|
|
*/
|
|
lResult = EDIT_WM_SetCursor(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case WM_SETFOCUS:
|
|
DPRINTF_EDIT_MSG32("WM_SETFOCUS");
|
|
lResult = EDIT_WM_SetFocus(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case WM_SETFONT:
|
|
DPRINTF_EDIT_MSG32("WM_SETFONT");
|
|
lResult = EDIT_WM_SetFont(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case WM_SETREDRAW:
|
|
DPRINTF_EDIT_MSG32("WM_SETREDRAW");
|
|
lResult = EDIT_WM_SetRedraw(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case WM_SETTEXT:
|
|
DPRINTF_EDIT_MSG32("WM_SETTEXT");
|
|
lResult = EDIT_WM_SetText(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case WM_SIZE:
|
|
DPRINTF_EDIT_MSG32("WM_SIZE");
|
|
lResult = EDIT_WM_Size(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case WM_SYSKEYDOWN:
|
|
DPRINTF_EDIT_MSG32("WM_SYSKEYDOWN");
|
|
lResult = EDIT_WM_SysKeyDown(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case WM_TIMER:
|
|
DPRINTF_EDIT_MSG32("WM_TIMER");
|
|
lResult = EDIT_WM_Timer(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
case WM_VSCROLL:
|
|
DPRINTF_EDIT_MSG32("WM_VSCROLL");
|
|
lResult = EDIT_WM_VScroll(wndPtr, wParam, lParam);
|
|
break;
|
|
|
|
default:
|
|
lResult = DefWindowProc32A(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);
|
|
LPSTR text = EDIT_GetPasswordPointer(wndPtr);
|
|
INT32 ww = EDIT_GetWndWidth(wndPtr);
|
|
HDC32 hdc;
|
|
HFONT32 hFont;
|
|
HFONT32 oldFont = 0;
|
|
LPSTR start, cp;
|
|
INT32 prev, next;
|
|
INT32 width;
|
|
INT32 length;
|
|
LINE_END ending;
|
|
|
|
hdc = GetDC32(wndPtr->hwndSelf);
|
|
hFont = (HFONT32)EDIT_WM_GetFont(wndPtr, 0, 0);
|
|
if (hFont) oldFont = SelectObject32(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, 0);
|
|
es->LineDefs[0].ending = END_0;
|
|
es->TextWidth = (INT32)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 = lstrlen32A(start);
|
|
} else if ((cp > start) && (*(cp - 1) == '\r')) {
|
|
ending = END_SOFT;
|
|
length = cp - start - 1;
|
|
} else {
|
|
ending = END_HARD;
|
|
length = cp - start;
|
|
}
|
|
width = (INT32)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 = (INT32)LOWORD(GetTabbedTextExtent(hdc, start, next,
|
|
es->NumTabStops, es->TabStops));
|
|
} while (width <= ww);
|
|
if (!prev) {
|
|
next = 0;
|
|
do {
|
|
prev = next;
|
|
next++;
|
|
width = (INT32)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 = (INT32)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) SelectObject32(hdc, oldFont);
|
|
ReleaseDC32(wndPtr->hwndSelf, hdc);
|
|
|
|
free(text);
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_CallWordBreakProc
|
|
*
|
|
* Call appropriate WordBreakProc (internal or external).
|
|
*
|
|
* FIXME: Heavily broken now that we have a LOCAL32 buffer.
|
|
* External wordbreak functions have been disabled in
|
|
* EM_SETWORDBREAKPROC.
|
|
*
|
|
*/
|
|
static INT32 EDIT_CallWordBreakProc(WND *wndPtr, LPSTR s, INT32 index, INT32 count, INT32 action)
|
|
{
|
|
return EDIT_WordBreakProc(s, index, count, action);
|
|
/*
|
|
* EDITWORDBREAKPROC wbp = (EDITWORDBREAKPROC)EDIT_EM_GetWordBreakProc(wndPtr, 0, 0);
|
|
*
|
|
* if (!wbp) return EDIT_WordBreakProc(s, index, count, action);
|
|
* else {
|
|
* EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
* SEGPTR ptr = LOCAL_LockSegptr( wndPtr->hInstance, es->hBuf16 ) +
|
|
* (INT16)(s - EDIT_GetPointer(wndPtr));
|
|
* INT ret = CallWordBreakProc( (FARPROC16)wbp, ptr,
|
|
* index, count, action);
|
|
* LOCAL_Unlock( wndPtr->hInstance, es->hBuf16 );
|
|
* return ret;
|
|
* }
|
|
*/
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_ColFromWndX
|
|
*
|
|
* Calculates, for a given line and X-coordinate on the screen, the column.
|
|
*
|
|
*/
|
|
static INT32 EDIT_ColFromWndX(WND *wndPtr, INT32 line, INT32 x)
|
|
{
|
|
INT32 lc = (INT32)EDIT_EM_GetLineCount(wndPtr, 0, 0);
|
|
INT32 li = (INT32)EDIT_EM_LineIndex(wndPtr, line, 0);
|
|
INT32 ll = (INT32)EDIT_EM_LineLength(wndPtr, li, 0);
|
|
INT32 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, 0);
|
|
EDIT_MoveEnd(wndPtr, TRUE);
|
|
EDIT_WM_Clear(wndPtr, 0, 0);
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_DelLeft
|
|
*
|
|
* Delete character to left of cursor.
|
|
*
|
|
*/
|
|
static void EDIT_DelLeft(WND *wndPtr)
|
|
{
|
|
EDIT_EM_SetSel(wndPtr, -1, 0);
|
|
EDIT_MoveBackward(wndPtr, TRUE);
|
|
EDIT_WM_Clear(wndPtr, 0, 0);
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_DelRight
|
|
*
|
|
* Delete character to right of cursor.
|
|
*
|
|
*/
|
|
static void EDIT_DelRight(WND *wndPtr)
|
|
{
|
|
EDIT_EM_SetSel(wndPtr, -1, 0);
|
|
EDIT_MoveForward(wndPtr, TRUE);
|
|
EDIT_WM_Clear(wndPtr, 0, 0);
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_GetAveCharWidth
|
|
*
|
|
*/
|
|
static INT32 EDIT_GetAveCharWidth(WND *wndPtr)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
return es->AveCharWidth;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_GetLineHeight
|
|
*
|
|
*/
|
|
static INT32 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, INT32 line, INT32 scol, INT32 ecol, LPRECT32 rc)
|
|
{
|
|
rc->top = EDIT_WndYFromLine(wndPtr, line);
|
|
rc->bottom = rc->top + EDIT_GetLineHeight(wndPtr);
|
|
rc->left = EDIT_WndXFromCol(wndPtr, line, scol);
|
|
rc->right = (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 LPSTR EDIT_GetPointer(WND *wndPtr)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
if (!es->text && (es->hBuf32 || es->hBuf16)) {
|
|
if (es->hBuf32)
|
|
es->text = (LPSTR)LocalLock32(es->hBuf32);
|
|
else
|
|
es->text = LOCAL_Lock(wndPtr->hInstance, es->hBuf16);
|
|
}
|
|
return es->text;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_GetPasswordPointer
|
|
*
|
|
*
|
|
*/
|
|
static LPSTR EDIT_GetPasswordPointer(WND *wndPtr)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
LPSTR text = xstrdup(EDIT_GetPointer(wndPtr));
|
|
LPSTR p;
|
|
|
|
if(es->PasswordChar) {
|
|
p = text;
|
|
while(*p != '\0') {
|
|
if(*p != '\r' && *p != '\n')
|
|
*p = es->PasswordChar;
|
|
p++;
|
|
}
|
|
}
|
|
return text;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_GetRedraw
|
|
*
|
|
*/
|
|
static BOOL32 EDIT_GetRedraw(WND *wndPtr)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
return es->Redraw;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_GetSel
|
|
*
|
|
* Beware: This is not the function called on EM_GETSEL.
|
|
* This is the unordered version used internally
|
|
* (s can be > e). No return value either.
|
|
*
|
|
*/
|
|
static void EDIT_GetSel(WND *wndPtr, LPINT32 s, LPINT32 e)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
if (s)
|
|
*s = es->SelStart;
|
|
if (e)
|
|
*e = es->SelEnd;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_GetTextWidth
|
|
*
|
|
*/
|
|
static INT32 EDIT_GetTextWidth(WND *wndPtr)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
return es->TextWidth;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_GetUndoPointer
|
|
*
|
|
* This acts as a LocalLock32(), but it locks only once. This way
|
|
* you can call it whenever you like, without unlocking.
|
|
*
|
|
*/
|
|
static LPSTR EDIT_GetUndoPointer(WND *wndPtr)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
if (!es->UndoText && es->hUndoBuf)
|
|
es->UndoText = (LPSTR)LocalLock32(es->hUndoBuf);
|
|
return es->UndoText;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_GetVisibleLineCount
|
|
*
|
|
*/
|
|
static INT32 EDIT_GetVisibleLineCount(WND *wndPtr)
|
|
{
|
|
RECT32 rc;
|
|
|
|
EDIT_EM_GetRect(wndPtr, 0, (LPARAM)&rc);
|
|
return MAX(1, MAX(rc.bottom - rc.top, 0) / EDIT_GetLineHeight(wndPtr));
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_GetWndWidth
|
|
*
|
|
*/
|
|
static INT32 EDIT_GetWndWidth(WND *wndPtr)
|
|
{
|
|
RECT32 rc;
|
|
|
|
EDIT_EM_GetRect(wndPtr, 0, (LPARAM)&rc);
|
|
return rc.right - rc.left;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_GetXOffset
|
|
*
|
|
*/
|
|
static INT32 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, INT32 start, INT32 end)
|
|
{
|
|
INT32 fv = (INT32)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0);
|
|
INT32 vlc = EDIT_GetVisibleLineCount(wndPtr);
|
|
INT32 sl;
|
|
INT32 el;
|
|
INT32 sc;
|
|
INT32 ec;
|
|
RECT32 rcWnd;
|
|
RECT32 rcLine;
|
|
RECT32 rcUpdate;
|
|
INT32 l;
|
|
|
|
if (end == start)
|
|
return;
|
|
|
|
if (end == -1)
|
|
end = (INT32)EDIT_WM_GetTextLength(wndPtr, 0, 0);
|
|
ORDER_INT32(start, end);
|
|
sl = (INT32)EDIT_EM_LineFromChar(wndPtr, start, 0);
|
|
el = (INT32)EDIT_EM_LineFromChar(wndPtr, end, 0);
|
|
if ((el < fv) || (sl > fv + vlc))
|
|
return;
|
|
|
|
sc = start - (INT32)EDIT_EM_LineIndex(wndPtr, sl, 0);
|
|
ec = end - (INT32)EDIT_EM_LineIndex(wndPtr, el, 0);
|
|
if (sl < fv) {
|
|
sl = fv;
|
|
sc = 0;
|
|
}
|
|
if (el > fv + vlc) {
|
|
el = fv + vlc;
|
|
ec = (INT32)EDIT_EM_LineLength(wndPtr,
|
|
(INT32)EDIT_EM_LineIndex(wndPtr, el, 0), 0);
|
|
}
|
|
EDIT_EM_GetRect(wndPtr, 0, (LPARAM)&rcWnd);
|
|
if (sl == el) {
|
|
EDIT_GetLineRect(wndPtr, sl, sc, ec, &rcLine);
|
|
if (IntersectRect32(&rcUpdate, &rcWnd, &rcLine))
|
|
InvalidateRect32( wndPtr->hwndSelf, &rcUpdate, FALSE );
|
|
} else {
|
|
EDIT_GetLineRect(wndPtr, sl, sc,
|
|
(INT32)EDIT_EM_LineLength(wndPtr,
|
|
(INT32)EDIT_EM_LineIndex(wndPtr, sl, 0), 0),
|
|
&rcLine);
|
|
if (IntersectRect32(&rcUpdate, &rcWnd, &rcLine))
|
|
InvalidateRect32( wndPtr->hwndSelf, &rcUpdate, FALSE );
|
|
for (l = sl + 1 ; l < el ; l++) {
|
|
EDIT_GetLineRect(wndPtr, l, 0,
|
|
(INT32)EDIT_EM_LineLength(wndPtr,
|
|
(INT32)EDIT_EM_LineIndex(wndPtr, l, 0), 0),
|
|
&rcLine);
|
|
if (IntersectRect32(&rcUpdate, &rcWnd, &rcLine))
|
|
InvalidateRect32(wndPtr->hwndSelf, &rcUpdate, FALSE);
|
|
}
|
|
EDIT_GetLineRect(wndPtr, el, 0, ec, &rcLine);
|
|
if (IntersectRect32(&rcUpdate, &rcWnd, &rcLine))
|
|
InvalidateRect32( wndPtr->hwndSelf, &rcUpdate, FALSE );
|
|
}
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_LineFromWndY
|
|
*
|
|
* Calculates, for a given Y-coordinate on the screen, the line.
|
|
*
|
|
*/
|
|
static INT32 EDIT_LineFromWndY(WND *wndPtr, INT32 y)
|
|
{
|
|
INT32 fv = (INT32)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0);
|
|
INT32 lh = EDIT_GetLineHeight(wndPtr);
|
|
INT32 lc = (INT32)EDIT_EM_GetLineCount(wndPtr, 0, 0);
|
|
|
|
return MAX(0, MIN(lc - 1, y / lh + fv));
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_MakeFit
|
|
*
|
|
* Try to fit size + 1 bytes in the buffer. Constrain to limits.
|
|
*
|
|
*/
|
|
static BOOL32 EDIT_MakeFit(WND *wndPtr, INT32 size)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
HLOCAL32 hNew32;
|
|
HLOCAL16 hNew16;
|
|
|
|
if (size <= es->BufSize)
|
|
return TRUE;
|
|
if (size > es->BufLimit) {
|
|
dprintf_edit(stddeb, "edit: notification EN_MAXTEXT sent\n");
|
|
EDIT_NOTIFY_PARENT(wndPtr, EN_MAXTEXT);
|
|
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);
|
|
|
|
EDIT_ReleasePointer(wndPtr);
|
|
if (es->hBuf32) {
|
|
if ((hNew32 = LocalReAlloc32(es->hBuf32, size + 1, 0))) {
|
|
dprintf_edit(stddeb, "edit: EDIT_MakeFit: Old 32 bit handle %08x, new handle %08x\n", es->hBuf32, hNew32);
|
|
es->hBuf32 = hNew32;
|
|
es->BufSize = MIN(LocalSize32(es->hBuf32) - 1, es->BufLimit);
|
|
if (es->BufSize < size) {
|
|
dprintf_edit(stddeb, "edit: EDIT_MakeFit: FAILED ! We now have %d+1\n", es->BufSize);
|
|
dprintf_edit(stddeb, "edit: notification EN_ERRSPACE sent\n");
|
|
EDIT_NOTIFY_PARENT(wndPtr, EN_ERRSPACE);
|
|
return FALSE;
|
|
}
|
|
dprintf_edit(stddeb, "edit: EDIT_MakeFit: We now have %d+1\n", es->BufSize);
|
|
return TRUE;
|
|
}
|
|
} else {
|
|
if ((hNew16 = LOCAL_ReAlloc(wndPtr->hInstance, es->hBuf16, size + 1, LMEM_MOVEABLE))) {
|
|
dprintf_edit(stddeb, "edit: EDIT_MakeFit: Old 16 bit handle %08x, new handle %08x\n", es->hBuf16, hNew16);
|
|
es->hBuf16 = hNew16;
|
|
es->BufSize = MIN(LOCAL_Size(wndPtr->hInstance, es->hBuf16) - 1, es->BufLimit);
|
|
if (es->BufSize < size) {
|
|
dprintf_edit(stddeb, "edit: EDIT_MakeFit: FAILED ! We now have %d+1\n", es->BufSize);
|
|
dprintf_edit(stddeb, "edit: notification EN_ERRSPACE sent\n");
|
|
EDIT_NOTIFY_PARENT(wndPtr, EN_ERRSPACE);
|
|
return FALSE;
|
|
}
|
|
dprintf_edit(stddeb, "edit: EDIT_MakeFit: We now have %d+1\n", es->BufSize);
|
|
return TRUE;
|
|
}
|
|
}
|
|
dprintf_edit(stddeb, "edit: EDIT_MakeFit: Reallocation failed\n");
|
|
dprintf_edit(stddeb, "edit: notification EN_ERRSPACE sent\n");
|
|
EDIT_NOTIFY_PARENT(wndPtr, EN_ERRSPACE);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_MakeUndoFit
|
|
*
|
|
* Try to fit size + 1 bytes in the undo buffer.
|
|
*
|
|
*/
|
|
static BOOL32 EDIT_MakeUndoFit(WND *wndPtr, INT32 size)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
HLOCAL32 hNew;
|
|
|
|
if (size <= es->UndoBufSize)
|
|
return TRUE;
|
|
size = ((size / GROWLENGTH) + 1) * GROWLENGTH;
|
|
|
|
dprintf_edit(stddeb, "edit: EDIT_MakeUndoFit: trying to ReAlloc to %d+1\n", size);
|
|
|
|
EDIT_ReleaseUndoPointer(wndPtr);
|
|
if ((hNew = LocalReAlloc32(es->hUndoBuf, size + 1, 0))) {
|
|
dprintf_edit(stddeb, "edit: EDIT_MakeUndoFit: Old handle %08x, new handle %08x\n", es->hUndoBuf, hNew);
|
|
es->hUndoBuf = hNew;
|
|
es->UndoBufSize = LocalSize32(es->hUndoBuf) - 1;
|
|
if (es->UndoBufSize < size) {
|
|
dprintf_edit(stddeb, "edit: EDIT_MakeUndoFit: FAILED ! We now have %d+1\n", es->UndoBufSize);
|
|
return FALSE;
|
|
}
|
|
dprintf_edit(stddeb, "edit: EDIT_MakeUndoFit: We now have %d+1\n", es->UndoBufSize);
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_MoveBackward
|
|
*
|
|
*/
|
|
static void EDIT_MoveBackward(WND *wndPtr, BOOL32 extend)
|
|
{
|
|
INT32 s;
|
|
INT32 e;
|
|
INT32 l;
|
|
INT32 li;
|
|
|
|
EDIT_GetSel(wndPtr, &s, &e);
|
|
l = (INT32)EDIT_EM_LineFromChar(wndPtr, e, 0);
|
|
li = (INT32)EDIT_EM_LineIndex(wndPtr, l, 0);
|
|
if (e - li == 0) {
|
|
if (l) {
|
|
li = (INT32)EDIT_EM_LineIndex(wndPtr, l - 1, 0);
|
|
e = li + (INT32)EDIT_EM_LineLength(wndPtr, li, 0);
|
|
}
|
|
} else
|
|
e--;
|
|
if (!extend)
|
|
s = e;
|
|
EDIT_SetSel(wndPtr, s, e);
|
|
EDIT_EM_ScrollCaret(wndPtr, 0, 0);
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_MoveDownward
|
|
*
|
|
*/
|
|
static void EDIT_MoveDownward(WND *wndPtr, BOOL32 extend)
|
|
{
|
|
INT32 s;
|
|
INT32 e;
|
|
INT32 l;
|
|
INT32 lc;
|
|
INT32 li;
|
|
INT32 x;
|
|
|
|
EDIT_GetSel(wndPtr, &s, &e);
|
|
l = (INT32)EDIT_EM_LineFromChar(wndPtr, e, 0);
|
|
lc = (INT32)EDIT_EM_GetLineCount(wndPtr, e, 0);
|
|
li = (INT32)EDIT_EM_LineIndex(wndPtr, l, 0);
|
|
if (l < lc - 1) {
|
|
x = EDIT_WndXFromCol(wndPtr, l, e - li);
|
|
l++;
|
|
e = (INT32)EDIT_EM_LineIndex(wndPtr, l, 0) +
|
|
EDIT_ColFromWndX(wndPtr, l, x);
|
|
}
|
|
if (!extend)
|
|
s = e;
|
|
EDIT_SetSel(wndPtr, s, e);
|
|
EDIT_EM_ScrollCaret(wndPtr, 0, 0);
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_MoveEnd
|
|
*
|
|
*/
|
|
static void EDIT_MoveEnd(WND *wndPtr, BOOL32 extend)
|
|
{
|
|
INT32 s;
|
|
INT32 e;
|
|
INT32 l;
|
|
INT32 ll;
|
|
INT32 li;
|
|
|
|
EDIT_GetSel(wndPtr, &s, &e);
|
|
l = (INT32)EDIT_EM_LineFromChar(wndPtr, e, 0);
|
|
ll = (INT32)EDIT_EM_LineLength(wndPtr, e, 0);
|
|
li = (INT32)EDIT_EM_LineIndex(wndPtr, l, 0);
|
|
e = li + ll;
|
|
if (!extend)
|
|
s = e;
|
|
EDIT_SetSel(wndPtr, s, e);
|
|
EDIT_EM_ScrollCaret(wndPtr, 0, 0);
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_MoveForward
|
|
*
|
|
*/
|
|
static void EDIT_MoveForward(WND *wndPtr, BOOL32 extend)
|
|
{
|
|
INT32 s;
|
|
INT32 e;
|
|
INT32 l;
|
|
INT32 lc;
|
|
INT32 ll;
|
|
INT32 li;
|
|
|
|
EDIT_GetSel(wndPtr, &s, &e);
|
|
l = (INT32)EDIT_EM_LineFromChar(wndPtr, e, 0);
|
|
lc = (INT32)EDIT_EM_GetLineCount(wndPtr, e, 0);
|
|
ll = (INT32)EDIT_EM_LineLength(wndPtr, e, 0);
|
|
li = (INT32)EDIT_EM_LineIndex(wndPtr, l, 0);
|
|
if (e - li == ll) {
|
|
if (l != lc - 1)
|
|
e = (INT32)EDIT_EM_LineIndex(wndPtr, l + 1, 0);
|
|
} else
|
|
e++;
|
|
if (!extend)
|
|
s = e;
|
|
EDIT_SetSel(wndPtr, s, e);
|
|
EDIT_EM_ScrollCaret(wndPtr, 0, 0);
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_MoveHome
|
|
*
|
|
* Home key: move to beginning of line.
|
|
*
|
|
*/
|
|
static void EDIT_MoveHome(WND *wndPtr, BOOL32 extend)
|
|
{
|
|
INT32 s;
|
|
INT32 e;
|
|
INT32 l;
|
|
INT32 li;
|
|
|
|
EDIT_GetSel(wndPtr, &s, &e);
|
|
l = (INT32)EDIT_EM_LineFromChar(wndPtr, e, 0);
|
|
li = (INT32)EDIT_EM_LineIndex(wndPtr, l, 0);
|
|
e = li;
|
|
if (!extend)
|
|
s = e;
|
|
EDIT_SetSel(wndPtr, s, e);
|
|
EDIT_EM_ScrollCaret(wndPtr, 0, 0);
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_MovePageDown
|
|
*
|
|
*/
|
|
static void EDIT_MovePageDown(WND *wndPtr, BOOL32 extend)
|
|
{
|
|
INT32 s;
|
|
INT32 e;
|
|
INT32 l;
|
|
INT32 lc;
|
|
INT32 li;
|
|
INT32 x;
|
|
|
|
EDIT_GetSel(wndPtr, &s, &e);
|
|
l = (INT32)EDIT_EM_LineFromChar(wndPtr, e, 0);
|
|
lc = (INT32)EDIT_EM_GetLineCount(wndPtr, e, 0);
|
|
li = (INT32)EDIT_EM_LineIndex(wndPtr, l, 0);
|
|
if (l < lc - 1) {
|
|
x = EDIT_WndXFromCol(wndPtr, l, e - li);
|
|
l = MIN(lc - 1, l + EDIT_GetVisibleLineCount(wndPtr));
|
|
e = (INT32)EDIT_EM_LineIndex(wndPtr, l, 0) +
|
|
EDIT_ColFromWndX(wndPtr, l, x);
|
|
}
|
|
if (!extend)
|
|
s = e;
|
|
EDIT_SetSel(wndPtr, s, e);
|
|
EDIT_EM_ScrollCaret(wndPtr, 0, 0);
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_MovePageUp
|
|
*
|
|
*/
|
|
static void EDIT_MovePageUp(WND *wndPtr, BOOL32 extend)
|
|
{
|
|
INT32 s;
|
|
INT32 e;
|
|
INT32 l;
|
|
INT32 li;
|
|
INT32 x;
|
|
|
|
EDIT_GetSel(wndPtr, &s, &e);
|
|
l = (INT32)EDIT_EM_LineFromChar(wndPtr, e, 0);
|
|
li = (INT32)EDIT_EM_LineIndex(wndPtr, l, 0);
|
|
if (l) {
|
|
x = EDIT_WndXFromCol(wndPtr, l, e - li);
|
|
l = MAX(0, l - EDIT_GetVisibleLineCount(wndPtr));
|
|
e = (INT32)EDIT_EM_LineIndex(wndPtr, l, 0) +
|
|
EDIT_ColFromWndX(wndPtr, l, x);
|
|
}
|
|
if (!extend)
|
|
s = e;
|
|
EDIT_SetSel(wndPtr, s, e);
|
|
EDIT_EM_ScrollCaret(wndPtr, 0, 0);
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_MoveUpward
|
|
*
|
|
*/
|
|
static void EDIT_MoveUpward(WND *wndPtr, BOOL32 extend)
|
|
{
|
|
INT32 s;
|
|
INT32 e;
|
|
INT32 l;
|
|
INT32 li;
|
|
INT32 x;
|
|
|
|
EDIT_GetSel(wndPtr, &s, &e);
|
|
l = (INT32)EDIT_EM_LineFromChar(wndPtr, e, 0);
|
|
li = (INT32)EDIT_EM_LineIndex(wndPtr, l, 0);
|
|
if (l) {
|
|
x = EDIT_WndXFromCol(wndPtr, l, e - li);
|
|
l--;
|
|
e = (INT32)EDIT_EM_LineIndex(wndPtr, l, 0) +
|
|
EDIT_ColFromWndX(wndPtr, l, x);
|
|
}
|
|
if (!extend)
|
|
s = e;
|
|
EDIT_SetSel(wndPtr, s, e);
|
|
EDIT_EM_ScrollCaret(wndPtr, 0, 0);
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_MoveWordBackward
|
|
*
|
|
*/
|
|
static void EDIT_MoveWordBackward(WND *wndPtr, BOOL32 extend)
|
|
{
|
|
INT32 s;
|
|
INT32 e;
|
|
INT32 l;
|
|
INT32 ll;
|
|
INT32 li;
|
|
LPSTR text;
|
|
|
|
EDIT_GetSel(wndPtr, &s, &e);
|
|
l = (INT32)EDIT_EM_LineFromChar(wndPtr, e, 0);
|
|
ll = (INT32)EDIT_EM_LineLength(wndPtr, e, 0);
|
|
li = (INT32)EDIT_EM_LineIndex(wndPtr, l, 0);
|
|
if (e - li == 0) {
|
|
if (l) {
|
|
li = (INT32)EDIT_EM_LineIndex(wndPtr, l - 1, 0);
|
|
e = li + (INT32)EDIT_EM_LineLength(wndPtr, li, 0);
|
|
}
|
|
} else {
|
|
text = EDIT_GetPointer(wndPtr);
|
|
e = li + (INT32)EDIT_CallWordBreakProc(wndPtr,
|
|
text + li, e - li, ll, WB_LEFT);
|
|
}
|
|
if (!extend)
|
|
s = e;
|
|
EDIT_SetSel(wndPtr, s, e);
|
|
EDIT_EM_ScrollCaret(wndPtr, 0, 0);
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_MoveWordForward
|
|
*
|
|
*/
|
|
static void EDIT_MoveWordForward(WND *wndPtr, BOOL32 extend)
|
|
{
|
|
INT32 s;
|
|
INT32 e;
|
|
INT32 l;
|
|
INT32 lc;
|
|
INT32 ll;
|
|
INT32 li;
|
|
LPSTR text;
|
|
|
|
EDIT_GetSel(wndPtr, &s, &e);
|
|
l = (INT32)EDIT_EM_LineFromChar(wndPtr, e, 0);
|
|
lc = (INT32)EDIT_EM_GetLineCount(wndPtr, e, 0);
|
|
ll = (INT32)EDIT_EM_LineLength(wndPtr, e, 0);
|
|
li = (INT32)EDIT_EM_LineIndex(wndPtr, l, 0);
|
|
if (e - li == ll) {
|
|
if (l != lc - 1)
|
|
e = (INT32)EDIT_EM_LineIndex(wndPtr, l + 1, 0);
|
|
} else {
|
|
text = EDIT_GetPointer(wndPtr);
|
|
e = li + EDIT_CallWordBreakProc(wndPtr,
|
|
text + li, e - li + 1, ll, WB_RIGHT);
|
|
}
|
|
if (!extend)
|
|
s = e;
|
|
EDIT_SetSel(wndPtr, s, e);
|
|
EDIT_EM_ScrollCaret(wndPtr, 0, 0);
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_PaintLine
|
|
*
|
|
*/
|
|
static void EDIT_PaintLine(WND *wndPtr, HDC32 hdc, INT32 line, BOOL32 rev)
|
|
{
|
|
INT32 fv = (INT32)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0);
|
|
INT32 vlc = EDIT_GetVisibleLineCount(wndPtr);
|
|
INT32 lc = (INT32)EDIT_EM_GetLineCount(wndPtr, 0, 0);
|
|
INT32 li;
|
|
INT32 ll;
|
|
INT32 s;
|
|
INT32 e;
|
|
INT32 x;
|
|
INT32 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 = (INT32)EDIT_EM_LineIndex(wndPtr, line, 0);
|
|
ll = (INT32)EDIT_EM_LineLength(wndPtr, li, 0);
|
|
EDIT_GetSel(wndPtr, &s, &e);
|
|
ORDER_INT32(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 INT32 EDIT_PaintText(WND *wndPtr, HDC32 hdc, INT32 x, INT32 y, INT32 line, INT32 col, INT32 count, BOOL32 rev)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
COLORREF BkColor;
|
|
COLORREF TextColor;
|
|
INT32 ret;
|
|
LPSTR text;
|
|
INT32 li;
|
|
INT32 xoff;
|
|
|
|
if (!count)
|
|
return 0;
|
|
BkColor = GetBkColor32(hdc);
|
|
TextColor = GetTextColor32(hdc);
|
|
if (rev) {
|
|
SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
|
|
SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
|
|
}
|
|
text = EDIT_GetPasswordPointer(wndPtr);
|
|
li = (INT32)EDIT_EM_LineIndex(wndPtr, line, 0);
|
|
xoff = EDIT_GetXOffset(wndPtr);
|
|
ret = (INT32)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->hBuf32 || es->hBuf16)) {
|
|
if (es->hBuf32)
|
|
LocalUnlock32(es->hBuf32);
|
|
else
|
|
LOCAL_Unlock(wndPtr->hInstance, es->hBuf16);
|
|
}
|
|
es->text = NULL;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_ReleaseUndoPointer
|
|
*
|
|
* 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_ReleaseUndoPointer(WND *wndPtr)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
if (!es)
|
|
return;
|
|
if (es->UndoText && es->hUndoBuf)
|
|
LocalUnlock32(es->hUndoBuf);
|
|
es->UndoText = NULL;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_SetSel
|
|
*
|
|
* Beware: This is not the function called on EM_SETSEL.
|
|
* This is the unordered version used internally
|
|
* (s can be > e). Doesn't accept -1 parameters either.
|
|
* No range checking.
|
|
*
|
|
*/
|
|
static void EDIT_SetSel(WND *wndPtr, INT32 ns, INT32 ne)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
LRESULT pos;
|
|
INT32 s;
|
|
INT32 e;
|
|
|
|
EDIT_EM_GetSel(wndPtr, (WPARAM32)&s, (LPARAM)&e);
|
|
es->SelStart = ns;
|
|
es->SelEnd = ne;
|
|
if (EDIT_GetRedraw(wndPtr)) {
|
|
if (wndPtr->hwndSelf == GetFocus32()) {
|
|
pos = EDIT_EM_PosFromChar(wndPtr, ne, 0);
|
|
SetCaretPos((INT16)LOWORD(pos), (INT16)HIWORD(pos));
|
|
}
|
|
ORDER_INT32(s, ns);
|
|
ORDER_INT32(s, ne);
|
|
ORDER_INT32(e, ns);
|
|
ORDER_INT32(e, ne);
|
|
ORDER_INT32(ns, ne);
|
|
if (e != ns) {
|
|
EDIT_InvalidateText(wndPtr, s, e);
|
|
EDIT_InvalidateText(wndPtr, ns, ne);
|
|
} else
|
|
EDIT_InvalidateText(wndPtr, s, ne);
|
|
}
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_WndXFromCol
|
|
*
|
|
* Calculates, for a given line and column, the X-coordinate on the screen.
|
|
*
|
|
*/
|
|
static INT32 EDIT_WndXFromCol(WND *wndPtr, INT32 line, INT32 col)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
LPSTR text = EDIT_GetPasswordPointer(wndPtr);
|
|
INT32 ret;
|
|
HDC32 hdc;
|
|
HFONT32 hFont;
|
|
HFONT32 oldFont = 0;
|
|
INT32 lc = (INT32)EDIT_EM_GetLineCount(wndPtr, 0, 0);
|
|
INT32 li = (INT32)EDIT_EM_LineIndex(wndPtr, line, 0);
|
|
INT32 ll = (INT32)EDIT_EM_LineLength(wndPtr, li, 0);
|
|
INT32 xoff = EDIT_GetXOffset(wndPtr);
|
|
|
|
hdc = GetDC32(wndPtr->hwndSelf);
|
|
hFont = (HFONT32)EDIT_WM_GetFont(wndPtr, 0, 0);
|
|
if (hFont) oldFont = SelectObject32(hdc, hFont);
|
|
line = MAX(0, MIN(line, lc - 1));
|
|
col = MIN(col, ll);
|
|
ret = (INT32)LOWORD(GetTabbedTextExtent(hdc,
|
|
text + li, col,
|
|
es->NumTabStops, es->TabStops)) - xoff;
|
|
if (hFont) SelectObject32(hdc, oldFont);
|
|
ReleaseDC32(wndPtr->hwndSelf, hdc);
|
|
free(text);
|
|
return ret;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EDIT_WndYFromLine
|
|
*
|
|
* Calculates, for a given line, the Y-coordinate on the screen.
|
|
*
|
|
*/
|
|
static INT32 EDIT_WndYFromLine(WND *wndPtr, INT32 line)
|
|
{
|
|
INT32 fv = (INT32)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0);
|
|
INT32 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 INT32 EDIT_WordBreakProc(LPSTR s, INT32 index, INT32 count, INT32 action)
|
|
{
|
|
INT32 ret = 0;
|
|
|
|
dprintf_edit(stddeb, "edit: EDIT_WordBreakProc: s=%p, index=%u"
|
|
", count=%u, 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, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
return (LRESULT)(es->UndoInsertLen || lstrlen32A(EDIT_GetUndoPointer(wndPtr)));
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_CHARFROMPOS
|
|
*
|
|
* FIXME: do the specs mean LineIndex or LineNumber (li v.s. l) ???
|
|
*/
|
|
static LRESULT EDIT_EM_CharFromPos(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
POINT32 pt;
|
|
RECT32 rc;
|
|
INT32 l;
|
|
INT32 li;
|
|
INT32 c;
|
|
|
|
pt.x = LOWORD(lParam);
|
|
pt.y = HIWORD(lParam);
|
|
GetClientRect32(wndPtr->hwndSelf, &rc);
|
|
|
|
if (!PtInRect32(&rc, pt))
|
|
return -1;
|
|
|
|
l = EDIT_LineFromWndY(wndPtr, pt.y);
|
|
li = EDIT_EM_LineIndex(wndPtr, l, 0);
|
|
c = EDIT_ColFromWndX(wndPtr, l, pt.x);
|
|
|
|
return (LRESULT)MAKELONG(li + c, li);
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_EMPTYUNDOBUFFER
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_EmptyUndoBuffer(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
es->UndoInsertLen = 0;
|
|
*EDIT_GetUndoPointer(wndPtr) = '\0';
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_FMTLINES
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_FmtLines(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
fprintf(stdnimp, "edit: EM_FMTLINES: message not implemented\n");
|
|
return wParam ? TRUE : FALSE;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_GETFIRSTVISIBLELINE
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_GetFirstVisibleLine(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
if (IsMultiLine(wndPtr))
|
|
return (LRESULT)es->FirstVisibleLine;
|
|
else
|
|
return (LRESULT)EDIT_ColFromWndX(wndPtr, 0, 0);
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_GETHANDLE
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_GetHandle(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
if (!IsMultiLine(wndPtr))
|
|
return 0;
|
|
|
|
if (es->hBuf32)
|
|
return (LRESULT)es->hBuf32;
|
|
else
|
|
return (LRESULT)es->hBuf16;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_GETHANDLE16
|
|
*
|
|
* Hopefully this won't fire back at us.
|
|
* We always start with a buffer in 32 bit linear memory.
|
|
* However, with this message a 16 bit application requests
|
|
* a handle of 16 bit local heap memory, where it expects to find
|
|
* the text.
|
|
* It's a pitty that from this moment on we have to use this
|
|
* local heap, because applications may rely on the handle
|
|
* in the future.
|
|
*
|
|
* In this function we'll try to switch to local heap.
|
|
*/
|
|
static LRESULT EDIT_EM_GetHandle16(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
LPSTR text;
|
|
HLOCAL16 newBuf;
|
|
LPSTR newText;
|
|
INT16 newSize;
|
|
|
|
if (!IsMultiLine(wndPtr))
|
|
return 0;
|
|
|
|
if (es->hBuf16)
|
|
return (LRESULT)es->hBuf16;
|
|
|
|
if (!LOCAL_HeapSize(wndPtr->hInstance)) {
|
|
if (!LocalInit(wndPtr->hInstance, 0,
|
|
GlobalSize16(wndPtr->hInstance))) {
|
|
fprintf(stderr, "edit: EM_GETHANDLE: could not initialize local heap\n");
|
|
return 0;
|
|
}
|
|
dprintf_edit(stddeb, "edit: EM_GETHANDLE: local heap initialized\n");
|
|
}
|
|
if (!(newBuf = LOCAL_Alloc(wndPtr->hInstance,
|
|
EDIT_WM_GetTextLength(wndPtr, 0, 0) + 1,
|
|
LMEM_MOVEABLE))) {
|
|
fprintf(stderr, "edit: EM_GETHANDLE: could not allocate new 16 bit buffer\n");
|
|
return 0;
|
|
}
|
|
newSize = MIN(LOCAL_Size(wndPtr->hInstance, newBuf) - 1, es->BufLimit);
|
|
if (!(newText = LOCAL_Lock(wndPtr->hInstance, newBuf))) {
|
|
fprintf(stderr, "edit: EM_GETHANDLE: could not lock new 16 bit buffer\n");
|
|
LOCAL_Free(wndPtr->hInstance, newBuf);
|
|
return 0;
|
|
}
|
|
text = EDIT_GetPointer(wndPtr);
|
|
lstrcpy32A(newText, text);
|
|
EDIT_ReleasePointer(wndPtr);
|
|
GlobalFree32(es->hBuf32);
|
|
es->hBuf32 = (HLOCAL32)NULL;
|
|
es->hBuf16 = newBuf;
|
|
es->BufSize = newSize;
|
|
es->text = newText;
|
|
dprintf_edit(stddeb, "edit: EM_GETHANDLE: switched to 16 bit buffer\n");
|
|
|
|
return (LRESULT)es->hBuf16;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_GETLIMITTEXT
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_GetLimitText(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
return es->BufLimit;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_GETLINE
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_GetLine(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
LPSTR text;
|
|
LPSTR src;
|
|
LPSTR dst;
|
|
INT32 len;
|
|
INT32 i;
|
|
INT32 lc = (INT32)EDIT_EM_GetLineCount(wndPtr, 0, 0);
|
|
|
|
if (!IsMultiLine(wndPtr))
|
|
wParam = 0;
|
|
if ((INT32)wParam >= lc)
|
|
return 0;
|
|
text = EDIT_GetPointer(wndPtr);
|
|
src = text + (INT32)EDIT_EM_LineIndex(wndPtr, wParam, 0);
|
|
dst = (LPSTR)lParam;
|
|
len = MIN(*(WORD *)dst, (INT32)EDIT_EM_LineLength(wndPtr, wParam, 0));
|
|
for (i = 0 ; i < len ; i++) {
|
|
*dst = *src;
|
|
src++;
|
|
dst++;
|
|
}
|
|
return (LRESULT)len;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_GETLINECOUNT
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_GetLineCount(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
return (LRESULT)es->LineCount;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_GETMARGINS
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_GetMargins(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
return (LRESULT)MAKELONG(es->LeftMargin, es->RightMargin);
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_GETMODIFY
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_GetModify(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
return (LRESULT)es->TextChanged;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_GETPASSWORDCHAR
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_GetPasswordChar(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
return (LRESULT)es->PasswordChar;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_GETRECT
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_GetRect(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
CopyRect32((LPRECT32)lParam, &es->FormatRect);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_GETRECT16
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_GetRect16(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
CONV_RECT32TO16(&es->FormatRect, (LPRECT16)PTR_SEG_TO_LIN((SEGPTR)lParam));
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_GETSEL
|
|
*
|
|
* Returns the ordered selection range so that
|
|
* LOWORD(result) < HIWORD(result)
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_GetSel(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
INT32 s;
|
|
INT32 e;
|
|
|
|
EDIT_GetSel(wndPtr, &s, &e);
|
|
ORDER_INT32(s, e);
|
|
if (wParam)
|
|
*(LPINT32)wParam = s;
|
|
if (lParam)
|
|
*(LPINT32)lParam = e;
|
|
return MAKELONG((INT16)s, (INT16)e);
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_GETTHUMB
|
|
*
|
|
* FIXME: is this right ? (or should it be only HSCROLL)
|
|
* (and maybe only for edit controls that really have their
|
|
* own scrollbars) (and maybe only for multiline controls ?)
|
|
* All in all: very poorly documented
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_GetThumb(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
return MAKELONG(EDIT_WM_VScroll(wndPtr, EM_GETTHUMB16, 0),
|
|
EDIT_WM_HScroll(wndPtr, EM_GETTHUMB16, 0));
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_GETWORDBREAKPROC
|
|
*
|
|
* FIXME: Application defined WordBreakProc should be returned
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_GetWordBreakProc(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
/*
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
return (LRESULT)es->WordBreakProc;
|
|
*/
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_LINEFROMCHAR
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_LineFromChar(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
INT32 l;
|
|
|
|
if (!IsMultiLine(wndPtr))
|
|
return 0;
|
|
if ((INT32)wParam == -1)
|
|
EDIT_EM_GetSel(wndPtr, (WPARAM32)&wParam, 0); /* intentional (looks weird, doesn't it ?) */
|
|
l = (INT32)EDIT_EM_GetLineCount(wndPtr, 0, 0) - 1;
|
|
while ((INT32)EDIT_EM_LineIndex(wndPtr, l, 0) > (INT32)wParam)
|
|
l--;
|
|
return (LRESULT)l;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_LINEINDEX
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_LineIndex(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
INT32 e;
|
|
INT32 l;
|
|
INT32 lc = (INT32)EDIT_EM_GetLineCount(wndPtr, 0, 0);
|
|
|
|
if ((INT32)wParam == -1) {
|
|
EDIT_GetSel(wndPtr, NULL, &e);
|
|
l = lc - 1;
|
|
while (es->LineDefs[l].offset > e)
|
|
l--;
|
|
return (LRESULT)es->LineDefs[l].offset;
|
|
}
|
|
if ((INT32)wParam >= lc)
|
|
return -1;
|
|
return (LRESULT)es->LineDefs[(INT32)wParam].offset;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_LINELENGTH
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_LineLength(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
INT32 s;
|
|
INT32 e;
|
|
INT32 sl;
|
|
INT32 el;
|
|
|
|
if (!IsMultiLine(wndPtr))
|
|
return (LRESULT)es->LineDefs[0].length;
|
|
if ((INT32)wParam == -1) {
|
|
EDIT_GetSel(wndPtr, &s, &e);
|
|
sl = (INT32)EDIT_EM_LineFromChar(wndPtr, s, 0);
|
|
el = (INT32)EDIT_EM_LineFromChar(wndPtr, e, 0);
|
|
return (LRESULT)(s - es->LineDefs[sl].offset +
|
|
es->LineDefs[el].offset +
|
|
es->LineDefs[el].length - e);
|
|
}
|
|
return (LRESULT)es->LineDefs[(INT32)EDIT_EM_LineFromChar(wndPtr, wParam, 0)].length;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_LINESCROLL
|
|
*
|
|
* FIXME: is wParam in pixels or in average character widths ???
|
|
* FIXME: we use this internally to scroll single line controls as well
|
|
* (specs are vague about whether this message is valid or not for
|
|
* single line controls)
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_LineScroll(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
INT32 lc = (INT32)EDIT_EM_GetLineCount(wndPtr, 0, 0);
|
|
INT32 fv = (INT32)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0);
|
|
INT32 nfv = MAX(0, fv + (INT32)lParam);
|
|
INT32 xoff = EDIT_GetXOffset(wndPtr);
|
|
INT32 nxoff = MAX(0, xoff + (INT32)wParam);
|
|
INT32 tw = EDIT_GetTextWidth(wndPtr);
|
|
INT32 dx;
|
|
INT32 dy;
|
|
|
|
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 (EDIT_GetRedraw(wndPtr))
|
|
ScrollWindow32(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_GETTHUMB16, 0), TRUE);
|
|
if (IsHScrollBar(wndPtr))
|
|
SetScrollPos32(wndPtr->hwndSelf, SB_HORZ,
|
|
EDIT_WM_HScroll(wndPtr, EM_GETTHUMB16, 0), TRUE);
|
|
}
|
|
if (IsMultiLine(wndPtr))
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_POSFROMCHAR
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_PosFromChar(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
INT32 len = (INT32)EDIT_WM_GetTextLength(wndPtr, 0, 0);
|
|
INT32 l;
|
|
INT32 li;
|
|
|
|
wParam = MIN(wParam, len);
|
|
l = EDIT_EM_LineFromChar(wndPtr, wParam, 0);
|
|
li = EDIT_EM_LineIndex(wndPtr, l, 0);
|
|
return (LRESULT)MAKELONG(EDIT_WndXFromCol(wndPtr, l, wParam - li),
|
|
EDIT_WndYFromLine(wndPtr, l));
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_REPLACESEL
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_ReplaceSel(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
LPCSTR str = (LPCSTR)lParam;
|
|
INT32 strl = lstrlen32A(str);
|
|
INT32 tl = (INT32)EDIT_WM_GetTextLength(wndPtr, 0, 0);
|
|
INT32 utl;
|
|
INT32 s;
|
|
INT32 e;
|
|
INT32 i;
|
|
LPSTR p;
|
|
LPSTR text;
|
|
LPSTR utext;
|
|
BOOL32 redraw;
|
|
|
|
EDIT_EM_GetSel(wndPtr, (WPARAM32)&s, (LPARAM)&e);
|
|
|
|
if ((s == e) && !strl)
|
|
return 0;
|
|
|
|
if (!EDIT_MakeFit(wndPtr, tl - (e - s) + strl))
|
|
return 0;
|
|
|
|
text = EDIT_GetPointer(wndPtr);
|
|
utext = EDIT_GetUndoPointer(wndPtr);
|
|
if (e != s) {
|
|
/* there is something to be deleted */
|
|
if ((BOOL32)wParam) {
|
|
/* we have to be able to undo */
|
|
utl = lstrlen32A(utext);
|
|
if (!es->UndoInsertLen && (*utext && (s == es->UndoPos))) {
|
|
/* undo-buffer is extended to the right */
|
|
EDIT_MakeUndoFit(wndPtr, utl + e - s);
|
|
lstrcpyn32A(utext + utl, text + s, e - s + 1);
|
|
} else if (!es->UndoInsertLen && (*utext && (e == es->UndoPos))) {
|
|
/* undo-buffer is extended to the left */
|
|
EDIT_MakeUndoFit(wndPtr, utl + e - s);
|
|
for (p = utext + utl ; p >= utext ; p--)
|
|
p[e - s] = p[0];
|
|
for (i = 0 , p = utext ; i < e - s ; i++)
|
|
p[i] = (text + s)[i];
|
|
es->UndoPos = s;
|
|
} else {
|
|
/* new undo-buffer */
|
|
EDIT_MakeUndoFit(wndPtr, e - s);
|
|
lstrcpyn32A(utext, text + s, e - s + 1);
|
|
es->UndoPos = s;
|
|
}
|
|
/* any deletion makes the old insertion-undo invalid */
|
|
es->UndoInsertLen = 0;
|
|
} else
|
|
EDIT_EM_EmptyUndoBuffer(wndPtr, 0, 0);
|
|
|
|
/* now delete */
|
|
lstrcpy32A(text + s, text + e);
|
|
}
|
|
if (strl) {
|
|
/* there is an insertion */
|
|
if ((BOOL32)wParam) {
|
|
/* we have to be able to undo */
|
|
if ((s == es->UndoPos) ||
|
|
((es->UndoInsertLen) &&
|
|
(s == es->UndoPos + es->UndoInsertLen)))
|
|
/*
|
|
* insertion is new and at delete position or
|
|
* an extension to either left or right
|
|
*/
|
|
es->UndoInsertLen += strl;
|
|
else {
|
|
/* new insertion undo */
|
|
es->UndoPos = s;
|
|
es->UndoInsertLen = strl;
|
|
/* new insertion makes old delete-buffer invalid */
|
|
*utext = '\0';
|
|
}
|
|
} else
|
|
EDIT_EM_EmptyUndoBuffer(wndPtr, 0, 0);
|
|
|
|
/* now insert */
|
|
tl = lstrlen32A(text);
|
|
for (p = text + tl ; p >= text + s ; p--)
|
|
p[strl] = p[0];
|
|
for (i = 0 , p = text + s ; i < strl ; i++)
|
|
p[i] = str[i];
|
|
if(IsUpper(wndPtr))
|
|
CharUpperBuff32A(p, strl);
|
|
else if(IsLower(wndPtr))
|
|
CharLowerBuff32A(p, strl);
|
|
s += strl;
|
|
}
|
|
redraw = EDIT_GetRedraw(wndPtr);
|
|
EDIT_WM_SetRedraw(wndPtr, FALSE, 0);
|
|
EDIT_BuildLineDefs(wndPtr);
|
|
EDIT_EM_SetSel(wndPtr, s, s);
|
|
EDIT_EM_ScrollCaret(wndPtr, 0, 0);
|
|
EDIT_EM_SetModify(wndPtr, TRUE, 0);
|
|
dprintf_edit(stddeb, "edit: notification EN_UPDATE sent\n");
|
|
EDIT_NOTIFY_PARENT(wndPtr, EN_UPDATE);
|
|
EDIT_WM_SetRedraw(wndPtr, redraw, 0);
|
|
if (redraw) {
|
|
InvalidateRect32( wndPtr->hwndSelf, NULL, TRUE );
|
|
dprintf_edit(stddeb, "edit: notification EN_CHANGE sent\n");
|
|
EDIT_NOTIFY_PARENT(wndPtr, EN_CHANGE);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_SCROLL
|
|
*
|
|
* FIXME: Scroll what ??? And where ???
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_Scroll(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
fprintf(stdnimp, "edit: EM_SCROLL: message not implemented\n");
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_SCROLLCARET
|
|
*
|
|
* Makes sure the caret is visible.
|
|
* FIXME: We use EM_LINESCROLL, but may we do that for single line
|
|
* controls ???
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_ScrollCaret(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
INT32 e;
|
|
INT32 l;
|
|
INT32 li;
|
|
INT32 fv = (INT32)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0);
|
|
INT32 vlc = EDIT_GetVisibleLineCount(wndPtr);
|
|
INT32 ww = EDIT_GetWndWidth(wndPtr);
|
|
INT32 cw = EDIT_GetAveCharWidth(wndPtr);
|
|
INT32 x;
|
|
INT32 dy = 0;
|
|
INT32 dx = 0;
|
|
|
|
EDIT_GetSel(wndPtr, NULL, &e);
|
|
l = (INT32)EDIT_EM_LineFromChar(wndPtr, e, 0);
|
|
li = (INT32)EDIT_EM_LineIndex(wndPtr, l, 0);
|
|
x = EDIT_WndXFromCol(wndPtr, l, e - li);
|
|
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, dx, dy);
|
|
if (dy) {
|
|
dprintf_edit(stddeb, "edit: notification EN_VSCROLL sent\n");
|
|
EDIT_NOTIFY_PARENT(wndPtr, EN_VSCROLL);
|
|
}
|
|
if (dx) {
|
|
dprintf_edit(stddeb, "edit: notification EN_HSCROLL sent\n");
|
|
EDIT_NOTIFY_PARENT(wndPtr, EN_HSCROLL);
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_SETHANDLE
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_SetHandle(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
if (IsMultiLine(wndPtr)) {
|
|
EDIT_ReleasePointer(wndPtr);
|
|
/*
|
|
* old buffer is freed by caller
|
|
*/
|
|
es->hBuf16 = (HLOCAL16)NULL;
|
|
es->hBuf32 = (HLOCAL32)wParam;
|
|
es->BufSize = LocalSize32(es->hBuf32) - 1;
|
|
es->LineCount = 0;
|
|
es->FirstVisibleLine = 0;
|
|
es->SelStart = es->SelEnd = 0;
|
|
EDIT_EM_EmptyUndoBuffer(wndPtr, 0, 0);
|
|
EDIT_EM_SetModify(wndPtr, FALSE, 0);
|
|
EDIT_BuildLineDefs(wndPtr);
|
|
if (EDIT_GetRedraw(wndPtr))
|
|
InvalidateRect32( wndPtr->hwndSelf, NULL, TRUE );
|
|
EDIT_EM_ScrollCaret(wndPtr, 0, 0);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_SETHANDLE16
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_SetHandle16(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
if (IsMultiLine(wndPtr)) {
|
|
EDIT_ReleasePointer(wndPtr);
|
|
/*
|
|
* old buffer is freed by caller
|
|
*/
|
|
es->hBuf16 = (HLOCAL16)wParam;
|
|
es->hBuf32 = (HLOCAL32)NULL;
|
|
es->BufSize = LOCAL_Size(wndPtr->hInstance, es->hBuf16) - 1;
|
|
es->LineCount = 0;
|
|
es->FirstVisibleLine = 0;
|
|
es->SelStart = es->SelEnd = 0;
|
|
EDIT_EM_EmptyUndoBuffer(wndPtr, 0, 0);
|
|
EDIT_EM_SetModify(wndPtr, FALSE, 0);
|
|
EDIT_BuildLineDefs(wndPtr);
|
|
if (EDIT_GetRedraw(wndPtr))
|
|
InvalidateRect32( wndPtr->hwndSelf, NULL, TRUE );
|
|
EDIT_EM_ScrollCaret(wndPtr, 0, 0);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_SETLIMITTEXT
|
|
*
|
|
* FIXME: in WinNT maxsize is 0x7FFFFFFF / 0xFFFFFFFF
|
|
* However, the windows version is not complied to yet in all of edit.c
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_SetLimitText(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
if (IsMultiLine(wndPtr)) {
|
|
if (wParam)
|
|
es->BufLimit = MIN((INT32)wParam, BUFLIMIT_MULTI);
|
|
else
|
|
es->BufLimit = BUFLIMIT_MULTI;
|
|
} else {
|
|
if (wParam)
|
|
es->BufLimit = MIN((INT32)wParam, BUFLIMIT_SINGLE);
|
|
else
|
|
es->BufLimit = BUFLIMIT_SINGLE;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_SETMARGINS
|
|
*
|
|
* FIXME: We let the margins be set, but we don't use them yet !?!
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_SetMargins(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
if (wParam & EC_USEFONTINFO) {
|
|
if (IsMultiLine(wndPtr)) {
|
|
/*
|
|
* FIXME: do some GetABCCharWidth, or so
|
|
* This is just preliminary
|
|
*/
|
|
es->LeftMargin = es->RightMargin = EDIT_GetAveCharWidth(wndPtr);
|
|
} else
|
|
es->LeftMargin = es->RightMargin = EDIT_GetAveCharWidth(wndPtr);
|
|
return 0;
|
|
}
|
|
if (wParam & EC_LEFTMARGIN)
|
|
es->LeftMargin = LOWORD(lParam);
|
|
if (wParam & EC_RIGHTMARGIN)
|
|
es->RightMargin = HIWORD(lParam);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_SETMODIFY
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_SetModify(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
es->TextChanged = (BOOL32)wParam;
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_SETPASSWORDCHAR
|
|
*
|
|
* FIXME: This imlementation is way too simple
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_SetPasswordChar(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
es->PasswordChar = (CHAR)wParam;
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_SETREADONLY
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_SetReadOnly(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
if ((BOOL32)wParam)
|
|
wndPtr->dwStyle |= ES_READONLY;
|
|
else
|
|
wndPtr->dwStyle &= ~(DWORD)ES_READONLY;
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_SETRECT
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_SetRect(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
fprintf(stdnimp,"edit: EM_SETRECT: message not implemented\n");
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_SETRECTNP
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_SetRectNP(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
fprintf(stdnimp,"edit: EM_SETRECTNP: message not implemented\n");
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_SETSEL
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_SetSel(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
INT32 ns = (INT32)wParam;
|
|
INT32 ne = (INT32)lParam;
|
|
INT32 tl = (INT32)EDIT_WM_GetTextLength(wndPtr, 0, 0);
|
|
|
|
if (ns == -1) {
|
|
EDIT_GetSel(wndPtr, NULL, &ne);
|
|
ns = ne;
|
|
} else if ((!ns) && (ne == -1))
|
|
ne = tl;
|
|
else {
|
|
ns = MAX(0, MIN(ns, tl));
|
|
ne = MAX(0, MIN(ne, tl));
|
|
ORDER_INT32(ns, ne);
|
|
}
|
|
EDIT_SetSel(wndPtr, ns, ne);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_SETSEL16
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_SetSel16(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
INT32 ns = (INT32)LOWORD(lParam);
|
|
INT32 ne = (INT32)HIWORD(lParam);
|
|
|
|
if ((INT16)LOWORD(lParam) == -1)
|
|
ns = -1;
|
|
if ((!ns) && ((INT16)HIWORD(lParam) == -1))
|
|
ne = -1;
|
|
EDIT_EM_SetSel(wndPtr, ns, ne);
|
|
if (!wParam)
|
|
EDIT_EM_ScrollCaret(wndPtr, 0, 0);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_SETTABSTOPS
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_SetTabStops(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
INT32 i;
|
|
|
|
if (!IsMultiLine(wndPtr))
|
|
return FALSE;
|
|
if (es->TabStops)
|
|
free(es->TabStops);
|
|
es->NumTabStops = (INT32)wParam;
|
|
if (!wParam)
|
|
es->TabStops = NULL;
|
|
else {
|
|
es->TabStops = (LPINT16)xmalloc(wParam * sizeof(INT16));
|
|
for ( i = 0 ; i < (INT32)wParam ; i++ )
|
|
es->TabStops[i] = (INT16)((LPINT32)lParam)[i];
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_SETTABSTOPS16
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_SetTabStops16(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
if (!IsMultiLine(wndPtr))
|
|
return FALSE;
|
|
if (es->TabStops)
|
|
free(es->TabStops);
|
|
es->NumTabStops = (INT32)wParam;
|
|
if (!wParam)
|
|
es->TabStops = NULL;
|
|
else {
|
|
es->TabStops = (LPINT16)xmalloc(wParam * sizeof(INT16));
|
|
memcpy(es->TabStops, (LPINT16)PTR_SEG_TO_LIN(lParam),
|
|
(INT32)wParam * sizeof(INT16));
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_SETWORDBREAKPROC
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_SetWordBreakProc(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
/*
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
es->WordBreakProc = (EDITWORDBREAKPROC)lParam;
|
|
*/
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* EM_UNDO / WM_UNDO
|
|
*
|
|
*/
|
|
static LRESULT EDIT_EM_Undo(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
LPSTR utext = xstrdup(EDIT_GetUndoPointer(wndPtr));
|
|
|
|
dprintf_edit(stddeb, "edit: before UNDO:insertion length = %d, deletion buffer = %s\n",
|
|
es->UndoInsertLen, utext);
|
|
|
|
EDIT_EM_SetSel(wndPtr, es->UndoPos, es->UndoPos + es->UndoInsertLen);
|
|
EDIT_EM_EmptyUndoBuffer(wndPtr, 0, 0);
|
|
EDIT_EM_ReplaceSel(wndPtr, TRUE, (LPARAM)utext);
|
|
EDIT_EM_SetSel(wndPtr, es->UndoPos, es->UndoPos + es->UndoInsertLen);
|
|
free(utext);
|
|
|
|
dprintf_edit(stddeb, "edit: after UNDO: insertion length = %d, deletion buffer = %s\n",
|
|
es->UndoInsertLen, EDIT_GetUndoPointer(wndPtr));
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_CHAR
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_Char(WND *wndPtr, WPARAM32 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_EM_ReplaceSel(wndPtr, (WPARAM32)TRUE, (LPARAM)"\r\n");
|
|
}
|
|
break;
|
|
case '\t':
|
|
if (IsMultiLine(wndPtr) && !IsReadOnly(wndPtr))
|
|
EDIT_EM_ReplaceSel(wndPtr, (WPARAM32)TRUE, (LPARAM)"\t");
|
|
break;
|
|
default:
|
|
if (!IsReadOnly(wndPtr) && (c >= ' ') && (c != 127)) {
|
|
str[0] = c;
|
|
str[1] = '\0';
|
|
EDIT_EM_ReplaceSel(wndPtr, (WPARAM32)TRUE, (LPARAM)str);
|
|
}
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_CLEAR
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_Clear(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
EDIT_EM_ReplaceSel(wndPtr, TRUE, (LPARAM)"");
|
|
|
|
return -1;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_COMMAND
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_Command(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
if (HIWORD(wParam))
|
|
return 0;
|
|
|
|
switch (LOWORD(wParam)) {
|
|
case EM_UNDO32:
|
|
EDIT_EM_Undo(wndPtr, 0, 0);
|
|
break;
|
|
case WM_CUT:
|
|
EDIT_WM_Cut(wndPtr, 0, 0);
|
|
break;
|
|
case WM_COPY:
|
|
EDIT_WM_Copy(wndPtr, 0, 0);
|
|
break;
|
|
case WM_PASTE:
|
|
EDIT_WM_Paste(wndPtr, 0, 0);
|
|
break;
|
|
case WM_CLEAR:
|
|
EDIT_WM_Clear(wndPtr, 0, 0);
|
|
break;
|
|
case EM_SETSEL32:
|
|
EDIT_EM_SetSel(wndPtr, 0, -1);
|
|
EDIT_EM_ScrollCaret(wndPtr, 0, 0);
|
|
break;
|
|
default:
|
|
dprintf_edit(stddeb, "edit: unknown menu item, please report\n");
|
|
break;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_CONTEXTMENU
|
|
*
|
|
* Note: the resource files resource/sysres_??.rc cannot define a
|
|
* single popup menu. Hence we use a (dummy) menubar
|
|
* containing the single popup menu as its first item.
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_ContextMenu(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
HMENU32 hMenu = LoadMenuIndirect32A(SYSRES_GetResPtr(SYSRES_MENU_EDITMENU));
|
|
HMENU32 hPopup = GetSubMenu32(hMenu, 0);
|
|
|
|
TrackPopupMenu32(hPopup, TPM_LEFTALIGN | TPM_RIGHTBUTTON, LOWORD(lParam),
|
|
HIWORD(lParam), 0, wndPtr->hwndSelf, NULL);
|
|
DestroyMenu32(hMenu);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_COPY
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_Copy(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
INT32 s;
|
|
INT32 e;
|
|
HGLOBAL16 hdst;
|
|
LPSTR text;
|
|
LPSTR dst;
|
|
|
|
EDIT_GetSel(wndPtr, &s, &e);
|
|
if (e == s)
|
|
return -1;
|
|
ORDER_INT32(s, e);
|
|
hdst = GlobalAlloc16(GMEM_MOVEABLE, (DWORD)(e - s + 1));
|
|
dst = GlobalLock16(hdst);
|
|
text = EDIT_GetPointer(wndPtr);
|
|
lstrcpyn32A(dst, text + s, e - s + 1);
|
|
GlobalUnlock16(hdst);
|
|
OpenClipboard(wndPtr->hwndSelf);
|
|
EmptyClipboard();
|
|
SetClipboardData(CF_TEXT, hdst);
|
|
CloseClipboard();
|
|
return -1;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_CREATE
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_Create(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
CREATESTRUCT32A *cs = (CREATESTRUCT32A *)lParam;
|
|
EDITSTATE *es;
|
|
LPSTR 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 (!(es->hBuf32 = LocalAlloc32(LMEM_MOVEABLE, es->BufSize + 1))) {
|
|
fprintf(stderr, "edit: WM_CREATE: unable to allocate buffer\n");
|
|
return -1;
|
|
}
|
|
if (!(es->hUndoBuf = LocalAlloc32(LMEM_MOVEABLE, es->BufSize + 1))) {
|
|
fprintf(stderr, "edit: WM_CREATE: unable to allocate undo buffer\n");
|
|
LocalFree32(es->hBuf32);
|
|
es->hBuf32 = (HLOCAL32)NULL;
|
|
return -1;
|
|
}
|
|
es->BufSize = LocalSize32(es->hBuf32) - 1;
|
|
es->UndoBufSize = LocalSize32(es->hUndoBuf) - 1;
|
|
EDIT_EM_EmptyUndoBuffer(wndPtr, 0, 0);
|
|
text = EDIT_GetPointer(wndPtr);
|
|
*text = '\0';
|
|
EDIT_BuildLineDefs(wndPtr);
|
|
EDIT_WM_SetFont(wndPtr, 0, 0);
|
|
if (cs->lpszName && *(cs->lpszName) != '\0')
|
|
EDIT_EM_ReplaceSel(wndPtr, (WPARAM32)FALSE, (LPARAM)cs->lpszName);
|
|
EDIT_WM_SetRedraw(wndPtr, TRUE, 0);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_CUT
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_Cut(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
EDIT_WM_Copy(wndPtr, 0, 0);
|
|
EDIT_WM_Clear(wndPtr, 0, 0);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_DESTROY
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_Destroy(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
free(es->LineDefs);
|
|
if (es->TabStops)
|
|
free(es->TabStops);
|
|
EDIT_ReleaseUndoPointer(wndPtr);
|
|
LocalFree32(es->hUndoBuf);
|
|
EDIT_ReleasePointer(wndPtr);
|
|
if (es->hBuf32)
|
|
LocalFree32(es->hBuf32);
|
|
else
|
|
LOCAL_Free(wndPtr->hInstance, es->hBuf16);
|
|
free(es);
|
|
*(EDITSTATE **)&wndPtr->wExtra = NULL;
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_ENABLE
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_Enable(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
EDIT_InvalidateText(wndPtr, 0, -1);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_ERASEBKGND
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_EraseBkGnd(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
HBRUSH32 hBrush;
|
|
RECT32 rc;
|
|
|
|
hBrush = (HBRUSH32)EDIT_SEND_CTLCOLOR(wndPtr, wParam);
|
|
if (!hBrush) hBrush = (HBRUSH32)GetStockObject32(WHITE_BRUSH);
|
|
|
|
GetClientRect32(wndPtr->hwndSelf, &rc);
|
|
IntersectClipRect32((HDC32)wParam, rc.left, rc.top,
|
|
rc.right, rc.bottom);
|
|
GetClipBox32((HDC32)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.
|
|
*/
|
|
FillRect32((HDC32)wParam, &rc, hBrush);
|
|
return -1;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_GETDLGCODE
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_GetDlgCode(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
return DLGC_HASSETSEL | DLGC_WANTCHARS | DLGC_WANTARROWS;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_GETFONT
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_GetFont(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
return (LRESULT)es->hFont;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_GETTEXT
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_GetText(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
LPSTR text = EDIT_GetPointer(wndPtr);
|
|
INT32 len;
|
|
LRESULT lResult = 0;
|
|
|
|
len = lstrlen32A(text);
|
|
if ((INT32)wParam > len) {
|
|
lstrcpy32A((LPSTR)lParam, text);
|
|
lResult = (LRESULT)len + 1;
|
|
}
|
|
return lResult;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_GETTEXTLENGTH
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_GetTextLength(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
LPSTR text = EDIT_GetPointer(wndPtr);
|
|
|
|
return (LRESULT)lstrlen32A(text);
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_HSCROLL
|
|
*
|
|
* FIXME: scrollbar code itself is broken, so this one is a hack.
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_HScroll(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
INT32 ww = EDIT_GetWndWidth(wndPtr);
|
|
INT32 tw = EDIT_GetTextWidth(wndPtr);
|
|
INT32 cw = EDIT_GetAveCharWidth(wndPtr);
|
|
INT32 xoff = EDIT_GetXOffset(wndPtr);
|
|
INT32 dx = 0;
|
|
BOOL32 not = TRUE;
|
|
LRESULT ret = 0;
|
|
|
|
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 = HIWORD(wParam) * tw / 100 - xoff;
|
|
break;
|
|
/* The next two are undocumented ! */
|
|
case EM_GETTHUMB16:
|
|
ret = tw ? xoff * 100 / tw : 0;
|
|
break;
|
|
case EM_LINESCROLL16:
|
|
dx = (INT16)HIWORD(wParam);
|
|
break;
|
|
case SB_ENDSCROLL:
|
|
default:
|
|
break;
|
|
}
|
|
if (dx) {
|
|
EDIT_EM_LineScroll(wndPtr, dx, 0);
|
|
if (not) {
|
|
dprintf_edit(stddeb, "edit: notification EN_HSCROLL sent\n");
|
|
EDIT_NOTIFY_PARENT(wndPtr, EN_HSCROLL);
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_INITMENUPOPUP
|
|
*
|
|
* FIXME: the message identifiers have been chosen arbitrarily,
|
|
* hence we use MF_BYPOSITION.
|
|
* We might as well use the "real" values (anybody knows ?)
|
|
* The menu definition is in resources/sysres_??.rc.
|
|
* Once these are OK, we better use MF_BYCOMMAND here
|
|
* (as we do in EDIT_WM_Command()).
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_InitMenuPopup(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
HMENU32 hPopup = (HMENU32)wParam;
|
|
INT32 s;
|
|
INT32 e;
|
|
|
|
EDIT_EM_GetSel(wndPtr, (WPARAM32)&s, (LPARAM)&e);
|
|
|
|
/* undo */
|
|
EnableMenuItem32(hPopup, 0, MF_BYPOSITION |
|
|
(EDIT_EM_CanUndo(wndPtr, 0, 0) ? MF_ENABLED : MF_GRAYED));
|
|
/* cut */
|
|
EnableMenuItem32(hPopup, 2, MF_BYPOSITION |
|
|
((e - s) && !IsPassword(wndPtr) ? MF_ENABLED : MF_GRAYED));
|
|
/* copy */
|
|
EnableMenuItem32(hPopup, 3, MF_BYPOSITION |
|
|
((e - s) && !IsPassword(wndPtr) ? MF_ENABLED : MF_GRAYED));
|
|
/* paste */
|
|
EnableMenuItem32(hPopup, 4, MF_BYPOSITION |
|
|
(IsClipboardFormatAvailable(CF_TEXT) ? MF_ENABLED : MF_GRAYED));
|
|
/* delete */
|
|
EnableMenuItem32(hPopup, 5, MF_BYPOSITION |
|
|
((e - s) ? MF_ENABLED : MF_GRAYED));
|
|
/* select all */
|
|
EnableMenuItem32(hPopup, 7, MF_BYPOSITION |
|
|
(s || (e != EDIT_WM_GetTextLength(wndPtr, 0, 0)) ? MF_ENABLED : MF_GRAYED));
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* 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, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
INT32 s;
|
|
INT32 e;
|
|
BOOL32 shift;
|
|
BOOL32 control;
|
|
|
|
if (GetKeyState(VK_MENU) & 0x8000)
|
|
return 0;
|
|
|
|
shift = GetKeyState(VK_SHIFT) & 0x8000;
|
|
control = GetKeyState(VK_CONTROL) & 0x8000;
|
|
|
|
EDIT_GetSel(wndPtr, &s, &e);
|
|
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, 0);
|
|
else
|
|
EDIT_DelLeft(wndPtr);
|
|
break;
|
|
case VK_DELETE:
|
|
if (!IsReadOnly(wndPtr) && !(shift && control))
|
|
if (e != s) {
|
|
if (shift)
|
|
EDIT_WM_Cut(wndPtr, 0, 0);
|
|
else
|
|
EDIT_WM_Clear(wndPtr, 0, 0);
|
|
} 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, 0);
|
|
} else if (control)
|
|
EDIT_WM_Copy(wndPtr, 0, 0);
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_KILLFOCUS
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_KillFocus(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
INT32 s;
|
|
INT32 e;
|
|
|
|
DestroyCaret();
|
|
if(!(wndPtr->dwStyle & ES_NOHIDESEL)) {
|
|
EDIT_EM_GetSel(wndPtr, (WPARAM32)&s, (LPARAM)&e);
|
|
EDIT_InvalidateText(wndPtr, s, e);
|
|
}
|
|
dprintf_edit(stddeb, "edit: notification EN_KILLFOCUS sent\n");
|
|
EDIT_NOTIFY_PARENT(wndPtr, EN_KILLFOCUS);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_LBUTTONDBLCLK
|
|
*
|
|
* The caret position has been set on the WM_LBUTTONDOWN message
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_LButtonDblClk(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
INT32 s;
|
|
INT32 e;
|
|
INT32 l;
|
|
INT32 li;
|
|
INT32 ll;
|
|
LPSTR text = EDIT_GetPointer(wndPtr);
|
|
|
|
EDIT_GetSel(wndPtr, NULL, &e);
|
|
l = (INT32)EDIT_EM_LineFromChar(wndPtr, e, 0);
|
|
li = (INT32)EDIT_EM_LineIndex(wndPtr, l, 0);
|
|
ll = (INT32)EDIT_EM_LineLength(wndPtr, e, 0);
|
|
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, s, e);
|
|
EDIT_EM_ScrollCaret(wndPtr, 0, 0);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_LBUTTONDOWN
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_LButtonDown(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
INT32 x = (INT32)(INT16)LOWORD(lParam);
|
|
INT32 y = (INT32)(INT16)HIWORD(lParam);
|
|
INT32 l = EDIT_LineFromWndY(wndPtr, y);
|
|
INT32 c;
|
|
INT32 s;
|
|
INT32 e;
|
|
INT32 fv = (INT32)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0);
|
|
INT32 vlc = EDIT_GetVisibleLineCount(wndPtr);
|
|
INT32 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 = (INT32)EDIT_EM_LineIndex(wndPtr, l, 0);
|
|
e = li + c;
|
|
if (GetKeyState(VK_SHIFT) & 0x8000)
|
|
EDIT_GetSel(wndPtr, &s, NULL);
|
|
else
|
|
s = e;
|
|
EDIT_SetSel(wndPtr, s, e);
|
|
EDIT_EM_ScrollCaret(wndPtr, 0, 0);
|
|
SetTimer32(wndPtr->hwndSelf, 0, 100, NULL);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_LBUTTONUP
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_LButtonUp(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
if (GetCapture32() == wndPtr->hwndSelf) {
|
|
KillTimer32(wndPtr->hwndSelf, 0);
|
|
ReleaseCapture();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_MOUSEMOVE
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_MouseMove(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
INT32 x;
|
|
INT32 y;
|
|
INT32 l;
|
|
INT32 c;
|
|
INT32 s;
|
|
INT32 fv;
|
|
INT32 vlc;
|
|
INT32 li;
|
|
|
|
if (GetCapture32() == wndPtr->hwndSelf) {
|
|
x = (INT32)(INT16)LOWORD(lParam);
|
|
y = (INT32)(INT16)HIWORD(lParam);
|
|
fv = (INT32)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0);
|
|
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);
|
|
EDIT_GetSel(wndPtr, &s, NULL);
|
|
li = (INT32)EDIT_EM_LineIndex(wndPtr, l, 0);
|
|
EDIT_SetSel(wndPtr, s, li + c);
|
|
}
|
|
/*
|
|
* FIXME: gotta do some scrolling if outside client (format ?)
|
|
* area. Maybe reset the timer ?
|
|
*/
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_PAINT
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_Paint(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
PAINTSTRUCT32 ps;
|
|
INT32 i;
|
|
INT32 fv = (INT32)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0);
|
|
INT32 vlc = EDIT_GetVisibleLineCount(wndPtr);
|
|
INT32 lc = (INT32)EDIT_EM_GetLineCount(wndPtr, 0, 0);
|
|
HDC32 hdc;
|
|
HFONT32 hFont;
|
|
HFONT32 oldFont = 0;
|
|
RECT32 rc;
|
|
RECT32 rcLine;
|
|
RECT32 rcRgn;
|
|
LRESULT pos;
|
|
INT32 e;
|
|
BOOL32 rev = IsWindowEnabled32(wndPtr->hwndSelf) &&
|
|
((GetFocus32() == wndPtr->hwndSelf) ||
|
|
(wndPtr->dwStyle & ES_NOHIDESEL));
|
|
|
|
hdc = BeginPaint32(wndPtr->hwndSelf, &ps);
|
|
GetClientRect32(wndPtr->hwndSelf, &rc);
|
|
IntersectClipRect32( hdc, rc.left, rc.top, rc.right, rc.bottom );
|
|
hFont = (HFONT32)EDIT_WM_GetFont(wndPtr, 0, 0);
|
|
if (hFont)
|
|
oldFont = (HFONT32)SelectObject32(hdc, hFont);
|
|
EDIT_SEND_CTLCOLOR(wndPtr, hdc);
|
|
if (!IsWindowEnabled32(wndPtr->hwndSelf))
|
|
SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT));
|
|
GetClipBox32(hdc, &rcRgn);
|
|
for (i = fv ; i <= MIN(fv + vlc, fv + lc - 1) ; i++ ) {
|
|
EDIT_GetLineRect(wndPtr, i, 0, -1, &rcLine);
|
|
if (IntersectRect32(&rc, &rcRgn, &rcLine))
|
|
EDIT_PaintLine(wndPtr, hdc, i, rev);
|
|
}
|
|
if (hFont) SelectObject32(hdc, oldFont);
|
|
if (wndPtr->hwndSelf == GetFocus32()) {
|
|
EDIT_GetSel(wndPtr, NULL, &e);
|
|
pos = EDIT_EM_PosFromChar(wndPtr, e, 0);
|
|
SetCaretPos((INT16)LOWORD(pos), (INT16)HIWORD(pos));
|
|
}
|
|
EndPaint32(wndPtr->hwndSelf, &ps);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_PASTE
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_Paste(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
HGLOBAL16 hsrc;
|
|
LPSTR src;
|
|
|
|
OpenClipboard(wndPtr->hwndSelf);
|
|
if ((hsrc = GetClipboardData(CF_TEXT))) {
|
|
src = (LPSTR)GlobalLock16(hsrc);
|
|
EDIT_EM_ReplaceSel(wndPtr, (WPARAM32)TRUE, (LPARAM)src);
|
|
GlobalUnlock16(hsrc);
|
|
}
|
|
CloseClipboard();
|
|
return -1;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_SETCURSOR
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_SetCursor(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
if (LOWORD(lParam) == HTCLIENT) {
|
|
SetCursor(LoadCursor16(0, IDC_IBEAM));
|
|
return -1;
|
|
} else
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_SETFOCUS
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_SetFocus(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
INT32 s;
|
|
INT32 e;
|
|
|
|
EDIT_GetSel(wndPtr, &s, &e);
|
|
CreateCaret(wndPtr->hwndSelf, 0, 2, EDIT_GetLineHeight(wndPtr));
|
|
EDIT_SetSel(wndPtr, s, e);
|
|
if(!(wndPtr->dwStyle & ES_NOHIDESEL))
|
|
EDIT_InvalidateText(wndPtr, s, e);
|
|
ShowCaret(wndPtr->hwndSelf);
|
|
dprintf_edit(stddeb, "edit: notification EN_SETFOCUS sent\n");
|
|
EDIT_NOTIFY_PARENT(wndPtr, EN_SETFOCUS);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_SETFONT
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_SetFont(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
TEXTMETRIC32A tm;
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
INT32 s;
|
|
INT32 e;
|
|
HDC32 hdc;
|
|
HFONT32 oldFont = 0;
|
|
|
|
EDIT_GetSel(wndPtr, &s, &e);
|
|
es->hFont = (HFONT32)wParam;
|
|
hdc = GetDC32(wndPtr->hwndSelf);
|
|
if (es->hFont) oldFont = SelectObject32(hdc, es->hFont);
|
|
GetTextMetrics32A(hdc, &tm);
|
|
es->LineHeight = tm.tmHeight;
|
|
es->AveCharWidth = tm.tmAveCharWidth;
|
|
if (es->hFont) SelectObject32(hdc, oldFont);
|
|
ReleaseDC32(wndPtr->hwndSelf, hdc);
|
|
EDIT_BuildLineDefs(wndPtr);
|
|
if ((BOOL32)lParam && EDIT_GetRedraw(wndPtr))
|
|
InvalidateRect32( wndPtr->hwndSelf, NULL, TRUE );
|
|
if (wndPtr->hwndSelf == GetFocus32()) {
|
|
DestroyCaret();
|
|
CreateCaret(wndPtr->hwndSelf, 0, 2, EDIT_GetLineHeight(wndPtr));
|
|
EDIT_SetSel(wndPtr, s, e);
|
|
ShowCaret(wndPtr->hwndSelf);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_SETREDRAW
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_SetRedraw(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
|
|
es->Redraw = (BOOL32)wParam;
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_SETTEXT
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_SetText(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
EDIT_EM_SetSel(wndPtr, 0, -1);
|
|
if (lParam)
|
|
EDIT_EM_ReplaceSel(wndPtr, (WPARAM32)FALSE, lParam);
|
|
EDIT_EM_SetModify(wndPtr, TRUE, 0);
|
|
EDIT_EM_ScrollCaret(wndPtr, 0, 0);
|
|
return 1;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_SIZE
|
|
*
|
|
* FIXME: What about that FormatRect ???
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_Size(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
EDITSTATE *es = EDITSTATEPTR(wndPtr);
|
|
INT32 e;
|
|
|
|
EDIT_GetSel(wndPtr, 0, &e);
|
|
GetClientRect32(wndPtr->hwndSelf, &es->FormatRect);
|
|
if (EDIT_GetRedraw(wndPtr) &&
|
|
((wParam == SIZE_MAXIMIZED) ||
|
|
(wParam == SIZE_RESTORED))) {
|
|
if (IsMultiLine(wndPtr) && IsWordWrap(wndPtr))
|
|
EDIT_BuildLineDefs(wndPtr);
|
|
InvalidateRect32( wndPtr->hwndSelf, NULL, TRUE );
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_SYSKEYDOWN
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_SysKeyDown(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
if ((wParam == VK_BACK) && (lParam & 0x2000) &&
|
|
(BOOL32)EDIT_EM_CanUndo(wndPtr, 0, 0))
|
|
EDIT_EM_Undo(wndPtr, 0, 0);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_TIMER
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_Timer(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
/*
|
|
* FIXME: gotta do some scrolling here, like
|
|
* EDIT_EM_LineScroll(wndPtr, 0, 1);
|
|
*/
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
*
|
|
* WM_VSCROLL
|
|
*
|
|
* FIXME: scrollbar code itself is broken, so this one is a hack.
|
|
*
|
|
*/
|
|
static LRESULT EDIT_WM_VScroll(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
|
|
{
|
|
INT32 lc = (INT32)EDIT_EM_GetLineCount(wndPtr, 0, 0);
|
|
INT32 fv = (INT32)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0);
|
|
INT32 vlc = EDIT_GetVisibleLineCount(wndPtr);
|
|
INT32 dy = 0;
|
|
BOOL32 not = TRUE;
|
|
LRESULT ret = 0;
|
|
|
|
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;
|
|
/* fall through */
|
|
case SB_THUMBPOSITION:
|
|
dy = HIWORD(wParam) * (lc - 1) / 100 - fv;
|
|
break;
|
|
/* The next two are undocumented ! */
|
|
case EM_GETTHUMB16:
|
|
ret = (lc > 1) ? MAKELONG(fv * 100 / (lc - 1), 0) : 0;
|
|
break;
|
|
case EM_LINESCROLL16:
|
|
dy = (INT16)LOWORD(lParam);
|
|
break;
|
|
case SB_ENDSCROLL:
|
|
default:
|
|
break;
|
|
}
|
|
if (dy) {
|
|
EDIT_EM_LineScroll(wndPtr, 0, dy);
|
|
if (not) {
|
|
dprintf_edit(stddeb, "edit: notification EN_VSCROLL sent\n");
|
|
EDIT_NOTIFY_PARENT(wndPtr, EN_VSCROLL);
|
|
}
|
|
}
|
|
return ret;
|
|
}
|