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 */
32 #define BUFLIMIT_MULTI 65534 /* maximum text buffer length (not including '\0') */
33 /* FIXME: BTW, new specs say 65535 (do you dare ???) */
34 #define BUFLIMIT_SINGLE 32766
35 #define BUFSTART_MULTI 1024 /* starting length for multi-line control */
36 #define BUFSTART_SINGLE 256 /* starting length for single line control */
37 #define GROWLENGTH 64 /* buffers grow by this much */
38 #define HSCROLL_FRACTION 3 /* scroll window by 1/3 width */
57 HLOCAL16 hBuf16
; /* For when a 16-bit multiline edit
58 * control gets a EM_GETHANDLE (which
59 * should return 16-bit local heap).
60 * From that point on we _have_ to keep
61 * using 16-bit local heap (apps rely
62 * on that ... bummer).
64 HLOCAL32 hBuf32
; /* Don't worry about 'LOCAL'. LOCAL32 is
65 * identical to GLOBAL32, which is
66 * essentially a HANDLE32 created with
67 * HeapAlloc(GetProcessHeap(), ...) plus
68 * a global32 (and thus local32)
69 * descriptor, which we can return upon
71 * It is 32-bit linear addressing, so
74 LPSTR text
; /* Depending on the fact that we are a
75 * 16 or 32 bit control, this is the
76 * pointer that we get after
77 * LocalLock32(hBuf23) (which is a typecast :-)
78 * or LOCAL_Lock(hBuf16).
79 * This is always a 32-bit linear pointer.
82 LINEDEF
*LineDefs
; /* Internal table for (soft) linebreaks */
83 INT32 TextWidth
; /* width of the widest line in pixels */
84 INT32 XOffset
; /* offset of the viewport in pixels */
85 INT32 FirstVisibleLine
;
87 INT32 LineHeight
; /* height of a screen line in pixels */
88 INT32 AveCharWidth
; /* average character width in pixels */
98 INT32 SelStart
; /* offset of selection start, == SelEnd if no selection */
99 INT32 SelEnd
; /* offset of selection end == current caret position */
103 * FIXME: The following should probably be a (VOID *) that is
104 * typecast to either 16- or 32-bit callback when used,
105 * depending on the type of edit control (16 or 32 bit).
107 * EDITWORDBREAKPROC WordBreakProc;
109 * For now: no more application specific wordbreaking.
110 * (Internal wordbreak function still works)
119 #define SWAP_INT32(x,y) do { INT32 temp = (INT32)(x); (x) = (INT32)(y); (y) = temp; } while(0)
120 #define ORDER_INT32(x,y) do { if ((INT32)(y) < (INT32)(x)) SWAP_INT32((x),(y)); } while(0)
122 /* macros to access window styles */
123 #define IsMultiLine(wndPtr) ((wndPtr)->dwStyle & ES_MULTILINE)
124 #define IsVScrollBar(wndPtr) ((wndPtr)->dwStyle & WS_VSCROLL)
125 #define IsHScrollBar(wndPtr) ((wndPtr)->dwStyle & WS_HSCROLL)
126 #define IsReadOnly(wndPtr) ((wndPtr)->dwStyle & ES_READONLY)
127 #define IsWordWrap(wndPtr) (((wndPtr)->dwStyle & ES_AUTOHSCROLL) == 0)
128 #define IsPassword(wndPtr) ((wndPtr)->dwStyle & ES_PASSWORD)
129 #define IsLower(wndPtr) ((wndPtr)->dwStyle & ES_LOWERCASE)
130 #define IsUpper(wndPtr) ((wndPtr)->dwStyle & ES_UPPERCASE)
132 #define EDITSTATEPTR(wndPtr) (*(EDITSTATE **)((wndPtr)->wExtra))
134 #define EDIT_SEND_CTLCOLOR(wndPtr,hdc) \
135 (SendMessage32A((wndPtr)->parent->hwndSelf, WM_CTLCOLOREDIT, \
136 (WPARAM32)(hdc), (LPARAM)(wndPtr)->hwndSelf ))
137 #define EDIT_NOTIFY_PARENT(wndPtr, wNotifyCode) \
138 (SendMessage32A((wndPtr)->parent->hwndSelf, WM_COMMAND, \
139 MAKEWPARAM((wndPtr)->wIDmenu, wNotifyCode), \
140 (LPARAM)(wndPtr)->hwndSelf ))
141 #define DPRINTF_EDIT_MSG16(str) \
142 dprintf_edit(stddeb, \
143 "edit: 16 bit : " str ": hwnd=%08x, wParam=%08x, lParam=%08x\n", \
144 (UINT32)hwnd, (UINT32)wParam, (UINT32)lParam)
145 #define DPRINTF_EDIT_MSG32(str) \
146 dprintf_edit(stddeb, \
147 "edit: 32 bit : " str ": hwnd=%08x, wParam=%08x, lParam=%08x\n", \
148 (UINT32)hwnd, (UINT32)wParam, (UINT32)lParam)
151 /*********************************************************************
155 * Files like these should really be kept in alphabetical order.
158 LRESULT
EditWndProc(HWND32 hwnd
, UINT32 msg
, WPARAM32 wParam
, LPARAM lParam
);
160 static void EDIT_BuildLineDefs(WND
*wndPtr
);
161 static INT32
EDIT_CallWordBreakProc(WND
*wndPtr
, LPSTR s
, INT32 index
, INT32 count
, INT32 action
);
162 static INT32
EDIT_ColFromWndX(WND
*wndPtr
, INT32 line
, INT32 x
);
163 static void EDIT_DelEnd(WND
*wndPtr
);
164 static void EDIT_DelLeft(WND
*wndPtr
);
165 static void EDIT_DelRight(WND
*wndPtr
);
166 static INT32
EDIT_GetAveCharWidth(WND
*wndPtr
);
167 static INT32
EDIT_GetLineHeight(WND
*wndPtr
);
168 static void EDIT_GetLineRect(WND
*wndPtr
, INT32 line
, INT32 scol
, INT32 ecol
, LPRECT32 rc
);
169 static LPSTR
EDIT_GetPointer(WND
*wndPtr
);
170 static LPSTR
EDIT_GetPasswordPointer(WND
*wndPtr
);
171 static BOOL32
EDIT_GetRedraw(WND
*wndPtr
);
172 static void EDIT_GetSel(WND
*wndPtr
, LPINT32 s
, LPINT32 e
);
173 static INT32
EDIT_GetTextWidth(WND
*wndPtr
);
174 static LPSTR
EDIT_GetUndoPointer(WND
*wndPtr
);
175 static INT32
EDIT_GetVisibleLineCount(WND
*wndPtr
);
176 static INT32
EDIT_GetWndWidth(WND
*wndPtr
);
177 static INT32
EDIT_GetXOffset(WND
*wndPtr
);
178 static void EDIT_InvalidateText(WND
*wndPtr
, INT32 start
, INT32 end
);
179 static INT32
EDIT_LineFromWndY(WND
*wndPtr
, INT32 y
);
180 static BOOL32
EDIT_MakeFit(WND
*wndPtr
, INT32 size
);
181 static BOOL32
EDIT_MakeUndoFit(WND
*wndPtr
, INT32 size
);
182 static void EDIT_MoveBackward(WND
*wndPtr
, BOOL32 extend
);
183 static void EDIT_MoveDownward(WND
*wndPtr
, BOOL32 extend
);
184 static void EDIT_MoveEnd(WND
*wndPtr
, BOOL32 extend
);
185 static void EDIT_MoveForward(WND
*wndPtr
, BOOL32 extend
);
186 static void EDIT_MoveHome(WND
*wndPtr
, BOOL32 extend
);
187 static void EDIT_MovePageDown(WND
*wndPtr
, BOOL32 extend
);
188 static void EDIT_MovePageUp(WND
*wndPtr
, BOOL32 extend
);
189 static void EDIT_MoveUpward(WND
*wndPtr
, BOOL32 extend
);
190 static void EDIT_MoveWordBackward(WND
*wndPtr
, BOOL32 extend
);
191 static void EDIT_MoveWordForward(WND
*wndPtr
, BOOL32 extend
);
192 static void EDIT_PaintLine(WND
*wndPtr
, HDC32 hdc
, INT32 line
, BOOL32 rev
);
193 static INT32
EDIT_PaintText(WND
*wndPtr
, HDC32 hdc
, INT32 x
, INT32 y
, INT32 line
, INT32 col
, INT32 count
, BOOL32 rev
);
194 static void EDIT_ReleasePointer(WND
*wndPtr
);
195 static void EDIT_ReleaseUndoPointer(WND
*wndPtr
);
196 static void EDIT_SetSel(WND
*wndPtr
, INT32 ns
, INT32 ne
);
197 static INT32
EDIT_WndXFromCol(WND
*wndPtr
, INT32 line
, INT32 col
);
198 static INT32
EDIT_WndYFromLine(WND
*wndPtr
, INT32 line
);
199 static INT32
EDIT_WordBreakProc(LPSTR s
, INT32 index
, INT32 count
, INT32 action
);
201 static LRESULT
EDIT_EM_CanUndo(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
202 static LRESULT
EDIT_EM_CharFromPos(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
203 static LRESULT
EDIT_EM_EmptyUndoBuffer(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
204 static LRESULT
EDIT_EM_FmtLines(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
205 static LRESULT
EDIT_EM_GetFirstVisibleLine(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
206 static LRESULT
EDIT_EM_GetHandle(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
207 static LRESULT
EDIT_EM_GetHandle16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
208 static LRESULT
EDIT_EM_GetLimitText(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
209 static LRESULT
EDIT_EM_GetLine(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
210 static LRESULT
EDIT_EM_GetLineCount(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
211 static LRESULT
EDIT_EM_GetMargins(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
212 static LRESULT
EDIT_EM_GetModify(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
213 static LRESULT
EDIT_EM_GetPasswordChar(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
214 static LRESULT
EDIT_EM_GetRect(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
215 static LRESULT
EDIT_EM_GetRect16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
216 static LRESULT
EDIT_EM_GetSel(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
217 static LRESULT
EDIT_EM_GetThumb(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
218 static LRESULT
EDIT_EM_GetWordBreakProc(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
219 static LRESULT
EDIT_EM_LineFromChar(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
220 static LRESULT
EDIT_EM_LineIndex(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
221 static LRESULT
EDIT_EM_LineLength(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
222 static LRESULT
EDIT_EM_LineScroll(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
223 static LRESULT
EDIT_EM_PosFromChar(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
224 static LRESULT
EDIT_EM_ReplaceSel(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
225 static LRESULT
EDIT_EM_Scroll(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
226 static LRESULT
EDIT_EM_ScrollCaret(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
227 static LRESULT
EDIT_EM_SetHandle(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
228 static LRESULT
EDIT_EM_SetHandle16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
229 static LRESULT
EDIT_EM_SetLimitText(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
230 static LRESULT
EDIT_EM_SetMargins(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
231 static LRESULT
EDIT_EM_SetModify(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
232 static LRESULT
EDIT_EM_SetPasswordChar(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
233 static LRESULT
EDIT_EM_SetReadOnly(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
234 static LRESULT
EDIT_EM_SetRect(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
235 static LRESULT
EDIT_EM_SetRectNP(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
236 static LRESULT
EDIT_EM_SetSel(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
237 static LRESULT
EDIT_EM_SetSel16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
238 static LRESULT
EDIT_EM_SetTabStops(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
239 static LRESULT
EDIT_EM_SetTabStops16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
240 static LRESULT
EDIT_EM_SetWordBreakProc(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
241 static LRESULT
EDIT_EM_Undo(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
243 static LRESULT
EDIT_WM_Char(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
244 static LRESULT
EDIT_WM_Clear(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
245 static LRESULT
EDIT_WM_Command(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
246 static LRESULT
EDIT_WM_ContextMenu(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
247 static LRESULT
EDIT_WM_Copy(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
248 static LRESULT
EDIT_WM_Cut(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
249 static LRESULT
EDIT_WM_Create(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
250 static LRESULT
EDIT_WM_Destroy(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
251 static LRESULT
EDIT_WM_Enable(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
252 static LRESULT
EDIT_WM_EraseBkGnd(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
253 static LRESULT
EDIT_WM_GetDlgCode(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
254 static LRESULT
EDIT_WM_GetFont(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
255 static LRESULT
EDIT_WM_GetText(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
256 static LRESULT
EDIT_WM_GetTextLength(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
257 static LRESULT
EDIT_WM_HScroll(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
258 static LRESULT
EDIT_WM_InitMenuPopup(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
259 static LRESULT
EDIT_WM_KeyDown(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
260 static LRESULT
EDIT_WM_KillFocus(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
261 static LRESULT
EDIT_WM_LButtonDblClk(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
262 static LRESULT
EDIT_WM_LButtonDown(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
263 static LRESULT
EDIT_WM_LButtonUp(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
264 static LRESULT
EDIT_WM_MouseMove(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
265 static LRESULT
EDIT_WM_Paint(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
266 static LRESULT
EDIT_WM_Paste(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
267 static LRESULT
EDIT_WM_SetCursor(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
268 static LRESULT
EDIT_WM_SetFocus(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
269 static LRESULT
EDIT_WM_SetFont(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
270 static LRESULT
EDIT_WM_SetRedraw(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
271 static LRESULT
EDIT_WM_SetText(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
272 static LRESULT
EDIT_WM_Size(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
273 static LRESULT
EDIT_WM_SysKeyDown(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
274 static LRESULT
EDIT_WM_Timer(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
275 static LRESULT
EDIT_WM_VScroll(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
278 /*********************************************************************
280 * General shortcuts for variable names:
284 * INT32 s; offset of selection start
285 * INT32 e; offset of selection end
286 * INT32 sl; line on which the selection starts
287 * INT32 el; line on which the selection ends
288 * INT32 sc; column on which the selection starts
289 * INT32 ec; column on which the selection ends
290 * INT32 li; line index (offset)
291 * INT32 fv; first visible line
292 * INT32 vlc; vissible line count
293 * INT32 lc; line count
294 * INT32 lh; line height (in pixels)
295 * INT32 tw; text width (in pixels)
296 * INT32 ww; window width (in pixels)
297 * INT32 cw; character width (average, in pixels)
302 /*********************************************************************
306 * The messages are in the order of the actual integer values
307 * (which can be found in include/windows.h)
308 * Whereever possible the 16 bit versions are converted to
309 * the 32 bit ones, so that we can 'fall through' to the
310 * helper functions. These are mostly 32 bit (with a few
311 * exceptions, clearly indicated by a '16' extension to their
315 LRESULT
EditWndProc(HWND32 hwnd
, UINT32 msg
, WPARAM32 wParam
, LPARAM lParam
)
318 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
320 if ((!EDITSTATEPTR(wndPtr
)) && (msg
!= WM_CREATE
))
321 return DefWindowProc32A(hwnd
, msg
, wParam
, lParam
);
325 DPRINTF_EDIT_MSG16("EM_GETSEL");
330 DPRINTF_EDIT_MSG32("EM_GETSEL");
331 lResult
= EDIT_EM_GetSel(wndPtr
, wParam
, lParam
);
335 DPRINTF_EDIT_MSG16("EM_SETSEL");
336 lResult
= EDIT_EM_SetSel16(wndPtr
, wParam
, lParam
);
339 DPRINTF_EDIT_MSG32("EM_SETSEL");
340 lResult
= EDIT_EM_SetSel(wndPtr
, wParam
, lParam
);
344 DPRINTF_EDIT_MSG16("EM_GETRECT");
345 lResult
= EDIT_EM_GetRect16(wndPtr
, wParam
, lParam
);
348 DPRINTF_EDIT_MSG32("EM_GETRECT");
349 lResult
= EDIT_EM_GetRect(wndPtr
, wParam
, lParam
);
353 DPRINTF_EDIT_MSG16("EM_SETRECT");
356 DPRINTF_EDIT_MSG32("EM_SETRECT");
357 lResult
= EDIT_EM_SetRect(wndPtr
, wParam
, lParam
);
361 DPRINTF_EDIT_MSG16("EM_SETRECTNP");
364 DPRINTF_EDIT_MSG32("EM_SETRECTNP");
365 lResult
= EDIT_EM_SetRectNP(wndPtr
, wParam
, lParam
);
369 DPRINTF_EDIT_MSG16("EM_SCROLL");
372 DPRINTF_EDIT_MSG32("EM_SCROLL");
373 lResult
= EDIT_EM_Scroll(wndPtr
, wParam
, lParam
);
376 case EM_LINESCROLL16
:
377 DPRINTF_EDIT_MSG16("EM_LINESCROLL");
378 wParam
= (WPARAM32
)(INT32
)(INT16
)HIWORD(lParam
);
379 lParam
= (LPARAM
)(INT32
)(INT16
)LOWORD(lParam
);
381 case EM_LINESCROLL32
:
382 DPRINTF_EDIT_MSG32("EM_LINESCROLL");
383 lResult
= EDIT_EM_LineScroll(wndPtr
, wParam
, lParam
);
386 case EM_SCROLLCARET16
:
387 DPRINTF_EDIT_MSG16("EM_SCROLLCARET");
389 case EM_SCROLLCARET32
:
390 DPRINTF_EDIT_MSG32("EM_SCROLLCARET");
391 lResult
= EDIT_EM_ScrollCaret(wndPtr
, wParam
, lParam
);
395 DPRINTF_EDIT_MSG16("EM_GETMODIFY");
398 DPRINTF_EDIT_MSG32("EM_GETMODIFY");
399 lResult
= EDIT_EM_GetModify(wndPtr
, wParam
, lParam
);
403 DPRINTF_EDIT_MSG16("EM_SETMODIFY");
406 DPRINTF_EDIT_MSG32("EM_SETMODIFY");
407 lResult
= EDIT_EM_SetModify(wndPtr
, wParam
, lParam
);
410 case EM_GETLINECOUNT16
:
411 DPRINTF_EDIT_MSG16("EM_GETLINECOUNT");
413 case EM_GETLINECOUNT32
:
414 DPRINTF_EDIT_MSG32("EM_GETLINECOUNT");
415 lResult
= EDIT_EM_GetLineCount(wndPtr
, wParam
, lParam
);
419 DPRINTF_EDIT_MSG16("EM_LINEINDEX");
422 DPRINTF_EDIT_MSG32("EM_LINEINDEX");
423 lResult
= EDIT_EM_LineIndex(wndPtr
, wParam
, lParam
);
427 DPRINTF_EDIT_MSG16("EM_SETHANDLE");
428 lResult
= EDIT_EM_SetHandle16(wndPtr
, wParam
, lParam
);
431 DPRINTF_EDIT_MSG32("EM_SETHANDLE");
432 lResult
= EDIT_EM_SetHandle(wndPtr
, wParam
, lParam
);
436 DPRINTF_EDIT_MSG16("EM_GETHANDLE");
437 lResult
= EDIT_EM_GetHandle16(wndPtr
, wParam
, lParam
);
440 DPRINTF_EDIT_MSG32("EM_GETHANDLE");
441 lResult
= EDIT_EM_GetHandle(wndPtr
, wParam
, lParam
);
445 DPRINTF_EDIT_MSG16("EM_GETTHUMB");
448 DPRINTF_EDIT_MSG32("EM_GETTHUMB");
449 lResult
= EDIT_EM_GetThumb(wndPtr
, wParam
, lParam
);
452 /* messages 0x00bf and 0x00c0 missing from specs */
455 DPRINTF_EDIT_MSG16("undocumented WM_USER+15, please report");
458 DPRINTF_EDIT_MSG32("undocumented 0x00bf, please report");
459 lResult
= DefWindowProc32A(hwnd
, msg
, wParam
, lParam
);
463 DPRINTF_EDIT_MSG16("undocumented WM_USER+16, please report");
466 DPRINTF_EDIT_MSG32("undocumented 0x00c0, please report");
467 lResult
= DefWindowProc32A(hwnd
, msg
, wParam
, lParam
);
470 case EM_LINELENGTH16
:
471 DPRINTF_EDIT_MSG16("EM_LINELENGTH");
473 case EM_LINELENGTH32
:
474 DPRINTF_EDIT_MSG32("EM_LINELENGTH");
475 lResult
= EDIT_EM_LineLength(wndPtr
, wParam
, lParam
);
478 case EM_REPLACESEL16
:
479 DPRINTF_EDIT_MSG16("EM_REPLACESEL");
480 lParam
= (LPARAM
)PTR_SEG_TO_LIN((SEGPTR
)lParam
);
482 case EM_REPLACESEL32
:
483 DPRINTF_EDIT_MSG32("EM_REPLACESEL");
484 lResult
= EDIT_EM_ReplaceSel(wndPtr
, wParam
, lParam
);
487 /* message 0x00c3 missing from specs */
490 DPRINTF_EDIT_MSG16("undocumented WM_USER+19, please report");
493 DPRINTF_EDIT_MSG32("undocumented 0x00c3, please report");
494 lResult
= DefWindowProc32A(hwnd
, msg
, wParam
, lParam
);
498 DPRINTF_EDIT_MSG16("EM_GETLINE");
499 lParam
= (LPARAM
)PTR_SEG_TO_LIN((SEGPTR
)lParam
);
502 DPRINTF_EDIT_MSG32("EM_GETLINE");
503 lResult
= EDIT_EM_GetLine(wndPtr
, wParam
, lParam
);
507 DPRINTF_EDIT_MSG16("EM_LIMITTEXT");
509 case EM_SETLIMITTEXT32
:
510 DPRINTF_EDIT_MSG32("EM_SETLIMITTEXT");
511 lResult
= EDIT_EM_SetLimitText(wndPtr
, wParam
, lParam
);
515 DPRINTF_EDIT_MSG16("EM_CANUNDO");
518 DPRINTF_EDIT_MSG32("EM_CANUNDO");
519 lResult
= EDIT_EM_CanUndo(wndPtr
, wParam
, lParam
);
523 DPRINTF_EDIT_MSG16("EM_UNDO");
528 DPRINTF_EDIT_MSG32("EM_UNDO / WM_UNDO");
529 lResult
= EDIT_EM_Undo(wndPtr
, wParam
, lParam
);
533 DPRINTF_EDIT_MSG16("EM_FMTLINES");
536 DPRINTF_EDIT_MSG32("EM_FMTLINES");
537 lResult
= EDIT_EM_FmtLines(wndPtr
, wParam
, lParam
);
540 case EM_LINEFROMCHAR16
:
541 DPRINTF_EDIT_MSG16("EM_LINEFROMCHAR");
543 case EM_LINEFROMCHAR32
:
544 DPRINTF_EDIT_MSG32("EM_LINEFROMCHAR");
545 lResult
= EDIT_EM_LineFromChar(wndPtr
, wParam
, lParam
);
548 /* message 0x00ca missing from specs */
551 DPRINTF_EDIT_MSG16("undocumented WM_USER+26, please report");
554 DPRINTF_EDIT_MSG32("undocumented 0x00ca, please report");
555 lResult
= DefWindowProc32A(hwnd
, msg
, wParam
, lParam
);
558 case EM_SETTABSTOPS16
:
559 DPRINTF_EDIT_MSG16("EM_SETTABSTOPS");
560 lResult
= EDIT_EM_SetTabStops16(wndPtr
, wParam
, lParam
);
562 case EM_SETTABSTOPS32
:
563 DPRINTF_EDIT_MSG32("EM_SETTABSTOPS");
564 lResult
= EDIT_EM_SetTabStops(wndPtr
, wParam
, lParam
);
567 case EM_SETPASSWORDCHAR16
:
568 DPRINTF_EDIT_MSG16("EM_SETPASSWORDCHAR");
570 case EM_SETPASSWORDCHAR32
:
571 DPRINTF_EDIT_MSG32("EM_SETPASSWORDCHAR");
572 lResult
= EDIT_EM_SetPasswordChar(wndPtr
, wParam
, lParam
);
575 case EM_EMPTYUNDOBUFFER16
:
576 DPRINTF_EDIT_MSG16("EM_EMPTYUNDOBUFFER");
578 case EM_EMPTYUNDOBUFFER32
:
579 DPRINTF_EDIT_MSG32("EM_EMPTYUNDOBUFFER");
580 lResult
= EDIT_EM_EmptyUndoBuffer(wndPtr
, wParam
, lParam
);
583 case EM_GETFIRSTVISIBLELINE16
:
584 DPRINTF_EDIT_MSG16("EM_GETFIRSTVISIBLELINE");
586 case EM_GETFIRSTVISIBLELINE32
:
587 DPRINTF_EDIT_MSG32("EM_GETFIRSTVISIBLELINE");
588 lResult
= EDIT_EM_GetFirstVisibleLine(wndPtr
, wParam
, lParam
);
591 case EM_SETREADONLY16
:
592 DPRINTF_EDIT_MSG16("EM_SETREADONLY");
594 case EM_SETREADONLY32
:
595 DPRINTF_EDIT_MSG32("EM_SETREADONLY");
596 lResult
= EDIT_EM_SetReadOnly(wndPtr
, wParam
, lParam
);
599 case EM_SETWORDBREAKPROC16
:
600 DPRINTF_EDIT_MSG16("EM_SETWORDBREAKPROC");
602 case EM_SETWORDBREAKPROC32
:
603 DPRINTF_EDIT_MSG32("EM_SETWORDBREAKPROC");
604 lResult
= EDIT_EM_SetWordBreakProc(wndPtr
, wParam
, lParam
);
607 case EM_GETWORDBREAKPROC16
:
608 DPRINTF_EDIT_MSG16("EM_GETWORDBREAKPROC");
610 case EM_GETWORDBREAKPROC32
:
611 DPRINTF_EDIT_MSG32("EM_GETWORDBREAKPROC");
612 lResult
= EDIT_EM_GetWordBreakProc(wndPtr
, wParam
, lParam
);
615 case EM_GETPASSWORDCHAR16
:
616 DPRINTF_EDIT_MSG16("EM_GETPASSWORDCHAR");
618 case EM_GETPASSWORDCHAR32
:
619 DPRINTF_EDIT_MSG32("EM_GETPASSWORDCHAR");
620 lResult
= EDIT_EM_GetPasswordChar(wndPtr
, wParam
, lParam
);
623 /* The following EM_xxx are new to win95 and don't exist for 16 bit */
625 case EM_SETMARGINS32
:
626 DPRINTF_EDIT_MSG16("EM_SETMARGINS");
627 lResult
= EDIT_EM_SetMargins(wndPtr
, wParam
, lParam
);
630 case EM_GETMARGINS32
:
631 DPRINTF_EDIT_MSG16("EM_GETMARGINS");
632 lResult
= EDIT_EM_GetMargins(wndPtr
, wParam
, lParam
);
635 case EM_GETLIMITTEXT32
:
636 DPRINTF_EDIT_MSG16("EM_GETLIMITTEXT");
637 lResult
= EDIT_EM_GetLimitText(wndPtr
, wParam
, lParam
);
640 case EM_POSFROMCHAR32
:
641 DPRINTF_EDIT_MSG16("EM_POSFROMCHAR");
642 lResult
= EDIT_EM_PosFromChar(wndPtr
, wParam
, lParam
);
645 case EM_CHARFROMPOS32
:
646 DPRINTF_EDIT_MSG16("EM_CHARFROMPOS");
647 lResult
= EDIT_EM_CharFromPos(wndPtr
, wParam
, lParam
);
651 DPRINTF_EDIT_MSG32("WM_GETDLGCODE");
652 lResult
= EDIT_WM_GetDlgCode(wndPtr
, wParam
, lParam
);
656 DPRINTF_EDIT_MSG32("WM_CHAR");
657 lResult
= EDIT_WM_Char(wndPtr
, wParam
, lParam
);
661 DPRINTF_EDIT_MSG32("WM_CLEAR");
662 lResult
= EDIT_WM_Clear(wndPtr
, wParam
, lParam
);
666 DPRINTF_EDIT_MSG32("WM_COMMAND");
667 lResult
= EDIT_WM_Command(wndPtr
, wParam
, lParam
);
671 * FIXME: when this one is added to WINE, change RBUTTONUP to CONTEXTMENU
672 * Furthermore, coordinate conversion should no longer be required
674 * case WM_CONTEXTMENU:
677 DPRINTF_EDIT_MSG32("WM_RBUTTONUP");
678 ClientToScreen16(wndPtr
->hwndSelf
, (LPPOINT16
)&lParam
);
679 lResult
= EDIT_WM_ContextMenu(wndPtr
, wParam
, lParam
);
683 DPRINTF_EDIT_MSG32("WM_COPY");
684 lResult
= EDIT_WM_Copy(wndPtr
, wParam
, lParam
);
688 DPRINTF_EDIT_MSG32("WM_CREATE");
689 lResult
= EDIT_WM_Create(wndPtr
, wParam
, lParam
);
693 DPRINTF_EDIT_MSG32("WM_CUT");
694 lResult
= EDIT_WM_Cut(wndPtr
, wParam
, lParam
);
698 DPRINTF_EDIT_MSG32("WM_DESTROY");
699 lResult
= EDIT_WM_Destroy(wndPtr
, wParam
, lParam
);
703 DPRINTF_EDIT_MSG32("WM_ENABLE");
704 lResult
= EDIT_WM_Enable(wndPtr
, wParam
, lParam
);
708 DPRINTF_EDIT_MSG32("WM_ERASEBKGND");
709 lResult
= EDIT_WM_EraseBkGnd(wndPtr
, wParam
, lParam
);
713 DPRINTF_EDIT_MSG32("WM_GETFONT");
714 lResult
= EDIT_WM_GetFont(wndPtr
, wParam
, lParam
);
718 DPRINTF_EDIT_MSG32("WM_GETTEXT");
719 lResult
= EDIT_WM_GetText(wndPtr
, wParam
, lParam
);
722 case WM_GETTEXTLENGTH
:
723 DPRINTF_EDIT_MSG32("WM_GETTEXTLENGTH");
724 lResult
= EDIT_WM_GetTextLength(wndPtr
, wParam
, lParam
);
728 DPRINTF_EDIT_MSG32("WM_HSCROLL");
729 lResult
= EDIT_WM_HScroll(wndPtr
, wParam
, lParam
);
732 case WM_INITMENUPOPUP
:
733 DPRINTF_EDIT_MSG32("WM_INITMENUPOPUP");
734 lResult
= EDIT_WM_InitMenuPopup(wndPtr
, wParam
, lParam
);
738 DPRINTF_EDIT_MSG32("WM_KEYDOWN");
739 lResult
= EDIT_WM_KeyDown(wndPtr
, wParam
, lParam
);
743 DPRINTF_EDIT_MSG32("WM_KILLFOCUS");
744 lResult
= EDIT_WM_KillFocus(wndPtr
, wParam
, lParam
);
747 case WM_LBUTTONDBLCLK
:
748 DPRINTF_EDIT_MSG32("WM_LBUTTONDBLCLK");
749 lResult
= EDIT_WM_LButtonDblClk(wndPtr
, wParam
, lParam
);
753 DPRINTF_EDIT_MSG32("WM_LBUTTONDOWN");
754 lResult
= EDIT_WM_LButtonDown(wndPtr
, wParam
, lParam
);
758 DPRINTF_EDIT_MSG32("WM_LBUTTONUP");
759 lResult
= EDIT_WM_LButtonUp(wndPtr
, wParam
, lParam
);
764 * DPRINTF_EDIT_MSG32("WM_MOUSEMOVE");
766 lResult
= EDIT_WM_MouseMove(wndPtr
, wParam
, lParam
);
770 DPRINTF_EDIT_MSG32("WM_PAINT");
771 lResult
= EDIT_WM_Paint(wndPtr
, wParam
, lParam
);
775 DPRINTF_EDIT_MSG32("WM_PASTE");
776 lResult
= EDIT_WM_Paste(wndPtr
, wParam
, lParam
);
781 * DPRINTF_EDIT_MSG32("WM_SETCURSOR");
783 lResult
= EDIT_WM_SetCursor(wndPtr
, wParam
, lParam
);
787 DPRINTF_EDIT_MSG32("WM_SETFOCUS");
788 lResult
= EDIT_WM_SetFocus(wndPtr
, wParam
, lParam
);
792 DPRINTF_EDIT_MSG32("WM_SETFONT");
793 lResult
= EDIT_WM_SetFont(wndPtr
, wParam
, lParam
);
797 DPRINTF_EDIT_MSG32("WM_SETREDRAW");
798 lResult
= EDIT_WM_SetRedraw(wndPtr
, wParam
, lParam
);
802 DPRINTF_EDIT_MSG32("WM_SETTEXT");
803 lResult
= EDIT_WM_SetText(wndPtr
, wParam
, lParam
);
807 DPRINTF_EDIT_MSG32("WM_SIZE");
808 lResult
= EDIT_WM_Size(wndPtr
, wParam
, lParam
);
812 DPRINTF_EDIT_MSG32("WM_SYSKEYDOWN");
813 lResult
= EDIT_WM_SysKeyDown(wndPtr
, wParam
, lParam
);
817 DPRINTF_EDIT_MSG32("WM_TIMER");
818 lResult
= EDIT_WM_Timer(wndPtr
, wParam
, lParam
);
822 DPRINTF_EDIT_MSG32("WM_VSCROLL");
823 lResult
= EDIT_WM_VScroll(wndPtr
, wParam
, lParam
);
827 lResult
= DefWindowProc32A(hwnd
, msg
, wParam
, lParam
);
830 EDIT_ReleasePointer(wndPtr
);
835 /*********************************************************************
839 * Build array of pointers to text lines.
840 * Lines can end with '\0' (last line), nothing (if it is too long),
841 * a delimiter (usually ' '), a soft return '\r\r\n' or a hard return '\r\n'
844 static void EDIT_BuildLineDefs(WND
*wndPtr
)
846 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
847 LPSTR text
= EDIT_GetPasswordPointer(wndPtr
);
848 INT32 ww
= EDIT_GetWndWidth(wndPtr
);
858 hdc
= GetDC32(wndPtr
->hwndSelf
);
859 hFont
= (HFONT32
)EDIT_WM_GetFont(wndPtr
, 0, 0);
860 if (hFont
) oldFont
= SelectObject32(hdc
, hFont
);
862 if (!IsMultiLine(wndPtr
)) {
864 es
->LineDefs
= xrealloc(es
->LineDefs
, sizeof(LINEDEF
));
865 es
->LineDefs
[0].offset
= 0;
866 es
->LineDefs
[0].length
= EDIT_WM_GetTextLength(wndPtr
, 0, 0);
867 es
->LineDefs
[0].ending
= END_0
;
868 es
->TextWidth
= (INT32
)LOWORD(GetTabbedTextExtent(hdc
, text
,
869 es
->LineDefs
[0].length
,
870 es
->NumTabStops
, es
->TabStops
));
875 if (!(cp
= strstr(start
, "\r\n"))) {
877 length
= lstrlen32A(start
);
878 } else if ((cp
> start
) && (*(cp
- 1) == '\r')) {
880 length
= cp
- start
- 1;
885 width
= (INT32
)LOWORD(GetTabbedTextExtent(hdc
, start
, length
,
886 es
->NumTabStops
, es
->TabStops
));
888 if (IsWordWrap(wndPtr
) && (width
> ww
)) {
892 next
= EDIT_CallWordBreakProc(wndPtr
, start
,
893 prev
+ 1, length
, WB_RIGHT
);
894 width
= (INT32
)LOWORD(GetTabbedTextExtent(hdc
, start
, next
,
895 es
->NumTabStops
, es
->TabStops
));
896 } while (width
<= ww
);
902 width
= (INT32
)LOWORD(GetTabbedTextExtent(hdc
, start
, next
,
903 es
->NumTabStops
, es
->TabStops
));
904 } while (width
<= ww
);
908 if (EDIT_CallWordBreakProc(wndPtr
, start
, length
- 1,
909 length
, WB_ISDELIMITER
)) {
911 ending
= END_DELIMIT
;
914 width
= (INT32
)LOWORD(GetTabbedTextExtent(hdc
, start
, length
,
915 es
->NumTabStops
, es
->TabStops
));
918 es
->LineDefs
= xrealloc(es
->LineDefs
, (es
->LineCount
+ 1) * sizeof(LINEDEF
));
919 es
->LineDefs
[es
->LineCount
].offset
= start
- text
;
920 es
->LineDefs
[es
->LineCount
].length
= length
;
921 es
->LineDefs
[es
->LineCount
].ending
= ending
;
923 es
->TextWidth
= MAX(es
->TextWidth
, width
);
939 } while (*start
|| (ending
== END_SOFT
) || (ending
== END_HARD
));
941 if (hFont
) SelectObject32(hdc
, oldFont
);
942 ReleaseDC32(wndPtr
->hwndSelf
, hdc
);
948 /*********************************************************************
950 * EDIT_CallWordBreakProc
952 * Call appropriate WordBreakProc (internal or external).
954 * FIXME: Heavily broken now that we have a LOCAL32 buffer.
955 * External wordbreak functions have been disabled in
956 * EM_SETWORDBREAKPROC.
959 static INT32
EDIT_CallWordBreakProc(WND
*wndPtr
, LPSTR s
, INT32 index
, INT32 count
, INT32 action
)
961 return EDIT_WordBreakProc(s
, index
, count
, action
);
963 * EDITWORDBREAKPROC wbp = (EDITWORDBREAKPROC)EDIT_EM_GetWordBreakProc(wndPtr, 0, 0);
965 * if (!wbp) return EDIT_WordBreakProc(s, index, count, action);
967 * EDITSTATE *es = EDITSTATEPTR(wndPtr);
968 * SEGPTR ptr = LOCAL_LockSegptr( wndPtr->hInstance, es->hBuf16 ) +
969 * (INT16)(s - EDIT_GetPointer(wndPtr));
970 * INT ret = CallWordBreakProc( (FARPROC16)wbp, ptr,
971 * index, count, action);
972 * LOCAL_Unlock( wndPtr->hInstance, es->hBuf16 );
979 /*********************************************************************
983 * Calculates, for a given line and X-coordinate on the screen, the column.
986 static INT32
EDIT_ColFromWndX(WND
*wndPtr
, INT32 line
, INT32 x
)
988 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, 0, 0);
989 INT32 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, line
, 0);
990 INT32 ll
= (INT32
)EDIT_EM_LineLength(wndPtr
, li
, 0);
993 line
= MAX(0, MIN(line
, lc
- 1));
994 for (i
= 0 ; i
< ll
; i
++)
995 if (EDIT_WndXFromCol(wndPtr
, line
, i
) >= x
)
1001 /*********************************************************************
1005 * Delete all characters on this line to right of cursor.
1008 static void EDIT_DelEnd(WND
*wndPtr
)
1010 EDIT_EM_SetSel(wndPtr
, -1, 0);
1011 EDIT_MoveEnd(wndPtr
, TRUE
);
1012 EDIT_WM_Clear(wndPtr
, 0, 0);
1016 /*********************************************************************
1020 * Delete character to left of cursor.
1023 static void EDIT_DelLeft(WND
*wndPtr
)
1025 EDIT_EM_SetSel(wndPtr
, -1, 0);
1026 EDIT_MoveBackward(wndPtr
, TRUE
);
1027 EDIT_WM_Clear(wndPtr
, 0, 0);
1031 /*********************************************************************
1035 * Delete character to right of cursor.
1038 static void EDIT_DelRight(WND
*wndPtr
)
1040 EDIT_EM_SetSel(wndPtr
, -1, 0);
1041 EDIT_MoveForward(wndPtr
, TRUE
);
1042 EDIT_WM_Clear(wndPtr
, 0, 0);
1046 /*********************************************************************
1048 * EDIT_GetAveCharWidth
1051 static INT32
EDIT_GetAveCharWidth(WND
*wndPtr
)
1053 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1055 return es
->AveCharWidth
;
1059 /*********************************************************************
1061 * EDIT_GetLineHeight
1064 static INT32
EDIT_GetLineHeight(WND
*wndPtr
)
1066 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1068 return es
->LineHeight
;
1072 /*********************************************************************
1076 * Calculates the bounding rectangle for a line from a starting
1077 * column to an ending column.
1080 static void EDIT_GetLineRect(WND
*wndPtr
, INT32 line
, INT32 scol
, INT32 ecol
, LPRECT32 rc
)
1082 rc
->top
= EDIT_WndYFromLine(wndPtr
, line
);
1083 rc
->bottom
= rc
->top
+ EDIT_GetLineHeight(wndPtr
);
1084 rc
->left
= EDIT_WndXFromCol(wndPtr
, line
, scol
);
1085 rc
->right
= (ecol
== -1) ? EDIT_GetWndWidth(wndPtr
) :
1086 EDIT_WndXFromCol(wndPtr
, line
, ecol
);
1090 /*********************************************************************
1094 * This acts as a LOCAL_Lock(), but it locks only once. This way
1095 * you can call it whenever you like, without unlocking.
1098 static LPSTR
EDIT_GetPointer(WND
*wndPtr
)
1100 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1102 if (!es
->text
&& (es
->hBuf32
|| es
->hBuf16
)) {
1104 es
->text
= (LPSTR
)LocalLock32(es
->hBuf32
);
1106 es
->text
= LOCAL_Lock(wndPtr
->hInstance
, es
->hBuf16
);
1112 /*********************************************************************
1114 * EDIT_GetPasswordPointer
1118 static LPSTR
EDIT_GetPasswordPointer(WND
*wndPtr
)
1120 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1121 LPSTR text
= xstrdup(EDIT_GetPointer(wndPtr
));
1124 if(es
->PasswordChar
) {
1127 if(*p
!= '\r' && *p
!= '\n')
1128 *p
= es
->PasswordChar
;
1136 /*********************************************************************
1141 static BOOL32
EDIT_GetRedraw(WND
*wndPtr
)
1143 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1149 /*********************************************************************
1153 * Beware: This is not the function called on EM_GETSEL.
1154 * This is the unordered version used internally
1155 * (s can be > e). No return value either.
1158 static void EDIT_GetSel(WND
*wndPtr
, LPINT32 s
, LPINT32 e
)
1160 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1169 /*********************************************************************
1174 static INT32
EDIT_GetTextWidth(WND
*wndPtr
)
1176 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1178 return es
->TextWidth
;
1182 /*********************************************************************
1184 * EDIT_GetUndoPointer
1186 * This acts as a LocalLock32(), but it locks only once. This way
1187 * you can call it whenever you like, without unlocking.
1190 static LPSTR
EDIT_GetUndoPointer(WND
*wndPtr
)
1192 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1194 if (!es
->UndoText
&& es
->hUndoBuf
)
1195 es
->UndoText
= (LPSTR
)LocalLock32(es
->hUndoBuf
);
1196 return es
->UndoText
;
1200 /*********************************************************************
1202 * EDIT_GetVisibleLineCount
1205 static INT32
EDIT_GetVisibleLineCount(WND
*wndPtr
)
1209 EDIT_EM_GetRect(wndPtr
, 0, (LPARAM
)&rc
);
1210 return MAX(1, MAX(rc
.bottom
- rc
.top
, 0) / EDIT_GetLineHeight(wndPtr
));
1214 /*********************************************************************
1219 static INT32
EDIT_GetWndWidth(WND
*wndPtr
)
1223 EDIT_EM_GetRect(wndPtr
, 0, (LPARAM
)&rc
);
1224 return rc
.right
- rc
.left
;
1228 /*********************************************************************
1233 static INT32
EDIT_GetXOffset(WND
*wndPtr
)
1235 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1241 /*********************************************************************
1243 * EDIT_InvalidateText
1245 * Invalidate the text from offset start upto, but not including,
1246 * offset end. Useful for (re)painting the selection.
1247 * Regions outside the linewidth are not invalidated.
1248 * end == -1 means end == TextLength.
1249 * start and end need not be ordered.
1252 static void EDIT_InvalidateText(WND
*wndPtr
, INT32 start
, INT32 end
)
1254 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0);
1255 INT32 vlc
= EDIT_GetVisibleLineCount(wndPtr
);
1269 end
= (INT32
)EDIT_WM_GetTextLength(wndPtr
, 0, 0);
1270 ORDER_INT32(start
, end
);
1271 sl
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, start
, 0);
1272 el
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, end
, 0);
1273 if ((el
< fv
) || (sl
> fv
+ vlc
))
1276 sc
= start
- (INT32
)EDIT_EM_LineIndex(wndPtr
, sl
, 0);
1277 ec
= end
- (INT32
)EDIT_EM_LineIndex(wndPtr
, el
, 0);
1282 if (el
> fv
+ vlc
) {
1284 ec
= (INT32
)EDIT_EM_LineLength(wndPtr
,
1285 (INT32
)EDIT_EM_LineIndex(wndPtr
, el
, 0), 0);
1287 EDIT_EM_GetRect(wndPtr
, 0, (LPARAM
)&rcWnd
);
1289 EDIT_GetLineRect(wndPtr
, sl
, sc
, ec
, &rcLine
);
1290 if (IntersectRect32(&rcUpdate
, &rcWnd
, &rcLine
))
1291 InvalidateRect32( wndPtr
->hwndSelf
, &rcUpdate
, FALSE
);
1293 EDIT_GetLineRect(wndPtr
, sl
, sc
,
1294 (INT32
)EDIT_EM_LineLength(wndPtr
,
1295 (INT32
)EDIT_EM_LineIndex(wndPtr
, sl
, 0), 0),
1297 if (IntersectRect32(&rcUpdate
, &rcWnd
, &rcLine
))
1298 InvalidateRect32( wndPtr
->hwndSelf
, &rcUpdate
, FALSE
);
1299 for (l
= sl
+ 1 ; l
< el
; l
++) {
1300 EDIT_GetLineRect(wndPtr
, l
, 0,
1301 (INT32
)EDIT_EM_LineLength(wndPtr
,
1302 (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0), 0),
1304 if (IntersectRect32(&rcUpdate
, &rcWnd
, &rcLine
))
1305 InvalidateRect32(wndPtr
->hwndSelf
, &rcUpdate
, FALSE
);
1307 EDIT_GetLineRect(wndPtr
, el
, 0, ec
, &rcLine
);
1308 if (IntersectRect32(&rcUpdate
, &rcWnd
, &rcLine
))
1309 InvalidateRect32( wndPtr
->hwndSelf
, &rcUpdate
, FALSE
);
1314 /*********************************************************************
1318 * Calculates, for a given Y-coordinate on the screen, the line.
1321 static INT32
EDIT_LineFromWndY(WND
*wndPtr
, INT32 y
)
1323 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0);
1324 INT32 lh
= EDIT_GetLineHeight(wndPtr
);
1325 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, 0, 0);
1327 return MAX(0, MIN(lc
- 1, y
/ lh
+ fv
));
1331 /*********************************************************************
1335 * Try to fit size + 1 bytes in the buffer. Constrain to limits.
1338 static BOOL32
EDIT_MakeFit(WND
*wndPtr
, INT32 size
)
1340 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1344 if (size
<= es
->BufSize
)
1346 if (size
> es
->BufLimit
) {
1347 dprintf_edit(stddeb
, "edit: notification EN_MAXTEXT sent\n");
1348 EDIT_NOTIFY_PARENT(wndPtr
, EN_MAXTEXT
);
1351 size
= ((size
/ GROWLENGTH
) + 1) * GROWLENGTH
;
1352 if (size
> es
->BufLimit
)
1353 size
= es
->BufLimit
;
1355 dprintf_edit(stddeb
, "edit: EDIT_MakeFit: trying to ReAlloc to %d+1\n", size
);
1357 EDIT_ReleasePointer(wndPtr
);
1359 if ((hNew32
= LocalReAlloc32(es
->hBuf32
, size
+ 1, 0))) {
1360 dprintf_edit(stddeb
, "edit: EDIT_MakeFit: Old 32 bit handle %08x, new handle %08x\n", es
->hBuf32
, hNew32
);
1361 es
->hBuf32
= hNew32
;
1362 es
->BufSize
= MIN(LocalSize32(es
->hBuf32
) - 1, es
->BufLimit
);
1363 if (es
->BufSize
< size
) {
1364 dprintf_edit(stddeb
, "edit: EDIT_MakeFit: FAILED ! We now have %d+1\n", es
->BufSize
);
1365 dprintf_edit(stddeb
, "edit: notification EN_ERRSPACE sent\n");
1366 EDIT_NOTIFY_PARENT(wndPtr
, EN_ERRSPACE
);
1369 dprintf_edit(stddeb
, "edit: EDIT_MakeFit: We now have %d+1\n", es
->BufSize
);
1373 if ((hNew16
= LOCAL_ReAlloc(wndPtr
->hInstance
, es
->hBuf16
, size
+ 1, LMEM_MOVEABLE
))) {
1374 dprintf_edit(stddeb
, "edit: EDIT_MakeFit: Old 16 bit handle %08x, new handle %08x\n", es
->hBuf16
, hNew16
);
1375 es
->hBuf16
= hNew16
;
1376 es
->BufSize
= MIN(LOCAL_Size(wndPtr
->hInstance
, es
->hBuf16
) - 1, es
->BufLimit
);
1377 if (es
->BufSize
< size
) {
1378 dprintf_edit(stddeb
, "edit: EDIT_MakeFit: FAILED ! We now have %d+1\n", es
->BufSize
);
1379 dprintf_edit(stddeb
, "edit: notification EN_ERRSPACE sent\n");
1380 EDIT_NOTIFY_PARENT(wndPtr
, EN_ERRSPACE
);
1383 dprintf_edit(stddeb
, "edit: EDIT_MakeFit: We now have %d+1\n", es
->BufSize
);
1387 dprintf_edit(stddeb
, "edit: EDIT_MakeFit: Reallocation failed\n");
1388 dprintf_edit(stddeb
, "edit: notification EN_ERRSPACE sent\n");
1389 EDIT_NOTIFY_PARENT(wndPtr
, EN_ERRSPACE
);
1394 /*********************************************************************
1398 * Try to fit size + 1 bytes in the undo buffer.
1401 static BOOL32
EDIT_MakeUndoFit(WND
*wndPtr
, INT32 size
)
1403 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1406 if (size
<= es
->UndoBufSize
)
1408 size
= ((size
/ GROWLENGTH
) + 1) * GROWLENGTH
;
1410 dprintf_edit(stddeb
, "edit: EDIT_MakeUndoFit: trying to ReAlloc to %d+1\n", size
);
1412 EDIT_ReleaseUndoPointer(wndPtr
);
1413 if ((hNew
= LocalReAlloc32(es
->hUndoBuf
, size
+ 1, 0))) {
1414 dprintf_edit(stddeb
, "edit: EDIT_MakeUndoFit: Old handle %08x, new handle %08x\n", es
->hUndoBuf
, hNew
);
1415 es
->hUndoBuf
= hNew
;
1416 es
->UndoBufSize
= LocalSize32(es
->hUndoBuf
) - 1;
1417 if (es
->UndoBufSize
< size
) {
1418 dprintf_edit(stddeb
, "edit: EDIT_MakeUndoFit: FAILED ! We now have %d+1\n", es
->UndoBufSize
);
1421 dprintf_edit(stddeb
, "edit: EDIT_MakeUndoFit: We now have %d+1\n", es
->UndoBufSize
);
1428 /*********************************************************************
1433 static void EDIT_MoveBackward(WND
*wndPtr
, BOOL32 extend
)
1440 EDIT_GetSel(wndPtr
, &s
, &e
);
1441 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
1442 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
1445 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
- 1, 0);
1446 e
= li
+ (INT32
)EDIT_EM_LineLength(wndPtr
, li
, 0);
1452 EDIT_SetSel(wndPtr
, s
, e
);
1453 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
1457 /*********************************************************************
1462 static void EDIT_MoveDownward(WND
*wndPtr
, BOOL32 extend
)
1471 EDIT_GetSel(wndPtr
, &s
, &e
);
1472 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
1473 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, e
, 0);
1474 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
1476 x
= EDIT_WndXFromCol(wndPtr
, l
, e
- li
);
1478 e
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0) +
1479 EDIT_ColFromWndX(wndPtr
, l
, x
);
1483 EDIT_SetSel(wndPtr
, s
, e
);
1484 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
1488 /*********************************************************************
1493 static void EDIT_MoveEnd(WND
*wndPtr
, BOOL32 extend
)
1501 EDIT_GetSel(wndPtr
, &s
, &e
);
1502 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
1503 ll
= (INT32
)EDIT_EM_LineLength(wndPtr
, e
, 0);
1504 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
1508 EDIT_SetSel(wndPtr
, s
, e
);
1509 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
1513 /*********************************************************************
1518 static void EDIT_MoveForward(WND
*wndPtr
, BOOL32 extend
)
1527 EDIT_GetSel(wndPtr
, &s
, &e
);
1528 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
1529 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, e
, 0);
1530 ll
= (INT32
)EDIT_EM_LineLength(wndPtr
, e
, 0);
1531 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
1534 e
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
+ 1, 0);
1539 EDIT_SetSel(wndPtr
, s
, e
);
1540 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
1544 /*********************************************************************
1548 * Home key: move to beginning of line.
1551 static void EDIT_MoveHome(WND
*wndPtr
, BOOL32 extend
)
1558 EDIT_GetSel(wndPtr
, &s
, &e
);
1559 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
1560 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
1564 EDIT_SetSel(wndPtr
, s
, e
);
1565 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
1569 /*********************************************************************
1574 static void EDIT_MovePageDown(WND
*wndPtr
, BOOL32 extend
)
1583 EDIT_GetSel(wndPtr
, &s
, &e
);
1584 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
1585 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, e
, 0);
1586 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
1588 x
= EDIT_WndXFromCol(wndPtr
, l
, e
- li
);
1589 l
= MIN(lc
- 1, l
+ EDIT_GetVisibleLineCount(wndPtr
));
1590 e
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0) +
1591 EDIT_ColFromWndX(wndPtr
, l
, x
);
1595 EDIT_SetSel(wndPtr
, s
, e
);
1596 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
1600 /*********************************************************************
1605 static void EDIT_MovePageUp(WND
*wndPtr
, BOOL32 extend
)
1613 EDIT_GetSel(wndPtr
, &s
, &e
);
1614 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
1615 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
1617 x
= EDIT_WndXFromCol(wndPtr
, l
, e
- li
);
1618 l
= MAX(0, l
- EDIT_GetVisibleLineCount(wndPtr
));
1619 e
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0) +
1620 EDIT_ColFromWndX(wndPtr
, l
, x
);
1624 EDIT_SetSel(wndPtr
, s
, e
);
1625 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
1629 /*********************************************************************
1634 static void EDIT_MoveUpward(WND
*wndPtr
, BOOL32 extend
)
1642 EDIT_GetSel(wndPtr
, &s
, &e
);
1643 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
1644 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
1646 x
= EDIT_WndXFromCol(wndPtr
, l
, e
- li
);
1648 e
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0) +
1649 EDIT_ColFromWndX(wndPtr
, l
, x
);
1653 EDIT_SetSel(wndPtr
, s
, e
);
1654 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
1658 /*********************************************************************
1660 * EDIT_MoveWordBackward
1663 static void EDIT_MoveWordBackward(WND
*wndPtr
, BOOL32 extend
)
1672 EDIT_GetSel(wndPtr
, &s
, &e
);
1673 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
1674 ll
= (INT32
)EDIT_EM_LineLength(wndPtr
, e
, 0);
1675 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
1678 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
- 1, 0);
1679 e
= li
+ (INT32
)EDIT_EM_LineLength(wndPtr
, li
, 0);
1682 text
= EDIT_GetPointer(wndPtr
);
1683 e
= li
+ (INT32
)EDIT_CallWordBreakProc(wndPtr
,
1684 text
+ li
, e
- li
, ll
, WB_LEFT
);
1688 EDIT_SetSel(wndPtr
, s
, e
);
1689 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
1693 /*********************************************************************
1695 * EDIT_MoveWordForward
1698 static void EDIT_MoveWordForward(WND
*wndPtr
, BOOL32 extend
)
1708 EDIT_GetSel(wndPtr
, &s
, &e
);
1709 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
1710 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, e
, 0);
1711 ll
= (INT32
)EDIT_EM_LineLength(wndPtr
, e
, 0);
1712 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
1715 e
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
+ 1, 0);
1717 text
= EDIT_GetPointer(wndPtr
);
1718 e
= li
+ EDIT_CallWordBreakProc(wndPtr
,
1719 text
+ li
, e
- li
+ 1, ll
, WB_RIGHT
);
1723 EDIT_SetSel(wndPtr
, s
, e
);
1724 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
1728 /*********************************************************************
1733 static void EDIT_PaintLine(WND
*wndPtr
, HDC32 hdc
, INT32 line
, BOOL32 rev
)
1735 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0);
1736 INT32 vlc
= EDIT_GetVisibleLineCount(wndPtr
);
1737 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, 0, 0);
1745 if ((line
< fv
) || (line
> fv
+ vlc
) || (line
>= lc
))
1748 dprintf_edit(stddeb
, "edit: EDIT_PaintLine: line=%d\n", line
);
1750 x
= EDIT_WndXFromCol(wndPtr
, line
, 0);
1751 y
= EDIT_WndYFromLine(wndPtr
, line
);
1752 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, line
, 0);
1753 ll
= (INT32
)EDIT_EM_LineLength(wndPtr
, li
, 0);
1754 EDIT_GetSel(wndPtr
, &s
, &e
);
1756 s
= MIN(li
+ ll
, MAX(li
, s
));
1757 e
= MIN(li
+ ll
, MAX(li
, e
));
1758 if (rev
&& (s
!= e
) &&
1759 ((GetFocus32() == wndPtr
->hwndSelf
) ||
1760 (wndPtr
->dwStyle
& ES_NOHIDESEL
))) {
1761 x
+= EDIT_PaintText(wndPtr
, hdc
, x
, y
, line
, 0, s
- li
, FALSE
);
1762 x
+= EDIT_PaintText(wndPtr
, hdc
, x
, y
, line
, s
- li
, e
- s
, TRUE
);
1763 x
+= EDIT_PaintText(wndPtr
, hdc
, x
, y
, line
, e
- li
, li
+ ll
- e
, FALSE
);
1765 x
+= EDIT_PaintText(wndPtr
, hdc
, x
, y
, line
, 0, ll
, FALSE
);
1769 /*********************************************************************
1774 static INT32
EDIT_PaintText(WND
*wndPtr
, HDC32 hdc
, INT32 x
, INT32 y
, INT32 line
, INT32 col
, INT32 count
, BOOL32 rev
)
1776 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1786 BkColor
= GetBkColor32(hdc
);
1787 TextColor
= GetTextColor32(hdc
);
1789 SetBkColor(hdc
, GetSysColor(COLOR_HIGHLIGHT
));
1790 SetTextColor(hdc
, GetSysColor(COLOR_HIGHLIGHTTEXT
));
1792 text
= EDIT_GetPasswordPointer(wndPtr
);
1793 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, line
, 0);
1794 xoff
= EDIT_GetXOffset(wndPtr
);
1795 ret
= (INT32
)LOWORD(TabbedTextOut(hdc
, x
, y
, text
+ li
+ col
, count
,
1796 es
->NumTabStops
, es
->TabStops
, -xoff
));
1799 SetBkColor(hdc
, BkColor
);
1800 SetTextColor(hdc
, TextColor
);
1806 /*********************************************************************
1808 * EDIT_ReleasePointer
1810 * This is the only helper function that can be called with es = NULL.
1811 * It is called at the end of EditWndProc() to unlock the buffer.
1814 static void EDIT_ReleasePointer(WND
*wndPtr
)
1816 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1820 if (es
->text
&& (es
->hBuf32
|| es
->hBuf16
)) {
1822 LocalUnlock32(es
->hBuf32
);
1824 LOCAL_Unlock(wndPtr
->hInstance
, es
->hBuf16
);
1830 /*********************************************************************
1832 * EDIT_ReleaseUndoPointer
1834 * This is the only helper function that can be called with es = NULL.
1835 * It is called at the end of EditWndProc() to unlock the buffer.
1838 static void EDIT_ReleaseUndoPointer(WND
*wndPtr
)
1840 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1844 if (es
->UndoText
&& es
->hUndoBuf
)
1845 LocalUnlock32(es
->hUndoBuf
);
1846 es
->UndoText
= NULL
;
1850 /*********************************************************************
1854 * Beware: This is not the function called on EM_SETSEL.
1855 * This is the unordered version used internally
1856 * (s can be > e). Doesn't accept -1 parameters either.
1857 * No range checking.
1860 static void EDIT_SetSel(WND
*wndPtr
, INT32 ns
, INT32 ne
)
1862 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1867 EDIT_EM_GetSel(wndPtr
, (WPARAM32
)&s
, (LPARAM
)&e
);
1870 if (EDIT_GetRedraw(wndPtr
)) {
1871 if (wndPtr
->hwndSelf
== GetFocus32()) {
1872 pos
= EDIT_EM_PosFromChar(wndPtr
, ne
, 0);
1873 SetCaretPos((INT16
)LOWORD(pos
), (INT16
)HIWORD(pos
));
1879 ORDER_INT32(ns
, ne
);
1881 EDIT_InvalidateText(wndPtr
, s
, e
);
1882 EDIT_InvalidateText(wndPtr
, ns
, ne
);
1884 EDIT_InvalidateText(wndPtr
, s
, ne
);
1889 /*********************************************************************
1893 * Calculates, for a given line and column, the X-coordinate on the screen.
1896 static INT32
EDIT_WndXFromCol(WND
*wndPtr
, INT32 line
, INT32 col
)
1898 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1899 LPSTR text
= EDIT_GetPasswordPointer(wndPtr
);
1903 HFONT32 oldFont
= 0;
1904 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, 0, 0);
1905 INT32 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, line
, 0);
1906 INT32 ll
= (INT32
)EDIT_EM_LineLength(wndPtr
, li
, 0);
1907 INT32 xoff
= EDIT_GetXOffset(wndPtr
);
1909 hdc
= GetDC32(wndPtr
->hwndSelf
);
1910 hFont
= (HFONT32
)EDIT_WM_GetFont(wndPtr
, 0, 0);
1911 if (hFont
) oldFont
= SelectObject32(hdc
, hFont
);
1912 line
= MAX(0, MIN(line
, lc
- 1));
1914 ret
= (INT32
)LOWORD(GetTabbedTextExtent(hdc
,
1916 es
->NumTabStops
, es
->TabStops
)) - xoff
;
1917 if (hFont
) SelectObject32(hdc
, oldFont
);
1918 ReleaseDC32(wndPtr
->hwndSelf
, hdc
);
1924 /*********************************************************************
1928 * Calculates, for a given line, the Y-coordinate on the screen.
1931 static INT32
EDIT_WndYFromLine(WND
*wndPtr
, INT32 line
)
1933 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0);
1934 INT32 lh
= EDIT_GetLineHeight(wndPtr
);
1936 return (line
- fv
) * lh
;
1940 /*********************************************************************
1942 * EDIT_WordBreakProc
1944 * Find the beginning of words.
1945 * Note: unlike the specs for a WordBreakProc, this function only
1946 * allows to be called without linebreaks between s[0] upto
1947 * s[count - 1]. Remember it is only called
1948 * internally, so we can decide this for ourselves.
1951 static INT32
EDIT_WordBreakProc(LPSTR s
, INT32 index
, INT32 count
, INT32 action
)
1955 dprintf_edit(stddeb
, "edit: EDIT_WordBreakProc: s=%p, index=%u"
1956 ", count=%u, action=%d\n", s
, index
, count
, action
);
1964 if (s
[index
] == ' ') {
1965 while (index
&& (s
[index
] == ' '))
1968 while (index
&& (s
[index
] != ' '))
1970 if (s
[index
] == ' ')
1974 while (index
&& (s
[index
] != ' '))
1976 if (s
[index
] == ' ')
1986 if (s
[index
] == ' ')
1987 while ((index
< count
) && (s
[index
] == ' ')) index
++;
1989 while (s
[index
] && (s
[index
] != ' ') && (index
< count
))
1991 while ((s
[index
] == ' ') && (index
< count
)) index
++;
1995 case WB_ISDELIMITER
:
1996 ret
= (s
[index
] == ' ');
1999 fprintf(stderr
, "edit: EDIT_WordBreakProc: unknown action code, please report !\n");
2006 /*********************************************************************
2011 static LRESULT
EDIT_EM_CanUndo(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2013 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2015 return (LRESULT
)(es
->UndoInsertLen
|| lstrlen32A(EDIT_GetUndoPointer(wndPtr
)));
2019 /*********************************************************************
2023 * FIXME: do the specs mean LineIndex or LineNumber (li v.s. l) ???
2025 static LRESULT
EDIT_EM_CharFromPos(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2033 pt
.x
= LOWORD(lParam
);
2034 pt
.y
= HIWORD(lParam
);
2035 GetClientRect32(wndPtr
->hwndSelf
, &rc
);
2037 if (!PtInRect32(&rc
, pt
))
2040 l
= EDIT_LineFromWndY(wndPtr
, pt
.y
);
2041 li
= EDIT_EM_LineIndex(wndPtr
, l
, 0);
2042 c
= EDIT_ColFromWndX(wndPtr
, l
, pt
.x
);
2044 return (LRESULT
)MAKELONG(li
+ c
, li
);
2048 /*********************************************************************
2050 * EM_EMPTYUNDOBUFFER
2053 static LRESULT
EDIT_EM_EmptyUndoBuffer(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2055 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2057 es
->UndoInsertLen
= 0;
2058 *EDIT_GetUndoPointer(wndPtr
) = '\0';
2063 /*********************************************************************
2068 static LRESULT
EDIT_EM_FmtLines(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2070 fprintf(stdnimp
, "edit: EM_FMTLINES: message not implemented\n");
2071 return wParam
? TRUE
: FALSE
;
2075 /*********************************************************************
2077 * EM_GETFIRSTVISIBLELINE
2080 static LRESULT
EDIT_EM_GetFirstVisibleLine(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2082 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2084 if (IsMultiLine(wndPtr
))
2085 return (LRESULT
)es
->FirstVisibleLine
;
2087 return (LRESULT
)EDIT_ColFromWndX(wndPtr
, 0, 0);
2091 /*********************************************************************
2096 static LRESULT
EDIT_EM_GetHandle(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2098 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2100 if (!IsMultiLine(wndPtr
))
2104 return (LRESULT
)es
->hBuf32
;
2106 return (LRESULT
)es
->hBuf16
;
2110 /*********************************************************************
2114 * Hopefully this won't fire back at us.
2115 * We always start with a buffer in 32 bit linear memory.
2116 * However, with this message a 16 bit application requests
2117 * a handle of 16 bit local heap memory, where it expects to find
2119 * It's a pitty that from this moment on we have to use this
2120 * local heap, because applications may rely on the handle
2123 * In this function we'll try to switch to local heap.
2125 static LRESULT
EDIT_EM_GetHandle16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2127 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2133 if (!IsMultiLine(wndPtr
))
2137 return (LRESULT
)es
->hBuf16
;
2139 if (!LOCAL_HeapSize(wndPtr
->hInstance
)) {
2140 if (!LocalInit(wndPtr
->hInstance
, 0,
2141 GlobalSize16(wndPtr
->hInstance
))) {
2142 fprintf(stderr
, "edit: EM_GETHANDLE: could not initialize local heap\n");
2145 dprintf_edit(stddeb
, "edit: EM_GETHANDLE: local heap initialized\n");
2147 if (!(newBuf
= LOCAL_Alloc(wndPtr
->hInstance
,
2148 EDIT_WM_GetTextLength(wndPtr
, 0, 0) + 1,
2150 fprintf(stderr
, "edit: EM_GETHANDLE: could not allocate new 16 bit buffer\n");
2153 newSize
= MIN(LOCAL_Size(wndPtr
->hInstance
, newBuf
) - 1, es
->BufLimit
);
2154 if (!(newText
= LOCAL_Lock(wndPtr
->hInstance
, newBuf
))) {
2155 fprintf(stderr
, "edit: EM_GETHANDLE: could not lock new 16 bit buffer\n");
2156 LOCAL_Free(wndPtr
->hInstance
, newBuf
);
2159 text
= EDIT_GetPointer(wndPtr
);
2160 lstrcpy32A(newText
, text
);
2161 EDIT_ReleasePointer(wndPtr
);
2162 GlobalFree32(es
->hBuf32
);
2163 es
->hBuf32
= (HLOCAL32
)NULL
;
2164 es
->hBuf16
= newBuf
;
2165 es
->BufSize
= newSize
;
2167 dprintf_edit(stddeb
, "edit: EM_GETHANDLE: switched to 16 bit buffer\n");
2169 return (LRESULT
)es
->hBuf16
;
2173 /*********************************************************************
2178 static LRESULT
EDIT_EM_GetLimitText(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2180 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2182 return es
->BufLimit
;
2186 /*********************************************************************
2191 static LRESULT
EDIT_EM_GetLine(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2198 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, 0, 0);
2200 if (!IsMultiLine(wndPtr
))
2202 if ((INT32
)wParam
>= lc
)
2204 text
= EDIT_GetPointer(wndPtr
);
2205 src
= text
+ (INT32
)EDIT_EM_LineIndex(wndPtr
, wParam
, 0);
2206 dst
= (LPSTR
)lParam
;
2207 len
= MIN(*(WORD
*)dst
, (INT32
)EDIT_EM_LineLength(wndPtr
, wParam
, 0));
2208 for (i
= 0 ; i
< len
; i
++) {
2213 return (LRESULT
)len
;
2217 /*********************************************************************
2222 static LRESULT
EDIT_EM_GetLineCount(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2224 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2226 return (LRESULT
)es
->LineCount
;
2230 /*********************************************************************
2235 static LRESULT
EDIT_EM_GetMargins(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2237 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2239 return (LRESULT
)MAKELONG(es
->LeftMargin
, es
->RightMargin
);
2243 /*********************************************************************
2248 static LRESULT
EDIT_EM_GetModify(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2250 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2252 return (LRESULT
)es
->TextChanged
;
2256 /*********************************************************************
2258 * EM_GETPASSWORDCHAR
2261 static LRESULT
EDIT_EM_GetPasswordChar(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2263 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2265 return (LRESULT
)es
->PasswordChar
;
2269 /*********************************************************************
2274 static LRESULT
EDIT_EM_GetRect(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2276 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2278 CopyRect32((LPRECT32
)lParam
, &es
->FormatRect
);
2283 /*********************************************************************
2288 static LRESULT
EDIT_EM_GetRect16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2290 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2292 CONV_RECT32TO16(&es
->FormatRect
, (LPRECT16
)PTR_SEG_TO_LIN((SEGPTR
)lParam
));
2297 /*********************************************************************
2301 * Returns the ordered selection range so that
2302 * LOWORD(result) < HIWORD(result)
2305 static LRESULT
EDIT_EM_GetSel(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2310 EDIT_GetSel(wndPtr
, &s
, &e
);
2313 *(LPINT32
)wParam
= s
;
2315 *(LPINT32
)lParam
= e
;
2316 return MAKELONG((INT16
)s
, (INT16
)e
);
2320 /*********************************************************************
2324 * FIXME: is this right ? (or should it be only HSCROLL)
2325 * (and maybe only for edit controls that really have their
2326 * own scrollbars) (and maybe only for multiline controls ?)
2327 * All in all: very poorly documented
2330 static LRESULT
EDIT_EM_GetThumb(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2332 return MAKELONG(EDIT_WM_VScroll(wndPtr
, EM_GETTHUMB16
, 0),
2333 EDIT_WM_HScroll(wndPtr
, EM_GETTHUMB16
, 0));
2337 /*********************************************************************
2339 * EM_GETWORDBREAKPROC
2341 * FIXME: Application defined WordBreakProc should be returned
2344 static LRESULT
EDIT_EM_GetWordBreakProc(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2347 EDITSTATE *es = EDITSTATEPTR(wndPtr);
2349 return (LRESULT)es->WordBreakProc;
2355 /*********************************************************************
2360 static LRESULT
EDIT_EM_LineFromChar(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2364 if (!IsMultiLine(wndPtr
))
2366 if ((INT32
)wParam
== -1)
2367 EDIT_EM_GetSel(wndPtr
, (WPARAM32
)&wParam
, 0); /* intentional (looks weird, doesn't it ?) */
2368 l
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, 0, 0) - 1;
2369 while ((INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0) > (INT32
)wParam
)
2375 /*********************************************************************
2380 static LRESULT
EDIT_EM_LineIndex(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2382 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2385 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, 0, 0);
2387 if ((INT32
)wParam
== -1) {
2388 EDIT_GetSel(wndPtr
, NULL
, &e
);
2390 while (es
->LineDefs
[l
].offset
> e
)
2392 return (LRESULT
)es
->LineDefs
[l
].offset
;
2394 if ((INT32
)wParam
>= lc
)
2396 return (LRESULT
)es
->LineDefs
[(INT32
)wParam
].offset
;
2400 /*********************************************************************
2405 static LRESULT
EDIT_EM_LineLength(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2407 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2413 if (!IsMultiLine(wndPtr
))
2414 return (LRESULT
)es
->LineDefs
[0].length
;
2415 if ((INT32
)wParam
== -1) {
2416 EDIT_GetSel(wndPtr
, &s
, &e
);
2417 sl
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, s
, 0);
2418 el
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
2419 return (LRESULT
)(s
- es
->LineDefs
[sl
].offset
+
2420 es
->LineDefs
[el
].offset
+
2421 es
->LineDefs
[el
].length
- e
);
2423 return (LRESULT
)es
->LineDefs
[(INT32
)EDIT_EM_LineFromChar(wndPtr
, wParam
, 0)].length
;
2427 /*********************************************************************
2431 * FIXME: is wParam in pixels or in average character widths ???
2432 * FIXME: we use this internally to scroll single line controls as well
2433 * (specs are vague about whether this message is valid or not for
2434 * single line controls)
2437 static LRESULT
EDIT_EM_LineScroll(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2439 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2440 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, 0, 0);
2441 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0);
2442 INT32 nfv
= MAX(0, fv
+ (INT32
)lParam
);
2443 INT32 xoff
= EDIT_GetXOffset(wndPtr
);
2444 INT32 nxoff
= MAX(0, xoff
+ (INT32
)wParam
);
2445 INT32 tw
= EDIT_GetTextWidth(wndPtr
);
2455 dy
= EDIT_WndYFromLine(wndPtr
, fv
) - EDIT_WndYFromLine(wndPtr
, nfv
);
2457 if (EDIT_GetRedraw(wndPtr
))
2458 ScrollWindow32(wndPtr
->hwndSelf
, dx
, dy
, NULL
, NULL
);
2459 es
->FirstVisibleLine
= nfv
;
2460 es
->XOffset
= nxoff
;
2461 if (IsVScrollBar(wndPtr
))
2462 SetScrollPos32(wndPtr
->hwndSelf
, SB_VERT
,
2463 EDIT_WM_VScroll(wndPtr
, EM_GETTHUMB16
, 0), TRUE
);
2464 if (IsHScrollBar(wndPtr
))
2465 SetScrollPos32(wndPtr
->hwndSelf
, SB_HORZ
,
2466 EDIT_WM_HScroll(wndPtr
, EM_GETTHUMB16
, 0), TRUE
);
2468 if (IsMultiLine(wndPtr
))
2475 /*********************************************************************
2480 static LRESULT
EDIT_EM_PosFromChar(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2482 INT32 len
= (INT32
)EDIT_WM_GetTextLength(wndPtr
, 0, 0);
2486 wParam
= MIN(wParam
, len
);
2487 l
= EDIT_EM_LineFromChar(wndPtr
, wParam
, 0);
2488 li
= EDIT_EM_LineIndex(wndPtr
, l
, 0);
2489 return (LRESULT
)MAKELONG(EDIT_WndXFromCol(wndPtr
, l
, wParam
- li
),
2490 EDIT_WndYFromLine(wndPtr
, l
));
2494 /*********************************************************************
2499 static LRESULT
EDIT_EM_ReplaceSel(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2501 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2502 LPCSTR str
= (LPCSTR
)lParam
;
2503 INT32 strl
= lstrlen32A(str
);
2504 INT32 tl
= (INT32
)EDIT_WM_GetTextLength(wndPtr
, 0, 0);
2514 EDIT_EM_GetSel(wndPtr
, (WPARAM32
)&s
, (LPARAM
)&e
);
2516 if ((s
== e
) && !strl
)
2519 if (!EDIT_MakeFit(wndPtr
, tl
- (e
- s
) + strl
))
2522 text
= EDIT_GetPointer(wndPtr
);
2523 utext
= EDIT_GetUndoPointer(wndPtr
);
2525 /* there is something to be deleted */
2526 if ((BOOL32
)wParam
) {
2527 /* we have to be able to undo */
2528 utl
= lstrlen32A(utext
);
2529 if (!es
->UndoInsertLen
&& (*utext
&& (s
== es
->UndoPos
))) {
2530 /* undo-buffer is extended to the right */
2531 EDIT_MakeUndoFit(wndPtr
, utl
+ e
- s
);
2532 lstrcpyn32A(utext
+ utl
, text
+ s
, e
- s
+ 1);
2533 } else if (!es
->UndoInsertLen
&& (*utext
&& (e
== es
->UndoPos
))) {
2534 /* undo-buffer is extended to the left */
2535 EDIT_MakeUndoFit(wndPtr
, utl
+ e
- s
);
2536 for (p
= utext
+ utl
; p
>= utext
; p
--)
2538 for (i
= 0 , p
= utext
; i
< e
- s
; i
++)
2539 p
[i
] = (text
+ s
)[i
];
2542 /* new undo-buffer */
2543 EDIT_MakeUndoFit(wndPtr
, e
- s
);
2544 lstrcpyn32A(utext
, text
+ s
, e
- s
+ 1);
2547 /* any deletion makes the old insertion-undo invalid */
2548 es
->UndoInsertLen
= 0;
2550 EDIT_EM_EmptyUndoBuffer(wndPtr
, 0, 0);
2553 lstrcpy32A(text
+ s
, text
+ e
);
2556 /* there is an insertion */
2557 if ((BOOL32
)wParam
) {
2558 /* we have to be able to undo */
2559 if ((s
== es
->UndoPos
) ||
2560 ((es
->UndoInsertLen
) &&
2561 (s
== es
->UndoPos
+ es
->UndoInsertLen
)))
2563 * insertion is new and at delete position or
2564 * an extension to either left or right
2566 es
->UndoInsertLen
+= strl
;
2568 /* new insertion undo */
2570 es
->UndoInsertLen
= strl
;
2571 /* new insertion makes old delete-buffer invalid */
2575 EDIT_EM_EmptyUndoBuffer(wndPtr
, 0, 0);
2578 tl
= lstrlen32A(text
);
2579 for (p
= text
+ tl
; p
>= text
+ s
; p
--)
2581 for (i
= 0 , p
= text
+ s
; i
< strl
; i
++)
2584 CharUpperBuff32A(p
, strl
);
2585 else if(IsLower(wndPtr
))
2586 CharLowerBuff32A(p
, strl
);
2589 redraw
= EDIT_GetRedraw(wndPtr
);
2590 EDIT_WM_SetRedraw(wndPtr
, FALSE
, 0);
2591 EDIT_BuildLineDefs(wndPtr
);
2592 EDIT_EM_SetSel(wndPtr
, s
, s
);
2593 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
2594 EDIT_EM_SetModify(wndPtr
, TRUE
, 0);
2595 dprintf_edit(stddeb
, "edit: notification EN_UPDATE sent\n");
2596 EDIT_NOTIFY_PARENT(wndPtr
, EN_UPDATE
);
2597 EDIT_WM_SetRedraw(wndPtr
, redraw
, 0);
2599 InvalidateRect32( wndPtr
->hwndSelf
, NULL
, TRUE
);
2600 dprintf_edit(stddeb
, "edit: notification EN_CHANGE sent\n");
2601 EDIT_NOTIFY_PARENT(wndPtr
, EN_CHANGE
);
2607 /*********************************************************************
2611 * FIXME: Scroll what ??? And where ???
2614 static LRESULT
EDIT_EM_Scroll(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2616 fprintf(stdnimp
, "edit: EM_SCROLL: message not implemented\n");
2621 /*********************************************************************
2625 * Makes sure the caret is visible.
2626 * FIXME: We use EM_LINESCROLL, but may we do that for single line
2630 static LRESULT
EDIT_EM_ScrollCaret(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2635 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0);
2636 INT32 vlc
= EDIT_GetVisibleLineCount(wndPtr
);
2637 INT32 ww
= EDIT_GetWndWidth(wndPtr
);
2638 INT32 cw
= EDIT_GetAveCharWidth(wndPtr
);
2643 EDIT_GetSel(wndPtr
, NULL
, &e
);
2644 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
2645 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
2646 x
= EDIT_WndXFromCol(wndPtr
, l
, e
- li
);
2648 dy
= l
- vlc
+ 1 - fv
;
2652 dx
= x
- ww
/ HSCROLL_FRACTION
/ cw
* cw
;
2654 dx
= x
- (HSCROLL_FRACTION
- 1) * ww
/ HSCROLL_FRACTION
/ cw
* cw
;
2656 EDIT_EM_LineScroll(wndPtr
, dx
, dy
);
2658 dprintf_edit(stddeb
, "edit: notification EN_VSCROLL sent\n");
2659 EDIT_NOTIFY_PARENT(wndPtr
, EN_VSCROLL
);
2662 dprintf_edit(stddeb
, "edit: notification EN_HSCROLL sent\n");
2663 EDIT_NOTIFY_PARENT(wndPtr
, EN_HSCROLL
);
2670 /*********************************************************************
2675 static LRESULT
EDIT_EM_SetHandle(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2677 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2679 if (IsMultiLine(wndPtr
)) {
2680 EDIT_ReleasePointer(wndPtr
);
2682 * old buffer is freed by caller
2684 es
->hBuf16
= (HLOCAL16
)NULL
;
2685 es
->hBuf32
= (HLOCAL32
)wParam
;
2686 es
->BufSize
= LocalSize32(es
->hBuf32
) - 1;
2688 es
->FirstVisibleLine
= 0;
2689 es
->SelStart
= es
->SelEnd
= 0;
2690 EDIT_EM_EmptyUndoBuffer(wndPtr
, 0, 0);
2691 EDIT_EM_SetModify(wndPtr
, FALSE
, 0);
2692 EDIT_BuildLineDefs(wndPtr
);
2693 if (EDIT_GetRedraw(wndPtr
))
2694 InvalidateRect32( wndPtr
->hwndSelf
, NULL
, TRUE
);
2695 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
2701 /*********************************************************************
2706 static LRESULT
EDIT_EM_SetHandle16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2708 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2710 if (IsMultiLine(wndPtr
)) {
2711 EDIT_ReleasePointer(wndPtr
);
2713 * old buffer is freed by caller
2715 es
->hBuf16
= (HLOCAL16
)wParam
;
2716 es
->hBuf32
= (HLOCAL32
)NULL
;
2717 es
->BufSize
= LOCAL_Size(wndPtr
->hInstance
, es
->hBuf16
) - 1;
2719 es
->FirstVisibleLine
= 0;
2720 es
->SelStart
= es
->SelEnd
= 0;
2721 EDIT_EM_EmptyUndoBuffer(wndPtr
, 0, 0);
2722 EDIT_EM_SetModify(wndPtr
, FALSE
, 0);
2723 EDIT_BuildLineDefs(wndPtr
);
2724 if (EDIT_GetRedraw(wndPtr
))
2725 InvalidateRect32( wndPtr
->hwndSelf
, NULL
, TRUE
);
2726 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
2732 /*********************************************************************
2736 * FIXME: in WinNT maxsize is 0x7FFFFFFF / 0xFFFFFFFF
2737 * However, the windows version is not complied to yet in all of edit.c
2740 static LRESULT
EDIT_EM_SetLimitText(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2742 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2744 if (IsMultiLine(wndPtr
)) {
2746 es
->BufLimit
= MIN((INT32
)wParam
, BUFLIMIT_MULTI
);
2748 es
->BufLimit
= BUFLIMIT_MULTI
;
2751 es
->BufLimit
= MIN((INT32
)wParam
, BUFLIMIT_SINGLE
);
2753 es
->BufLimit
= BUFLIMIT_SINGLE
;
2759 /*********************************************************************
2763 * FIXME: We let the margins be set, but we don't use them yet !?!
2766 static LRESULT
EDIT_EM_SetMargins(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2768 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2770 if (wParam
& EC_USEFONTINFO
) {
2771 if (IsMultiLine(wndPtr
)) {
2773 * FIXME: do some GetABCCharWidth, or so
2774 * This is just preliminary
2776 es
->LeftMargin
= es
->RightMargin
= EDIT_GetAveCharWidth(wndPtr
);
2778 es
->LeftMargin
= es
->RightMargin
= EDIT_GetAveCharWidth(wndPtr
);
2781 if (wParam
& EC_LEFTMARGIN
)
2782 es
->LeftMargin
= LOWORD(lParam
);
2783 if (wParam
& EC_RIGHTMARGIN
)
2784 es
->RightMargin
= HIWORD(lParam
);
2789 /*********************************************************************
2794 static LRESULT
EDIT_EM_SetModify(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2796 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2798 es
->TextChanged
= (BOOL32
)wParam
;
2803 /*********************************************************************
2805 * EM_SETPASSWORDCHAR
2807 * FIXME: This imlementation is way too simple
2810 static LRESULT
EDIT_EM_SetPasswordChar(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2812 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2814 es
->PasswordChar
= (CHAR
)wParam
;
2819 /*********************************************************************
2824 static LRESULT
EDIT_EM_SetReadOnly(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2827 wndPtr
->dwStyle
|= ES_READONLY
;
2829 wndPtr
->dwStyle
&= ~(DWORD
)ES_READONLY
;
2834 /*********************************************************************
2839 static LRESULT
EDIT_EM_SetRect(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2841 fprintf(stdnimp
,"edit: EM_SETRECT: message not implemented\n");
2846 /*********************************************************************
2851 static LRESULT
EDIT_EM_SetRectNP(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2853 fprintf(stdnimp
,"edit: EM_SETRECTNP: message not implemented\n");
2858 /*********************************************************************
2863 static LRESULT
EDIT_EM_SetSel(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2865 INT32 ns
= (INT32
)wParam
;
2866 INT32 ne
= (INT32
)lParam
;
2867 INT32 tl
= (INT32
)EDIT_WM_GetTextLength(wndPtr
, 0, 0);
2870 EDIT_GetSel(wndPtr
, NULL
, &ne
);
2872 } else if ((!ns
) && (ne
== -1))
2875 ns
= MAX(0, MIN(ns
, tl
));
2876 ne
= MAX(0, MIN(ne
, tl
));
2877 ORDER_INT32(ns
, ne
);
2879 EDIT_SetSel(wndPtr
, ns
, ne
);
2884 /*********************************************************************
2889 static LRESULT
EDIT_EM_SetSel16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2891 INT32 ns
= (INT32
)LOWORD(lParam
);
2892 INT32 ne
= (INT32
)HIWORD(lParam
);
2894 if ((INT16
)LOWORD(lParam
) == -1)
2896 if ((!ns
) && ((INT16
)HIWORD(lParam
) == -1))
2898 EDIT_EM_SetSel(wndPtr
, ns
, ne
);
2900 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
2905 /*********************************************************************
2910 static LRESULT
EDIT_EM_SetTabStops(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2912 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2915 if (!IsMultiLine(wndPtr
))
2919 es
->NumTabStops
= (INT32
)wParam
;
2921 es
->TabStops
= NULL
;
2923 es
->TabStops
= (LPINT16
)xmalloc(wParam
* sizeof(INT16
));
2924 for ( i
= 0 ; i
< (INT32
)wParam
; i
++ )
2925 es
->TabStops
[i
] = (INT16
)((LPINT32
)lParam
)[i
];
2931 /*********************************************************************
2936 static LRESULT
EDIT_EM_SetTabStops16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2938 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2940 if (!IsMultiLine(wndPtr
))
2944 es
->NumTabStops
= (INT32
)wParam
;
2946 es
->TabStops
= NULL
;
2948 es
->TabStops
= (LPINT16
)xmalloc(wParam
* sizeof(INT16
));
2949 memcpy(es
->TabStops
, (LPINT16
)PTR_SEG_TO_LIN(lParam
),
2950 (INT32
)wParam
* sizeof(INT16
));
2956 /*********************************************************************
2958 * EM_SETWORDBREAKPROC
2961 static LRESULT
EDIT_EM_SetWordBreakProc(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2964 EDITSTATE *es = EDITSTATEPTR(wndPtr);
2966 es->WordBreakProc = (EDITWORDBREAKPROC)lParam;
2972 /*********************************************************************
2977 static LRESULT
EDIT_EM_Undo(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2979 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2980 LPSTR utext
= xstrdup(EDIT_GetUndoPointer(wndPtr
));
2982 dprintf_edit(stddeb
, "edit: before UNDO:insertion length = %d, deletion buffer = %s\n",
2983 es
->UndoInsertLen
, utext
);
2985 EDIT_EM_SetSel(wndPtr
, es
->UndoPos
, es
->UndoPos
+ es
->UndoInsertLen
);
2986 EDIT_EM_EmptyUndoBuffer(wndPtr
, 0, 0);
2987 EDIT_EM_ReplaceSel(wndPtr
, TRUE
, (LPARAM
)utext
);
2988 EDIT_EM_SetSel(wndPtr
, es
->UndoPos
, es
->UndoPos
+ es
->UndoInsertLen
);
2991 dprintf_edit(stddeb
, "edit: after UNDO: insertion length = %d, deletion buffer = %s\n",
2992 es
->UndoInsertLen
, EDIT_GetUndoPointer(wndPtr
));
2998 /*********************************************************************
3003 static LRESULT
EDIT_WM_Char(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3006 unsigned char c
= (unsigned char)wParam
;
3011 if (IsMultiLine(wndPtr
)) {
3012 if (IsReadOnly(wndPtr
)) {
3013 EDIT_MoveHome(wndPtr
, FALSE
);
3014 EDIT_MoveDownward(wndPtr
, FALSE
);
3016 EDIT_EM_ReplaceSel(wndPtr
, (WPARAM32
)TRUE
, (LPARAM
)"\r\n");
3020 if (IsMultiLine(wndPtr
) && !IsReadOnly(wndPtr
))
3021 EDIT_EM_ReplaceSel(wndPtr
, (WPARAM32
)TRUE
, (LPARAM
)"\t");
3024 if (!IsReadOnly(wndPtr
) && (c
>= ' ') && (c
!= 127)) {
3027 EDIT_EM_ReplaceSel(wndPtr
, (WPARAM32
)TRUE
, (LPARAM
)str
);
3035 /*********************************************************************
3040 static LRESULT
EDIT_WM_Clear(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3042 EDIT_EM_ReplaceSel(wndPtr
, TRUE
, (LPARAM
)"");
3048 /*********************************************************************
3053 static LRESULT
EDIT_WM_Command(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3058 switch (LOWORD(wParam
)) {
3060 EDIT_EM_Undo(wndPtr
, 0, 0);
3063 EDIT_WM_Cut(wndPtr
, 0, 0);
3066 EDIT_WM_Copy(wndPtr
, 0, 0);
3069 EDIT_WM_Paste(wndPtr
, 0, 0);
3072 EDIT_WM_Clear(wndPtr
, 0, 0);
3075 EDIT_EM_SetSel(wndPtr
, 0, -1);
3076 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
3079 dprintf_edit(stddeb
, "edit: unknown menu item, please report\n");
3086 /*********************************************************************
3090 * Note: the resource files resource/sysres_??.rc cannot define a
3091 * single popup menu. Hence we use a (dummy) menubar
3092 * containing the single popup menu as its first item.
3095 static LRESULT
EDIT_WM_ContextMenu(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3097 HMENU32 hMenu
= LoadMenuIndirect32A(SYSRES_GetResPtr(SYSRES_MENU_EDITMENU
));
3098 HMENU32 hPopup
= GetSubMenu32(hMenu
, 0);
3100 TrackPopupMenu32(hPopup
, TPM_LEFTALIGN
| TPM_RIGHTBUTTON
, LOWORD(lParam
),
3101 HIWORD(lParam
), 0, wndPtr
->hwndSelf
, NULL
);
3102 DestroyMenu32(hMenu
);
3107 /*********************************************************************
3112 static LRESULT
EDIT_WM_Copy(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3120 EDIT_GetSel(wndPtr
, &s
, &e
);
3124 hdst
= GlobalAlloc16(GMEM_MOVEABLE
, (DWORD
)(e
- s
+ 1));
3125 dst
= GlobalLock16(hdst
);
3126 text
= EDIT_GetPointer(wndPtr
);
3127 lstrcpyn32A(dst
, text
+ s
, e
- s
+ 1);
3128 GlobalUnlock16(hdst
);
3129 OpenClipboard(wndPtr
->hwndSelf
);
3131 SetClipboardData(CF_TEXT
, hdst
);
3137 /*********************************************************************
3142 static LRESULT
EDIT_WM_Create(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3144 CREATESTRUCT32A
*cs
= (CREATESTRUCT32A
*)lParam
;
3148 es
= xmalloc(sizeof(EDITSTATE
));
3149 memset(es
, 0, sizeof(EDITSTATE
));
3150 *(EDITSTATE
**)wndPtr
->wExtra
= es
;
3152 if (cs
->style
& WS_VSCROLL
)
3153 cs
->style
|= ES_AUTOVSCROLL
;
3154 if (cs
->style
& WS_HSCROLL
)
3155 cs
->style
|= ES_AUTOHSCROLL
;
3157 /* remove the WS_CAPTION style if it has been set - this is really a */
3158 /* pseudo option made from a combination of WS_BORDER and WS_DLGFRAME */
3159 if ((cs
->style
& WS_BORDER
) && (cs
->style
& WS_DLGFRAME
))
3160 cs
->style
^= WS_DLGFRAME
;
3162 if (IsMultiLine(wndPtr
)) {
3163 es
->BufSize
= BUFSTART_MULTI
;
3164 es
->BufLimit
= BUFLIMIT_MULTI
;
3165 es
->PasswordChar
= '\0';
3167 es
->BufSize
= BUFSTART_SINGLE
;
3168 es
->BufLimit
= BUFLIMIT_SINGLE
;
3169 es
->PasswordChar
= (cs
->style
& ES_PASSWORD
) ? '*' : '\0';
3171 if (!(es
->hBuf32
= LocalAlloc32(LMEM_MOVEABLE
, es
->BufSize
+ 1))) {
3172 fprintf(stderr
, "edit: WM_CREATE: unable to allocate buffer\n");
3175 if (!(es
->hUndoBuf
= LocalAlloc32(LMEM_MOVEABLE
, es
->BufSize
+ 1))) {
3176 fprintf(stderr
, "edit: WM_CREATE: unable to allocate undo buffer\n");
3177 LocalFree32(es
->hBuf32
);
3178 es
->hBuf32
= (HLOCAL32
)NULL
;
3181 es
->BufSize
= LocalSize32(es
->hBuf32
) - 1;
3182 es
->UndoBufSize
= LocalSize32(es
->hUndoBuf
) - 1;
3183 EDIT_EM_EmptyUndoBuffer(wndPtr
, 0, 0);
3184 text
= EDIT_GetPointer(wndPtr
);
3186 EDIT_BuildLineDefs(wndPtr
);
3187 EDIT_WM_SetFont(wndPtr
, 0, 0);
3188 if (cs
->lpszName
&& *(cs
->lpszName
) != '\0')
3189 EDIT_EM_ReplaceSel(wndPtr
, (WPARAM32
)FALSE
, (LPARAM
)cs
->lpszName
);
3190 EDIT_WM_SetRedraw(wndPtr
, TRUE
, 0);
3195 /*********************************************************************
3200 static LRESULT
EDIT_WM_Cut(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3202 EDIT_WM_Copy(wndPtr
, 0, 0);
3203 EDIT_WM_Clear(wndPtr
, 0, 0);
3208 /*********************************************************************
3213 static LRESULT
EDIT_WM_Destroy(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3215 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
3220 EDIT_ReleaseUndoPointer(wndPtr
);
3221 LocalFree32(es
->hUndoBuf
);
3222 EDIT_ReleasePointer(wndPtr
);
3224 LocalFree32(es
->hBuf32
);
3226 LOCAL_Free(wndPtr
->hInstance
, es
->hBuf16
);
3228 *(EDITSTATE
**)&wndPtr
->wExtra
= NULL
;
3233 /*********************************************************************
3238 static LRESULT
EDIT_WM_Enable(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3240 EDIT_InvalidateText(wndPtr
, 0, -1);
3245 /*********************************************************************
3250 static LRESULT
EDIT_WM_EraseBkGnd(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3255 hBrush
= (HBRUSH32
)EDIT_SEND_CTLCOLOR(wndPtr
, wParam
);
3256 if (!hBrush
) hBrush
= (HBRUSH32
)GetStockObject32(WHITE_BRUSH
);
3258 GetClientRect32(wndPtr
->hwndSelf
, &rc
);
3259 IntersectClipRect32((HDC32
)wParam
, rc
.left
, rc
.top
,
3260 rc
.right
, rc
.bottom
);
3261 GetClipBox32((HDC32
)wParam
, &rc
);
3263 * FIXME: specs say that we should UnrealizeObject() the brush,
3264 * but the specs of UnrealizeObject() say that we shouldn't
3265 * unrealize a stock object. The default brush that
3266 * DefWndProc() returns is ... a stock object.
3268 FillRect32((HDC32
)wParam
, &rc
, hBrush
);
3273 /*********************************************************************
3278 static LRESULT
EDIT_WM_GetDlgCode(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3280 return DLGC_HASSETSEL
| DLGC_WANTCHARS
| DLGC_WANTARROWS
;
3284 /*********************************************************************
3289 static LRESULT
EDIT_WM_GetFont(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3291 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
3293 return (LRESULT
)es
->hFont
;
3297 /*********************************************************************
3302 static LRESULT
EDIT_WM_GetText(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3304 LPSTR text
= EDIT_GetPointer(wndPtr
);
3306 LRESULT lResult
= 0;
3308 len
= lstrlen32A(text
);
3309 if ((INT32
)wParam
> len
) {
3310 lstrcpy32A((LPSTR
)lParam
, text
);
3311 lResult
= (LRESULT
)len
+ 1;
3317 /*********************************************************************
3322 static LRESULT
EDIT_WM_GetTextLength(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3324 LPSTR text
= EDIT_GetPointer(wndPtr
);
3326 return (LRESULT
)lstrlen32A(text
);
3330 /*********************************************************************
3334 * FIXME: scrollbar code itself is broken, so this one is a hack.
3337 static LRESULT
EDIT_WM_HScroll(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3339 INT32 ww
= EDIT_GetWndWidth(wndPtr
);
3340 INT32 tw
= EDIT_GetTextWidth(wndPtr
);
3341 INT32 cw
= EDIT_GetAveCharWidth(wndPtr
);
3342 INT32 xoff
= EDIT_GetXOffset(wndPtr
);
3355 dx
= -ww
/ HSCROLL_FRACTION
/ cw
* cw
;
3358 dx
= ww
/ HSCROLL_FRACTION
/ cw
* cw
;
3370 case SB_THUMBPOSITION
:
3371 dx
= HIWORD(wParam
) * tw
/ 100 - xoff
;
3373 /* The next two are undocumented ! */
3375 ret
= tw
? xoff
* 100 / tw
: 0;
3377 case EM_LINESCROLL16
:
3378 dx
= (INT16
)HIWORD(wParam
);
3385 EDIT_EM_LineScroll(wndPtr
, dx
, 0);
3387 dprintf_edit(stddeb
, "edit: notification EN_HSCROLL sent\n");
3388 EDIT_NOTIFY_PARENT(wndPtr
, EN_HSCROLL
);
3395 /*********************************************************************
3399 * FIXME: the message identifiers have been chosen arbitrarily,
3400 * hence we use MF_BYPOSITION.
3401 * We might as well use the "real" values (anybody knows ?)
3402 * The menu definition is in resources/sysres_??.rc.
3403 * Once these are OK, we better use MF_BYCOMMAND here
3404 * (as we do in EDIT_WM_Command()).
3407 static LRESULT
EDIT_WM_InitMenuPopup(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3409 HMENU32 hPopup
= (HMENU32
)wParam
;
3413 EDIT_EM_GetSel(wndPtr
, (WPARAM32
)&s
, (LPARAM
)&e
);
3416 EnableMenuItem32(hPopup
, 0, MF_BYPOSITION
|
3417 (EDIT_EM_CanUndo(wndPtr
, 0, 0) ? MF_ENABLED
: MF_GRAYED
));
3419 EnableMenuItem32(hPopup
, 2, MF_BYPOSITION
|
3420 ((e
- s
) && !IsPassword(wndPtr
) ? MF_ENABLED
: MF_GRAYED
));
3422 EnableMenuItem32(hPopup
, 3, MF_BYPOSITION
|
3423 ((e
- s
) && !IsPassword(wndPtr
) ? MF_ENABLED
: MF_GRAYED
));
3425 EnableMenuItem32(hPopup
, 4, MF_BYPOSITION
|
3426 (IsClipboardFormatAvailable(CF_TEXT
) ? MF_ENABLED
: MF_GRAYED
));
3428 EnableMenuItem32(hPopup
, 5, MF_BYPOSITION
|
3429 ((e
- s
) ? MF_ENABLED
: MF_GRAYED
));
3431 EnableMenuItem32(hPopup
, 7, MF_BYPOSITION
|
3432 (s
|| (e
!= EDIT_WM_GetTextLength(wndPtr
, 0, 0)) ? MF_ENABLED
: MF_GRAYED
));
3438 /*********************************************************************
3442 * Handling of special keys that don't produce a WM_CHAR
3443 * (i.e. non-printable keys) & Backspace & Delete
3446 static LRESULT
EDIT_WM_KeyDown(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3453 if (GetKeyState32(VK_MENU
) & 0x8000)
3456 shift
= GetKeyState32(VK_SHIFT
) & 0x8000;
3457 control
= GetKeyState32(VK_CONTROL
) & 0x8000;
3459 EDIT_GetSel(wndPtr
, &s
, &e
);
3463 if (IsMultiLine(wndPtr
) && (wParam
== VK_UP
))
3464 EDIT_MoveUpward(wndPtr
, shift
);
3467 EDIT_MoveWordBackward(wndPtr
, shift
);
3469 EDIT_MoveBackward(wndPtr
, shift
);
3473 if (IsMultiLine(wndPtr
) && (wParam
== VK_DOWN
))
3474 EDIT_MoveDownward(wndPtr
, shift
);
3476 EDIT_MoveWordForward(wndPtr
, shift
);
3478 EDIT_MoveForward(wndPtr
, shift
);
3481 EDIT_MoveHome(wndPtr
, shift
);
3484 EDIT_MoveEnd(wndPtr
, shift
);
3487 if (IsMultiLine(wndPtr
))
3488 EDIT_MovePageUp(wndPtr
, shift
);
3491 if (IsMultiLine(wndPtr
))
3492 EDIT_MovePageDown(wndPtr
, shift
);
3495 if (!IsReadOnly(wndPtr
) && !control
)
3497 EDIT_WM_Clear(wndPtr
, 0, 0);
3499 EDIT_DelLeft(wndPtr
);
3502 if (!IsReadOnly(wndPtr
) && !(shift
&& control
))
3505 EDIT_WM_Cut(wndPtr
, 0, 0);
3507 EDIT_WM_Clear(wndPtr
, 0, 0);
3510 EDIT_DelLeft(wndPtr
);
3512 EDIT_DelEnd(wndPtr
);
3514 EDIT_DelRight(wndPtr
);
3519 if (!IsReadOnly(wndPtr
))
3520 EDIT_WM_Paste(wndPtr
, 0, 0);
3522 EDIT_WM_Copy(wndPtr
, 0, 0);
3529 /*********************************************************************
3534 static LRESULT
EDIT_WM_KillFocus(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3540 if(!(wndPtr
->dwStyle
& ES_NOHIDESEL
)) {
3541 EDIT_EM_GetSel(wndPtr
, (WPARAM32
)&s
, (LPARAM
)&e
);
3542 EDIT_InvalidateText(wndPtr
, s
, e
);
3544 dprintf_edit(stddeb
, "edit: notification EN_KILLFOCUS sent\n");
3545 EDIT_NOTIFY_PARENT(wndPtr
, EN_KILLFOCUS
);
3550 /*********************************************************************
3554 * The caret position has been set on the WM_LBUTTONDOWN message
3557 static LRESULT
EDIT_WM_LButtonDblClk(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3564 LPSTR text
= EDIT_GetPointer(wndPtr
);
3566 EDIT_GetSel(wndPtr
, NULL
, &e
);
3567 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
3568 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
3569 ll
= (INT32
)EDIT_EM_LineLength(wndPtr
, e
, 0);
3570 s
= li
+ EDIT_CallWordBreakProc (wndPtr
, text
+ li
, e
- li
, ll
, WB_LEFT
);
3571 e
= li
+ EDIT_CallWordBreakProc(wndPtr
, text
+ li
, e
- li
, ll
, WB_RIGHT
);
3572 EDIT_EM_SetSel(wndPtr
, s
, e
);
3573 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
3578 /*********************************************************************
3583 static LRESULT
EDIT_WM_LButtonDown(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3585 INT32 x
= (INT32
)(INT16
)LOWORD(lParam
);
3586 INT32 y
= (INT32
)(INT16
)HIWORD(lParam
);
3587 INT32 l
= EDIT_LineFromWndY(wndPtr
, y
);
3591 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0);
3592 INT32 vlc
= EDIT_GetVisibleLineCount(wndPtr
);
3595 SetFocus32(wndPtr
->hwndSelf
);
3596 SetCapture32(wndPtr
->hwndSelf
);
3597 l
= MIN(fv
+ vlc
- 1, MAX(fv
, l
));
3598 x
= MIN(EDIT_GetWndWidth(wndPtr
), MAX(0, x
));
3599 c
= EDIT_ColFromWndX(wndPtr
, l
, x
);
3600 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
3602 if (GetKeyState32(VK_SHIFT
) & 0x8000)
3603 EDIT_GetSel(wndPtr
, &s
, NULL
);
3606 EDIT_SetSel(wndPtr
, s
, e
);
3607 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
3608 SetTimer32(wndPtr
->hwndSelf
, 0, 100, NULL
);
3613 /*********************************************************************
3618 static LRESULT
EDIT_WM_LButtonUp(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3620 if (GetCapture32() == wndPtr
->hwndSelf
) {
3621 KillTimer32(wndPtr
->hwndSelf
, 0);
3628 /*********************************************************************
3633 static LRESULT
EDIT_WM_MouseMove(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3644 if (GetCapture32() == wndPtr
->hwndSelf
) {
3645 x
= (INT32
)(INT16
)LOWORD(lParam
);
3646 y
= (INT32
)(INT16
)HIWORD(lParam
);
3647 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0);
3648 vlc
= EDIT_GetVisibleLineCount(wndPtr
);
3649 l
= EDIT_LineFromWndY(wndPtr
, y
);
3650 l
= MIN(fv
+ vlc
- 1, MAX(fv
, l
));
3651 x
= MIN(EDIT_GetWndWidth(wndPtr
), MAX(0, x
));
3652 c
= EDIT_ColFromWndX(wndPtr
, l
, x
);
3653 EDIT_GetSel(wndPtr
, &s
, NULL
);
3654 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
3655 EDIT_SetSel(wndPtr
, s
, li
+ c
);
3658 * FIXME: gotta do some scrolling if outside client (format ?)
3659 * area. Maybe reset the timer ?
3665 /*********************************************************************
3670 static LRESULT
EDIT_WM_Paint(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3674 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0);
3675 INT32 vlc
= EDIT_GetVisibleLineCount(wndPtr
);
3676 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, 0, 0);
3679 HFONT32 oldFont
= 0;
3685 BOOL32 rev
= IsWindowEnabled32(wndPtr
->hwndSelf
) &&
3686 ((GetFocus32() == wndPtr
->hwndSelf
) ||
3687 (wndPtr
->dwStyle
& ES_NOHIDESEL
));
3689 hdc
= BeginPaint32(wndPtr
->hwndSelf
, &ps
);
3690 GetClientRect32(wndPtr
->hwndSelf
, &rc
);
3691 IntersectClipRect32( hdc
, rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
3692 hFont
= (HFONT32
)EDIT_WM_GetFont(wndPtr
, 0, 0);
3694 oldFont
= (HFONT32
)SelectObject32(hdc
, hFont
);
3695 EDIT_SEND_CTLCOLOR(wndPtr
, hdc
);
3696 if (!IsWindowEnabled32(wndPtr
->hwndSelf
))
3697 SetTextColor(hdc
, GetSysColor(COLOR_GRAYTEXT
));
3698 GetClipBox32(hdc
, &rcRgn
);
3699 for (i
= fv
; i
<= MIN(fv
+ vlc
, fv
+ lc
- 1) ; i
++ ) {
3700 EDIT_GetLineRect(wndPtr
, i
, 0, -1, &rcLine
);
3701 if (IntersectRect32(&rc
, &rcRgn
, &rcLine
))
3702 EDIT_PaintLine(wndPtr
, hdc
, i
, rev
);
3704 if (hFont
) SelectObject32(hdc
, oldFont
);
3705 if (wndPtr
->hwndSelf
== GetFocus32()) {
3706 EDIT_GetSel(wndPtr
, NULL
, &e
);
3707 pos
= EDIT_EM_PosFromChar(wndPtr
, e
, 0);
3708 SetCaretPos((INT16
)LOWORD(pos
), (INT16
)HIWORD(pos
));
3710 EndPaint32(wndPtr
->hwndSelf
, &ps
);
3715 /*********************************************************************
3720 static LRESULT
EDIT_WM_Paste(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3725 OpenClipboard(wndPtr
->hwndSelf
);
3726 if ((hsrc
= GetClipboardData(CF_TEXT
))) {
3727 src
= (LPSTR
)GlobalLock16(hsrc
);
3728 EDIT_EM_ReplaceSel(wndPtr
, (WPARAM32
)TRUE
, (LPARAM
)src
);
3729 GlobalUnlock16(hsrc
);
3736 /*********************************************************************
3741 static LRESULT
EDIT_WM_SetCursor(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3743 if (LOWORD(lParam
) == HTCLIENT
) {
3744 SetCursor(LoadCursor16(0, IDC_IBEAM
));
3751 /*********************************************************************
3756 static LRESULT
EDIT_WM_SetFocus(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3761 EDIT_GetSel(wndPtr
, &s
, &e
);
3762 CreateCaret(wndPtr
->hwndSelf
, 0, 2, EDIT_GetLineHeight(wndPtr
));
3763 EDIT_SetSel(wndPtr
, s
, e
);
3764 if(!(wndPtr
->dwStyle
& ES_NOHIDESEL
))
3765 EDIT_InvalidateText(wndPtr
, s
, e
);
3766 ShowCaret(wndPtr
->hwndSelf
);
3767 dprintf_edit(stddeb
, "edit: notification EN_SETFOCUS sent\n");
3768 EDIT_NOTIFY_PARENT(wndPtr
, EN_SETFOCUS
);
3773 /*********************************************************************
3778 static LRESULT
EDIT_WM_SetFont(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3781 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
3785 HFONT32 oldFont
= 0;
3787 EDIT_GetSel(wndPtr
, &s
, &e
);
3788 es
->hFont
= (HFONT32
)wParam
;
3789 hdc
= GetDC32(wndPtr
->hwndSelf
);
3790 if (es
->hFont
) oldFont
= SelectObject32(hdc
, es
->hFont
);
3791 GetTextMetrics32A(hdc
, &tm
);
3792 es
->LineHeight
= tm
.tmHeight
;
3793 es
->AveCharWidth
= tm
.tmAveCharWidth
;
3794 if (es
->hFont
) SelectObject32(hdc
, oldFont
);
3795 ReleaseDC32(wndPtr
->hwndSelf
, hdc
);
3796 EDIT_BuildLineDefs(wndPtr
);
3797 if ((BOOL32
)lParam
&& EDIT_GetRedraw(wndPtr
))
3798 InvalidateRect32( wndPtr
->hwndSelf
, NULL
, TRUE
);
3799 if (wndPtr
->hwndSelf
== GetFocus32()) {
3801 CreateCaret(wndPtr
->hwndSelf
, 0, 2, EDIT_GetLineHeight(wndPtr
));
3802 EDIT_SetSel(wndPtr
, s
, e
);
3803 ShowCaret(wndPtr
->hwndSelf
);
3809 /*********************************************************************
3814 static LRESULT
EDIT_WM_SetRedraw(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3816 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
3818 es
->Redraw
= (BOOL32
)wParam
;
3823 /*********************************************************************
3828 static LRESULT
EDIT_WM_SetText(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3830 EDIT_EM_SetSel(wndPtr
, 0, -1);
3832 EDIT_EM_ReplaceSel(wndPtr
, (WPARAM32
)FALSE
, lParam
);
3833 EDIT_EM_SetModify(wndPtr
, TRUE
, 0);
3834 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
3839 /*********************************************************************
3843 * FIXME: What about that FormatRect ???
3846 static LRESULT
EDIT_WM_Size(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3848 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
3851 EDIT_GetSel(wndPtr
, 0, &e
);
3852 GetClientRect32(wndPtr
->hwndSelf
, &es
->FormatRect
);
3853 if (EDIT_GetRedraw(wndPtr
) &&
3854 ((wParam
== SIZE_MAXIMIZED
) ||
3855 (wParam
== SIZE_RESTORED
))) {
3856 if (IsMultiLine(wndPtr
) && IsWordWrap(wndPtr
))
3857 EDIT_BuildLineDefs(wndPtr
);
3858 InvalidateRect32( wndPtr
->hwndSelf
, NULL
, TRUE
);
3864 /*********************************************************************
3869 static LRESULT
EDIT_WM_SysKeyDown(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3871 if ((wParam
== VK_BACK
) && (lParam
& 0x2000) &&
3872 (BOOL32
)EDIT_EM_CanUndo(wndPtr
, 0, 0))
3873 EDIT_EM_Undo(wndPtr
, 0, 0);
3878 /*********************************************************************
3883 static LRESULT
EDIT_WM_Timer(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3886 * FIXME: gotta do some scrolling here, like
3887 * EDIT_EM_LineScroll(wndPtr, 0, 1);
3893 /*********************************************************************
3897 * FIXME: scrollbar code itself is broken, so this one is a hack.
3900 static LRESULT
EDIT_WM_VScroll(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3902 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, 0, 0);
3903 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0);
3904 INT32 vlc
= EDIT_GetVisibleLineCount(wndPtr
);
3931 case SB_THUMBPOSITION
:
3932 dy
= HIWORD(wParam
) * (lc
- 1) / 100 - fv
;
3934 /* The next two are undocumented ! */
3936 ret
= (lc
> 1) ? MAKELONG(fv
* 100 / (lc
- 1), 0) : 0;
3938 case EM_LINESCROLL16
:
3939 dy
= (INT16
)LOWORD(lParam
);
3946 EDIT_EM_LineScroll(wndPtr
, 0, dy
);
3948 dprintf_edit(stddeb
, "edit: notification EN_VSCROLL sent\n");
3949 EDIT_NOTIFY_PARENT(wndPtr
, EN_VSCROLL
);