4 * Copyright David W. Metcalfe, 1994
5 * Copyright William Magro, 1995, 1996
6 * Copyright Frans van Dorsselaer, 1996, 1997
11 * please read EDIT.TODO (and update it when you change things)
12 * It also contains a discussion about the 16 to 32 bit transition.
17 #define NO_TRANSITION_TYPES /* This file is Win32-clean */
31 #define BUFLIMIT_MULTI 65534 /* maximum text buffer length (not including '\0') */
32 /* FIXME: BTW, new specs say 65535 (do you dare ???) */
33 #define BUFLIMIT_SINGLE 32766
34 #define BUFSTART_MULTI 1024 /* starting length for multi-line control */
35 #define BUFSTART_SINGLE 256 /* starting length for single line control */
36 #define GROWLENGTH 64 /* buffers grow by this much */
37 #define HSCROLL_FRACTION 3 /* scroll window by 1/3 width */
56 HLOCAL16 hBuf16
; /* For when a 16-bit multiline edit
57 * control gets a EM_GETHANDLE (which
58 * should return 16-bit local heap).
59 * From that point on we _have_ to keep
60 * using 16-bit local heap (apps rely
61 * on that ... bummer).
63 HLOCAL32 hBuf32
; /* Don't worry about 'LOCAL'. LOCAL32 is
64 * identical to GLOBAL32, which is
65 * essentially a HANDLE32 created with
66 * HeapAlloc(GetProcessHeap(), ...) plus
67 * a global32 (and thus local32)
68 * descriptor, which we can return upon
70 * It is 32-bit linear addressing, so
73 LPSTR text
; /* Depending on the fact that we are a
74 * 16 or 32 bit control, this is the
75 * pointer that we get after
76 * LocalLock32(hBuf23) (which is a typecast :-)
77 * or LOCAL_Lock(hBuf16).
78 * This is always a 32-bit linear pointer.
81 LINEDEF
*LineDefs
; /* Internal table for (soft) linebreaks */
82 INT32 TextWidth
; /* width of the widest line in pixels */
83 INT32 XOffset
; /* offset of the viewport in pixels */
84 INT32 FirstVisibleLine
;
86 INT32 LineHeight
; /* height of a screen line in pixels */
87 INT32 AveCharWidth
; /* average character width in pixels */
93 INT32 SelStart
; /* offset of selection start, == SelEnd if no selection */
94 INT32 SelEnd
; /* offset of selection end == current caret position */
98 * FIXME: The following should probably be a (VOID *) that is
99 * typecast to either 16- or 32-bit callback when used,
100 * depending on the type of edit control (16 or 32 bit).
102 * EDITWORDBREAKPROC WordBreakProc;
104 * For now: no more application specific wordbreaking.
105 * (Internal wordbreak function still works)
114 #define SWAP_INT32(x,y) do { INT32 temp = (INT32)(x); (x) = (INT32)(y); (y) = temp; } while(0)
115 #define ORDER_INT32(x,y) do { if ((INT32)(y) < (INT32)(x)) SWAP_INT32((x),(y)); } while(0)
117 /* macros to access window styles */
118 #define IsMultiLine(wndPtr) ((wndPtr)->dwStyle & ES_MULTILINE)
119 #define IsVScrollBar(wndPtr) ((wndPtr)->dwStyle & WS_VSCROLL)
120 #define IsHScrollBar(wndPtr) ((wndPtr)->dwStyle & WS_HSCROLL)
121 #define IsReadOnly(wndPtr) ((wndPtr)->dwStyle & ES_READONLY)
122 #define IsWordWrap(wndPtr) (((wndPtr)->dwStyle & ES_AUTOHSCROLL) == 0)
123 #define IsPassword(wndPtr) ((wndPtr)->dwStyle & ES_PASSWORD)
124 #define IsLower(wndPtr) ((wndPtr)->dwStyle & ES_LOWERCASE)
125 #define IsUpper(wndPtr) ((wndPtr)->dwStyle & ES_UPPERCASE)
127 #define EDITSTATEPTR(wndPtr) (*(EDITSTATE **)((wndPtr)->wExtra))
129 #define EDIT_SEND_CTLCOLOR(wndPtr,hdc) \
130 (SendMessage32A((wndPtr)->parent->hwndSelf, WM_CTLCOLOREDIT, \
131 (WPARAM32)(hdc), (LPARAM)(wndPtr)->hwndSelf ))
132 #define EDIT_NOTIFY_PARENT(wndPtr, wNotifyCode) \
133 (SendMessage32A((wndPtr)->parent->hwndSelf, WM_COMMAND, \
134 MAKEWPARAM((wndPtr)->wIDmenu, wNotifyCode), \
135 (LPARAM)(wndPtr)->hwndSelf ))
136 #define DPRINTF_EDIT_MSG16(str) \
137 dprintf_edit(stddeb, \
138 "edit: 16 bit : " str ": hwnd=%08x, wParam=%08x, lParam=%08x\n ", \
139 (UINT32)hwnd, (UINT32)wParam, (UINT32)lParam)
140 #define DPRINTF_EDIT_MSG32(str) \
141 dprintf_edit(stddeb, \
142 "edit: 32 bit : " str ": hwnd=%08x, wParam=%08x, lParam=%08x\n", \
143 (UINT32)hwnd, (UINT32)wParam, (UINT32)lParam)
146 /*********************************************************************
150 * Files like these should really be kept in alphabetical order.
153 LRESULT
EditWndProc(HWND32 hwnd
, UINT32 msg
, WPARAM32 wParam
, LPARAM lParam
);
155 static void EDIT_BuildLineDefs(WND
*wndPtr
);
156 static INT32
EDIT_CallWordBreakProc(WND
*wndPtr
, LPSTR s
, INT32 index
, INT32 count
, INT32 action
);
157 static INT32
EDIT_ColFromWndX(WND
*wndPtr
, INT32 line
, INT32 x
);
158 static void EDIT_DelEnd(WND
*wndPtr
);
159 static void EDIT_DelLeft(WND
*wndPtr
);
160 static void EDIT_DelRight(WND
*wndPtr
);
161 static INT32
EDIT_GetAveCharWidth(WND
*wndPtr
);
162 static INT32
EDIT_GetLineHeight(WND
*wndPtr
);
163 static void EDIT_GetLineRect(WND
*wndPtr
, INT32 line
, INT32 scol
, INT32 ecol
, LPRECT32 rc
);
164 static LPSTR
EDIT_GetPointer(WND
*wndPtr
);
165 static LPSTR
EDIT_GetPasswordPointer(WND
*wndPtr
);
166 static BOOL32
EDIT_GetRedraw(WND
*wndPtr
);
167 static void EDIT_GetSel(WND
*wndPtr
, LPINT32 s
, LPINT32 e
);
168 static INT32
EDIT_GetTextWidth(WND
*wndPtr
);
169 static INT32
EDIT_GetVisibleLineCount(WND
*wndPtr
);
170 static INT32
EDIT_GetWndWidth(WND
*wndPtr
);
171 static INT32
EDIT_GetXOffset(WND
*wndPtr
);
172 static void EDIT_InvalidateText(WND
*wndPtr
, INT32 start
, INT32 end
);
173 static INT32
EDIT_LineFromWndY(WND
*wndPtr
, INT32 y
);
174 static BOOL32
EDIT_MakeFit(WND
*wndPtr
, INT32 size
);
175 static void EDIT_MoveBackward(WND
*wndPtr
, BOOL32 extend
);
176 static void EDIT_MoveDownward(WND
*wndPtr
, BOOL32 extend
);
177 static void EDIT_MoveEnd(WND
*wndPtr
, BOOL32 extend
);
178 static void EDIT_MoveForward(WND
*wndPtr
, BOOL32 extend
);
179 static void EDIT_MoveHome(WND
*wndPtr
, BOOL32 extend
);
180 static void EDIT_MovePageDown(WND
*wndPtr
, BOOL32 extend
);
181 static void EDIT_MovePageUp(WND
*wndPtr
, BOOL32 extend
);
182 static void EDIT_MoveUpward(WND
*wndPtr
, BOOL32 extend
);
183 static void EDIT_MoveWordBackward(WND
*wndPtr
, BOOL32 extend
);
184 static void EDIT_MoveWordForward(WND
*wndPtr
, BOOL32 extend
);
185 static void EDIT_PaintLine(WND
*wndPtr
, HDC32 hdc
, INT32 line
, BOOL32 rev
);
186 static INT32
EDIT_PaintText(WND
*wndPtr
, HDC32 hdc
, INT32 x
, INT32 y
, INT32 line
, INT32 col
, INT32 count
, BOOL32 rev
);
187 static void EDIT_ReleasePointer(WND
*wndPtr
);
188 static INT32
EDIT_WndXFromCol(WND
*wndPtr
, INT32 line
, INT32 col
);
189 static INT32
EDIT_WndYFromLine(WND
*wndPtr
, INT32 line
);
190 static INT32
EDIT_WordBreakProc(LPSTR s
, INT32 index
, INT32 count
, INT32 action
);
192 static LRESULT
EDIT_EM_CanUndo(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
193 static LRESULT
EDIT_EM_CharFromPos(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
194 static LRESULT
EDIT_EM_EmptyUndoBuffer(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
195 static LRESULT
EDIT_EM_FmtLines(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
196 static LRESULT
EDIT_EM_GetFirstVisibleLine(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
197 static LRESULT
EDIT_EM_GetHandle(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
198 static LRESULT
EDIT_EM_GetHandle16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
199 static LRESULT
EDIT_EM_GetLimitText(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
200 static LRESULT
EDIT_EM_GetLine(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
201 static LRESULT
EDIT_EM_GetLineCount(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
202 static LRESULT
EDIT_EM_GetMargins(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
203 static LRESULT
EDIT_EM_GetModify(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
204 static LRESULT
EDIT_EM_GetPasswordChar(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
205 static LRESULT
EDIT_EM_GetRect(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
206 static LRESULT
EDIT_EM_GetRect16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
207 static LRESULT
EDIT_EM_GetSel(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
208 static LRESULT
EDIT_EM_GetThumb(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
209 static LRESULT
EDIT_EM_GetWordBreakProc(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
210 static LRESULT
EDIT_EM_LineFromChar(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
211 static LRESULT
EDIT_EM_LineIndex(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
212 static LRESULT
EDIT_EM_LineLength(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
213 static LRESULT
EDIT_EM_LineScroll(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
214 static LRESULT
EDIT_EM_PosFromChar(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
215 static LRESULT
EDIT_EM_ReplaceSel(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
216 static LRESULT
EDIT_EM_Scroll(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
217 static LRESULT
EDIT_EM_ScrollCaret(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
218 static LRESULT
EDIT_EM_SetHandle(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
219 static LRESULT
EDIT_EM_SetHandle16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
220 static LRESULT
EDIT_EM_SetLimitText(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
221 static LRESULT
EDIT_EM_SetMargins(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
222 static LRESULT
EDIT_EM_SetModify(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
223 static LRESULT
EDIT_EM_SetPasswordChar(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
224 static LRESULT
EDIT_EM_SetReadOnly(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
225 static LRESULT
EDIT_EM_SetRect(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
226 static LRESULT
EDIT_EM_SetRectNP(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
227 static LRESULT
EDIT_EM_SetSel(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
228 static LRESULT
EDIT_EM_SetSel16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
229 static LRESULT
EDIT_EM_SetTabStops(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
230 static LRESULT
EDIT_EM_SetTabStops16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
231 static LRESULT
EDIT_EM_SetWordBreakProc(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
232 static LRESULT
EDIT_EM_Undo(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
234 static LRESULT
EDIT_WM_Char(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
235 static LRESULT
EDIT_WM_Clear(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
236 static LRESULT
EDIT_WM_Copy(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
237 static LRESULT
EDIT_WM_Cut(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
238 static LRESULT
EDIT_WM_Create(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
239 static LRESULT
EDIT_WM_Destroy(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
240 static LRESULT
EDIT_WM_Enable(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
241 static LRESULT
EDIT_WM_EraseBkGnd(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
242 static LRESULT
EDIT_WM_GetDlgCode(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
243 static LRESULT
EDIT_WM_GetFont(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
244 static LRESULT
EDIT_WM_GetText(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
245 static LRESULT
EDIT_WM_GetTextLength(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
246 static LRESULT
EDIT_WM_HScroll(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
247 static LRESULT
EDIT_WM_KeyDown(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
248 static LRESULT
EDIT_WM_KillFocus(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
249 static LRESULT
EDIT_WM_LButtonDblClk(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
250 static LRESULT
EDIT_WM_LButtonDown(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
251 static LRESULT
EDIT_WM_LButtonUp(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
252 static LRESULT
EDIT_WM_MouseMove(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
253 static LRESULT
EDIT_WM_Paint(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
254 static LRESULT
EDIT_WM_Paste(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
255 static LRESULT
EDIT_WM_SetCursor(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
256 static LRESULT
EDIT_WM_SetFocus(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
257 static LRESULT
EDIT_WM_SetFont(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
258 static LRESULT
EDIT_WM_SetRedraw(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
259 static LRESULT
EDIT_WM_SetText(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
260 static LRESULT
EDIT_WM_Size(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
261 static LRESULT
EDIT_WM_VScroll(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
264 /*********************************************************************
266 * General shortcuts for variable names:
270 * INT32 s; offset of selection start
271 * INT32 e; offset of selection end
272 * INT32 sl; line on which the selection starts
273 * INT32 el; line on which the selection ends
274 * INT32 sc; column on which the selection starts
275 * INT32 ec; column on which the selection ends
276 * INT32 li; line index (offset)
277 * INT32 fv; first visible line
278 * INT32 vlc; vissible line count
279 * INT32 lc; line count
280 * INT32 lh; line height (in pixels)
281 * INT32 tw; text width (in pixels)
282 * INT32 ww; window width (in pixels)
283 * INT32 cw; character width (average, in pixels)
288 /*********************************************************************
292 * The messages are in the order of the actual integer values
293 * (which can be found in include/windows.h)
294 * Whereever possible the 16 bit versions are converted to
295 * the 32 bit ones, so that we can 'fall through' to the
296 * helper functions. These are mostly 32 bit (with a few
297 * exceptions, clearly indicated by a '16' extension to their
301 LRESULT
EditWndProc(HWND32 hwnd
, UINT32 msg
, WPARAM32 wParam
, LPARAM lParam
)
304 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
306 if ((!EDITSTATEPTR(wndPtr
)) && (msg
!= WM_CREATE
))
307 return DefWindowProc32A(hwnd
, msg
, wParam
, lParam
);
311 DPRINTF_EDIT_MSG16("EM_GETSEL");
316 DPRINTF_EDIT_MSG32("EM_GETSEL");
317 lResult
= EDIT_EM_GetSel(wndPtr
, wParam
, lParam
);
321 DPRINTF_EDIT_MSG16("EM_SETSEL");
322 lResult
= EDIT_EM_SetSel16(wndPtr
, wParam
, lParam
);
325 DPRINTF_EDIT_MSG32("EM_SETSEL");
326 lResult
= EDIT_EM_SetSel(wndPtr
, wParam
, lParam
);
330 DPRINTF_EDIT_MSG16("EM_GETRECT");
331 lResult
= EDIT_EM_GetRect16(wndPtr
, wParam
, lParam
);
334 DPRINTF_EDIT_MSG32("EM_GETRECT");
335 lResult
= EDIT_EM_GetRect(wndPtr
, wParam
, lParam
);
339 DPRINTF_EDIT_MSG16("EM_SETRECT");
342 DPRINTF_EDIT_MSG32("EM_SETRECT");
343 lResult
= EDIT_EM_SetRect(wndPtr
, wParam
, lParam
);
347 DPRINTF_EDIT_MSG16("EM_SETRECTNP");
350 DPRINTF_EDIT_MSG32("EM_SETRECTNP");
351 lResult
= EDIT_EM_SetRectNP(wndPtr
, wParam
, lParam
);
355 DPRINTF_EDIT_MSG16("EM_SCROLL");
358 DPRINTF_EDIT_MSG32("EM_SCROLL");
359 lResult
= EDIT_EM_Scroll(wndPtr
, wParam
, lParam
);
362 case EM_LINESCROLL16
:
363 DPRINTF_EDIT_MSG16("EM_LINESCROLL");
364 wParam
= (WPARAM32
)(INT32
)(INT16
)HIWORD(lParam
);
365 lParam
= (LPARAM
)(INT32
)(INT16
)LOWORD(lParam
);
367 case EM_LINESCROLL32
:
368 DPRINTF_EDIT_MSG32("EM_LINESCROLL");
369 lResult
= EDIT_EM_LineScroll(wndPtr
, wParam
, lParam
);
372 case EM_SCROLLCARET16
:
373 DPRINTF_EDIT_MSG16("EM_SCROLLCARET");
375 case EM_SCROLLCARET32
:
376 DPRINTF_EDIT_MSG32("EM_SCROLLCARET");
377 lResult
= EDIT_EM_ScrollCaret(wndPtr
, wParam
, lParam
);
381 DPRINTF_EDIT_MSG16("EM_GETMODIFY");
384 DPRINTF_EDIT_MSG32("EM_GETMODIFY");
385 lResult
= EDIT_EM_GetModify(wndPtr
, wParam
, lParam
);
389 DPRINTF_EDIT_MSG16("EM_SETMODIFY");
392 DPRINTF_EDIT_MSG32("EM_SETMODIFY");
393 lResult
= EDIT_EM_SetModify(wndPtr
, wParam
, lParam
);
396 case EM_GETLINECOUNT16
:
397 DPRINTF_EDIT_MSG16("EM_GETLINECOUNT");
399 case EM_GETLINECOUNT32
:
400 DPRINTF_EDIT_MSG32("EM_GETLINECOUNT");
401 lResult
= EDIT_EM_GetLineCount(wndPtr
, wParam
, lParam
);
405 DPRINTF_EDIT_MSG16("EM_LINEINDEX");
408 DPRINTF_EDIT_MSG32("EM_LINEINDEX");
409 lResult
= EDIT_EM_LineIndex(wndPtr
, wParam
, lParam
);
413 DPRINTF_EDIT_MSG16("EM_SETHANDLE");
414 lResult
= EDIT_EM_SetHandle16(wndPtr
, wParam
, lParam
);
417 DPRINTF_EDIT_MSG32("EM_SETHANDLE");
418 lResult
= EDIT_EM_SetHandle(wndPtr
, wParam
, lParam
);
422 DPRINTF_EDIT_MSG16("EM_GETHANDLE");
423 lResult
= EDIT_EM_GetHandle16(wndPtr
, wParam
, lParam
);
426 DPRINTF_EDIT_MSG32("EM_GETHANDLE");
427 lResult
= EDIT_EM_GetHandle(wndPtr
, wParam
, lParam
);
431 DPRINTF_EDIT_MSG16("EM_GETTHUMB");
434 DPRINTF_EDIT_MSG32("EM_GETTHUMB");
435 lResult
= EDIT_EM_GetThumb(wndPtr
, wParam
, lParam
);
438 /* messages 0x00bf and 0x00c0 missing from specs */
441 DPRINTF_EDIT_MSG16("undocumented WM_USER+15, please report");
444 DPRINTF_EDIT_MSG32("undocumented 0x00bf, please report");
445 lResult
= DefWindowProc32A(hwnd
, msg
, wParam
, lParam
);
449 DPRINTF_EDIT_MSG16("undocumented WM_USER+16, please report");
452 DPRINTF_EDIT_MSG32("undocumented 0x00c0, please report");
453 lResult
= DefWindowProc32A(hwnd
, msg
, wParam
, lParam
);
456 case EM_LINELENGTH16
:
457 DPRINTF_EDIT_MSG16("EM_LINELENGTH");
459 case EM_LINELENGTH32
:
460 DPRINTF_EDIT_MSG32("EM_LINELENGTH");
461 lResult
= EDIT_EM_LineLength(wndPtr
, wParam
, lParam
);
464 case EM_REPLACESEL16
:
465 DPRINTF_EDIT_MSG16("EM_REPLACESEL");
466 lParam
= (LPARAM
)PTR_SEG_TO_LIN((SEGPTR
)lParam
);
468 case EM_REPLACESEL32
:
469 DPRINTF_EDIT_MSG32("EM_REPLACESEL");
470 lResult
= EDIT_EM_ReplaceSel(wndPtr
, wParam
, lParam
);
473 /* message 0x00c3 missing from specs */
476 DPRINTF_EDIT_MSG16("undocumented WM_USER+19, please report");
479 DPRINTF_EDIT_MSG32("undocumented 0x00c3, please report");
480 lResult
= DefWindowProc32A(hwnd
, msg
, wParam
, lParam
);
484 DPRINTF_EDIT_MSG16("EM_GETLINE");
485 lParam
= (LPARAM
)PTR_SEG_TO_LIN((SEGPTR
)lParam
);
488 DPRINTF_EDIT_MSG32("EM_GETLINE");
489 lResult
= EDIT_EM_GetLine(wndPtr
, wParam
, lParam
);
493 DPRINTF_EDIT_MSG16("EM_LIMITTEXT");
495 case EM_SETLIMITTEXT32
:
496 DPRINTF_EDIT_MSG32("EM_SETLIMITTEXT");
497 lResult
= EDIT_EM_SetLimitText(wndPtr
, wParam
, lParam
);
501 DPRINTF_EDIT_MSG16("EM_CANUNDO");
504 DPRINTF_EDIT_MSG32("EM_CANUNDO");
505 lResult
= EDIT_EM_CanUndo(wndPtr
, wParam
, lParam
);
509 DPRINTF_EDIT_MSG16("EM_UNDO");
514 DPRINTF_EDIT_MSG32("EM_UNDO / WM_UNDO");
515 lResult
= EDIT_EM_Undo(wndPtr
, wParam
, lParam
);
519 DPRINTF_EDIT_MSG16("EM_FMTLINES");
522 DPRINTF_EDIT_MSG32("EM_FMTLINES");
523 lResult
= EDIT_EM_FmtLines(wndPtr
, wParam
, lParam
);
526 case EM_LINEFROMCHAR16
:
527 DPRINTF_EDIT_MSG16("EM_LINEFROMCHAR");
529 case EM_LINEFROMCHAR32
:
530 DPRINTF_EDIT_MSG32("EM_LINEFROMCHAR");
531 lResult
= EDIT_EM_LineFromChar(wndPtr
, wParam
, lParam
);
534 /* message 0x00ca missing from specs */
537 DPRINTF_EDIT_MSG16("undocumented WM_USER+26, please report");
540 DPRINTF_EDIT_MSG32("undocumented 0x00ca, please report");
541 lResult
= DefWindowProc32A(hwnd
, msg
, wParam
, lParam
);
544 case EM_SETTABSTOPS16
:
545 DPRINTF_EDIT_MSG16("EM_SETTABSTOPS");
546 lResult
= EDIT_EM_SetTabStops16(wndPtr
, wParam
, lParam
);
548 case EM_SETTABSTOPS32
:
549 DPRINTF_EDIT_MSG32("EM_SETTABSTOPS");
550 lResult
= EDIT_EM_SetTabStops(wndPtr
, wParam
, lParam
);
553 case EM_SETPASSWORDCHAR16
:
554 DPRINTF_EDIT_MSG16("EM_SETPASSWORDCHAR");
556 case EM_SETPASSWORDCHAR32
:
557 DPRINTF_EDIT_MSG32("EM_SETPASSWORDCHAR");
558 lResult
= EDIT_EM_SetPasswordChar(wndPtr
, wParam
, lParam
);
561 case EM_EMPTYUNDOBUFFER16
:
562 DPRINTF_EDIT_MSG16("EM_EMPTYUNDOBUFFER");
564 case EM_EMPTYUNDOBUFFER32
:
565 DPRINTF_EDIT_MSG32("EM_EMPTYUNDOBUFFER");
566 lResult
= EDIT_EM_EmptyUndoBuffer(wndPtr
, wParam
, lParam
);
569 case EM_GETFIRSTVISIBLELINE16
:
570 DPRINTF_EDIT_MSG16("EM_GETFIRSTVISIBLELINE");
572 case EM_GETFIRSTVISIBLELINE32
:
573 DPRINTF_EDIT_MSG32("EM_GETFIRSTVISIBLELINE");
574 lResult
= EDIT_EM_GetFirstVisibleLine(wndPtr
, wParam
, lParam
);
577 case EM_SETREADONLY16
:
578 DPRINTF_EDIT_MSG16("EM_SETREADONLY");
580 case EM_SETREADONLY32
:
581 DPRINTF_EDIT_MSG32("EM_SETREADONLY");
582 lResult
= EDIT_EM_SetReadOnly(wndPtr
, wParam
, lParam
);
585 case EM_SETWORDBREAKPROC16
:
586 DPRINTF_EDIT_MSG16("EM_SETWORDBREAKPROC");
588 case EM_SETWORDBREAKPROC32
:
589 DPRINTF_EDIT_MSG32("EM_SETWORDBREAKPROC");
590 lResult
= EDIT_EM_SetWordBreakProc(wndPtr
, wParam
, lParam
);
593 case EM_GETWORDBREAKPROC16
:
594 DPRINTF_EDIT_MSG16("EM_GETWORDBREAKPROC");
596 case EM_GETWORDBREAKPROC32
:
597 DPRINTF_EDIT_MSG32("EM_GETWORDBREAKPROC");
598 lResult
= EDIT_EM_GetWordBreakProc(wndPtr
, wParam
, lParam
);
601 case EM_GETPASSWORDCHAR16
:
602 DPRINTF_EDIT_MSG16("EM_GETPASSWORDCHAR");
604 case EM_GETPASSWORDCHAR32
:
605 DPRINTF_EDIT_MSG32("EM_GETPASSWORDCHAR");
606 lResult
= EDIT_EM_GetPasswordChar(wndPtr
, wParam
, lParam
);
609 /* The following EM_xxx are new to win95 and don't exist for 16 bit */
611 case EM_SETMARGINS32
:
612 DPRINTF_EDIT_MSG16("EM_SETMARGINS");
613 lResult
= EDIT_EM_SetMargins(wndPtr
, wParam
, lParam
);
616 case EM_GETMARGINS32
:
617 DPRINTF_EDIT_MSG16("EM_GETMARGINS");
618 lResult
= EDIT_EM_GetMargins(wndPtr
, wParam
, lParam
);
621 case EM_GETLIMITTEXT32
:
622 DPRINTF_EDIT_MSG16("EM_GETLIMITTEXT");
623 lResult
= EDIT_EM_GetLimitText(wndPtr
, wParam
, lParam
);
626 case EM_POSFROMCHAR32
:
627 DPRINTF_EDIT_MSG16("EM_POSFROMCHAR");
628 lResult
= EDIT_EM_PosFromChar(wndPtr
, wParam
, lParam
);
631 case EM_CHARFROMPOS32
:
632 DPRINTF_EDIT_MSG16("EM_CHARFROMPOS");
633 lResult
= EDIT_EM_CharFromPos(wndPtr
, wParam
, lParam
);
637 DPRINTF_EDIT_MSG32("WM_GETDLGCODE");
638 lResult
= EDIT_WM_GetDlgCode(wndPtr
, wParam
, lParam
);
642 DPRINTF_EDIT_MSG32("WM_CHAR");
643 lResult
= EDIT_WM_Char(wndPtr
, wParam
, lParam
);
647 DPRINTF_EDIT_MSG32("WM_CLEAR");
648 lResult
= EDIT_WM_Clear(wndPtr
, wParam
, lParam
);
652 DPRINTF_EDIT_MSG32("WM_COPY");
653 lResult
= EDIT_WM_Copy(wndPtr
, wParam
, lParam
);
657 DPRINTF_EDIT_MSG32("WM_CREATE");
658 lResult
= EDIT_WM_Create(wndPtr
, wParam
, lParam
);
662 DPRINTF_EDIT_MSG32("WM_CUT");
663 lResult
= EDIT_WM_Cut(wndPtr
, wParam
, lParam
);
667 DPRINTF_EDIT_MSG32("WM_DESTROY");
668 lResult
= EDIT_WM_Destroy(wndPtr
, wParam
, lParam
);
672 DPRINTF_EDIT_MSG32("WM_ENABLE");
673 lResult
= EDIT_WM_Enable(wndPtr
, wParam
, lParam
);
677 DPRINTF_EDIT_MSG32("WM_ERASEBKGND");
678 lResult
= EDIT_WM_EraseBkGnd(wndPtr
, wParam
, lParam
);
682 DPRINTF_EDIT_MSG32("WM_GETFONT");
683 lResult
= EDIT_WM_GetFont(wndPtr
, wParam
, lParam
);
687 DPRINTF_EDIT_MSG32("WM_GETTEXT");
688 lResult
= EDIT_WM_GetText(wndPtr
, wParam
, lParam
);
691 case WM_GETTEXTLENGTH
:
692 DPRINTF_EDIT_MSG32("WM_GETTEXTLENGTH");
693 lResult
= EDIT_WM_GetTextLength(wndPtr
, wParam
, lParam
);
697 DPRINTF_EDIT_MSG32("WM_HSCROLL");
698 lResult
= EDIT_WM_HScroll(wndPtr
, wParam
, lParam
);
702 DPRINTF_EDIT_MSG32("WM_KEYDOWN");
703 lResult
= EDIT_WM_KeyDown(wndPtr
, wParam
, lParam
);
707 DPRINTF_EDIT_MSG32("WM_KILLFOCUS");
708 lResult
= EDIT_WM_KillFocus(wndPtr
, wParam
, lParam
);
711 case WM_LBUTTONDBLCLK
:
712 DPRINTF_EDIT_MSG32("WM_LBUTTONDBLCLK");
713 lResult
= EDIT_WM_LButtonDblClk(wndPtr
, wParam
, lParam
);
717 DPRINTF_EDIT_MSG32("WM_LBUTTONDOWN");
718 lResult
= EDIT_WM_LButtonDown(wndPtr
, wParam
, lParam
);
722 DPRINTF_EDIT_MSG32("WM_LBUTTONUP");
723 lResult
= EDIT_WM_LButtonUp(wndPtr
, wParam
, lParam
);
728 * DPRINTF_EDIT_MSG32("WM_MOUSEMOVE");
730 lResult
= EDIT_WM_MouseMove(wndPtr
, wParam
, lParam
);
734 DPRINTF_EDIT_MSG32("WM_PAINT");
735 lResult
= EDIT_WM_Paint(wndPtr
, wParam
, lParam
);
739 DPRINTF_EDIT_MSG32("WM_PASTE");
740 lResult
= EDIT_WM_Paste(wndPtr
, wParam
, lParam
);
745 * DPRINTF_EDIT_MSG32("WM_SETCURSOR");
747 lResult
= EDIT_WM_SetCursor(wndPtr
, wParam
, lParam
);
751 DPRINTF_EDIT_MSG32("WM_SETFOCUS");
752 lResult
= EDIT_WM_SetFocus(wndPtr
, wParam
, lParam
);
756 DPRINTF_EDIT_MSG32("WM_SETFONT");
757 lResult
= EDIT_WM_SetFont(wndPtr
, wParam
, lParam
);
761 DPRINTF_EDIT_MSG32("WM_SETREDRAW");
762 lResult
= EDIT_WM_SetRedraw(wndPtr
, wParam
, lParam
);
766 DPRINTF_EDIT_MSG32("WM_SETTEXT");
767 lResult
= EDIT_WM_SetText(wndPtr
, wParam
, lParam
);
771 DPRINTF_EDIT_MSG32("WM_SIZE");
772 lResult
= EDIT_WM_Size(wndPtr
, wParam
, lParam
);
776 DPRINTF_EDIT_MSG32("WM_VSCROLL");
777 lResult
= EDIT_WM_VScroll(wndPtr
, wParam
, lParam
);
781 lResult
= DefWindowProc32A(hwnd
, msg
, wParam
, lParam
);
784 EDIT_ReleasePointer(wndPtr
);
789 /*********************************************************************
793 * Build array of pointers to text lines.
794 * Lines can end with '\0' (last line), nothing (if it is too long),
795 * a delimiter (usually ' '), a soft return '\r\r\n' or a hard return '\r\n'
798 static void EDIT_BuildLineDefs(WND
*wndPtr
)
800 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
801 LPSTR text
= EDIT_GetPasswordPointer(wndPtr
);
802 INT32 ww
= EDIT_GetWndWidth(wndPtr
);
812 hdc
= GetDC32(wndPtr
->hwndSelf
);
813 hFont
= (HFONT32
)EDIT_WM_GetFont(wndPtr
, 0, 0);
814 if (hFont
) oldFont
= SelectObject32(hdc
, hFont
);
816 if (!IsMultiLine(wndPtr
)) {
818 es
->LineDefs
= xrealloc(es
->LineDefs
, sizeof(LINEDEF
));
819 es
->LineDefs
[0].offset
= 0;
820 es
->LineDefs
[0].length
= EDIT_WM_GetTextLength(wndPtr
, 0, 0);
821 es
->LineDefs
[0].ending
= END_0
;
822 es
->TextWidth
= (INT32
)LOWORD(GetTabbedTextExtent(hdc
, text
,
823 es
->LineDefs
[0].length
,
824 es
->NumTabStops
, es
->TabStops
));
829 if (!(cp
= strstr(start
, "\r\n"))) {
831 length
= lstrlen32A(start
);
832 } else if ((cp
> start
) && (*(cp
- 1) == '\r')) {
834 length
= cp
- start
- 1;
839 width
= (INT32
)LOWORD(GetTabbedTextExtent(hdc
, start
, length
,
840 es
->NumTabStops
, es
->TabStops
));
842 if (IsWordWrap(wndPtr
) && (width
> ww
)) {
846 next
= EDIT_CallWordBreakProc(wndPtr
, start
,
847 prev
+ 1, length
, WB_RIGHT
);
848 width
= (INT32
)LOWORD(GetTabbedTextExtent(hdc
, start
, next
,
849 es
->NumTabStops
, es
->TabStops
));
850 } while (width
<= ww
);
856 width
= (INT32
)LOWORD(GetTabbedTextExtent(hdc
, start
, next
,
857 es
->NumTabStops
, es
->TabStops
));
858 } while (width
<= ww
);
862 if (EDIT_CallWordBreakProc(wndPtr
, start
, length
- 1,
863 length
, WB_ISDELIMITER
)) {
865 ending
= END_DELIMIT
;
868 width
= (INT32
)LOWORD(GetTabbedTextExtent(hdc
, start
, length
,
869 es
->NumTabStops
, es
->TabStops
));
872 es
->LineDefs
= xrealloc(es
->LineDefs
, (es
->LineCount
+ 1) * sizeof(LINEDEF
));
873 es
->LineDefs
[es
->LineCount
].offset
= start
- text
;
874 es
->LineDefs
[es
->LineCount
].length
= length
;
875 es
->LineDefs
[es
->LineCount
].ending
= ending
;
877 es
->TextWidth
= MAX(es
->TextWidth
, width
);
893 } while (*start
|| (ending
== END_SOFT
) || (ending
== END_HARD
));
895 if (hFont
) SelectObject32(hdc
, oldFont
);
896 ReleaseDC32(wndPtr
->hwndSelf
, hdc
);
902 /*********************************************************************
904 * EDIT_CallWordBreakProc
906 * Call appropriate WordBreakProc (internal or external).
908 * FIXME: Heavily broken now that we have a LOCAL32 buffer.
909 * External wordbreak functions have been disabled in
910 * EM_SETWORDBREAKPROC.
913 static INT32
EDIT_CallWordBreakProc(WND
*wndPtr
, LPSTR s
, INT32 index
, INT32 count
, INT32 action
)
915 return EDIT_WordBreakProc(s
, index
, count
, action
);
917 * EDITWORDBREAKPROC wbp = (EDITWORDBREAKPROC)EDIT_EM_GetWordBreakProc(wndPtr, 0, 0);
919 * if (!wbp) return EDIT_WordBreakProc(s, index, count, action);
921 * EDITSTATE *es = EDITSTATEPTR(wndPtr);
922 * SEGPTR ptr = LOCAL_LockSegptr( wndPtr->hInstance, es->hBuf16 ) +
923 * (INT16)(s - EDIT_GetPointer(wndPtr));
924 * INT ret = CallWordBreakProc( (FARPROC16)wbp, ptr,
925 * index, count, action);
926 * LOCAL_Unlock( wndPtr->hInstance, es->hBuf16 );
933 /*********************************************************************
937 * Calculates, for a given line and X-coordinate on the screen, the column.
940 static INT32
EDIT_ColFromWndX(WND
*wndPtr
, INT32 line
, INT32 x
)
942 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, 0, 0);
943 INT32 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, line
, 0);
944 INT32 ll
= (INT32
)EDIT_EM_LineLength(wndPtr
, li
, 0);
947 line
= MAX(0, MIN(line
, lc
- 1));
948 for (i
= 0 ; i
< ll
; i
++)
949 if (EDIT_WndXFromCol(wndPtr
, line
, i
) >= x
)
955 /*********************************************************************
959 * Delete all characters on this line to right of cursor.
962 static void EDIT_DelEnd(WND
*wndPtr
)
964 EDIT_EM_SetSel(wndPtr
, -1, 0);
965 EDIT_MoveEnd(wndPtr
, TRUE
);
966 EDIT_WM_Clear(wndPtr
, 0, 0);
970 /*********************************************************************
974 * Delete character to left of cursor.
977 static void EDIT_DelLeft(WND
*wndPtr
)
979 EDIT_EM_SetSel(wndPtr
, -1, 0);
980 EDIT_MoveBackward(wndPtr
, TRUE
);
981 EDIT_WM_Clear(wndPtr
, 0, 0);
985 /*********************************************************************
989 * Delete character to right of cursor.
992 static void EDIT_DelRight(WND
*wndPtr
)
994 EDIT_EM_SetSel(wndPtr
, -1, 0);
995 EDIT_MoveForward(wndPtr
, TRUE
);
996 EDIT_WM_Clear(wndPtr
, 0, 0);
1000 /*********************************************************************
1002 * EDIT_GetAveCharWidth
1005 static INT32
EDIT_GetAveCharWidth(WND
*wndPtr
)
1007 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1009 return es
->AveCharWidth
;
1013 /*********************************************************************
1015 * EDIT_GetLineHeight
1018 static INT32
EDIT_GetLineHeight(WND
*wndPtr
)
1020 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1022 return es
->LineHeight
;
1026 /*********************************************************************
1030 * Calculates the bounding rectangle for a line from a starting
1031 * column to an ending column.
1034 static void EDIT_GetLineRect(WND
*wndPtr
, INT32 line
, INT32 scol
, INT32 ecol
, LPRECT32 rc
)
1036 rc
->top
= EDIT_WndYFromLine(wndPtr
, line
);
1037 rc
->bottom
= rc
->top
+ EDIT_GetLineHeight(wndPtr
);
1038 rc
->left
= EDIT_WndXFromCol(wndPtr
, line
, scol
);
1039 rc
->right
= (ecol
== -1) ? EDIT_GetWndWidth(wndPtr
) :
1040 EDIT_WndXFromCol(wndPtr
, line
, ecol
);
1044 /*********************************************************************
1048 * This acts as a LOCAL_Lock(), but it locks only once. This way
1049 * you can call it whenever you like, without unlocking.
1052 static LPSTR
EDIT_GetPointer(WND
*wndPtr
)
1054 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1056 if (!es
->text
&& (es
->hBuf32
|| es
->hBuf16
)) {
1058 es
->text
= (LPSTR
)LocalLock32(es
->hBuf32
);
1060 es
->text
= LOCAL_Lock(wndPtr
->hInstance
, es
->hBuf16
);
1066 /*********************************************************************
1068 * EDIT_GetPasswordPointer
1072 static LPSTR
EDIT_GetPasswordPointer(WND
*wndPtr
)
1074 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1075 LPSTR text
= xstrdup(EDIT_GetPointer(wndPtr
));
1078 if(es
->PasswordChar
) {
1081 if(*p
!= '\r' && *p
!= '\n')
1082 *p
= es
->PasswordChar
;
1090 /*********************************************************************
1095 static BOOL32
EDIT_GetRedraw(WND
*wndPtr
)
1097 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1103 /*********************************************************************
1107 * Beware: This is not the function called on EM_GETSEL.
1108 * (because s can be greater than e).
1111 static void EDIT_GetSel(WND
*wndPtr
, LPINT32 s
, LPINT32 e
)
1113 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1122 /*********************************************************************
1127 static INT32
EDIT_GetTextWidth(WND
*wndPtr
)
1129 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1131 return es
->TextWidth
;
1135 /*********************************************************************
1137 * EDIT_GetVisibleLineCount
1140 static INT32
EDIT_GetVisibleLineCount(WND
*wndPtr
)
1144 EDIT_EM_GetRect(wndPtr
, 0, (LPARAM
)&rc
);
1145 return MAX(1, MAX(rc
.bottom
- rc
.top
, 0) / EDIT_GetLineHeight(wndPtr
));
1149 /*********************************************************************
1154 static INT32
EDIT_GetWndWidth(WND
*wndPtr
)
1158 EDIT_EM_GetRect(wndPtr
, 0, (LPARAM
)&rc
);
1159 return rc
.right
- rc
.left
;
1163 /*********************************************************************
1168 static INT32
EDIT_GetXOffset(WND
*wndPtr
)
1170 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1176 /*********************************************************************
1178 * EDIT_InvalidateText
1180 * Invalidate the text from offset start upto, but not including,
1181 * offset end. Useful for (re)painting the selection.
1182 * Regions outside the linewidth are not invalidated.
1183 * end == -1 means end == TextLength.
1184 * start and end need not be ordered.
1187 static void EDIT_InvalidateText(WND
*wndPtr
, INT32 start
, INT32 end
)
1189 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0);
1190 INT32 vlc
= EDIT_GetVisibleLineCount(wndPtr
);
1204 end
= (INT32
)EDIT_WM_GetTextLength(wndPtr
, 0, 0);
1205 ORDER_INT32(start
, end
);
1206 sl
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, start
, 0);
1207 el
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, end
, 0);
1208 if ((el
< fv
) || (sl
> fv
+ vlc
))
1211 sc
= start
- (INT32
)EDIT_EM_LineIndex(wndPtr
, sl
, 0);
1212 ec
= end
- (INT32
)EDIT_EM_LineIndex(wndPtr
, el
, 0);
1217 if (el
> fv
+ vlc
) {
1219 ec
= (INT32
)EDIT_EM_LineLength(wndPtr
,
1220 (INT32
)EDIT_EM_LineIndex(wndPtr
, el
, 0), 0);
1222 EDIT_EM_GetRect(wndPtr
, 0, (LPARAM
)&rcWnd
);
1224 EDIT_GetLineRect(wndPtr
, sl
, sc
, ec
, &rcLine
);
1225 if (IntersectRect32(&rcUpdate
, &rcWnd
, &rcLine
))
1226 InvalidateRect32( wndPtr
->hwndSelf
, &rcUpdate
, FALSE
);
1228 EDIT_GetLineRect(wndPtr
, sl
, sc
,
1229 (INT32
)EDIT_EM_LineLength(wndPtr
,
1230 (INT32
)EDIT_EM_LineIndex(wndPtr
, sl
, 0), 0),
1232 if (IntersectRect32(&rcUpdate
, &rcWnd
, &rcLine
))
1233 InvalidateRect32( wndPtr
->hwndSelf
, &rcUpdate
, FALSE
);
1234 for (l
= sl
+ 1 ; l
< el
; l
++) {
1235 EDIT_GetLineRect(wndPtr
, l
, 0,
1236 (INT32
)EDIT_EM_LineLength(wndPtr
,
1237 (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0), 0),
1239 if (IntersectRect32(&rcUpdate
, &rcWnd
, &rcLine
))
1240 InvalidateRect32(wndPtr
->hwndSelf
, &rcUpdate
, FALSE
);
1242 EDIT_GetLineRect(wndPtr
, el
, 0, ec
, &rcLine
);
1243 if (IntersectRect32(&rcUpdate
, &rcWnd
, &rcLine
))
1244 InvalidateRect32( wndPtr
->hwndSelf
, &rcUpdate
, FALSE
);
1249 /*********************************************************************
1253 * Calculates, for a given Y-coordinate on the screen, the line.
1256 static INT32
EDIT_LineFromWndY(WND
*wndPtr
, INT32 y
)
1258 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0);
1259 INT32 lh
= EDIT_GetLineHeight(wndPtr
);
1260 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, 0, 0);
1262 return MAX(0, MIN(lc
- 1, y
/ lh
+ fv
));
1266 /*********************************************************************
1270 * Try to fit size + 1 bytes in the buffer. Constrain to limits.
1273 static BOOL32
EDIT_MakeFit(WND
*wndPtr
, INT32 size
)
1275 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1279 if (size
<= es
->BufSize
)
1281 if (size
> es
->BufLimit
)
1283 size
= ((size
/ GROWLENGTH
) + 1) * GROWLENGTH
;
1284 if (size
> es
->BufLimit
)
1285 size
= es
->BufLimit
;
1287 dprintf_edit(stddeb
, "edit: EDIT_MakeFit: trying to ReAlloc to %d+1\n", size
);
1289 EDIT_ReleasePointer(wndPtr
);
1291 if ((hNew32
= LocalReAlloc32(es
->hBuf32
, size
+ 1, 0))) {
1292 dprintf_edit(stddeb
, "edit: EDIT_MakeFit: Old 32 bit handle %08x, new handle %08x\n", es
->hBuf32
, hNew32
);
1293 es
->hBuf32
= hNew32
;
1294 es
->BufSize
= MIN(LocalSize32(es
->hBuf32
) - 1, es
->BufLimit
);
1295 if (es
->BufSize
< size
) {
1296 dprintf_edit(stddeb
, "edit: EDIT_MakeFit: FAILED ! We now have %d+1\n", es
->BufSize
);
1299 dprintf_edit(stddeb
, "edit: EDIT_MakeFit: We now have %d+1\n", es
->BufSize
);
1303 if ((hNew16
= LOCAL_ReAlloc(wndPtr
->hInstance
, es
->hBuf16
, size
+ 1, LMEM_MOVEABLE
))) {
1304 dprintf_edit(stddeb
, "edit: EDIT_MakeFit: Old 16 bit handle %08x, new handle %08x\n", es
->hBuf16
, hNew16
);
1305 es
->hBuf16
= hNew16
;
1306 es
->BufSize
= MIN(LOCAL_Size(wndPtr
->hInstance
, es
->hBuf16
) - 1, es
->BufLimit
);
1307 if (es
->BufSize
< size
) {
1308 dprintf_edit(stddeb
, "edit: EDIT_MakeFit: FAILED ! We now have %d+1\n", es
->BufSize
);
1311 dprintf_edit(stddeb
, "edit: EDIT_MakeFit: We now have %d+1\n", es
->BufSize
);
1319 /*********************************************************************
1324 static void EDIT_MoveBackward(WND
*wndPtr
, BOOL32 extend
)
1331 EDIT_GetSel(wndPtr
, &s
, &e
);
1332 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
1333 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
1336 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
- 1, 0);
1337 e
= li
+ (INT32
)EDIT_EM_LineLength(wndPtr
, li
, 0);
1343 EDIT_EM_SetSel(wndPtr
, s
, e
);
1344 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
1348 /*********************************************************************
1353 static void EDIT_MoveDownward(WND
*wndPtr
, BOOL32 extend
)
1362 EDIT_GetSel(wndPtr
, &s
, &e
);
1363 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
1364 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, e
, 0);
1365 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
1367 x
= EDIT_WndXFromCol(wndPtr
, l
, e
- li
);
1369 e
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0) +
1370 EDIT_ColFromWndX(wndPtr
, l
, x
);
1374 EDIT_EM_SetSel(wndPtr
, s
, e
);
1375 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
1379 /*********************************************************************
1384 static void EDIT_MoveEnd(WND
*wndPtr
, BOOL32 extend
)
1392 EDIT_GetSel(wndPtr
, &s
, &e
);
1393 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
1394 ll
= (INT32
)EDIT_EM_LineLength(wndPtr
, e
, 0);
1395 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
1399 EDIT_EM_SetSel(wndPtr
, s
, e
);
1400 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
1404 /*********************************************************************
1409 static void EDIT_MoveForward(WND
*wndPtr
, BOOL32 extend
)
1418 EDIT_GetSel(wndPtr
, &s
, &e
);
1419 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
1420 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, e
, 0);
1421 ll
= (INT32
)EDIT_EM_LineLength(wndPtr
, e
, 0);
1422 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
1425 e
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
+ 1, 0);
1430 EDIT_EM_SetSel(wndPtr
, s
, e
);
1431 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
1435 /*********************************************************************
1439 * Home key: move to beginning of line.
1442 static void EDIT_MoveHome(WND
*wndPtr
, BOOL32 extend
)
1449 EDIT_GetSel(wndPtr
, &s
, &e
);
1450 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
1451 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
1455 EDIT_EM_SetSel(wndPtr
, s
, e
);
1456 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
1460 /*********************************************************************
1465 static void EDIT_MovePageDown(WND
*wndPtr
, BOOL32 extend
)
1474 EDIT_GetSel(wndPtr
, &s
, &e
);
1475 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
1476 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, e
, 0);
1477 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
1479 x
= EDIT_WndXFromCol(wndPtr
, l
, e
- li
);
1480 l
= MIN(lc
- 1, l
+ EDIT_GetVisibleLineCount(wndPtr
));
1481 e
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0) +
1482 EDIT_ColFromWndX(wndPtr
, l
, x
);
1486 EDIT_EM_SetSel(wndPtr
, s
, e
);
1487 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
1491 /*********************************************************************
1496 static void EDIT_MovePageUp(WND
*wndPtr
, BOOL32 extend
)
1504 EDIT_GetSel(wndPtr
, &s
, &e
);
1505 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
1506 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
1508 x
= EDIT_WndXFromCol(wndPtr
, l
, e
- li
);
1509 l
= MAX(0, l
- EDIT_GetVisibleLineCount(wndPtr
));
1510 e
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0) +
1511 EDIT_ColFromWndX(wndPtr
, l
, x
);
1515 EDIT_EM_SetSel(wndPtr
, s
, e
);
1516 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
1520 /*********************************************************************
1525 static void EDIT_MoveUpward(WND
*wndPtr
, BOOL32 extend
)
1533 EDIT_GetSel(wndPtr
, &s
, &e
);
1534 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
1535 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
1537 x
= EDIT_WndXFromCol(wndPtr
, l
, e
- li
);
1539 e
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0) +
1540 EDIT_ColFromWndX(wndPtr
, l
, x
);
1544 EDIT_EM_SetSel(wndPtr
, s
, e
);
1545 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
1549 /*********************************************************************
1551 * EDIT_MoveWordBackward
1554 static void EDIT_MoveWordBackward(WND
*wndPtr
, BOOL32 extend
)
1563 EDIT_GetSel(wndPtr
, &s
, &e
);
1564 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
1565 ll
= (INT32
)EDIT_EM_LineLength(wndPtr
, e
, 0);
1566 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
1569 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
- 1, 0);
1570 e
= li
+ (INT32
)EDIT_EM_LineLength(wndPtr
, li
, 0);
1573 text
= EDIT_GetPointer(wndPtr
);
1574 e
= li
+ (INT32
)EDIT_CallWordBreakProc(wndPtr
,
1575 text
+ li
, e
- li
, ll
, WB_LEFT
);
1579 EDIT_EM_SetSel(wndPtr
, s
, e
);
1580 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
1584 /*********************************************************************
1586 * EDIT_MoveWordForward
1589 static void EDIT_MoveWordForward(WND
*wndPtr
, BOOL32 extend
)
1599 EDIT_GetSel(wndPtr
, &s
, &e
);
1600 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
1601 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, e
, 0);
1602 ll
= (INT32
)EDIT_EM_LineLength(wndPtr
, e
, 0);
1603 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
1606 e
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
+ 1, 0);
1608 text
= EDIT_GetPointer(wndPtr
);
1609 e
= li
+ EDIT_CallWordBreakProc(wndPtr
,
1610 text
+ li
, e
- li
+ 1, ll
, WB_RIGHT
);
1614 EDIT_EM_SetSel(wndPtr
, s
, e
);
1615 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
1619 /*********************************************************************
1624 static void EDIT_PaintLine(WND
*wndPtr
, HDC32 hdc
, INT32 line
, BOOL32 rev
)
1626 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0);
1627 INT32 vlc
= EDIT_GetVisibleLineCount(wndPtr
);
1628 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, 0, 0);
1636 if ((line
< fv
) || (line
> fv
+ vlc
) || (line
>= lc
))
1639 dprintf_edit(stddeb
, "edit: EDIT_PaintLine: line=%d\n", line
);
1641 x
= EDIT_WndXFromCol(wndPtr
, line
, 0);
1642 y
= EDIT_WndYFromLine(wndPtr
, line
);
1643 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, line
, 0);
1644 ll
= (INT32
)EDIT_EM_LineLength(wndPtr
, li
, 0);
1645 EDIT_GetSel(wndPtr
, &s
, &e
);
1647 s
= MIN(li
+ ll
, MAX(li
, s
));
1648 e
= MIN(li
+ ll
, MAX(li
, e
));
1649 if (rev
&& (s
!= e
) &&
1650 ((GetFocus32() == wndPtr
->hwndSelf
) ||
1651 (wndPtr
->dwStyle
& ES_NOHIDESEL
))) {
1652 x
+= EDIT_PaintText(wndPtr
, hdc
, x
, y
, line
, 0, s
- li
, FALSE
);
1653 x
+= EDIT_PaintText(wndPtr
, hdc
, x
, y
, line
, s
- li
, e
- s
, TRUE
);
1654 x
+= EDIT_PaintText(wndPtr
, hdc
, x
, y
, line
, e
- li
, li
+ ll
- e
, FALSE
);
1656 x
+= EDIT_PaintText(wndPtr
, hdc
, x
, y
, line
, 0, ll
, FALSE
);
1660 /*********************************************************************
1665 static INT32
EDIT_PaintText(WND
*wndPtr
, HDC32 hdc
, INT32 x
, INT32 y
, INT32 line
, INT32 col
, INT32 count
, BOOL32 rev
)
1667 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1677 BkColor
= GetBkColor32(hdc
);
1678 TextColor
= GetTextColor32(hdc
);
1680 SetBkColor(hdc
, GetSysColor(COLOR_HIGHLIGHT
));
1681 SetTextColor(hdc
, GetSysColor(COLOR_HIGHLIGHTTEXT
));
1683 text
= EDIT_GetPasswordPointer(wndPtr
);
1684 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, line
, 0);
1685 xoff
= EDIT_GetXOffset(wndPtr
);
1686 ret
= (INT32
)LOWORD(TabbedTextOut(hdc
, x
, y
, text
+ li
+ col
, count
,
1687 es
->NumTabStops
, es
->TabStops
, -xoff
));
1690 SetBkColor(hdc
, BkColor
);
1691 SetTextColor(hdc
, TextColor
);
1697 /*********************************************************************
1699 * EDIT_ReleasePointer
1701 * This is the only helper function that can be called with es = NULL.
1702 * It is called at the end of EditWndProc() to unlock the buffer.
1705 static void EDIT_ReleasePointer(WND
*wndPtr
)
1707 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1711 if (es
->text
&& (es
->hBuf32
|| es
->hBuf16
))
1714 LocalUnlock32(es
->hBuf32
);
1716 LOCAL_Unlock(wndPtr
->hInstance
, es
->hBuf16
);
1722 /*********************************************************************
1726 * Calculates, for a given line and column, the X-coordinate on the screen.
1729 static INT32
EDIT_WndXFromCol(WND
*wndPtr
, INT32 line
, INT32 col
)
1731 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1732 LPSTR text
= EDIT_GetPasswordPointer(wndPtr
);
1736 HFONT32 oldFont
= 0;
1737 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, 0, 0);
1738 INT32 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, line
, 0);
1739 INT32 ll
= (INT32
)EDIT_EM_LineLength(wndPtr
, li
, 0);
1740 INT32 xoff
= EDIT_GetXOffset(wndPtr
);
1742 hdc
= GetDC32(wndPtr
->hwndSelf
);
1743 hFont
= (HFONT32
)EDIT_WM_GetFont(wndPtr
, 0, 0);
1744 if (hFont
) oldFont
= SelectObject32(hdc
, hFont
);
1745 line
= MAX(0, MIN(line
, lc
- 1));
1747 ret
= (INT32
)LOWORD(GetTabbedTextExtent(hdc
,
1749 es
->NumTabStops
, es
->TabStops
)) - xoff
;
1750 if (hFont
) SelectObject32(hdc
, oldFont
);
1751 ReleaseDC32(wndPtr
->hwndSelf
, hdc
);
1757 /*********************************************************************
1761 * Calculates, for a given line, the Y-coordinate on the screen.
1764 static INT32
EDIT_WndYFromLine(WND
*wndPtr
, INT32 line
)
1766 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0);
1767 INT32 lh
= EDIT_GetLineHeight(wndPtr
);
1769 return (line
- fv
) * lh
;
1773 /*********************************************************************
1775 * EDIT_WordBreakProc
1777 * Find the beginning of words.
1778 * Note: unlike the specs for a WordBreakProc, this function only
1779 * allows to be called without linebreaks between s[0] upto
1780 * s[count - 1]. Remember it is only called
1781 * internally, so we can decide this for ourselves.
1784 static INT32
EDIT_WordBreakProc(LPSTR s
, INT32 index
, INT32 count
, INT32 action
)
1788 dprintf_edit(stddeb
, "edit: EDIT_WordBreakProc: s=%p, index=%u"
1789 ", count=%u, action=%d\n", s
, index
, count
, action
);
1797 if (s
[index
] == ' ') {
1798 while (index
&& (s
[index
] == ' '))
1801 while (index
&& (s
[index
] != ' '))
1803 if (s
[index
] == ' ')
1807 while (index
&& (s
[index
] != ' '))
1809 if (s
[index
] == ' ')
1819 if (s
[index
] == ' ')
1820 while ((index
< count
) && (s
[index
] == ' ')) index
++;
1822 while (s
[index
] && (s
[index
] != ' ') && (index
< count
))
1824 while ((s
[index
] == ' ') && (index
< count
)) index
++;
1828 case WB_ISDELIMITER
:
1829 ret
= (s
[index
] == ' ');
1832 fprintf(stderr
, "edit: EDIT_WordBreakProc: unknown action code, please report !\n");
1839 /*********************************************************************
1844 static LRESULT
EDIT_EM_CanUndo(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
1846 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1848 return (LRESULT
)es
->CanUndo
;
1852 /*********************************************************************
1856 * FIXME: do the specs mean LineIndex or LineNumber (li v.s. l) ???
1858 static LRESULT
EDIT_EM_CharFromPos(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
1866 pt
.x
= LOWORD(lParam
);
1867 pt
.y
= HIWORD(lParam
);
1868 GetClientRect32(wndPtr
->hwndSelf
, &rc
);
1870 if (!PtInRect32(&rc
, pt
))
1873 l
= EDIT_LineFromWndY(wndPtr
, pt
.y
);
1874 li
= EDIT_EM_LineIndex(wndPtr
, l
, 0);
1875 c
= EDIT_ColFromWndX(wndPtr
, l
, pt
.x
);
1877 return (LRESULT
)MAKELONG(li
+ c
, li
);
1881 /*********************************************************************
1883 * EM_EMPTYUNDOBUFFER
1886 static LRESULT
EDIT_EM_EmptyUndoBuffer(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
1888 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1890 es
->CanUndo
= FALSE
;
1895 /*********************************************************************
1900 static LRESULT
EDIT_EM_FmtLines(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
1902 fprintf(stdnimp
, "edit: EM_FMTLINES: message not implemented\n");
1903 return wParam
? TRUE
: FALSE
;
1907 /*********************************************************************
1909 * EM_GETFIRSTVISIBLELINE
1912 static LRESULT
EDIT_EM_GetFirstVisibleLine(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
1914 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1916 if (IsMultiLine(wndPtr
))
1917 return (LRESULT
)es
->FirstVisibleLine
;
1919 return (LRESULT
)EDIT_ColFromWndX(wndPtr
, 0, 0);
1923 /*********************************************************************
1928 static LRESULT
EDIT_EM_GetHandle(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
1930 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1932 if (!IsMultiLine(wndPtr
))
1936 return (LRESULT
)es
->hBuf32
;
1938 return (LRESULT
)es
->hBuf16
;
1942 /*********************************************************************
1946 * Hopefully this won't fire back at us.
1947 * We always start with a buffer in 32 bit linear memory.
1948 * However, with this message a 16 bit application requests
1949 * a handle of 16 bit local heap memory, where it expects to find
1951 * It's a pitty that from this moment on we have to use this
1952 * local heap, because applications may rely on the handle
1955 * In this function we'll try to switch to local heap.
1957 static LRESULT
EDIT_EM_GetHandle16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
1959 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1965 if (!IsMultiLine(wndPtr
))
1969 return (LRESULT
)es
->hBuf16
;
1971 if (!LOCAL_HeapSize(wndPtr
->hInstance
)) {
1972 if (!LocalInit(wndPtr
->hInstance
, 0,
1973 GlobalSize16(wndPtr
->hInstance
))) {
1974 fprintf(stderr
, "edit: EM_GETHANDLE: could not initialize local heap\n");
1977 dprintf_edit(stddeb
, "edit: EM_GETHANDLE: local heap initialized\n");
1979 if (!(newBuf
= LOCAL_Alloc(wndPtr
->hInstance
,
1980 EDIT_WM_GetTextLength(wndPtr
, 0, 0) + 1,
1982 fprintf(stderr
, "edit: EM_GETHANDLE: could not allocate new 16 bit buffer\n");
1985 newSize
= MIN(LOCAL_Size(wndPtr
->hInstance
, newBuf
) - 1, es
->BufLimit
);
1986 if (!(newText
= LOCAL_Lock(wndPtr
->hInstance
, newBuf
))) {
1987 fprintf(stderr
, "edit: EM_GETHANDLE: could not lock new 16 bit buffer\n");
1988 LOCAL_Free(wndPtr
->hInstance
, newBuf
);
1991 text
= EDIT_GetPointer(wndPtr
);
1992 lstrcpy32A(newText
, text
);
1993 EDIT_ReleasePointer(wndPtr
);
1994 GlobalFree32(es
->hBuf32
);
1995 es
->hBuf32
= (HLOCAL32
)NULL
;
1996 es
->hBuf16
= newBuf
;
1997 es
->BufSize
= newSize
;
1999 dprintf_edit(stddeb
, "edit: EM_GETHANDLE: switched to 16 bit buffer\n");
2001 return (LRESULT
)es
->hBuf16
;
2005 /*********************************************************************
2010 static LRESULT
EDIT_EM_GetLimitText(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2012 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2014 return es
->BufLimit
;
2018 /*********************************************************************
2023 static LRESULT
EDIT_EM_GetLine(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2030 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, 0, 0);
2032 if (!IsMultiLine(wndPtr
))
2034 if ((INT32
)wParam
>= lc
)
2036 text
= EDIT_GetPointer(wndPtr
);
2037 src
= text
+ (INT32
)EDIT_EM_LineIndex(wndPtr
, wParam
, 0);
2038 dst
= (LPSTR
)lParam
;
2039 len
= MIN(*(WORD
*)dst
, (INT32
)EDIT_EM_LineLength(wndPtr
, wParam
, 0));
2040 for (i
= 0 ; i
< len
; i
++) {
2045 return (LRESULT
)len
;
2049 /*********************************************************************
2054 static LRESULT
EDIT_EM_GetLineCount(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2056 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2058 return (LRESULT
)es
->LineCount
;
2062 /*********************************************************************
2067 static LRESULT
EDIT_EM_GetMargins(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2069 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2071 return (LRESULT
)MAKELONG(es
->LeftMargin
, es
->RightMargin
);
2075 /*********************************************************************
2080 static LRESULT
EDIT_EM_GetModify(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2082 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2084 return (LRESULT
)es
->TextChanged
;
2088 /*********************************************************************
2090 * EM_GETPASSWORDCHAR
2093 static LRESULT
EDIT_EM_GetPasswordChar(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2095 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2097 return (LRESULT
)es
->PasswordChar
;
2101 /*********************************************************************
2106 static LRESULT
EDIT_EM_GetRect(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2108 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2110 CopyRect32((LPRECT32
)lParam
, &es
->FormatRect
);
2115 /*********************************************************************
2120 static LRESULT
EDIT_EM_GetRect16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2122 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2124 CONV_RECT32TO16(&es
->FormatRect
, (LPRECT16
)PTR_SEG_TO_LIN((SEGPTR
)lParam
));
2129 /*********************************************************************
2133 * Returns the ordered selection range so that
2134 * LOWORD(result) < HIWORD(result)
2137 static LRESULT
EDIT_EM_GetSel(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2142 EDIT_GetSel(wndPtr
, &s
, &e
);
2145 *(LPINT32
)wParam
= s
;
2147 *(LPINT32
)lParam
= e
;
2148 return MAKELONG((INT16
)s
, (INT16
)e
);
2152 /*********************************************************************
2156 * FIXME: is this right ? (or should it be only HSCROLL)
2157 * (and maybe only for edit controls that really have their
2158 * own scrollbars) (and maybe only for multiline controls ?)
2159 * All in all: very poorly documented
2162 static LRESULT
EDIT_EM_GetThumb(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2164 return MAKELONG(EDIT_WM_VScroll(wndPtr
, EM_GETTHUMB16
, 0),
2165 EDIT_WM_HScroll(wndPtr
, EM_GETTHUMB16
, 0));
2169 /*********************************************************************
2171 * EM_GETWORDBREAKPROC
2173 * FIXME: Application defined WordBreakProc should be returned
2176 static LRESULT
EDIT_EM_GetWordBreakProc(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2179 EDITSTATE *es = EDITSTATEPTR(wndPtr);
2181 return (LRESULT)es->WordBreakProc;
2187 /*********************************************************************
2192 static LRESULT
EDIT_EM_LineFromChar(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2196 if (!IsMultiLine(wndPtr
))
2198 if ((INT32
)wParam
== -1)
2199 EDIT_EM_GetSel(wndPtr
, (WPARAM32
)&wParam
, 0); /* intentional (looks weird, doesn't it ?) */
2200 l
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, 0, 0) - 1;
2201 while ((INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0) > (INT32
)wParam
)
2207 /*********************************************************************
2212 static LRESULT
EDIT_EM_LineIndex(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2214 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2217 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, 0, 0);
2219 if ((INT32
)wParam
== -1) {
2220 EDIT_GetSel(wndPtr
, NULL
, &e
);
2222 while (es
->LineDefs
[l
].offset
> e
)
2224 return (LRESULT
)es
->LineDefs
[l
].offset
;
2226 if ((INT32
)wParam
>= lc
)
2228 return (LRESULT
)es
->LineDefs
[(INT32
)wParam
].offset
;
2232 /*********************************************************************
2237 static LRESULT
EDIT_EM_LineLength(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2239 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2245 if (!IsMultiLine(wndPtr
))
2246 return (LRESULT
)es
->LineDefs
[0].length
;
2247 if ((INT32
)wParam
== -1) {
2248 EDIT_GetSel(wndPtr
, &s
, &e
);
2249 sl
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, s
, 0);
2250 el
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
2251 return (LRESULT
)(s
- es
->LineDefs
[sl
].offset
+
2252 es
->LineDefs
[el
].offset
+
2253 es
->LineDefs
[el
].length
- e
);
2255 return (LRESULT
)es
->LineDefs
[(INT32
)EDIT_EM_LineFromChar(wndPtr
, wParam
, 0)].length
;
2259 /*********************************************************************
2263 * FIXME: is wParam in pixels or in average character widths ???
2264 * FIXME: we use this internally to scroll single line controls as well
2265 * (specs are vague about whether this message is valid or not for
2266 * single line controls)
2269 static LRESULT
EDIT_EM_LineScroll(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2271 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2272 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, 0, 0);
2273 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0);
2274 INT32 nfv
= MAX(0, fv
+ (INT32
)lParam
);
2275 INT32 xoff
= EDIT_GetXOffset(wndPtr
);
2276 INT32 nxoff
= MAX(0, xoff
+ (INT32
)wParam
);
2277 INT32 tw
= EDIT_GetTextWidth(wndPtr
);
2288 dy
= EDIT_WndYFromLine(wndPtr
, fv
) - EDIT_WndYFromLine(wndPtr
, nfv
);
2290 if (wndPtr
->hwndSelf
== GetFocus32())
2291 HideCaret(wndPtr
->hwndSelf
);
2292 if (EDIT_GetRedraw(wndPtr
))
2293 ScrollWindow32(wndPtr
->hwndSelf
, dx
, dy
, NULL
, NULL
);
2294 es
->FirstVisibleLine
= nfv
;
2295 es
->XOffset
= nxoff
;
2296 if (IsVScrollBar(wndPtr
))
2297 SetScrollPos32(wndPtr
->hwndSelf
, SB_VERT
,
2298 EDIT_WM_VScroll(wndPtr
, EM_GETTHUMB16
, 0), TRUE
);
2299 if (IsHScrollBar(wndPtr
))
2300 SetScrollPos32(wndPtr
->hwndSelf
, SB_HORZ
,
2301 EDIT_WM_HScroll(wndPtr
, EM_GETTHUMB16
, 0), TRUE
);
2302 if (wndPtr
->hwndSelf
== GetFocus32()) {
2303 GetCaretPos32(&pos
);
2304 SetCaretPos(pos
.x
+ dx
, pos
.y
+ dy
);
2305 ShowCaret(wndPtr
->hwndSelf
);
2308 if (IsMultiLine(wndPtr
))
2315 /*********************************************************************
2320 static LRESULT
EDIT_EM_PosFromChar(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2322 INT32 len
= (INT32
)EDIT_WM_GetTextLength(wndPtr
, 0, 0);
2326 wParam
= MIN(wParam
, len
);
2327 l
= EDIT_EM_LineFromChar(wndPtr
, wParam
, 0);
2328 li
= EDIT_EM_LineIndex(wndPtr
, l
, 0);
2329 return (LRESULT
)MAKELONG(EDIT_WndXFromCol(wndPtr
, l
, wParam
- li
),
2330 EDIT_WndYFromLine(wndPtr
, l
));
2334 /*********************************************************************
2338 * FIXME: wParam indicates whether we should maintain an undo buffer
2339 * for this operation.
2342 static LRESULT
EDIT_EM_ReplaceSel(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2344 LPCSTR str
= (LPCSTR
)lParam
;
2345 INT32 strl
= lstrlen32A(str
);
2346 INT32 tl
= (INT32
)EDIT_WM_GetTextLength(wndPtr
, 0, 0);
2354 EDIT_GetSel(wndPtr
, &s
, &e
);
2356 if (!EDIT_MakeFit(wndPtr
, tl
- (e
- s
) + strl
)) {
2357 dprintf_edit(stddeb
, "edit: notification EN_MAXTEXT sent\n");
2358 EDIT_NOTIFY_PARENT(wndPtr
, EN_MAXTEXT
);
2361 redraw
= EDIT_GetRedraw(wndPtr
);
2362 EDIT_WM_SetRedraw(wndPtr
, FALSE
, 0);
2363 EDIT_WM_Clear(wndPtr
, 0, 0);
2364 tl
= EDIT_WM_GetTextLength(wndPtr
, 0, 0);
2365 EDIT_GetSel(wndPtr
, NULL
, &e
);
2366 text
= EDIT_GetPointer(wndPtr
);
2367 for (p
= text
+ tl
; p
>= text
+ e
; p
--)
2369 for (i
= 0 , p
= text
+ e
; i
< strl
; i
++)
2372 CharUpperBuff32A(p
, strl
);
2373 else if(IsLower(wndPtr
))
2374 CharLowerBuff32A(p
, strl
);
2375 EDIT_BuildLineDefs(wndPtr
);
2377 EDIT_EM_SetSel(wndPtr
, e
, e
);
2378 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
2379 EDIT_EM_SetModify(wndPtr
, TRUE
, 0);
2380 dprintf_edit(stddeb
, "edit: notification EN_UPDATE sent\n");
2381 EDIT_NOTIFY_PARENT(wndPtr
, EN_UPDATE
);
2382 EDIT_WM_SetRedraw(wndPtr
, redraw
, 0);
2384 InvalidateRect32( wndPtr
->hwndSelf
, NULL
, TRUE
);
2385 dprintf_edit(stddeb
, "edit: notification EN_CHANGE sent\n");
2386 EDIT_NOTIFY_PARENT(wndPtr
, EN_CHANGE
);
2392 /*********************************************************************
2396 * FIXME: Scroll what ??? And where ???
2399 static LRESULT
EDIT_EM_Scroll(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2401 fprintf(stdnimp
, "edit: EM_SCROLL: message not implemented\n");
2406 /*********************************************************************
2410 * Makes sure the caret is visible.
2411 * FIXME: We use EM_LINESCROLL, but may we do that for single line
2415 static LRESULT
EDIT_EM_ScrollCaret(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2420 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0);
2421 INT32 vlc
= EDIT_GetVisibleLineCount(wndPtr
);
2422 INT32 ww
= EDIT_GetWndWidth(wndPtr
);
2423 INT32 cw
= EDIT_GetAveCharWidth(wndPtr
);
2428 EDIT_GetSel(wndPtr
, NULL
, &e
);
2429 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
2430 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
2431 x
= EDIT_WndXFromCol(wndPtr
, l
, e
- li
);
2433 dy
= l
- vlc
+ 1 - fv
;
2437 dx
= x
- ww
/ HSCROLL_FRACTION
/ cw
* cw
;
2439 dx
= x
- (HSCROLL_FRACTION
- 1) * ww
/ HSCROLL_FRACTION
/ cw
* cw
;
2441 EDIT_EM_LineScroll(wndPtr
, dx
, dy
);
2443 dprintf_edit(stddeb
, "edit: notification EN_VSCROLL sent\n");
2444 EDIT_NOTIFY_PARENT(wndPtr
, EN_VSCROLL
);
2447 dprintf_edit(stddeb
, "edit: notification EN_HSCROLL sent\n");
2448 EDIT_NOTIFY_PARENT(wndPtr
, EN_HSCROLL
);
2455 /*********************************************************************
2460 static LRESULT
EDIT_EM_SetHandle(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2462 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2464 if (IsMultiLine(wndPtr
)) {
2465 EDIT_ReleasePointer(wndPtr
);
2467 * old buffer is freed by caller
2469 es
->hBuf16
= (HLOCAL16
)NULL
;
2470 es
->hBuf32
= (HLOCAL32
)wParam
;
2471 es
->BufSize
= LocalSize32(es
->hBuf32
) - 1;
2473 es
->FirstVisibleLine
= 0;
2474 es
->SelStart
= es
->SelEnd
= 0;
2475 EDIT_EM_EmptyUndoBuffer(wndPtr
, 0, 0);
2476 EDIT_EM_SetModify(wndPtr
, FALSE
, 0);
2477 EDIT_BuildLineDefs(wndPtr
);
2478 if (EDIT_GetRedraw(wndPtr
))
2479 InvalidateRect32( wndPtr
->hwndSelf
, NULL
, TRUE
);
2480 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
2486 /*********************************************************************
2491 static LRESULT
EDIT_EM_SetHandle16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2493 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2495 if (IsMultiLine(wndPtr
)) {
2496 EDIT_ReleasePointer(wndPtr
);
2498 * old buffer is freed by caller
2500 es
->hBuf16
= (HLOCAL16
)wParam
;
2501 es
->hBuf32
= (HLOCAL32
)NULL
;
2502 es
->BufSize
= LOCAL_Size(wndPtr
->hInstance
, es
->hBuf16
) - 1;
2504 es
->FirstVisibleLine
= 0;
2505 es
->SelStart
= es
->SelEnd
= 0;
2506 EDIT_EM_EmptyUndoBuffer(wndPtr
, 0, 0);
2507 EDIT_EM_SetModify(wndPtr
, FALSE
, 0);
2508 EDIT_BuildLineDefs(wndPtr
);
2509 if (EDIT_GetRedraw(wndPtr
))
2510 InvalidateRect32( wndPtr
->hwndSelf
, NULL
, TRUE
);
2511 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
2517 /*********************************************************************
2522 static LRESULT
EDIT_EM_SetLimitText(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2524 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2526 if (IsMultiLine(wndPtr
)) {
2528 es
->BufLimit
= MIN((INT32
)wParam
, BUFLIMIT_MULTI
);
2530 es
->BufLimit
= BUFLIMIT_MULTI
;
2533 es
->BufLimit
= MIN((INT32
)wParam
, BUFLIMIT_SINGLE
);
2535 es
->BufLimit
= BUFLIMIT_SINGLE
;
2541 /*********************************************************************
2545 * FIXME: We let the margins be set, but we don't use them yet !?!
2548 static LRESULT
EDIT_EM_SetMargins(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2550 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2552 if (wParam
& EC_USEFONTINFO
) {
2553 if (IsMultiLine(wndPtr
)) {
2555 * FIXME: do some GetABCCharWidth, or so
2556 * This is just preliminary
2558 es
->LeftMargin
= es
->RightMargin
= EDIT_GetAveCharWidth(wndPtr
);
2560 es
->LeftMargin
= es
->RightMargin
= EDIT_GetAveCharWidth(wndPtr
);
2563 if (wParam
& EC_LEFTMARGIN
)
2564 es
->LeftMargin
= LOWORD(lParam
);
2565 if (wParam
& EC_RIGHTMARGIN
)
2566 es
->RightMargin
= HIWORD(lParam
);
2571 /*********************************************************************
2576 static LRESULT
EDIT_EM_SetModify(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2578 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2580 es
->TextChanged
= (BOOL32
)wParam
;
2585 /*********************************************************************
2587 * EM_SETPASSWORDCHAR
2589 * FIXME: This imlementation is way too simple
2592 static LRESULT
EDIT_EM_SetPasswordChar(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2594 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2596 es
->PasswordChar
= (CHAR
)wParam
;
2601 /*********************************************************************
2606 static LRESULT
EDIT_EM_SetReadOnly(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2609 wndPtr
->dwStyle
|= ES_READONLY
;
2611 wndPtr
->dwStyle
&= ~(DWORD
)ES_READONLY
;
2616 /*********************************************************************
2621 static LRESULT
EDIT_EM_SetRect(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2623 fprintf(stdnimp
,"edit: EM_SETRECT: message not implemented\n");
2628 /*********************************************************************
2633 static LRESULT
EDIT_EM_SetRectNP(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2635 fprintf(stdnimp
,"edit: EM_SETRECTNP: message not implemented\n");
2640 /*********************************************************************
2644 * FIXME: specs state that we should order start and end.
2645 * However, we use internally that this is not the case.
2648 static LRESULT
EDIT_EM_SetSel(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2650 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2651 INT32 ns
= (INT32
)wParam
;
2652 INT32 ne
= (INT32
)lParam
;
2657 INT32 tl
= (INT32
)EDIT_WM_GetTextLength(wndPtr
, 0, 0);
2659 EDIT_GetSel(wndPtr
, &s
, &e
);
2667 ORDER_INT32(ns, ne);
2673 if (wndPtr
->hwndSelf
== GetFocus32()) {
2674 el
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, ne
, 0);
2675 eli
= (INT32
)EDIT_EM_LineIndex(wndPtr
, el
, 0);
2676 SetCaretPos(EDIT_WndXFromCol(wndPtr
, el
, ne
- eli
),
2677 EDIT_WndYFromLine(wndPtr
, el
));
2679 if (EDIT_GetRedraw(wndPtr
)) {
2685 ORDER_INT32(ns
, ne
);
2687 EDIT_InvalidateText(wndPtr
, s
, e
);
2688 EDIT_InvalidateText(wndPtr
, ns
, ne
);
2690 EDIT_InvalidateText(wndPtr
, s
, ne
);
2696 /*********************************************************************
2701 static LRESULT
EDIT_EM_SetSel16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2703 INT32 ns
= (INT32
)LOWORD(lParam
);
2704 INT32 ne
= (INT32
)HIWORD(lParam
);
2706 if ((INT16
)LOWORD(lParam
) == -1)
2708 if ((INT16
)HIWORD(lParam
) == -1)
2710 EDIT_EM_SetSel(wndPtr
, ns
, ne
);
2712 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
2717 /*********************************************************************
2722 static LRESULT
EDIT_EM_SetTabStops(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2724 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2727 if (!IsMultiLine(wndPtr
))
2731 es
->NumTabStops
= (INT32
)wParam
;
2733 es
->TabStops
= NULL
;
2735 es
->TabStops
= (LPINT16
)xmalloc(wParam
* sizeof(INT16
));
2736 for ( i
= 0 ; i
< (INT32
)wParam
; i
++ )
2737 es
->TabStops
[i
] = (INT16
)((LPINT32
)lParam
)[i
];
2743 /*********************************************************************
2748 static LRESULT
EDIT_EM_SetTabStops16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2750 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2752 if (!IsMultiLine(wndPtr
))
2756 es
->NumTabStops
= (INT32
)wParam
;
2758 es
->TabStops
= NULL
;
2760 es
->TabStops
= (LPINT16
)xmalloc(wParam
* sizeof(INT16
));
2761 memcpy(es
->TabStops
, (LPINT16
)PTR_SEG_TO_LIN(lParam
),
2762 (INT32
)wParam
* sizeof(INT16
));
2768 /*********************************************************************
2770 * EM_SETWORDBREAKPROC
2773 static LRESULT
EDIT_EM_SetWordBreakProc(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2776 EDITSTATE *es = EDITSTATEPTR(wndPtr);
2778 es->WordBreakProc = (EDITWORDBREAKPROC)lParam;
2784 /*********************************************************************
2789 static LRESULT
EDIT_EM_Undo(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2791 fprintf(stdnimp
,"edit: EM_UNDO: message not implemented\n");
2792 if (IsMultiLine(wndPtr
))
2799 /*********************************************************************
2804 static LRESULT
EDIT_WM_Char(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2807 unsigned char c
= (unsigned char)wParam
;
2812 if (IsMultiLine(wndPtr
)) {
2813 if (IsReadOnly(wndPtr
)) {
2814 EDIT_MoveHome(wndPtr
, FALSE
);
2815 EDIT_MoveDownward(wndPtr
, FALSE
);
2817 EDIT_EM_ReplaceSel(wndPtr
, 0, (LPARAM
)"\r\n");
2821 if (IsMultiLine(wndPtr
) && !IsReadOnly(wndPtr
))
2822 EDIT_EM_ReplaceSel(wndPtr
, 0, (LPARAM
)"\t");
2825 if (!IsReadOnly(wndPtr
) && (c
>= ' ') && (c
!= 127)) {
2828 EDIT_EM_ReplaceSel(wndPtr
, 0, (LPARAM
)str
);
2836 /*********************************************************************
2841 static LRESULT
EDIT_WM_Clear(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2848 EDIT_GetSel(wndPtr
, &s
, &e
);
2850 redraw
= EDIT_GetRedraw(wndPtr
);
2851 EDIT_WM_SetRedraw(wndPtr
, FALSE
, 0);
2853 text
= EDIT_GetPointer(wndPtr
);
2854 lstrcpy32A(text
+ s
, text
+ e
);
2855 EDIT_BuildLineDefs(wndPtr
);
2856 EDIT_EM_SetSel(wndPtr
, s
, s
);
2857 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
2858 EDIT_EM_SetModify(wndPtr
, TRUE
, 0);
2859 dprintf_edit(stddeb
, "edit: notification EN_UPDATE sent\n");
2860 EDIT_NOTIFY_PARENT(wndPtr
, EN_UPDATE
);
2861 EDIT_WM_SetRedraw(wndPtr
, redraw
, 0);
2863 InvalidateRect32( wndPtr
->hwndSelf
, NULL
, TRUE
);
2864 dprintf_edit(stddeb
, "edit: notification EN_CHANGE sent\n");
2865 EDIT_NOTIFY_PARENT(wndPtr
, EN_CHANGE
);
2872 /*********************************************************************
2877 static LRESULT
EDIT_WM_Copy(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2887 EDIT_GetSel(wndPtr
, &s
, &e
);
2891 hdst
= GlobalAlloc16(GMEM_MOVEABLE
, (DWORD
)(e
- s
+ 1));
2892 dst
= GlobalLock16(hdst
);
2893 text
= EDIT_GetPointer(wndPtr
);
2895 for (i
= 0 ; i
< e
- s
; i
++)
2898 GlobalUnlock16(hdst
);
2899 OpenClipboard(wndPtr
->hwndSelf
);
2901 SetClipboardData(CF_TEXT
, hdst
);
2907 /*********************************************************************
2912 static LRESULT
EDIT_WM_Create(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2914 CREATESTRUCT32A
*cs
= (CREATESTRUCT32A
*)lParam
;
2918 es
= xmalloc(sizeof(EDITSTATE
));
2919 memset(es
, 0, sizeof(EDITSTATE
));
2920 *(EDITSTATE
**)wndPtr
->wExtra
= es
;
2922 if (cs
->style
& WS_VSCROLL
)
2923 cs
->style
|= ES_AUTOVSCROLL
;
2924 if (cs
->style
& WS_HSCROLL
)
2925 cs
->style
|= ES_AUTOHSCROLL
;
2927 /* remove the WS_CAPTION style if it has been set - this is really a */
2928 /* pseudo option made from a combination of WS_BORDER and WS_DLGFRAME */
2929 if ((cs
->style
& WS_BORDER
) && (cs
->style
& WS_DLGFRAME
))
2930 cs
->style
^= WS_DLGFRAME
;
2932 if (IsMultiLine(wndPtr
)) {
2933 es
->BufSize
= BUFSTART_MULTI
;
2934 es
->BufLimit
= BUFLIMIT_MULTI
;
2935 es
->PasswordChar
= '\0';
2937 es
->BufSize
= BUFSTART_SINGLE
;
2938 es
->BufLimit
= BUFLIMIT_SINGLE
;
2939 es
->PasswordChar
= (cs
->style
& ES_PASSWORD
) ? '*' : '\0';
2941 if (!(es
->hBuf32
= LocalAlloc32(LMEM_MOVEABLE
, es
->BufSize
+ 1))) {
2942 fprintf(stderr
, "edit: WM_CREATE: unable to allocate buffer\n");
2945 es
->BufSize
= LocalSize32(es
->hBuf32
) - 1;
2946 text
= EDIT_GetPointer(wndPtr
);
2948 EDIT_BuildLineDefs(wndPtr
);
2949 EDIT_WM_SetFont(wndPtr
, 0, 0);
2950 if (cs
->lpszName
&& *(cs
->lpszName
) != '\0')
2951 EDIT_EM_ReplaceSel(wndPtr
, FALSE
, (LPARAM
)cs
->lpszName
);
2952 EDIT_WM_SetRedraw(wndPtr
, TRUE
, 0);
2957 /*********************************************************************
2962 static LRESULT
EDIT_WM_Cut(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2964 EDIT_WM_Copy(wndPtr
, 0, 0);
2965 EDIT_WM_Clear(wndPtr
, 0, 0);
2970 /*********************************************************************
2975 static LRESULT
EDIT_WM_Destroy(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2977 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2982 EDIT_ReleasePointer(wndPtr
);
2984 LocalFree32(es
->hBuf32
);
2986 LOCAL_Free(wndPtr
->hInstance
, es
->hBuf16
);
2988 *(EDITSTATE
**)&wndPtr
->wExtra
= NULL
;
2993 /*********************************************************************
2998 static LRESULT
EDIT_WM_Enable(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3000 EDIT_InvalidateText(wndPtr
, 0, -1);
3005 /*********************************************************************
3010 static LRESULT
EDIT_WM_EraseBkGnd(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3015 hBrush
= (HBRUSH32
)EDIT_SEND_CTLCOLOR(wndPtr
, wParam
);
3016 if (!hBrush
) hBrush
= (HBRUSH32
)GetStockObject32(WHITE_BRUSH
);
3018 GetClientRect32(wndPtr
->hwndSelf
, &rc
);
3019 IntersectClipRect32((HDC32
)wParam
, rc
.left
, rc
.top
,
3020 rc
.right
, rc
.bottom
);
3021 GetClipBox32((HDC32
)wParam
, &rc
);
3023 * FIXME: specs say that we should UnrealizeObject() the brush,
3024 * but the specs of UnrealizeObject() say that we shouldn't
3025 * unrealize a stock object. The default brush that
3026 * DefWndProc() returns is ... a stock object.
3028 FillRect32((HDC32
)wParam
, &rc
, hBrush
);
3033 /*********************************************************************
3038 static LRESULT
EDIT_WM_GetDlgCode(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3040 return DLGC_HASSETSEL
| DLGC_WANTCHARS
| DLGC_WANTARROWS
;
3044 /*********************************************************************
3049 static LRESULT
EDIT_WM_GetFont(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3051 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
3053 return (LRESULT
)es
->hFont
;
3057 /*********************************************************************
3062 static LRESULT
EDIT_WM_GetText(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3064 LPSTR text
= EDIT_GetPointer(wndPtr
);
3066 LRESULT lResult
= 0;
3068 len
= lstrlen32A(text
);
3069 if ((INT32
)wParam
> len
) {
3070 lstrcpy32A((LPSTR
)lParam
, text
);
3071 lResult
= (LRESULT
)len
+ 1;
3077 /*********************************************************************
3082 static LRESULT
EDIT_WM_GetTextLength(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3084 LPSTR text
= EDIT_GetPointer(wndPtr
);
3086 return (LRESULT
)lstrlen32A(text
);
3090 /*********************************************************************
3094 * FIXME: scrollbar code itself is broken, so this one is a hack.
3097 static LRESULT
EDIT_WM_HScroll(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3099 INT32 ww
= EDIT_GetWndWidth(wndPtr
);
3100 INT32 tw
= EDIT_GetTextWidth(wndPtr
);
3101 INT32 cw
= EDIT_GetAveCharWidth(wndPtr
);
3102 INT32 xoff
= EDIT_GetXOffset(wndPtr
);
3115 dx
= -ww
/ HSCROLL_FRACTION
/ cw
* cw
;
3118 dx
= ww
/ HSCROLL_FRACTION
/ cw
* cw
;
3130 case SB_THUMBPOSITION
:
3131 dx
= HIWORD(wParam
) * tw
/ 100 - xoff
;
3133 /* The next two are undocumented ! */
3135 ret
= tw
? xoff
* 100 / tw
: 0;
3137 case EM_LINESCROLL16
:
3138 dx
= (INT16
)HIWORD(wParam
);
3145 EDIT_EM_LineScroll(wndPtr
, dx
, 0);
3147 dprintf_edit(stddeb
, "edit: notification EN_HSCROLL sent\n");
3148 EDIT_NOTIFY_PARENT(wndPtr
, EN_HSCROLL
);
3155 /*********************************************************************
3159 * Handling of special keys that don't produce a WM_CHAR
3160 * (i.e. non-printable keys) & Backspace & Delete
3163 static LRESULT
EDIT_WM_KeyDown(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3170 if (GetKeyState(VK_MENU
) & 0x8000)
3173 shift
= GetKeyState(VK_SHIFT
) & 0x8000;
3174 control
= GetKeyState(VK_CONTROL
) & 0x8000;
3176 EDIT_GetSel(wndPtr
, &s
, &e
);
3180 if (IsMultiLine(wndPtr
) && (wParam
== VK_UP
))
3181 EDIT_MoveUpward(wndPtr
, shift
);
3184 EDIT_MoveWordBackward(wndPtr
, shift
);
3186 EDIT_MoveBackward(wndPtr
, shift
);
3190 if (IsMultiLine(wndPtr
) && (wParam
== VK_DOWN
))
3191 EDIT_MoveDownward(wndPtr
, shift
);
3193 EDIT_MoveWordForward(wndPtr
, shift
);
3195 EDIT_MoveForward(wndPtr
, shift
);
3198 EDIT_MoveHome(wndPtr
, shift
);
3201 EDIT_MoveEnd(wndPtr
, shift
);
3204 if (IsMultiLine(wndPtr
))
3205 EDIT_MovePageUp(wndPtr
, shift
);
3208 if (IsMultiLine(wndPtr
))
3209 EDIT_MovePageDown(wndPtr
, shift
);
3212 if (!IsReadOnly(wndPtr
) && !control
)
3214 EDIT_WM_Clear(wndPtr
, 0, 0);
3216 EDIT_DelLeft(wndPtr
);
3219 if (!IsReadOnly(wndPtr
) && !(shift
&& control
))
3222 EDIT_WM_Cut(wndPtr
, 0, 0);
3224 EDIT_WM_Clear(wndPtr
, 0, 0);
3227 EDIT_DelLeft(wndPtr
);
3229 EDIT_DelEnd(wndPtr
);
3231 EDIT_DelRight(wndPtr
);
3236 if (!IsReadOnly(wndPtr
))
3237 EDIT_WM_Paste(wndPtr
, 0, 0);
3239 EDIT_WM_Copy(wndPtr
, 0, 0);
3246 /*********************************************************************
3251 static LRESULT
EDIT_WM_KillFocus(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3257 if(!(wndPtr
->dwStyle
& ES_NOHIDESEL
)) {
3258 EDIT_GetSel(wndPtr
, &s
, &e
);
3259 EDIT_InvalidateText(wndPtr
, s
, e
);
3261 dprintf_edit(stddeb
, "edit: notification EN_KILLFOCUS sent\n");
3262 EDIT_NOTIFY_PARENT(wndPtr
, EN_KILLFOCUS
);
3267 /*********************************************************************
3271 * The caret position has been set on the WM_LBUTTONDOWN message
3274 static LRESULT
EDIT_WM_LButtonDblClk(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3281 LPSTR text
= EDIT_GetPointer(wndPtr
);
3283 EDIT_GetSel(wndPtr
, NULL
, &e
);
3284 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
3285 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
3286 ll
= (INT32
)EDIT_EM_LineLength(wndPtr
, e
, 0);
3287 s
= li
+ EDIT_CallWordBreakProc (wndPtr
, text
+ li
, e
- li
, ll
, WB_LEFT
);
3288 e
= li
+ EDIT_CallWordBreakProc(wndPtr
, text
+ li
, e
- li
, ll
, WB_RIGHT
);
3289 EDIT_EM_SetSel(wndPtr
, s
, e
);
3290 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
3295 /*********************************************************************
3300 static LRESULT
EDIT_WM_LButtonDown(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3302 INT32 x
= (INT32
)(INT16
)LOWORD(lParam
);
3303 INT32 y
= (INT32
)(INT16
)HIWORD(lParam
);
3304 INT32 l
= EDIT_LineFromWndY(wndPtr
, y
);
3308 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0);
3309 INT32 vlc
= EDIT_GetVisibleLineCount(wndPtr
);
3312 SetFocus32(wndPtr
->hwndSelf
);
3313 SetCapture32(wndPtr
->hwndSelf
);
3314 l
= MIN(fv
+ vlc
- 1, MAX(fv
, l
));
3315 x
= MIN(EDIT_GetWndWidth(wndPtr
), MAX(0, x
));
3316 c
= EDIT_ColFromWndX(wndPtr
, l
, x
);
3317 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
3319 if (GetKeyState(VK_SHIFT
) & 0x8000)
3320 EDIT_GetSel(wndPtr
, &s
, NULL
);
3323 EDIT_EM_SetSel(wndPtr
, s
, e
);
3324 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
3329 /*********************************************************************
3334 static LRESULT
EDIT_WM_LButtonUp(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3336 if (GetCapture32() == wndPtr
->hwndSelf
)
3342 /*********************************************************************
3347 static LRESULT
EDIT_WM_MouseMove(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3358 if (GetCapture32() == wndPtr
->hwndSelf
) {
3359 x
= (INT32
)(INT16
)LOWORD(lParam
);
3360 y
= (INT32
)(INT16
)HIWORD(lParam
);
3361 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0);
3362 vlc
= EDIT_GetVisibleLineCount(wndPtr
);
3363 l
= EDIT_LineFromWndY(wndPtr
, y
);
3364 l
= MIN(fv
+ vlc
- 1, MAX(fv
, l
));
3365 x
= MIN(EDIT_GetWndWidth(wndPtr
), MAX(0, x
));
3366 c
= EDIT_ColFromWndX(wndPtr
, l
, x
);
3367 EDIT_GetSel(wndPtr
, &s
, NULL
);
3368 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
3369 EDIT_EM_SetSel(wndPtr
, s
, li
+ c
);
3375 /*********************************************************************
3380 static LRESULT
EDIT_WM_Paint(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3384 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0);
3385 INT32 vlc
= EDIT_GetVisibleLineCount(wndPtr
);
3386 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, 0, 0);
3389 HFONT32 oldFont
= 0;
3393 BOOL32 rev
= IsWindowEnabled(wndPtr
->hwndSelf
) &&
3394 ((GetFocus32() == wndPtr
->hwndSelf
) ||
3395 (wndPtr
->dwStyle
& ES_NOHIDESEL
));
3397 hdc
= BeginPaint32(wndPtr
->hwndSelf
, &ps
);
3398 GetClientRect32(wndPtr
->hwndSelf
, &rc
);
3399 IntersectClipRect32( hdc
, rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
3400 hFont
= (HFONT32
)EDIT_WM_GetFont(wndPtr
, 0, 0);
3402 oldFont
= (HFONT32
)SelectObject32(hdc
, hFont
);
3403 EDIT_SEND_CTLCOLOR(wndPtr
, hdc
);
3404 if (!IsWindowEnabled(wndPtr
->hwndSelf
))
3405 SetTextColor(hdc
, GetSysColor(COLOR_GRAYTEXT
));
3406 GetClipBox32(hdc
, &rcRgn
);
3407 for (i
= fv
; i
<= MIN(fv
+ vlc
, fv
+ lc
- 1) ; i
++ ) {
3408 EDIT_GetLineRect(wndPtr
, i
, 0, -1, &rcLine
);
3409 if (IntersectRect32(&rc
, &rcRgn
, &rcLine
))
3410 EDIT_PaintLine(wndPtr
, hdc
, i
, rev
);
3412 if (hFont
) SelectObject32(hdc
, oldFont
);
3413 EndPaint32(wndPtr
->hwndSelf
, &ps
);
3418 /*********************************************************************
3423 static LRESULT
EDIT_WM_Paste(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3428 OpenClipboard(wndPtr
->hwndSelf
);
3429 if ((hsrc
= GetClipboardData(CF_TEXT
))) {
3430 src
= (LPSTR
)GlobalLock16(hsrc
);
3431 EDIT_EM_ReplaceSel(wndPtr
, 0, (LPARAM
)src
);
3432 GlobalUnlock16(hsrc
);
3439 /*********************************************************************
3444 static LRESULT
EDIT_WM_SetCursor(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3446 if (LOWORD(lParam
) == HTCLIENT
) {
3447 SetCursor(LoadCursor16(0, IDC_IBEAM
));
3454 /*********************************************************************
3459 static LRESULT
EDIT_WM_SetFocus(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3464 EDIT_GetSel(wndPtr
, &s
, &e
);
3465 CreateCaret(wndPtr
->hwndSelf
, 0, 2, EDIT_GetLineHeight(wndPtr
));
3466 EDIT_EM_SetSel(wndPtr
, s
, e
);
3467 if(!(wndPtr
->dwStyle
& ES_NOHIDESEL
))
3468 EDIT_InvalidateText(wndPtr
, s
, e
);
3469 ShowCaret(wndPtr
->hwndSelf
);
3470 dprintf_edit(stddeb
, "edit: notification EN_SETFOCUS sent\n");
3471 EDIT_NOTIFY_PARENT(wndPtr
, EN_SETFOCUS
);
3476 /*********************************************************************
3481 static LRESULT
EDIT_WM_SetFont(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3484 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
3488 HFONT32 oldFont
= 0;
3490 EDIT_GetSel(wndPtr
, &s
, &e
);
3491 es
->hFont
= (HFONT32
)wParam
;
3492 hdc
= GetDC32(wndPtr
->hwndSelf
);
3493 if (es
->hFont
) oldFont
= SelectObject32(hdc
, es
->hFont
);
3494 GetTextMetrics32A(hdc
, &tm
);
3495 es
->LineHeight
= tm
.tmHeight
;
3496 es
->AveCharWidth
= tm
.tmAveCharWidth
;
3497 if (es
->hFont
) SelectObject32(hdc
, oldFont
);
3498 ReleaseDC32(wndPtr
->hwndSelf
, hdc
);
3499 EDIT_BuildLineDefs(wndPtr
);
3500 if ((BOOL32
)lParam
&& EDIT_GetRedraw(wndPtr
))
3501 InvalidateRect32( wndPtr
->hwndSelf
, NULL
, TRUE
);
3502 if (wndPtr
->hwndSelf
== GetFocus32()) {
3504 CreateCaret(wndPtr
->hwndSelf
, 0, 2, EDIT_GetLineHeight(wndPtr
));
3505 EDIT_EM_SetSel16(wndPtr
, s
, e
);
3506 ShowCaret(wndPtr
->hwndSelf
);
3512 /*********************************************************************
3517 static LRESULT
EDIT_WM_SetRedraw(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3519 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
3521 es
->Redraw
= (BOOL32
)wParam
;
3526 /*********************************************************************
3531 static LRESULT
EDIT_WM_SetText(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3533 EDIT_EM_SetSel(wndPtr
, 0, -1);
3535 EDIT_EM_ReplaceSel(wndPtr
, 0, lParam
);
3537 EDIT_WM_Clear(wndPtr
, 0, 0);
3538 EDIT_EM_EmptyUndoBuffer(wndPtr
, 0, 0);
3539 EDIT_EM_SetModify(wndPtr
, TRUE
, 0);
3540 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
3545 /*********************************************************************
3549 * FIXME: What about that FormatRect ???
3552 static LRESULT
EDIT_WM_Size(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3554 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
3556 GetClientRect32(wndPtr
->hwndSelf
, &es
->FormatRect
);
3557 if (EDIT_GetRedraw(wndPtr
) &&
3558 ((wParam
== SIZE_MAXIMIZED
) ||
3559 (wParam
== SIZE_RESTORED
))) {
3560 if (IsMultiLine(wndPtr
) && IsWordWrap(wndPtr
))
3561 EDIT_BuildLineDefs(wndPtr
);
3562 InvalidateRect32( wndPtr
->hwndSelf
, NULL
, TRUE
);
3568 /*********************************************************************
3572 * FIXME: scrollbar code itself is broken, so this one is a hack.
3575 static LRESULT
EDIT_WM_VScroll(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3577 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, 0, 0);
3578 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0);
3579 INT32 vlc
= EDIT_GetVisibleLineCount(wndPtr
);
3606 case SB_THUMBPOSITION
:
3607 dy
= HIWORD(wParam
) * (lc
- 1) / 100 - fv
;
3609 /* The next two are undocumented ! */
3611 ret
= (lc
> 1) ? MAKELONG(fv
* 100 / (lc
- 1), 0) : 0;
3613 case EM_LINESCROLL16
:
3614 dy
= (INT16
)LOWORD(lParam
);
3621 EDIT_EM_LineScroll(wndPtr
, 0, dy
);
3623 dprintf_edit(stddeb
, "edit: notification EN_VSCROLL sent\n");
3624 EDIT_NOTIFY_PARENT(wndPtr
, EN_VSCROLL
);