4 * Copyright David W. Metcalfe, 1994
5 * Copyright William Magro, 1995, 1996
6 * Copyright Frans van Dorsselaer, 1996
11 * UNDER CONSTRUCTION, please read EDIT.TODO
20 #include "stackframe.h"
26 #define BUFLIMIT_MULTI 65534 /* maximum text buffer length (not including '\0') */
27 #define BUFLIMIT_SINGLE 32766
28 #define BUFSTART_MULTI 1024 /* starting length for multi-line control */
29 #define BUFSTART_SINGLE 256 /* starting length for single line control */
30 #define GROWLENGTH 64 /* buffers grow by this much */
31 #define HSCROLL_FRACTION 3 /* scroll window by 1/3 width */
50 UINT TextWidth
; /* width of the widest line in pixels */
55 UINT XOffset
; /* offset of the viewport in pixels */
56 UINT FirstVisibleLine
;
58 UINT LineHeight
; /* height of a screen line in pixels */
59 UINT AveCharWidth
; /* average character width in pixels */
64 UINT SelStart
; /* offset of selection start, == SelEnd if no selection */
65 UINT SelEnd
; /* offset of selection end == current caret position */
68 EDITWORDBREAKPROC WordBreakProc
;
73 #define SWAP_UINT(x,y) do { UINT temp = (UINT)(x); (x) = (UINT)(y); (y) = temp; } while(0)
74 #define ORDER_UINT(x,y) do { if ((UINT)(y) < (UINT)(x)) SWAP_UINT((x),(y)); } while(0)
76 /* macros to access window styles */
77 #define IsMultiLine(wndPtr) ((wndPtr)->dwStyle & ES_MULTILINE)
78 #define IsVScrollBar(wndPtr) ((wndPtr)->dwStyle & WS_VSCROLL)
79 #define IsHScrollBar(wndPtr) ((wndPtr)->dwStyle & WS_HSCROLL)
80 #define IsReadOnly(wndPtr) ((wndPtr)->dwStyle & ES_READONLY)
81 #define IsWordWrap(wndPtr) (((wndPtr)->dwStyle & ES_AUTOHSCROLL) == 0)
82 #define IsPassword(wndPtr) ((wndPtr)->dwStyle & ES_PASSWORD)
83 #define IsLower(wndPtr) ((wndPtr)->dwStyle & ES_LOWERCASE)
84 #define IsUpper(wndPtr) ((wndPtr)->dwStyle & ES_UPPERCASE)
86 #define EDITSTATEPTR(wndPtr) (*(EDITSTATE **)((wndPtr)->wExtra))
88 #define EDIT_SEND_CTLCOLOR(wndPtr,hdc) \
89 (SendMessage32A((wndPtr)->parent->hwndSelf, WM_CTLCOLOREDIT, \
90 (WPARAM)(hdc), (LPARAM)(wndPtr)->hwndSelf ))
91 #define EDIT_NOTIFY_PARENT(wndPtr, wNotifyCode) \
92 (SendMessage32A((wndPtr)->parent->hwndSelf, WM_COMMAND, \
93 MAKEWPARAM((wndPtr)->wIDmenu, wNotifyCode), \
94 (LPARAM)(wndPtr)->hwndSelf ))
95 #define DPRINTF_EDIT_MSG(str) \
96 dprintf_edit(stddeb, \
97 "edit: " str ": hwnd=%04x, wParam=%04x, lParam=%08x\n", \
98 (UINT32)hwnd, (UINT32)wParam, (UINT32)lParam)
101 /*********************************************************************
105 * Files like these should really be kept in alphabetical order.
108 LRESULT
EditWndProc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
);
110 static void EDIT_BuildLineDefs(WND
*wndPtr
);
111 static INT
EDIT_CallWordBreakProc(WND
*wndPtr
, char *s
, INT index
, INT count
, INT action
);
112 static UINT
EDIT_ColFromWndX(WND
*wndPtr
, UINT line
, INT x
);
113 static void EDIT_DelEnd(WND
*wndPtr
);
114 static void EDIT_DelLeft(WND
*wndPtr
);
115 static void EDIT_DelRight(WND
*wndPtr
);
116 static UINT
EDIT_GetAveCharWidth(WND
*wndPtr
);
117 static UINT
EDIT_GetLineHeight(WND
*wndPtr
);
118 static void EDIT_GetLineRect(WND
*wndPtr
, UINT line
, UINT scol
, UINT ecol
, LPRECT16 rc
);
119 static char * EDIT_GetPointer(WND
*wndPtr
);
120 static char * EDIT_GetPasswordPointer(WND
*wndPtr
);
121 static LRESULT
EDIT_GetRect(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
122 static BOOL
EDIT_GetRedraw(WND
*wndPtr
);
123 static UINT
EDIT_GetTextWidth(WND
*wndPtr
);
124 static UINT
EDIT_GetVisibleLineCount(WND
*wndPtr
);
125 static UINT
EDIT_GetWndWidth(WND
*wndPtr
);
126 static UINT
EDIT_GetXOffset(WND
*wndPtr
);
127 static void EDIT_InvalidateText(WND
*wndPtr
, UINT start
, UINT end
);
128 static UINT
EDIT_LineFromWndY(WND
*wndPtr
, INT y
);
129 static BOOL
EDIT_MakeFit(WND
*wndPtr
, UINT size
);
130 static void EDIT_MoveBackward(WND
*wndPtr
, BOOL extend
);
131 static void EDIT_MoveDownward(WND
*wndPtr
, BOOL extend
);
132 static void EDIT_MoveEnd(WND
*wndPtr
, BOOL extend
);
133 static void EDIT_MoveForward(WND
*wndPtr
, BOOL extend
);
134 static void EDIT_MoveHome(WND
*wndPtr
, BOOL extend
);
135 static void EDIT_MovePageDown(WND
*wndPtr
, BOOL extend
);
136 static void EDIT_MovePageUp(WND
*wndPtr
, BOOL extend
);
137 static void EDIT_MoveUpward(WND
*wndPtr
, BOOL extend
);
138 static void EDIT_MoveWordBackward(WND
*wndPtr
, BOOL extend
);
139 static void EDIT_MoveWordForward(WND
*wndPtr
, BOOL extend
);
140 static void EDIT_PaintLine(WND
*wndPtr
, HDC hdc
, UINT line
, BOOL rev
);
141 static UINT
EDIT_PaintText(WND
*wndPtr
, HDC hdc
, INT x
, INT y
, UINT line
, UINT col
, UINT count
, BOOL rev
);
142 static void EDIT_ReleasePointer(WND
*wndPtr
);
143 static LRESULT
EDIT_ReplaceSel(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
144 static void EDIT_ScrollIntoView(WND
*wndPtr
);
145 static INT
EDIT_WndXFromCol(WND
*wndPtr
, UINT line
, UINT col
);
146 static INT
EDIT_WndYFromLine(WND
*wndPtr
, UINT line
);
147 static INT
EDIT_WordBreakProc(char *s
, INT index
, INT count
, INT action
);
149 static LRESULT
EDIT_EM_CanUndo(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
150 static LRESULT
EDIT_EM_EmptyUndoBuffer(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
151 static LRESULT
EDIT_EM_FmtLines(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
152 static LRESULT
EDIT_EM_GetFirstVisibleLine(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
153 static LRESULT
EDIT_EM_GetHandle(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
154 static LRESULT
EDIT_EM_GetLine(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
155 static LRESULT
EDIT_EM_GetLineCount(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
156 static LRESULT
EDIT_EM_GetModify(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
157 static LRESULT
EDIT_EM_GetPasswordChar(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
158 static LRESULT
EDIT_EM_GetRect(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
159 static LRESULT
EDIT_EM_GetSel(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
160 static LRESULT
EDIT_EM_GetThumb(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
161 static LRESULT
EDIT_EM_GetWordBreakProc(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
162 static LRESULT
EDIT_EM_LimitText(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
163 static LRESULT
EDIT_EM_LineFromChar(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
164 static LRESULT
EDIT_EM_LineIndex(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
165 static LRESULT
EDIT_EM_LineLength(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
166 static LRESULT
EDIT_EM_LineScroll(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
167 static LRESULT
EDIT_EM_ReplaceSel(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
168 static LRESULT
EDIT_EM_Scroll(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
169 static LRESULT
EDIT_EM_SetHandle(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
170 static LRESULT
EDIT_EM_SetModify(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
171 static LRESULT
EDIT_EM_SetPasswordChar(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
172 static LRESULT
EDIT_EM_SetReadOnly(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
173 static LRESULT
EDIT_EM_SetRect(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
174 static LRESULT
EDIT_EM_SetRectNP(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
175 static LRESULT
EDIT_EM_SetSel(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
176 static LRESULT
EDIT_EM_SetTabStops(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
177 static LRESULT
EDIT_EM_SetWordBreakProc(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
178 static LRESULT
EDIT_EM_Undo(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
180 static LRESULT
EDIT_WM_Char(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
181 static LRESULT
EDIT_WM_Clear(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
182 static LRESULT
EDIT_WM_Copy(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
183 static LRESULT
EDIT_WM_Cut(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
184 static LRESULT
EDIT_WM_Create(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
185 static LRESULT
EDIT_WM_Destroy(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
186 static LRESULT
EDIT_WM_Enable(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
187 static LRESULT
EDIT_WM_EraseBkGnd(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
188 static LRESULT
EDIT_WM_GetDlgCode(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
189 static LRESULT
EDIT_WM_GetFont(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
190 static LRESULT
EDIT_WM_GetText(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
191 static LRESULT
EDIT_WM_GetTextLength(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
192 static LRESULT
EDIT_WM_HScroll(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
193 static LRESULT
EDIT_WM_KeyDown(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
194 static LRESULT
EDIT_WM_KillFocus(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
195 static LRESULT
EDIT_WM_LButtonDblClk(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
196 static LRESULT
EDIT_WM_LButtonDown(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
197 static LRESULT
EDIT_WM_LButtonUp(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
198 static LRESULT
EDIT_WM_MouseMove(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
199 static LRESULT
EDIT_WM_Paint(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
200 static LRESULT
EDIT_WM_Paste(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
201 static LRESULT
EDIT_WM_SetCursor(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
202 static LRESULT
EDIT_WM_SetFocus(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
203 static LRESULT
EDIT_WM_SetFont(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
204 static LRESULT
EDIT_WM_SetRedraw(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
205 static LRESULT
EDIT_WM_SetText(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
206 static LRESULT
EDIT_WM_Size(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
207 static LRESULT
EDIT_WM_VScroll(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
);
210 /*********************************************************************
212 * General shortcuts for variable names:
216 * UINT s; offset of selection start
217 * UINT e; offset of selection end
218 * UINT sl; line on which the selection starts
219 * UINT el; line on which the selection ends
220 * UINT sc; column on which the selection starts
221 * UINT ec; column on which the selection ends
222 * UINT li; line index (offset)
223 * UINT fv; first visible line
224 * UINT vlc; vissible line count
225 * UINT lc; line count
226 * UINT lh; line height (in pixels)
227 * UINT tw; text width (in pixels)
228 * UINT ww; window width (in pixels)
229 * UINT cw; character width (average, in pixels)
234 /*********************************************************************
239 LRESULT
EditWndProc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
241 LRESULT lResult
= 0L;
242 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
246 DPRINTF_EDIT_MSG("EM_CANUNDO");
247 lResult
= EDIT_EM_CanUndo(wndPtr
, wParam
, lParam
);
249 case EM_EMPTYUNDOBUFFER
:
250 DPRINTF_EDIT_MSG("EM_EMPTYUNDOBUFFER");
251 lResult
= EDIT_EM_EmptyUndoBuffer(wndPtr
, wParam
, lParam
);
254 DPRINTF_EDIT_MSG("EM_FMTLINES");
255 lResult
= EDIT_EM_FmtLines(wndPtr
, wParam
, lParam
);
257 case EM_GETFIRSTVISIBLELINE
:
258 DPRINTF_EDIT_MSG("EM_GETFIRSTVISIBLELINE");
259 lResult
= EDIT_EM_GetFirstVisibleLine(wndPtr
, wParam
, lParam
);
262 DPRINTF_EDIT_MSG("EM_GETHANDLE");
263 lResult
= EDIT_EM_GetHandle(wndPtr
, wParam
, lParam
);
266 DPRINTF_EDIT_MSG("EM_GETLINE");
267 lResult
= EDIT_EM_GetLine(wndPtr
, wParam
, lParam
);
269 case EM_GETLINECOUNT
:
270 DPRINTF_EDIT_MSG("EM_GETLINECOUNT");
271 lResult
= EDIT_EM_GetLineCount(wndPtr
, wParam
, lParam
);
274 DPRINTF_EDIT_MSG("EM_GETMODIFY");
275 lResult
= EDIT_EM_GetModify(wndPtr
, wParam
, lParam
);
277 case EM_GETPASSWORDCHAR
:
278 DPRINTF_EDIT_MSG("EM_GETPASSWORDCHAR");
279 lResult
= EDIT_EM_GetPasswordChar(wndPtr
, wParam
, lParam
);
282 DPRINTF_EDIT_MSG("EM_GETRECT");
283 lResult
= EDIT_EM_GetRect(wndPtr
, wParam
, lParam
);
286 DPRINTF_EDIT_MSG("EM_GETSEL");
287 lResult
= EDIT_EM_GetSel(wndPtr
, wParam
, lParam
);
290 DPRINTF_EDIT_MSG("EM_GETTHUMB");
291 lResult
= EDIT_EM_GetThumb(wndPtr
, wParam
, lParam
);
293 case EM_GETWORDBREAKPROC
:
294 DPRINTF_EDIT_MSG("EM_GETWORDBREAKPROC");
295 lResult
= EDIT_EM_GetWordBreakProc(wndPtr
, wParam
, lParam
);
298 DPRINTF_EDIT_MSG("EM_LIMITTEXT");
299 lResult
= EDIT_EM_LimitText(wndPtr
, wParam
, lParam
);
301 case EM_LINEFROMCHAR
:
302 DPRINTF_EDIT_MSG("EM_LINEFROMCHAR");
303 lResult
= EDIT_EM_LineFromChar(wndPtr
, wParam
, lParam
);
306 DPRINTF_EDIT_MSG("EM_LINEINDEX");
307 lResult
= EDIT_EM_LineIndex(wndPtr
, wParam
, lParam
);
310 DPRINTF_EDIT_MSG("EM_LINELENGTH");
311 lResult
= EDIT_EM_LineLength(wndPtr
, wParam
, lParam
);
314 DPRINTF_EDIT_MSG("EM_LINESCROLL");
315 lResult
= EDIT_EM_LineScroll(wndPtr
, wParam
, lParam
);
318 DPRINTF_EDIT_MSG("EM_REPLACESEL");
319 lResult
= EDIT_EM_ReplaceSel(wndPtr
, wParam
, lParam
);
322 DPRINTF_EDIT_MSG("EM_SCROLL");
323 lResult
= EDIT_EM_Scroll(wndPtr
, wParam
, lParam
);
326 DPRINTF_EDIT_MSG("EM_SETHANDLE");
327 lResult
= EDIT_EM_SetHandle(wndPtr
, wParam
, lParam
);
330 DPRINTF_EDIT_MSG("EM_SETMODIFY");
331 lResult
= EDIT_EM_SetModify(wndPtr
, wParam
, lParam
);
333 case EM_SETPASSWORDCHAR
:
334 DPRINTF_EDIT_MSG("EM_SETPASSWORDCHAR");
335 lResult
= EDIT_EM_SetPasswordChar(wndPtr
, wParam
, lParam
);
338 DPRINTF_EDIT_MSG("EM_SETREADONLY");
339 lResult
= EDIT_EM_SetReadOnly(wndPtr
, wParam
, lParam
);
342 DPRINTF_EDIT_MSG("EM_SETRECT");
343 lResult
= EDIT_EM_SetRect(wndPtr
, wParam
, lParam
);
346 DPRINTF_EDIT_MSG("EM_SETRECTNP");
347 lResult
= EDIT_EM_SetRectNP(wndPtr
, wParam
, lParam
);
350 DPRINTF_EDIT_MSG("EM_SETSEL");
351 lResult
= EDIT_EM_SetSel(wndPtr
, wParam
, lParam
);
354 DPRINTF_EDIT_MSG("EM_SETTABSTOPS");
355 lResult
= EDIT_EM_SetTabStops(wndPtr
, wParam
, lParam
);
357 case EM_SETWORDBREAKPROC
:
358 DPRINTF_EDIT_MSG("EM_SETWORDBREAKPROC");
359 lResult
= EDIT_EM_SetWordBreakProc(wndPtr
, wParam
, lParam
);
363 DPRINTF_EDIT_MSG("EM_UNDO / WM_UNDO");
364 lResult
= EDIT_EM_Undo(wndPtr
, wParam
, lParam
);
367 DPRINTF_EDIT_MSG("WM_GETDLGCODE");
368 lResult
= EDIT_WM_GetDlgCode(wndPtr
, wParam
, lParam
);
371 DPRINTF_EDIT_MSG("WM_CHAR");
372 lResult
= EDIT_WM_Char(wndPtr
, wParam
, lParam
);
375 DPRINTF_EDIT_MSG("WM_CLEAR");
376 lResult
= EDIT_WM_Clear(wndPtr
, wParam
, lParam
);
379 DPRINTF_EDIT_MSG("WM_COPY");
380 lResult
= EDIT_WM_Copy(wndPtr
, wParam
, lParam
);
383 DPRINTF_EDIT_MSG("WM_CREATE");
384 lResult
= EDIT_WM_Create(wndPtr
, wParam
, lParam
);
387 DPRINTF_EDIT_MSG("WM_CUT");
388 lResult
= EDIT_WM_Cut(wndPtr
, wParam
, lParam
);
391 DPRINTF_EDIT_MSG("WM_DESTROY");
392 lResult
= EDIT_WM_Destroy(wndPtr
, wParam
, lParam
);
395 DPRINTF_EDIT_MSG("WM_ENABLE");
396 lResult
= EDIT_WM_Enable(wndPtr
, wParam
, lParam
);
399 DPRINTF_EDIT_MSG("WM_ERASEBKGND");
400 lResult
= EDIT_WM_EraseBkGnd(wndPtr
, wParam
, lParam
);
403 DPRINTF_EDIT_MSG("WM_GETFONT");
404 lResult
= EDIT_WM_GetFont(wndPtr
, wParam
, lParam
);
407 DPRINTF_EDIT_MSG("WM_GETTEXT");
408 lResult
= EDIT_WM_GetText(wndPtr
, wParam
, lParam
);
410 case WM_GETTEXTLENGTH
:
411 DPRINTF_EDIT_MSG("WM_GETTEXTLENGTH");
412 lResult
= EDIT_WM_GetTextLength(wndPtr
, wParam
, lParam
);
415 DPRINTF_EDIT_MSG("WM_HSCROLL");
416 lResult
= EDIT_WM_HScroll(wndPtr
, wParam
, lParam
);
419 DPRINTF_EDIT_MSG("WM_KEYDOWN");
420 lResult
= EDIT_WM_KeyDown(wndPtr
, wParam
, lParam
);
423 DPRINTF_EDIT_MSG("WM_KILLFOCUS");
424 lResult
= EDIT_WM_KillFocus(wndPtr
, wParam
, lParam
);
426 case WM_LBUTTONDBLCLK
:
427 DPRINTF_EDIT_MSG("WM_LBUTTONDBLCLK");
428 lResult
= EDIT_WM_LButtonDblClk(wndPtr
, wParam
, lParam
);
431 DPRINTF_EDIT_MSG("WM_LBUTTONDOWN");
432 lResult
= EDIT_WM_LButtonDown(wndPtr
, wParam
, lParam
);
435 DPRINTF_EDIT_MSG("WM_LBUTTONUP");
436 lResult
= EDIT_WM_LButtonUp(wndPtr
, wParam
, lParam
);
440 * DPRINTF_EDIT_MSG("WM_MOUSEMOVE");
442 lResult
= EDIT_WM_MouseMove(wndPtr
, wParam
, lParam
);
445 DPRINTF_EDIT_MSG("WM_PAINT");
446 lResult
= EDIT_WM_Paint(wndPtr
, wParam
, lParam
);
449 DPRINTF_EDIT_MSG("WM_PASTE");
450 lResult
= EDIT_WM_Paste(wndPtr
, wParam
, lParam
);
454 * DPRINTF_EDIT_MSG("WM_SETCURSOR");
456 lResult
= EDIT_WM_SetCursor(wndPtr
, wParam
, lParam
);
459 DPRINTF_EDIT_MSG("WM_SETFOCUS");
460 lResult
= EDIT_WM_SetFocus(wndPtr
, wParam
, lParam
);
463 DPRINTF_EDIT_MSG("WM_SETFONT");
464 lResult
= EDIT_WM_SetFont(wndPtr
, wParam
, lParam
);
467 DPRINTF_EDIT_MSG("WM_SETREDRAW");
468 lResult
= EDIT_WM_SetRedraw(wndPtr
, wParam
, lParam
);
471 DPRINTF_EDIT_MSG("WM_SETTEXT");
472 lResult
= EDIT_WM_SetText(wndPtr
, wParam
, lParam
);
475 DPRINTF_EDIT_MSG("WM_SIZE");
476 lResult
= EDIT_WM_Size(wndPtr
, wParam
, lParam
);
479 DPRINTF_EDIT_MSG("WM_VSCROLL");
480 lResult
= EDIT_WM_VScroll(wndPtr
, wParam
, lParam
);
484 fprintf(stdnimp
, "edit: undocumented message %d >= WM_USER, please report.\n", msg
);
485 lResult
= DefWindowProc16(hwnd
, msg
, wParam
, lParam
);
488 EDIT_ReleasePointer(wndPtr
);
493 /*********************************************************************
497 * Build array of pointers to text lines.
498 * Lines can end with '\0' (last line), nothing (if it is too long),
499 * a delimiter (usually ' '), a soft return '\r\r\n' or a hard return '\r\n'
502 static void EDIT_BuildLineDefs(WND
*wndPtr
)
504 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
505 char *text
= EDIT_GetPasswordPointer(wndPtr
);
506 int ww
= EDIT_GetWndWidth(wndPtr
);
516 hdc
= GetDC(wndPtr
->hwndSelf
);
517 hFont
= (HFONT
)EDIT_WM_GetFont(wndPtr
, 0, 0L);
519 oldFont
= SelectObject(hdc
, hFont
);
521 if (!IsMultiLine(wndPtr
)) {
523 es
->LineDefs
= xrealloc(es
->LineDefs
, sizeof(LINEDEF
));
524 es
->LineDefs
[0].offset
= 0;
525 es
->LineDefs
[0].length
= EDIT_WM_GetTextLength(wndPtr
, 0, 0L);
526 es
->LineDefs
[0].ending
= END_0
;
527 es
->TextWidth
= LOWORD(GetTabbedTextExtent(hdc
, text
,
528 es
->LineDefs
[0].length
,
529 es
->NumTabStops
, es
->TabStops
));
534 if (!(cp
= strstr(start
, "\r\n"))) {
536 length
= strlen(start
);
537 } else if ((cp
> start
) && (*(cp
- 1) == '\r')) {
539 length
= cp
- start
- 1;
544 width
= LOWORD(GetTabbedTextExtent(hdc
, start
, length
,
545 es
->NumTabStops
, es
->TabStops
));
547 if (IsWordWrap(wndPtr
) && (width
> ww
)) {
551 next
= EDIT_CallWordBreakProc(wndPtr
, start
,
552 prev
+ 1, length
, WB_RIGHT
);
553 width
= LOWORD(GetTabbedTextExtent(hdc
, start
, next
,
554 es
->NumTabStops
, es
->TabStops
));
555 } while (width
<= ww
);
561 width
= LOWORD(GetTabbedTextExtent(hdc
, start
, next
,
562 es
->NumTabStops
, es
->TabStops
));
563 } while (width
<= ww
);
567 if (EDIT_CallWordBreakProc(wndPtr
, start
, length
- 1,
568 length
, WB_ISDELIMITER
)) {
570 ending
= END_DELIMIT
;
573 width
= LOWORD(GetTabbedTextExtent(hdc
, start
, length
,
574 es
->NumTabStops
, es
->TabStops
));
577 es
->LineDefs
= xrealloc(es
->LineDefs
, (es
->LineCount
+ 1) * sizeof(LINEDEF
));
578 es
->LineDefs
[es
->LineCount
].offset
= start
- text
;
579 es
->LineDefs
[es
->LineCount
].length
= length
;
580 es
->LineDefs
[es
->LineCount
].ending
= ending
;
582 es
->TextWidth
= MAX(es
->TextWidth
, width
);
598 } while (*start
|| (ending
== END_SOFT
) || (ending
== END_HARD
));
601 SelectObject(hdc
, oldFont
);
602 ReleaseDC(wndPtr
->hwndSelf
, hdc
);
608 /*********************************************************************
610 * EDIT_CallWordBreakProc
612 * Call appropriate WordBreakProc (internal or external).
615 static INT
EDIT_CallWordBreakProc(WND
*wndPtr
, char *s
, INT index
, INT count
, INT action
)
617 EDITWORDBREAKPROC wbp
= (EDITWORDBREAKPROC
)EDIT_EM_GetWordBreakProc(wndPtr
, 0, 0L);
620 return CallWordBreakProc((FARPROC16
)wbp
,
621 (LONG
)MAKE_SEGPTR(s
), index
, count
, action
);
623 return EDIT_WordBreakProc(s
, index
, count
, action
);
627 /*********************************************************************
631 * Calculates, for a given line and X-coordinate on the screen, the column.
634 static UINT
EDIT_ColFromWndX(WND
*wndPtr
, UINT line
, INT x
)
636 UINT lc
= (UINT
)EDIT_EM_GetLineCount(wndPtr
, 0, 0L);
637 UINT li
= (UINT
)EDIT_EM_LineIndex(wndPtr
, line
, 0L);
638 UINT ll
= (UINT
)EDIT_EM_LineLength(wndPtr
, li
, 0L);
641 line
= MAX(0, MIN(line
, lc
- 1));
642 for (i
= 0 ; i
< ll
; i
++)
643 if (EDIT_WndXFromCol(wndPtr
, line
, i
) >= x
)
649 /*********************************************************************
653 * Delete all characters on this line to right of cursor.
656 static void EDIT_DelEnd(WND
*wndPtr
)
658 EDIT_EM_SetSel(wndPtr
, 1, MAKELPARAM(-1, 0));
659 EDIT_MoveEnd(wndPtr
, TRUE
);
660 EDIT_WM_Clear(wndPtr
, 0, 0L);
664 /*********************************************************************
668 * Delete character to left of cursor.
671 static void EDIT_DelLeft(WND
*wndPtr
)
673 EDIT_EM_SetSel(wndPtr
, 1, MAKELPARAM(-1, 0));
674 EDIT_MoveBackward(wndPtr
, TRUE
);
675 EDIT_WM_Clear(wndPtr
, 0, 0L);
679 /*********************************************************************
683 * Delete character to right of cursor.
686 static void EDIT_DelRight(WND
*wndPtr
)
688 EDIT_EM_SetSel(wndPtr
, 1, MAKELPARAM(-1, 0));
689 EDIT_MoveForward(wndPtr
, TRUE
);
690 EDIT_WM_Clear(wndPtr
, 0, 0L);
694 /*********************************************************************
696 * EDIT_GetAveCharWidth
699 static UINT
EDIT_GetAveCharWidth(WND
*wndPtr
)
701 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
703 return es
->AveCharWidth
;
707 /*********************************************************************
712 static UINT
EDIT_GetLineHeight(WND
*wndPtr
)
714 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
716 return es
->LineHeight
;
720 /*********************************************************************
724 * Calculates the bounding rectangle for a line from a starting
725 * column to an ending column.
728 static void EDIT_GetLineRect(WND
*wndPtr
, UINT line
, UINT scol
, UINT ecol
, LPRECT16 rc
)
730 rc
->top
= EDIT_WndYFromLine(wndPtr
, line
);
731 rc
->bottom
= rc
->top
+ EDIT_GetLineHeight(wndPtr
);
732 rc
->left
= EDIT_WndXFromCol(wndPtr
, line
, scol
);
733 rc
->right
= ((INT
)ecol
== -1) ? EDIT_GetWndWidth(wndPtr
) :
734 EDIT_WndXFromCol(wndPtr
, line
, ecol
);
738 /*********************************************************************
742 * This acts as a LOCAL_Lock(), but it locks only once. This way
743 * you can call it whenever you like, without unlocking.
746 static char *EDIT_GetPointer(WND
*wndPtr
)
748 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
750 if (!es
->text
&& es
->hBuf
)
751 es
->text
= LOCAL_Lock(wndPtr
->hInstance
, es
->hBuf
);
756 /*********************************************************************
758 * EDIT_GetPasswordPointer
762 static char *EDIT_GetPasswordPointer(WND
*wndPtr
)
764 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
765 char *text
= xstrdup(EDIT_GetPointer(wndPtr
));
768 if(es
->PasswordChar
) {
771 if(*p
!= '\r' && *p
!= '\n')
772 *p
= es
->PasswordChar
;
780 /*********************************************************************
784 * Beware: This is not the function called on EM_GETRECT.
785 * It expects a (LPRECT) in lParam, not a (SEGPTR).
786 * It is used internally, as if there were no pointer difficulties.
789 static LRESULT
EDIT_GetRect(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
791 GetClientRect16( wndPtr
->hwndSelf
, (LPRECT16
)lParam
);
796 /*********************************************************************
801 static BOOL
EDIT_GetRedraw(WND
*wndPtr
)
803 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
809 /*********************************************************************
814 static UINT
EDIT_GetTextWidth(WND
*wndPtr
)
816 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
818 return es
->TextWidth
;
822 /*********************************************************************
824 * EDIT_GetVisibleLineCount
827 static UINT
EDIT_GetVisibleLineCount(WND
*wndPtr
)
831 EDIT_GetRect(wndPtr
, 0, (LPARAM
)&rc
);
832 return MAX(1, MAX(rc
.bottom
- rc
.top
, 0) / EDIT_GetLineHeight(wndPtr
));
836 /*********************************************************************
841 static UINT
EDIT_GetWndWidth(WND
*wndPtr
)
845 EDIT_GetRect(wndPtr
, 0, (LPARAM
)&rc
);
846 return rc
.right
- rc
.left
;
850 /*********************************************************************
855 static UINT
EDIT_GetXOffset(WND
*wndPtr
)
857 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
863 /*********************************************************************
865 * EDIT_InvalidateText
867 * Invalidate the text from offset start upto, but not including,
868 * offset end. Useful for (re)painting the selection.
869 * Regions outside the linewidth are not invalidated.
870 * end == -1 means end == TextLength.
871 * start and end need not be ordered.
874 static void EDIT_InvalidateText(WND
*wndPtr
, UINT start
, UINT end
)
876 UINT fv
= (UINT
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0L);
877 UINT vlc
= EDIT_GetVisibleLineCount(wndPtr
);
891 end
= (UINT
)EDIT_WM_GetTextLength(wndPtr
, 0, 0L);
892 ORDER_UINT(start
, end
);
893 sl
= (UINT
)EDIT_EM_LineFromChar(wndPtr
, start
, 0L);
894 el
= (UINT
)EDIT_EM_LineFromChar(wndPtr
, end
, 0L);
895 if ((el
< fv
) || (sl
> fv
+ vlc
))
898 sc
= start
- (UINT
)EDIT_EM_LineIndex(wndPtr
, sl
, 0L);
899 ec
= end
- (UINT
)EDIT_EM_LineIndex(wndPtr
, el
, 0L);
906 ec
= (UINT
)EDIT_EM_LineLength(wndPtr
,
907 (UINT
)EDIT_EM_LineIndex(wndPtr
, el
, 0L), 0L);
909 EDIT_GetRect(wndPtr
, 0, (LPARAM
)&rcWnd
);
911 EDIT_GetLineRect(wndPtr
, sl
, sc
, ec
, &rcLine
);
912 if (IntersectRect16(&rcUpdate
, &rcWnd
, &rcLine
))
913 InvalidateRect16( wndPtr
->hwndSelf
, &rcUpdate
, FALSE
);
915 EDIT_GetLineRect(wndPtr
, sl
, sc
,
916 (UINT
)EDIT_EM_LineLength(wndPtr
,
917 (UINT
)EDIT_EM_LineIndex(wndPtr
, sl
, 0L), 0L),
919 if (IntersectRect16(&rcUpdate
, &rcWnd
, &rcLine
))
920 InvalidateRect16( wndPtr
->hwndSelf
, &rcUpdate
, FALSE
);
921 for (l
= sl
+ 1 ; l
< el
; l
++) {
922 EDIT_GetLineRect(wndPtr
, l
, 0,
923 (UINT
)EDIT_EM_LineLength(wndPtr
,
924 (UINT
)EDIT_EM_LineIndex(wndPtr
, l
, 0L), 0L),
926 if (IntersectRect16(&rcUpdate
, &rcWnd
, &rcLine
))
927 InvalidateRect16(wndPtr
->hwndSelf
, &rcUpdate
, FALSE
);
929 EDIT_GetLineRect(wndPtr
, el
, 0, ec
, &rcLine
);
930 if (IntersectRect16(&rcUpdate
, &rcWnd
, &rcLine
))
931 InvalidateRect16( wndPtr
->hwndSelf
, &rcUpdate
, FALSE
);
936 /*********************************************************************
940 * Calculates, for a given Y-coordinate on the screen, the line.
943 static UINT
EDIT_LineFromWndY(WND
*wndPtr
, INT y
)
945 UINT fv
= (UINT
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0L);
946 UINT lh
= EDIT_GetLineHeight(wndPtr
);
947 UINT lc
= (UINT
)EDIT_EM_GetLineCount(wndPtr
, 0, 0L);
949 return MAX(0, MIN(lc
- 1, y
/ lh
+ fv
));
953 /*********************************************************************
957 * Try to fit size + 1 bytes in the buffer. Constrain to limits.
960 static BOOL
EDIT_MakeFit(WND
*wndPtr
, UINT size
)
962 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
964 if (size
<= es
->BufSize
)
966 if (size
> es
->BufLimit
)
968 size
= ((size
/ GROWLENGTH
) + 1) * GROWLENGTH
;
969 if (size
> es
->BufLimit
)
972 dprintf_edit(stddeb
, "edit: EDIT_MakeFit: trying to ReAlloc to %d+1\n", size
);
974 if (LOCAL_ReAlloc(wndPtr
->hInstance
, es
->hBuf
, size
+ 1, LMEM_MOVEABLE
)) {
975 es
->BufSize
= MIN(LOCAL_Size(wndPtr
->hInstance
, es
->hBuf
) - 1, es
->BufLimit
);
982 /*********************************************************************
987 static void EDIT_MoveBackward(WND
*wndPtr
, BOOL extend
)
989 UINT s
= LOWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
990 UINT e
= HIWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
991 UINT l
= (UINT
)EDIT_EM_LineFromChar(wndPtr
, e
, 0L);
992 UINT li
= (UINT
)EDIT_EM_LineIndex(wndPtr
, l
, 0L);
996 li
= (UINT
)EDIT_EM_LineIndex(wndPtr
, l
- 1, 0L);
997 e
= li
+ (UINT
)EDIT_EM_LineLength(wndPtr
, li
, 0L);
1003 EDIT_EM_SetSel(wndPtr
, 0, MAKELPARAM(s
, e
));
1007 /*********************************************************************
1012 static void EDIT_MoveDownward(WND
*wndPtr
, BOOL extend
)
1014 UINT s
= LOWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
1015 UINT e
= HIWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
1016 UINT l
= (UINT
)EDIT_EM_LineFromChar(wndPtr
, e
, 0L);
1017 UINT lc
= (UINT
)EDIT_EM_GetLineCount(wndPtr
, e
, 0L);
1018 UINT li
= (UINT
)EDIT_EM_LineIndex(wndPtr
, l
, 0L);
1022 x
= EDIT_WndXFromCol(wndPtr
, l
, e
- li
);
1024 e
= (UINT
)EDIT_EM_LineIndex(wndPtr
, l
, 0L) +
1025 EDIT_ColFromWndX(wndPtr
, l
, x
);
1029 EDIT_EM_SetSel(wndPtr
, 0, MAKELPARAM(s
, e
));
1033 /*********************************************************************
1038 static void EDIT_MoveEnd(WND
*wndPtr
, BOOL extend
)
1040 UINT s
= LOWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
1041 UINT e
= HIWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
1042 UINT l
= (UINT
)EDIT_EM_LineFromChar(wndPtr
, e
, 0L);
1043 UINT ll
= (UINT
)EDIT_EM_LineLength(wndPtr
, e
, 0L);
1044 UINT li
= (UINT
)EDIT_EM_LineIndex(wndPtr
, l
, 0L);
1049 EDIT_EM_SetSel(wndPtr
, 0, MAKELPARAM(s
, e
));
1053 /*********************************************************************
1058 static void EDIT_MoveForward(WND
*wndPtr
, BOOL extend
)
1060 UINT s
= LOWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
1061 UINT e
= HIWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
1062 UINT l
= (UINT
)EDIT_EM_LineFromChar(wndPtr
, e
, 0L);
1063 UINT lc
= (UINT
)EDIT_EM_GetLineCount(wndPtr
, e
, 0L);
1064 UINT ll
= (UINT
)EDIT_EM_LineLength(wndPtr
, e
, 0L);
1065 UINT li
= (UINT
)EDIT_EM_LineIndex(wndPtr
, l
, 0L);
1069 e
= (UINT
)EDIT_EM_LineIndex(wndPtr
, l
+ 1, 0L);
1074 EDIT_EM_SetSel(wndPtr
, 0, MAKELPARAM(s
, e
));
1078 /*********************************************************************
1082 * Home key: move to beginning of line.
1085 static void EDIT_MoveHome(WND
*wndPtr
, BOOL extend
)
1087 UINT s
= LOWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
1088 UINT e
= HIWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
1089 UINT l
= (UINT
)EDIT_EM_LineFromChar(wndPtr
, e
, 0L);
1090 UINT li
= (UINT
)EDIT_EM_LineIndex(wndPtr
, l
, 0L);
1095 EDIT_EM_SetSel(wndPtr
, 0, MAKELPARAM(s
, e
));
1099 /*********************************************************************
1104 static void EDIT_MovePageDown(WND
*wndPtr
, BOOL extend
)
1106 UINT s
= LOWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
1107 UINT e
= HIWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
1108 UINT l
= (UINT
)EDIT_EM_LineFromChar(wndPtr
, e
, 0L);
1109 UINT lc
= (UINT
)EDIT_EM_GetLineCount(wndPtr
, e
, 0L);
1110 UINT li
= (UINT
)EDIT_EM_LineIndex(wndPtr
, l
, 0L);
1114 x
= EDIT_WndXFromCol(wndPtr
, l
, e
- li
);
1115 l
= MIN(lc
- 1, l
+ EDIT_GetVisibleLineCount(wndPtr
));
1116 e
= (UINT
)EDIT_EM_LineIndex(wndPtr
, l
, 0L) +
1117 EDIT_ColFromWndX(wndPtr
, l
, x
);
1121 EDIT_EM_SetSel(wndPtr
, 0, MAKELPARAM(s
, e
));
1125 /*********************************************************************
1130 static void EDIT_MovePageUp(WND
*wndPtr
, BOOL extend
)
1132 UINT s
= LOWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
1133 UINT e
= HIWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
1134 UINT l
= (UINT
)EDIT_EM_LineFromChar(wndPtr
, e
, 0L);
1135 UINT li
= (UINT
)EDIT_EM_LineIndex(wndPtr
, l
, 0L);
1139 x
= EDIT_WndXFromCol(wndPtr
, l
, e
- li
);
1140 l
= MAX(0, l
- EDIT_GetVisibleLineCount(wndPtr
));
1141 e
= (UINT
)EDIT_EM_LineIndex(wndPtr
, l
, 0L) +
1142 EDIT_ColFromWndX(wndPtr
, l
, x
);
1146 EDIT_EM_SetSel(wndPtr
, 0, MAKELPARAM(s
, e
));
1150 /*********************************************************************
1155 static void EDIT_MoveUpward(WND
*wndPtr
, BOOL extend
)
1157 UINT s
= LOWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
1158 UINT e
= HIWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
1159 UINT l
= (UINT
)EDIT_EM_LineFromChar(wndPtr
, e
, 0L);
1160 UINT li
= (UINT
)EDIT_EM_LineIndex(wndPtr
, l
, 0L);
1164 x
= EDIT_WndXFromCol(wndPtr
, l
, e
- li
);
1166 e
= (UINT
)EDIT_EM_LineIndex(wndPtr
, l
, 0L) +
1167 EDIT_ColFromWndX(wndPtr
, l
, x
);
1171 EDIT_EM_SetSel(wndPtr
, 0, MAKELPARAM(s
, e
));
1175 /*********************************************************************
1177 * EDIT_MoveWordBackward
1180 static void EDIT_MoveWordBackward(WND
*wndPtr
, BOOL extend
)
1182 UINT s
= LOWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
1183 UINT e
= HIWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
1184 UINT l
= (UINT
)EDIT_EM_LineFromChar(wndPtr
, e
, 0L);
1185 UINT ll
= (UINT
)EDIT_EM_LineLength(wndPtr
, e
, 0L);
1186 UINT li
= (UINT
)EDIT_EM_LineIndex(wndPtr
, l
, 0L);
1191 li
= (UINT
)EDIT_EM_LineIndex(wndPtr
, l
- 1, 0L);
1192 e
= li
+ (UINT
)EDIT_EM_LineLength(wndPtr
, li
, 0L);
1195 text
= EDIT_GetPointer(wndPtr
);
1196 e
= li
+ (UINT
)EDIT_CallWordBreakProc(wndPtr
,
1197 text
+ li
, e
- li
, ll
, WB_LEFT
);
1201 EDIT_EM_SetSel(wndPtr
, 0, MAKELPARAM(s
, e
));
1205 /*********************************************************************
1207 * EDIT_MoveWordForward
1210 static void EDIT_MoveWordForward(WND
*wndPtr
, BOOL extend
)
1212 UINT s
= LOWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
1213 UINT e
= HIWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
1214 UINT l
= (UINT
)EDIT_EM_LineFromChar(wndPtr
, e
, 0L);
1215 UINT lc
= (UINT
)EDIT_EM_GetLineCount(wndPtr
, e
, 0L);
1216 UINT ll
= (UINT
)EDIT_EM_LineLength(wndPtr
, e
, 0L);
1217 UINT li
= (UINT
)EDIT_EM_LineIndex(wndPtr
, l
, 0L);
1222 e
= (UINT
)EDIT_EM_LineIndex(wndPtr
, l
+ 1, 0L);
1224 text
= EDIT_GetPointer(wndPtr
);
1225 e
= li
+ (UINT
)EDIT_CallWordBreakProc(wndPtr
,
1226 text
+ li
, e
- li
+ 1, ll
, WB_RIGHT
);
1230 EDIT_EM_SetSel(wndPtr
, 0, MAKELPARAM(s
, e
));
1234 /*********************************************************************
1239 static void EDIT_PaintLine(WND
*wndPtr
, HDC hdc
, UINT line
, BOOL rev
)
1241 UINT fv
= (UINT
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0L);
1242 UINT vlc
= EDIT_GetVisibleLineCount(wndPtr
);
1243 UINT lc
= (UINT
)EDIT_EM_GetLineCount(wndPtr
, 0, 0L);
1251 if ((line
< fv
) || (line
> fv
+ vlc
) || (line
>= lc
))
1254 dprintf_edit(stddeb
, "edit: EDIT_PaintLine: line=%d\n", line
);
1256 x
= EDIT_WndXFromCol(wndPtr
, line
, 0);
1257 y
= EDIT_WndYFromLine(wndPtr
, line
);
1258 li
= (UINT
)EDIT_EM_LineIndex(wndPtr
, line
, 0L);
1259 ll
= (UINT
)EDIT_EM_LineLength(wndPtr
, li
, 0L);
1260 s
= LOWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
1261 e
= HIWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
1263 s
= MIN(li
+ ll
, MAX(li
, s
));
1264 e
= MIN(li
+ ll
, MAX(li
, e
));
1265 if (rev
&& (s
!= e
) &&
1266 ((GetFocus() == wndPtr
->hwndSelf
) ||
1267 (wndPtr
->dwStyle
& ES_NOHIDESEL
))) {
1268 x
+= EDIT_PaintText(wndPtr
, hdc
, x
, y
, line
, 0, s
- li
, FALSE
);
1269 x
+= EDIT_PaintText(wndPtr
, hdc
, x
, y
, line
, s
- li
, e
- s
, TRUE
);
1270 x
+= EDIT_PaintText(wndPtr
, hdc
, x
, y
, line
, e
- li
, li
+ ll
- e
, FALSE
);
1272 x
+= EDIT_PaintText(wndPtr
, hdc
, x
, y
, line
, 0, ll
, FALSE
);
1276 /*********************************************************************
1281 static UINT
EDIT_PaintText(WND
*wndPtr
, HDC hdc
, INT x
, INT y
, UINT line
, UINT col
, UINT count
, BOOL rev
)
1283 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1293 BkColor
= GetBkColor(hdc
);
1294 TextColor
= GetTextColor(hdc
);
1296 SetBkColor(hdc
, GetSysColor(COLOR_HIGHLIGHT
));
1297 SetTextColor(hdc
, GetSysColor(COLOR_HIGHLIGHTTEXT
));
1299 text
= EDIT_GetPasswordPointer(wndPtr
);
1300 li
= (UINT
)EDIT_EM_LineIndex(wndPtr
, line
, 0L);
1301 xoff
= EDIT_GetXOffset(wndPtr
);
1302 ret
= LOWORD(TabbedTextOut(hdc
, x
, y
, text
+ li
+ col
, count
,
1303 es
->NumTabStops
, es
->TabStops
, -xoff
));
1306 SetBkColor(hdc
, BkColor
);
1307 SetTextColor(hdc
, TextColor
);
1313 /*********************************************************************
1315 * EDIT_ReleasePointer
1317 * This is the only helper function that can be called with es = NULL.
1318 * It is called at the end of EditWndProc() to unlock the buffer.
1321 static void EDIT_ReleasePointer(WND
*wndPtr
)
1323 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1327 if (es
->text
&& es
->hBuf
)
1328 LOCAL_Unlock(wndPtr
->hInstance
, es
->hBuf
);
1333 /*********************************************************************
1337 * Beware: This is not the function called on EM_REPLACESEL.
1338 * It expects a (char *) in lParam, not a (SEGPTR).
1339 * It is used internally, as if there were no pointer difficulties.
1342 static LRESULT
EDIT_ReplaceSel(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
1344 const char *str
= (char *)lParam
;
1345 int strl
= strlen(str
);
1346 UINT tl
= (UINT
)EDIT_WM_GetTextLength(wndPtr
, 0, 0L);
1347 UINT s
= LOWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
1348 UINT e
= HIWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
1355 if (!EDIT_MakeFit(wndPtr
, tl
- (e
- s
) + strl
)) {
1356 EDIT_NOTIFY_PARENT(wndPtr
, EN_MAXTEXT
);
1359 redraw
= EDIT_GetRedraw(wndPtr
);
1360 EDIT_WM_SetRedraw(wndPtr
, FALSE
, 0L);
1361 EDIT_WM_Clear(wndPtr
, 0, 0L);
1362 tl
= EDIT_WM_GetTextLength(wndPtr
, 0, 0L);
1363 e
= HIWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
1364 text
= EDIT_GetPointer(wndPtr
);
1365 for (p
= text
+ tl
; p
>= text
+ e
; p
--)
1367 for (i
= 0 , p
= text
+ e
; i
< strl
; i
++)
1370 AnsiUpperBuff(p
, strl
);
1371 else if(IsLower(wndPtr
))
1372 AnsiLowerBuff(p
, strl
);
1373 EDIT_BuildLineDefs(wndPtr
);
1375 EDIT_EM_SetSel(wndPtr
, 0, MAKELPARAM(e
, e
));
1376 EDIT_EM_SetModify(wndPtr
, TRUE
, 0L);
1377 EDIT_NOTIFY_PARENT(wndPtr
, EN_UPDATE
);
1378 EDIT_WM_SetRedraw(wndPtr
, redraw
, 0L);
1380 InvalidateRect32( wndPtr
->hwndSelf
, NULL
, TRUE
);
1381 EDIT_NOTIFY_PARENT(wndPtr
, EN_CHANGE
);
1387 /*********************************************************************
1389 * EDIT_ScrollIntoView
1391 * Makes sure the caret is visible.
1394 static void EDIT_ScrollIntoView(WND
*wndPtr
)
1396 UINT e
= HIWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
1397 UINT l
= (UINT
)EDIT_EM_LineFromChar(wndPtr
, e
, 0L);
1398 UINT li
= (UINT
)EDIT_EM_LineIndex(wndPtr
, l
, 0L);
1399 UINT fv
= (UINT
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0L);
1400 UINT vlc
= EDIT_GetVisibleLineCount(wndPtr
);
1401 UINT ww
= EDIT_GetWndWidth(wndPtr
);
1402 UINT cw
= EDIT_GetAveCharWidth(wndPtr
);
1403 INT x
= EDIT_WndXFromCol(wndPtr
, l
, e
- li
);
1408 dy
= l
- vlc
+ 1 - fv
;
1412 dx
= x
- ww
/ HSCROLL_FRACTION
/ cw
* cw
;
1414 dx
= x
- (HSCROLL_FRACTION
- 1) * ww
/ HSCROLL_FRACTION
/ cw
* cw
;
1416 EDIT_EM_LineScroll(wndPtr
, 0, MAKELPARAM(dy
, dx
));
1418 EDIT_NOTIFY_PARENT(wndPtr
, EN_VSCROLL
);
1420 EDIT_NOTIFY_PARENT(wndPtr
, EN_HSCROLL
);
1425 /*********************************************************************
1429 * Calculates, for a given line and column, the X-coordinate on the screen.
1432 static INT
EDIT_WndXFromCol(WND
*wndPtr
, UINT line
, UINT col
)
1434 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1435 char *text
= EDIT_GetPasswordPointer(wndPtr
);
1440 UINT lc
= (UINT
)EDIT_EM_GetLineCount(wndPtr
, 0, 0L);
1441 UINT li
= (UINT
)EDIT_EM_LineIndex(wndPtr
, line
, 0L);
1442 UINT ll
= (UINT
)EDIT_EM_LineLength(wndPtr
, li
, 0L);
1443 UINT xoff
= EDIT_GetXOffset(wndPtr
);
1445 hdc
= GetDC(wndPtr
->hwndSelf
);
1446 hFont
= (HFONT
)EDIT_WM_GetFont(wndPtr
, 0, 0L);
1448 oldFont
= SelectObject(hdc
, hFont
);
1449 line
= MAX(0, MIN(line
, lc
- 1));
1451 ret
= LOWORD(GetTabbedTextExtent(hdc
,
1453 es
->NumTabStops
, es
->TabStops
)) - xoff
;
1455 SelectObject(hdc
, oldFont
);
1456 ReleaseDC(wndPtr
->hwndSelf
, hdc
);
1462 /*********************************************************************
1466 * Calculates, for a given line, the Y-coordinate on the screen.
1469 static INT
EDIT_WndYFromLine(WND
*wndPtr
, UINT line
)
1471 UINT fv
= (UINT
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0L);
1472 UINT lh
= EDIT_GetLineHeight(wndPtr
);
1474 return (line
- fv
) * lh
;
1478 /*********************************************************************
1480 * EDIT_WordBreakProc
1482 * Find the beginning of words.
1483 * Note: unlike the specs for a WordBreakProc, this function only
1484 * allows to be called without linebreaks between s[0] upto
1485 * s[count - 1]. Remember it is only called
1486 * internally, so we can decide this for ourselves.
1489 static INT
EDIT_WordBreakProc(char *s
, INT index
, INT count
, INT action
)
1493 dprintf_edit(stddeb
, "edit: EDIT_WordBreakProc: s=%p, index=%d"
1494 ", count=%d, action=%d\n", s
, index
, count
, action
);
1502 if (s
[index
] == ' ') {
1503 while (index
&& (s
[index
] == ' '))
1506 while (index
&& (s
[index
] != ' '))
1508 if (s
[index
] == ' ')
1512 while (index
&& (s
[index
] != ' '))
1514 if (s
[index
] == ' ')
1524 if (s
[index
] == ' ')
1525 while ((index
< count
) && (s
[index
] == ' ')) index
++;
1527 while (s
[index
] && (s
[index
] != ' ') && (index
< count
))
1529 while ((s
[index
] == ' ') && (index
< count
)) index
++;
1533 case WB_ISDELIMITER
:
1534 ret
= (s
[index
] == ' ');
1537 fprintf(stderr
, "edit: EDIT_WordBreakProc: unknown action code, please report !\n");
1544 /*********************************************************************
1549 static LRESULT
EDIT_EM_CanUndo(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
1555 /*********************************************************************
1557 * EM_EMPTYUNDOBUFFER
1560 static LRESULT
EDIT_EM_EmptyUndoBuffer(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
1566 /*********************************************************************
1571 static LRESULT
EDIT_EM_FmtLines(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
1573 fprintf(stdnimp
, "edit: EM_FMTLINES: message not implemented.\n");
1574 return wParam
? -1L : 0L;
1578 /*********************************************************************
1580 * EM_GETFIRSTVISIBLELINE
1583 static LRESULT
EDIT_EM_GetFirstVisibleLine(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
1585 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1587 return (LRESULT
)es
->FirstVisibleLine
;
1591 /*********************************************************************
1596 static LRESULT
EDIT_EM_GetHandle(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
1598 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1600 return (LRESULT
)es
->hBuf
;
1604 /*********************************************************************
1609 static LRESULT
EDIT_EM_GetLine(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
1616 UINT lc
= (UINT
)EDIT_EM_GetLineCount(wndPtr
, 0, 0L);
1618 if (!IsMultiLine(wndPtr
))
1620 if ((UINT
)wParam
>= lc
)
1622 text
= EDIT_GetPointer(wndPtr
);
1623 src
= text
+ (UINT
)EDIT_EM_LineIndex(wndPtr
, wParam
, 0L);
1624 dst
= (char *)PTR_SEG_TO_LIN(lParam
);
1625 len
= MIN(*(WORD
*)dst
, (UINT
)EDIT_EM_LineLength(wndPtr
, wParam
, 0L));
1626 for (i
= 0 ; i
< len
; i
++) {
1631 return (LRESULT
)len
;
1635 /*********************************************************************
1640 static LRESULT
EDIT_EM_GetLineCount(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
1642 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1644 return (LRESULT
)es
->LineCount
;
1648 /*********************************************************************
1653 static LRESULT
EDIT_EM_GetModify(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
1655 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1657 return (LRESULT
)es
->TextChanged
;
1661 /*********************************************************************
1663 * EM_GETPASSWORDCHAR
1666 static LRESULT
EDIT_EM_GetPasswordChar(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
1668 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1670 return (LRESULT
)es
->PasswordChar
;
1674 /*********************************************************************
1679 static LRESULT
EDIT_EM_GetRect(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
1681 return EDIT_GetRect(wndPtr
, wParam
, (LPARAM
)PTR_SEG_TO_LIN(lParam
));
1685 /*********************************************************************
1690 static LRESULT
EDIT_EM_GetSel(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
1692 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1694 return MAKELONG(es
->SelStart
, es
->SelEnd
);
1698 /*********************************************************************
1702 * FIXME: undocumented: is this right ?
1705 static LRESULT
EDIT_EM_GetThumb(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
1707 return MAKELONG(EDIT_WM_VScroll(wndPtr
, EM_GETTHUMB
, 0L),
1708 EDIT_WM_HScroll(wndPtr
, EM_GETTHUMB
, 0L));
1712 /*********************************************************************
1714 * EM_GETWORDBREAKPROC
1717 static LRESULT
EDIT_EM_GetWordBreakProc(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
1719 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1721 return (LRESULT
)es
->WordBreakProc
;
1725 /*********************************************************************
1730 static LRESULT
EDIT_EM_LimitText(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
1732 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1734 if (IsMultiLine(wndPtr
)) {
1736 es
->BufLimit
= MIN((UINT
)wParam
, BUFLIMIT_MULTI
);
1738 es
->BufLimit
= BUFLIMIT_MULTI
;
1741 es
->BufLimit
= MIN((UINT
)wParam
, BUFLIMIT_SINGLE
);
1743 es
->BufLimit
= BUFLIMIT_SINGLE
;
1749 /*********************************************************************
1754 static LRESULT
EDIT_EM_LineFromChar(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
1758 if (!IsMultiLine(wndPtr
))
1760 if ((INT
)wParam
== -1)
1761 wParam
= HIWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
1762 l
= (UINT
)EDIT_EM_GetLineCount(wndPtr
, 0, 0L) - 1;
1763 while ((UINT
)EDIT_EM_LineIndex(wndPtr
, l
, 0L) > (UINT
)wParam
)
1769 /*********************************************************************
1774 static LRESULT
EDIT_EM_LineIndex(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
1776 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1779 UINT lc
= (UINT
)EDIT_EM_GetLineCount(wndPtr
, 0, 0L);
1781 if ((INT
)wParam
== -1) {
1782 e
= HIWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
1784 while (es
->LineDefs
[l
].offset
> e
)
1786 return (LRESULT
)es
->LineDefs
[l
].offset
;
1788 if ((UINT
)wParam
>= lc
)
1790 return (LRESULT
)es
->LineDefs
[(UINT
)wParam
].offset
;
1794 /*********************************************************************
1799 static LRESULT
EDIT_EM_LineLength(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
1801 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1807 if (!IsMultiLine(wndPtr
))
1808 return (LRESULT
)es
->LineDefs
[0].length
;
1809 if ((INT
)wParam
== -1) {
1810 s
= LOWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
1811 e
= HIWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
1812 sl
= (UINT
)EDIT_EM_LineFromChar(wndPtr
, s
, 0L);
1813 el
= (UINT
)EDIT_EM_LineFromChar(wndPtr
, e
, 0L);
1814 return (LRESULT
)(s
- es
->LineDefs
[sl
].offset
+
1815 es
->LineDefs
[el
].offset
+
1816 es
->LineDefs
[el
].length
- e
);
1818 return (LRESULT
)es
->LineDefs
[(UINT
)EDIT_EM_LineFromChar(wndPtr
, wParam
, 0L)].length
;
1822 /*********************************************************************
1827 static LRESULT
EDIT_EM_LineScroll(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
1829 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1830 UINT lc
= (UINT
)EDIT_EM_GetLineCount(wndPtr
, 0, 0L);
1831 UINT fv
= (UINT
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0L);
1832 UINT nfv
= MAX(0, fv
+ (INT
)LOWORD(lParam
));
1833 UINT xoff
= EDIT_GetXOffset(wndPtr
);
1834 UINT nxoff
= MAX(0, xoff
+ (INT
)HIWORD(lParam
));
1835 UINT tw
= EDIT_GetTextWidth(wndPtr
);
1847 dy
= EDIT_WndYFromLine(wndPtr
, fv
) - EDIT_WndYFromLine(wndPtr
, nfv
);
1849 if (wndPtr
->hwndSelf
== GetFocus())
1850 HideCaret(wndPtr
->hwndSelf
);
1851 if (EDIT_GetRedraw(wndPtr
)) {
1852 hRgn
= CreateRectRgn(0, 0, 0, 0);
1853 GetUpdateRgn(wndPtr
->hwndSelf
, hRgn
, FALSE
);
1854 ValidateRgn(wndPtr
->hwndSelf
, 0);
1855 OffsetRgn(hRgn
, dx
, dy
);
1856 InvalidateRgn( wndPtr
->hwndSelf
, hRgn
, TRUE
);
1858 ScrollWindow(wndPtr
->hwndSelf
, dx
, dy
, NULL
, NULL
);
1860 es
->FirstVisibleLine
= nfv
;
1861 es
->XOffset
= nxoff
;
1862 if (IsVScrollBar(wndPtr
))
1863 SetScrollPos(wndPtr
->hwndSelf
, SB_VERT
,
1864 EDIT_WM_VScroll(wndPtr
, EM_GETTHUMB
, 0L), TRUE
);
1865 if (IsHScrollBar(wndPtr
))
1866 SetScrollPos(wndPtr
->hwndSelf
, SB_HORZ
,
1867 EDIT_WM_HScroll(wndPtr
, EM_GETTHUMB
, 0L), TRUE
);
1868 if (wndPtr
->hwndSelf
== GetFocus()) {
1869 GetCaretPos16(&pos
);
1870 SetCaretPos(pos
.x
+ dx
, pos
.y
+ dy
);
1871 ShowCaret(wndPtr
->hwndSelf
);
1878 /*********************************************************************
1883 static LRESULT
EDIT_EM_ReplaceSel(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
1885 return (LRESULT
)EDIT_ReplaceSel(wndPtr
, wParam
,
1886 (LPARAM
)(char *)PTR_SEG_TO_LIN(lParam
));
1890 /*********************************************************************
1894 * FIXME: undocumented message.
1897 static LRESULT
EDIT_EM_Scroll(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
1899 fprintf(stdnimp
, "edit: EM_SCROLL: message not implemented (undocumented), please report.\n");
1904 /*********************************************************************
1909 static LRESULT
EDIT_EM_SetHandle(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
1911 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1913 if (IsMultiLine(wndPtr
)) {
1914 EDIT_ReleasePointer(wndPtr
);
1916 * old buffer is freed by caller
1918 es
->hBuf
= (HLOCAL16
)wParam
;
1919 es
->BufSize
= LOCAL_Size(wndPtr
->hInstance
, es
->hBuf
) - 1;
1921 es
->FirstVisibleLine
= 0;
1922 es
->SelStart
= es
->SelEnd
= 0;
1923 EDIT_EM_EmptyUndoBuffer(wndPtr
, 0, 0L);
1924 EDIT_EM_SetModify(wndPtr
, FALSE
, 0L);
1925 EDIT_BuildLineDefs(wndPtr
);
1926 if (EDIT_GetRedraw(wndPtr
))
1927 InvalidateRect32( wndPtr
->hwndSelf
, NULL
, TRUE
);
1928 EDIT_ScrollIntoView(wndPtr
);
1934 /*********************************************************************
1939 static LRESULT
EDIT_EM_SetModify(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
1941 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1943 es
->TextChanged
= (BOOL
)wParam
;
1948 /*********************************************************************
1950 * EM_SETPASSWORDCHAR
1953 static LRESULT
EDIT_EM_SetPasswordChar(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
1955 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1957 es
->PasswordChar
= (char)wParam
;
1962 /*********************************************************************
1967 static LRESULT
EDIT_EM_SetReadOnly(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
1970 wndPtr
->dwStyle
|= ES_READONLY
;
1972 wndPtr
->dwStyle
&= ~(DWORD
)ES_READONLY
;
1977 /*********************************************************************
1982 static LRESULT
EDIT_EM_SetRect(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
1984 fprintf(stdnimp
,"edit: EM_SETRECT: message not implemented, please report.\n");
1989 /*********************************************************************
1994 static LRESULT
EDIT_EM_SetRectNP(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
1996 fprintf(stdnimp
,"edit: EM_SETRECTNP: message not implemented, please report.\n");
2001 /*********************************************************************
2006 static LRESULT
EDIT_EM_SetSel(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
2008 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2009 UINT ns
= LOWORD(lParam
);
2010 UINT ne
= HIWORD(lParam
);
2011 UINT s
= LOWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
2012 UINT e
= HIWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
2015 UINT tl
= (UINT
)EDIT_WM_GetTextLength(wndPtr
, 0, 0L);
2017 if ((INT
)ns
== -1) {
2027 if (wndPtr
->hwndSelf
== GetFocus()) {
2028 el
= (UINT
)EDIT_EM_LineFromChar(wndPtr
, ne
, 0L);
2029 eli
= (UINT
)EDIT_EM_LineIndex(wndPtr
, el
, 0L);
2030 SetCaretPos(EDIT_WndXFromCol(wndPtr
, el
, ne
- eli
),
2031 EDIT_WndYFromLine(wndPtr
, el
));
2034 EDIT_ScrollIntoView(wndPtr
);
2035 if (EDIT_GetRedraw(wndPtr
)) {
2043 EDIT_InvalidateText(wndPtr
, s
, e
);
2044 EDIT_InvalidateText(wndPtr
, ns
, ne
);
2046 EDIT_InvalidateText(wndPtr
, s
, ne
);
2052 /*********************************************************************
2057 static LRESULT
EDIT_EM_SetTabStops(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
2059 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2061 if (!IsMultiLine(wndPtr
))
2065 es
->NumTabStops
= (UINT
)wParam
;
2067 es
->TabStops
= NULL
;
2069 es
->TabStops
= (LPINT16
)xmalloc(wParam
* sizeof(INT16
));
2070 memcpy(es
->TabStops
, (LPINT16
)PTR_SEG_TO_LIN(lParam
),
2071 (UINT
)wParam
* sizeof(INT16
));
2077 /*********************************************************************
2079 * EM_SETWORDBREAKPROC
2082 static LRESULT
EDIT_EM_SetWordBreakProc(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
2084 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2086 es
->WordBreakProc
= (EDITWORDBREAKPROC
)lParam
;
2091 /*********************************************************************
2096 static LRESULT
EDIT_EM_Undo(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
2102 /*********************************************************************
2107 static LRESULT
EDIT_WM_Char(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
2110 unsigned char c
= (unsigned char)wParam
;
2115 if (IsMultiLine(wndPtr
)) {
2116 if (IsReadOnly(wndPtr
)) {
2117 EDIT_MoveHome(wndPtr
, FALSE
);
2118 EDIT_MoveDownward(wndPtr
, FALSE
);
2120 EDIT_ReplaceSel(wndPtr
, 0, (LPARAM
)"\r\n");
2124 if (IsMultiLine(wndPtr
) && !IsReadOnly(wndPtr
))
2125 EDIT_ReplaceSel(wndPtr
, 0, (LPARAM
)"\t");
2128 if (!IsReadOnly(wndPtr
) && (c
>= ' ') && (c
!= 127)) {
2131 EDIT_ReplaceSel(wndPtr
, 0, (LPARAM
)str
);
2139 /*********************************************************************
2144 static LRESULT
EDIT_WM_Clear(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
2146 UINT s
= LOWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
2147 UINT e
= HIWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
2152 redraw
= EDIT_GetRedraw(wndPtr
);
2153 EDIT_WM_SetRedraw(wndPtr
, FALSE
, 0L);
2155 text
= EDIT_GetPointer(wndPtr
);
2156 strcpy(text
+ s
, text
+ e
);
2157 EDIT_BuildLineDefs(wndPtr
);
2158 EDIT_EM_SetSel(wndPtr
, 0, MAKELPARAM(s
, s
));
2159 EDIT_EM_SetModify(wndPtr
, TRUE
, 0L);
2160 EDIT_NOTIFY_PARENT(wndPtr
, EN_UPDATE
);
2161 EDIT_WM_SetRedraw(wndPtr
, redraw
, 0L);
2163 InvalidateRect32( wndPtr
->hwndSelf
, NULL
, TRUE
);
2164 EDIT_NOTIFY_PARENT(wndPtr
, EN_CHANGE
);
2171 /*********************************************************************
2176 static LRESULT
EDIT_WM_Copy(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
2178 UINT s
= LOWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
2179 UINT e
= HIWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
2189 hdst
= GlobalAlloc16(GMEM_MOVEABLE
, (DWORD
)(e
- s
+ 1));
2190 dst
= GlobalLock16(hdst
);
2191 text
= EDIT_GetPointer(wndPtr
);
2193 for (i
= 0 ; i
< e
- s
; i
++)
2196 GlobalUnlock16(hdst
);
2197 OpenClipboard(wndPtr
->hwndSelf
);
2199 SetClipboardData(CF_TEXT
, hdst
);
2205 /*********************************************************************
2210 static LRESULT
EDIT_WM_Create(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
2212 CREATESTRUCT16
*cs
= (CREATESTRUCT16
*)PTR_SEG_TO_LIN(lParam
);
2216 es
= xmalloc(sizeof(EDITSTATE
));
2217 memset(es
, 0, sizeof(EDITSTATE
));
2218 *(EDITSTATE
**)wndPtr
->wExtra
= es
;
2220 if (cs
->style
& WS_VSCROLL
)
2221 cs
->style
|= ES_AUTOVSCROLL
;
2222 if (cs
->style
& WS_HSCROLL
)
2223 cs
->style
|= ES_AUTOHSCROLL
;
2225 /* remove the WS_CAPTION style if it has been set - this is really a */
2226 /* pseudo option made from a combination of WS_BORDER and WS_DLGFRAME */
2227 if ((cs
->style
& WS_BORDER
) && (cs
->style
& WS_DLGFRAME
))
2228 cs
->style
^= WS_DLGFRAME
;
2230 if (IsMultiLine(wndPtr
)) {
2231 es
->BufSize
= BUFSTART_MULTI
;
2232 es
->BufLimit
= BUFLIMIT_MULTI
;
2233 es
->PasswordChar
= '\0';
2235 es
->BufSize
= BUFSTART_SINGLE
;
2236 es
->BufLimit
= BUFLIMIT_SINGLE
;
2237 es
->PasswordChar
= (cs
->style
& ES_PASSWORD
) ? '*' : '\0';
2239 if (!LOCAL_HeapSize(wndPtr
->hInstance
)) {
2240 if (!LocalInit(wndPtr
->hInstance
, 0,
2241 GlobalSize16(wndPtr
->hInstance
))) {
2242 fprintf(stderr
, "edit: WM_CREATE: could not initialize local heap\n");
2245 dprintf_edit(stddeb
, "edit: WM_CREATE: local heap initialized\n");
2247 if (!(es
->hBuf
= LOCAL_Alloc(wndPtr
->hInstance
, LMEM_MOVEABLE
, es
->BufSize
+ 1))) {
2248 fprintf(stderr
, "edit: WM_CREATE: unable to allocate buffer\n");
2251 es
->BufSize
= LOCAL_Size(wndPtr
->hInstance
, es
->hBuf
) - 1;
2252 text
= EDIT_GetPointer(wndPtr
);
2254 EDIT_BuildLineDefs(wndPtr
);
2255 EDIT_WM_SetFont(wndPtr
, 0, 0L);
2256 if (cs
->lpszName
&& *(char *)PTR_SEG_TO_LIN(cs
->lpszName
) != '\0')
2257 EDIT_EM_ReplaceSel(wndPtr
, FALSE
, (LPARAM
)cs
->lpszName
);
2258 EDIT_WM_SetRedraw(wndPtr
, TRUE
, 0L);
2263 /*********************************************************************
2268 static LRESULT
EDIT_WM_Cut(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
2270 EDIT_WM_Copy(wndPtr
, 0, 0L);
2271 EDIT_WM_Clear(wndPtr
, 0, 0L);
2276 /*********************************************************************
2281 static LRESULT
EDIT_WM_Destroy(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
2283 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2288 EDIT_ReleasePointer(wndPtr
);
2289 LOCAL_Free(wndPtr
->hInstance
, es
->hBuf
);
2291 *(EDITSTATE
**)&wndPtr
->wExtra
= NULL
;
2296 /*********************************************************************
2301 static LRESULT
EDIT_WM_Enable(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
2303 EDIT_InvalidateText(wndPtr
, 0, -1);
2308 /*********************************************************************
2313 static LRESULT
EDIT_WM_EraseBkGnd(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
2318 hBrush
= (HBRUSH
)EDIT_SEND_CTLCOLOR(wndPtr
, wParam
);
2320 hBrush
= (HBRUSH
)GetStockObject(WHITE_BRUSH
);
2322 GetClientRect16(wndPtr
->hwndSelf
, &rc
);
2323 IntersectClipRect((HDC
)wParam
, rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
2324 GetClipBox16((HDC
)wParam
, &rc
);
2326 * FIXME: specs say that we should UnrealizeObject() the brush,
2327 * but the specs of UnrealizeObject() say that we shouldn't
2328 * unrealize a stock object. The default brush that
2329 * DefWndProc() returns is ... a stock object.
2331 FillRect16((HDC
)wParam
, &rc
, hBrush
);
2336 /*********************************************************************
2341 static LRESULT
EDIT_WM_GetDlgCode(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
2343 return DLGC_HASSETSEL
| DLGC_WANTCHARS
| DLGC_WANTARROWS
;
2347 /*********************************************************************
2352 static LRESULT
EDIT_WM_GetFont(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
2354 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2356 return (LRESULT
)es
->hFont
;
2360 /*********************************************************************
2365 static LRESULT
EDIT_WM_GetText(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
2367 char *text
= EDIT_GetPointer(wndPtr
);
2369 LRESULT lResult
= 0L;
2372 if ((UINT
)wParam
> len
) {
2373 strcpy((char *)PTR_SEG_TO_LIN(lParam
), text
);
2374 lResult
= (LRESULT
)len
;
2380 /*********************************************************************
2385 static LRESULT
EDIT_WM_GetTextLength(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
2387 char *text
= EDIT_GetPointer(wndPtr
);
2389 return (LRESULT
)strlen(text
);
2393 /*********************************************************************
2397 * FIXME: scrollbar code itself is broken, so this one is a hack.
2400 static LRESULT
EDIT_WM_HScroll(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
2402 UINT ww
= EDIT_GetWndWidth(wndPtr
);
2403 UINT tw
= EDIT_GetTextWidth(wndPtr
);
2404 UINT cw
= EDIT_GetAveCharWidth(wndPtr
);
2405 UINT xoff
= EDIT_GetXOffset(wndPtr
);
2418 dx
= -ww
/ HSCROLL_FRACTION
/ cw
* cw
;
2421 dx
= ww
/ HSCROLL_FRACTION
/ cw
* cw
;
2433 case SB_THUMBPOSITION
:
2434 dx
= LOWORD(lParam
) * tw
/ 100 - xoff
;
2436 /* The next two are undocumented ! */
2438 ret
= tw
? MAKELONG(xoff
* 100 / tw
, 0) : 0;
2441 dx
= LOWORD(lParam
);
2448 EDIT_EM_LineScroll(wndPtr
, 0, MAKELPARAM(0, dx
));
2450 EDIT_NOTIFY_PARENT(wndPtr
, EN_HSCROLL
);
2456 /*********************************************************************
2460 * Handling of special keys that don't produce a WM_CHAR
2461 * (i.e. non-printable keys) & Backspace & Delete
2464 static LRESULT
EDIT_WM_KeyDown(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
2466 UINT s
= LOWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
2467 UINT e
= HIWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
2471 if (GetKeyState(VK_MENU
) & 0x8000)
2474 shift
= GetKeyState(VK_SHIFT
) & 0x8000;
2475 control
= GetKeyState(VK_CONTROL
) & 0x8000;
2480 if (IsMultiLine(wndPtr
) && (wParam
== VK_UP
))
2481 EDIT_MoveUpward(wndPtr
, shift
);
2484 EDIT_MoveWordBackward(wndPtr
, shift
);
2486 EDIT_MoveBackward(wndPtr
, shift
);
2490 if (IsMultiLine(wndPtr
) && (wParam
== VK_DOWN
))
2491 EDIT_MoveDownward(wndPtr
, shift
);
2493 EDIT_MoveWordForward(wndPtr
, shift
);
2495 EDIT_MoveForward(wndPtr
, shift
);
2498 EDIT_MoveHome(wndPtr
, shift
);
2501 EDIT_MoveEnd(wndPtr
, shift
);
2504 if (IsMultiLine(wndPtr
))
2505 EDIT_MovePageUp(wndPtr
, shift
);
2508 if (IsMultiLine(wndPtr
))
2509 EDIT_MovePageDown(wndPtr
, shift
);
2512 if (!IsReadOnly(wndPtr
) && !control
)
2514 EDIT_WM_Clear(wndPtr
, 0, 0L);
2516 EDIT_DelLeft(wndPtr
);
2519 if (!IsReadOnly(wndPtr
) && !(shift
&& control
))
2522 EDIT_WM_Cut(wndPtr
, 0, 0L);
2524 EDIT_WM_Clear(wndPtr
, 0, 0L);
2527 EDIT_DelLeft(wndPtr
);
2529 EDIT_DelEnd(wndPtr
);
2531 EDIT_DelRight(wndPtr
);
2536 if (!IsReadOnly(wndPtr
))
2537 EDIT_WM_Paste(wndPtr
, 0, 0L);
2539 EDIT_WM_Copy(wndPtr
, 0, 0L);
2546 /*********************************************************************
2551 static LRESULT
EDIT_WM_KillFocus(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
2557 if(!(wndPtr
->dwStyle
& ES_NOHIDESEL
)) {
2558 s
= LOWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
2559 e
= HIWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
2560 EDIT_InvalidateText(wndPtr
, s
, e
);
2562 EDIT_NOTIFY_PARENT(wndPtr
, EN_KILLFOCUS
);
2567 /*********************************************************************
2571 * The caret position has been set on the WM_LBUTTONDOWN message
2574 static LRESULT
EDIT_WM_LButtonDblClk(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
2577 UINT e
= HIWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
2578 UINT l
= (UINT
)EDIT_EM_LineFromChar(wndPtr
, e
, 0L);
2579 UINT li
= (UINT
)EDIT_EM_LineIndex(wndPtr
, l
, 0L);
2580 UINT ll
= (UINT
)EDIT_EM_LineLength(wndPtr
, e
, 0L);
2581 char *text
= EDIT_GetPointer(wndPtr
);
2583 s
= li
+ EDIT_CallWordBreakProc(wndPtr
, text
+ li
, e
- li
, ll
, WB_LEFT
);
2584 e
= li
+ EDIT_CallWordBreakProc(wndPtr
, text
+ li
, e
- li
, ll
, WB_RIGHT
);
2585 EDIT_EM_SetSel(wndPtr
, 0, MAKELPARAM(s
, e
));
2590 /*********************************************************************
2595 static LRESULT
EDIT_WM_LButtonDown(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
2597 INT x
= (INT
)LOWORD(lParam
);
2598 INT y
= (INT
)HIWORD(lParam
);
2599 UINT l
= EDIT_LineFromWndY(wndPtr
, y
);
2603 UINT fv
= (UINT
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0L);
2604 UINT vlc
= EDIT_GetVisibleLineCount(wndPtr
);
2607 SetFocus(wndPtr
->hwndSelf
);
2608 SetCapture(wndPtr
->hwndSelf
);
2609 l
= MIN(fv
+ vlc
- 1, MAX(fv
, l
));
2610 x
= MIN(EDIT_GetWndWidth(wndPtr
), MAX(0, x
));
2611 c
= EDIT_ColFromWndX(wndPtr
, l
, x
);
2612 li
= (UINT
)EDIT_EM_LineIndex(wndPtr
, l
, 0L);
2614 if (GetKeyState(VK_SHIFT
) & 0x8000)
2615 s
= LOWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
2618 EDIT_EM_SetSel(wndPtr
, 0, MAKELPARAM(s
, e
));
2623 /*********************************************************************
2628 static LRESULT
EDIT_WM_LButtonUp(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
2630 if (GetCapture() == wndPtr
->hwndSelf
)
2636 /*********************************************************************
2641 static LRESULT
EDIT_WM_MouseMove(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
2652 if (GetCapture() == wndPtr
->hwndSelf
) {
2653 x
= (INT
)LOWORD(lParam
);
2654 y
= (INT
)HIWORD(lParam
);
2655 fv
= (UINT
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0L);
2656 vlc
= EDIT_GetVisibleLineCount(wndPtr
);
2657 l
= EDIT_LineFromWndY(wndPtr
, y
);
2658 l
= MIN(fv
+ vlc
- 1, MAX(fv
, l
));
2659 x
= MIN(EDIT_GetWndWidth(wndPtr
), MAX(0, x
));
2660 c
= EDIT_ColFromWndX(wndPtr
, l
, x
);
2661 s
= LOWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
2662 li
= (UINT
)EDIT_EM_LineIndex(wndPtr
, l
, 0L);
2663 EDIT_EM_SetSel(wndPtr
, 1, MAKELPARAM(s
, li
+ c
));
2669 /*********************************************************************
2674 static LRESULT
EDIT_WM_Paint(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
2678 UINT fv
= (UINT
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0L);
2679 UINT vlc
= EDIT_GetVisibleLineCount(wndPtr
);
2680 UINT lc
= (UINT
)EDIT_EM_GetLineCount(wndPtr
, 0, 0L);
2687 BOOL rev
= IsWindowEnabled(wndPtr
->hwndSelf
) &&
2688 ((GetFocus() == wndPtr
->hwndSelf
) ||
2689 (wndPtr
->dwStyle
& ES_NOHIDESEL
));
2691 hdc
= BeginPaint16(wndPtr
->hwndSelf
, &ps
);
2692 GetClientRect16(wndPtr
->hwndSelf
, &rc
);
2693 IntersectClipRect(hdc
, rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
2694 hFont
= EDIT_WM_GetFont(wndPtr
, 0, 0L);
2696 oldFont
= SelectObject(hdc
, hFont
);
2697 EDIT_SEND_CTLCOLOR(wndPtr
, hdc
);
2698 if (!IsWindowEnabled(wndPtr
->hwndSelf
))
2699 SetTextColor(hdc
, GetSysColor(COLOR_GRAYTEXT
));
2700 GetClipBox16(hdc
, &rcRgn
);
2701 for (i
= fv
; i
<= MIN(fv
+ vlc
, fv
+ lc
- 1) ; i
++ ) {
2702 EDIT_GetLineRect(wndPtr
, i
, 0, -1, &rcLine
);
2703 if (IntersectRect16(&rc
, &rcRgn
, &rcLine
))
2704 EDIT_PaintLine(wndPtr
, hdc
, i
, rev
);
2707 SelectObject(hdc
, oldFont
);
2708 EndPaint16(wndPtr
->hwndSelf
, &ps
);
2713 /*********************************************************************
2718 static LRESULT
EDIT_WM_Paste(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
2723 OpenClipboard(wndPtr
->hwndSelf
);
2724 if ((hsrc
= GetClipboardData(CF_TEXT
))) {
2725 src
= (char *)GlobalLock16(hsrc
);
2726 EDIT_ReplaceSel(wndPtr
, 0, (LPARAM
)src
);
2727 GlobalUnlock16(hsrc
);
2734 /*********************************************************************
2739 static LRESULT
EDIT_WM_SetCursor(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
2741 if (LOWORD(lParam
) == HTCLIENT
) {
2742 SetCursor(LoadCursor16(0, IDC_IBEAM
));
2749 /*********************************************************************
2754 static LRESULT
EDIT_WM_SetFocus(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
2756 UINT s
= LOWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
2757 UINT e
= HIWORD(EDIT_EM_GetSel(wndPtr
, 0, 0L));
2759 CreateCaret(wndPtr
->hwndSelf
, 0, 2, EDIT_GetLineHeight(wndPtr
));
2760 EDIT_EM_SetSel(wndPtr
, 1, MAKELPARAM(s
, e
));
2761 if(!(wndPtr
->dwStyle
& ES_NOHIDESEL
))
2762 EDIT_InvalidateText(wndPtr
, s
, e
);
2763 ShowCaret(wndPtr
->hwndSelf
);
2764 EDIT_NOTIFY_PARENT(wndPtr
, EN_SETFOCUS
);
2769 /*********************************************************************
2774 static LRESULT
EDIT_WM_SetFont(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
2777 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2778 LPARAM sel
= EDIT_EM_GetSel(wndPtr
, 0, 0L);
2782 es
->hFont
= (HFONT
)wParam
;
2783 hdc
= GetDC(wndPtr
->hwndSelf
);
2785 oldFont
= SelectObject(hdc
, es
->hFont
);
2786 GetTextMetrics16(hdc
, &tm
);
2787 es
->LineHeight
= HIWORD(GetTextExtent(hdc
, "X", 1));
2788 es
->AveCharWidth
= tm
.tmAveCharWidth
;
2790 SelectObject(hdc
, oldFont
);
2791 ReleaseDC(wndPtr
->hwndSelf
, hdc
);
2792 EDIT_BuildLineDefs(wndPtr
);
2793 if ((BOOL
)lParam
&& EDIT_GetRedraw(wndPtr
))
2794 InvalidateRect32( wndPtr
->hwndSelf
, NULL
, TRUE
);
2795 if (wndPtr
->hwndSelf
== GetFocus()) {
2797 CreateCaret(wndPtr
->hwndSelf
, 0, 2, EDIT_GetLineHeight(wndPtr
));
2798 EDIT_EM_SetSel(wndPtr
, 1, sel
);
2799 ShowCaret(wndPtr
->hwndSelf
);
2805 /*********************************************************************
2810 static LRESULT
EDIT_WM_SetRedraw(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
2812 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2814 es
->Redraw
= (BOOL
)wParam
;
2819 /*********************************************************************
2824 static LRESULT
EDIT_WM_SetText(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
2826 EDIT_EM_SetSel(wndPtr
, 1, MAKELPARAM(0, -1));
2827 EDIT_WM_Clear(wndPtr
, 0, 0L);
2829 EDIT_EM_ReplaceSel(wndPtr
, 0, lParam
);
2830 EDIT_EM_EmptyUndoBuffer(wndPtr
, 0, 0L);
2831 EDIT_EM_SetModify(wndPtr
, TRUE
, 0L);
2832 EDIT_ScrollIntoView(wndPtr
);
2837 /*********************************************************************
2842 static LRESULT
EDIT_WM_Size(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
2844 if (EDIT_GetRedraw(wndPtr
) &&
2845 ((wParam
== SIZE_MAXIMIZED
) ||
2846 (wParam
== SIZE_RESTORED
))) {
2847 if (IsMultiLine(wndPtr
) && IsWordWrap(wndPtr
))
2848 EDIT_BuildLineDefs(wndPtr
);
2849 InvalidateRect32( wndPtr
->hwndSelf
, NULL
, TRUE
);
2855 /*********************************************************************
2859 * FIXME: scrollbar code itself is broken, so this one is a hack.
2862 static LRESULT
EDIT_WM_VScroll(WND
*wndPtr
, WPARAM wParam
, LPARAM lParam
)
2864 UINT lc
= (UINT
)EDIT_EM_GetLineCount(wndPtr
, 0, 0L);
2865 UINT fv
= (UINT
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0L);
2866 UINT vlc
= EDIT_GetVisibleLineCount(wndPtr
);
2894 case SB_THUMBPOSITION
:
2895 dy
= LOWORD(lParam
) * (lc
- 1) / 100 - fv
;
2897 /* The next two are undocumented ! */
2899 ret
= (lc
> 1) ? MAKELONG(fv
* 100 / (lc
- 1), 0) : 0L;
2902 dy
= LOWORD(lParam
);
2909 EDIT_EM_LineScroll(wndPtr
, 0, MAKELPARAM(dy
, 0));
2911 EDIT_NOTIFY_PARENT(wndPtr
, EN_VSCROLL
);