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.
30 #define BUFLIMIT_MULTI 65534 /* maximum text buffer length (not including '\0') */
31 /* FIXME: BTW, new specs say 65535 (do you dare ???) */
32 #define BUFLIMIT_SINGLE 32766
33 #define BUFSTART_MULTI 1024 /* starting length for multi-line control */
34 #define BUFSTART_SINGLE 256 /* starting length for single line control */
35 #define GROWLENGTH 64 /* buffers grow by this much */
36 #define HSCROLL_FRACTION 3 /* scroll window by 1/3 width */
55 HLOCAL16 hBuf16
; /* For when a 16-bit multiline edit
56 * control gets a EM_GETHANDLE (which
57 * should return 16-bit local heap).
58 * From that point on we _have_ to keep
59 * using 16-bit local heap (apps rely
60 * on that ... bummer).
62 HLOCAL32 hBuf32
; /* Don't worry about 'LOCAL'. LOCAL32 is
63 * identical to GLOBAL32, which is
64 * essentially a HANDLE32 created with
65 * HeapAlloc(GetProcessHeap(), ...) plus
66 * a global32 (and thus local32)
67 * descriptor, which we can return upon
69 * It is 32-bit linear addressing, so
72 LPSTR text
; /* Depending on the fact that we are a
73 * 16 or 32 bit control, this is the
74 * pointer that we get after
75 * LocalLock32(hBuf23) (which is a typecast :-)
76 * or LOCAL_Lock(hBuf16).
77 * This is always a 32-bit linear pointer.
80 LINEDEF
*LineDefs
; /* Internal table for (soft) linebreaks */
81 INT32 TextWidth
; /* width of the widest line in pixels */
82 INT32 XOffset
; /* offset of the viewport in pixels */
83 INT32 FirstVisibleLine
;
85 INT32 LineHeight
; /* height of a screen line in pixels */
86 INT32 AveCharWidth
; /* average character width in pixels */
96 INT32 SelStart
; /* offset of selection start, == SelEnd if no selection */
97 INT32 SelEnd
; /* offset of selection end == current caret position */
101 * FIXME: The following should probably be a (VOID *) that is
102 * typecast to either 16- or 32-bit callback when used,
103 * depending on the type of edit control (16 or 32 bit).
105 * EDITWORDBREAKPROC WordBreakProc;
107 * For now: no more application specific wordbreaking.
108 * (Internal wordbreak function still works)
117 #define SWAP_INT32(x,y) do { INT32 temp = (INT32)(x); (x) = (INT32)(y); (y) = temp; } while(0)
118 #define ORDER_INT32(x,y) do { if ((INT32)(y) < (INT32)(x)) SWAP_INT32((x),(y)); } while(0)
120 /* macros to access window styles */
121 #define IsMultiLine(wndPtr) ((wndPtr)->dwStyle & ES_MULTILINE)
122 #define IsVScrollBar(wndPtr) ((wndPtr)->dwStyle & WS_VSCROLL)
123 #define IsHScrollBar(wndPtr) ((wndPtr)->dwStyle & WS_HSCROLL)
124 #define IsReadOnly(wndPtr) ((wndPtr)->dwStyle & ES_READONLY)
125 #define IsWordWrap(wndPtr) (((wndPtr)->dwStyle & ES_AUTOHSCROLL) == 0)
126 #define IsPassword(wndPtr) ((wndPtr)->dwStyle & ES_PASSWORD)
127 #define IsLower(wndPtr) ((wndPtr)->dwStyle & ES_LOWERCASE)
128 #define IsUpper(wndPtr) ((wndPtr)->dwStyle & ES_UPPERCASE)
130 #define EDITSTATEPTR(wndPtr) (*(EDITSTATE **)((wndPtr)->wExtra))
132 #define EDIT_SEND_CTLCOLOR(wndPtr,hdc) \
133 (SendMessage32A((wndPtr)->parent->hwndSelf, WM_CTLCOLOREDIT, \
134 (WPARAM32)(hdc), (LPARAM)(wndPtr)->hwndSelf ))
135 #define EDIT_NOTIFY_PARENT(wndPtr, wNotifyCode) \
136 (SendMessage32A((wndPtr)->parent->hwndSelf, WM_COMMAND, \
137 MAKEWPARAM((wndPtr)->wIDmenu, wNotifyCode), \
138 (LPARAM)(wndPtr)->hwndSelf ))
139 #define DPRINTF_EDIT_MSG16(str) \
140 dprintf_edit(stddeb, \
141 "edit: 16 bit : " str ": hwnd=%08x, wParam=%08x, lParam=%08x\n", \
142 (UINT32)hwnd, (UINT32)wParam, (UINT32)lParam)
143 #define DPRINTF_EDIT_MSG32(str) \
144 dprintf_edit(stddeb, \
145 "edit: 32 bit : " str ": hwnd=%08x, wParam=%08x, lParam=%08x\n", \
146 (UINT32)hwnd, (UINT32)wParam, (UINT32)lParam)
149 /*********************************************************************
153 * Files like these should really be kept in alphabetical order.
156 LRESULT
EditWndProc(HWND32 hwnd
, UINT32 msg
, WPARAM32 wParam
, LPARAM lParam
);
158 static void EDIT_BuildLineDefs(WND
*wndPtr
);
159 static INT32
EDIT_CallWordBreakProc(WND
*wndPtr
, LPSTR s
, INT32 index
, INT32 count
, INT32 action
);
160 static INT32
EDIT_ColFromWndX(WND
*wndPtr
, INT32 line
, INT32 x
);
161 static void EDIT_DelEnd(WND
*wndPtr
);
162 static void EDIT_DelLeft(WND
*wndPtr
);
163 static void EDIT_DelRight(WND
*wndPtr
);
164 static INT32
EDIT_GetAveCharWidth(WND
*wndPtr
);
165 static INT32
EDIT_GetLineHeight(WND
*wndPtr
);
166 static void EDIT_GetLineRect(WND
*wndPtr
, INT32 line
, INT32 scol
, INT32 ecol
, LPRECT32 rc
);
167 static LPSTR
EDIT_GetPointer(WND
*wndPtr
);
168 static LPSTR
EDIT_GetPasswordPointer(WND
*wndPtr
);
169 static BOOL32
EDIT_GetRedraw(WND
*wndPtr
);
170 static void EDIT_GetSel(WND
*wndPtr
, LPINT32 s
, LPINT32 e
);
171 static INT32
EDIT_GetTextWidth(WND
*wndPtr
);
172 static LPSTR
EDIT_GetUndoPointer(WND
*wndPtr
);
173 static INT32
EDIT_GetVisibleLineCount(WND
*wndPtr
);
174 static INT32
EDIT_GetWndWidth(WND
*wndPtr
);
175 static INT32
EDIT_GetXOffset(WND
*wndPtr
);
176 static void EDIT_InvalidateText(WND
*wndPtr
, INT32 start
, INT32 end
);
177 static INT32
EDIT_LineFromWndY(WND
*wndPtr
, INT32 y
);
178 static BOOL32
EDIT_MakeFit(WND
*wndPtr
, INT32 size
);
179 static BOOL32
EDIT_MakeUndoFit(WND
*wndPtr
, INT32 size
);
180 static void EDIT_MoveBackward(WND
*wndPtr
, BOOL32 extend
);
181 static void EDIT_MoveDownward(WND
*wndPtr
, BOOL32 extend
);
182 static void EDIT_MoveEnd(WND
*wndPtr
, BOOL32 extend
);
183 static void EDIT_MoveForward(WND
*wndPtr
, BOOL32 extend
);
184 static void EDIT_MoveHome(WND
*wndPtr
, BOOL32 extend
);
185 static void EDIT_MovePageDown(WND
*wndPtr
, BOOL32 extend
);
186 static void EDIT_MovePageUp(WND
*wndPtr
, BOOL32 extend
);
187 static void EDIT_MoveUpward(WND
*wndPtr
, BOOL32 extend
);
188 static void EDIT_MoveWordBackward(WND
*wndPtr
, BOOL32 extend
);
189 static void EDIT_MoveWordForward(WND
*wndPtr
, BOOL32 extend
);
190 static void EDIT_PaintLine(WND
*wndPtr
, HDC32 hdc
, INT32 line
, BOOL32 rev
);
191 static INT32
EDIT_PaintText(WND
*wndPtr
, HDC32 hdc
, INT32 x
, INT32 y
, INT32 line
, INT32 col
, INT32 count
, BOOL32 rev
);
192 static void EDIT_ReleasePointer(WND
*wndPtr
);
193 static void EDIT_ReleaseUndoPointer(WND
*wndPtr
);
194 static void EDIT_SetSel(WND
*wndPtr
, INT32 ns
, INT32 ne
);
195 static INT32
EDIT_WndXFromCol(WND
*wndPtr
, INT32 line
, INT32 col
);
196 static INT32
EDIT_WndYFromLine(WND
*wndPtr
, INT32 line
);
197 static INT32
EDIT_WordBreakProc(LPSTR s
, INT32 index
, INT32 count
, INT32 action
);
199 static LRESULT
EDIT_EM_CanUndo(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
200 static LRESULT
EDIT_EM_CharFromPos(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
201 static LRESULT
EDIT_EM_EmptyUndoBuffer(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
202 static LRESULT
EDIT_EM_FmtLines(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
203 static LRESULT
EDIT_EM_GetFirstVisibleLine(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
204 static LRESULT
EDIT_EM_GetHandle(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
205 static LRESULT
EDIT_EM_GetHandle16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
206 static LRESULT
EDIT_EM_GetLimitText(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
207 static LRESULT
EDIT_EM_GetLine(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
208 static LRESULT
EDIT_EM_GetLineCount(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
209 static LRESULT
EDIT_EM_GetMargins(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
210 static LRESULT
EDIT_EM_GetModify(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
211 static LRESULT
EDIT_EM_GetPasswordChar(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
212 static LRESULT
EDIT_EM_GetRect(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
213 static LRESULT
EDIT_EM_GetRect16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
214 static LRESULT
EDIT_EM_GetSel(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
215 static LRESULT
EDIT_EM_GetThumb(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
216 static LRESULT
EDIT_EM_GetWordBreakProc(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
217 static LRESULT
EDIT_EM_LineFromChar(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
218 static LRESULT
EDIT_EM_LineIndex(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
219 static LRESULT
EDIT_EM_LineLength(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
220 static LRESULT
EDIT_EM_LineScroll(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
221 static LRESULT
EDIT_EM_PosFromChar(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
222 static LRESULT
EDIT_EM_ReplaceSel(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
223 static LRESULT
EDIT_EM_Scroll(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
224 static LRESULT
EDIT_EM_ScrollCaret(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
225 static LRESULT
EDIT_EM_SetHandle(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
226 static LRESULT
EDIT_EM_SetHandle16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
227 static LRESULT
EDIT_EM_SetLimitText(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
228 static LRESULT
EDIT_EM_SetMargins(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
229 static LRESULT
EDIT_EM_SetModify(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
230 static LRESULT
EDIT_EM_SetPasswordChar(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
231 static LRESULT
EDIT_EM_SetReadOnly(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
232 static LRESULT
EDIT_EM_SetRect(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
233 static LRESULT
EDIT_EM_SetRectNP(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
234 static LRESULT
EDIT_EM_SetSel(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
235 static LRESULT
EDIT_EM_SetSel16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
236 static LRESULT
EDIT_EM_SetTabStops(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
237 static LRESULT
EDIT_EM_SetTabStops16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
238 static LRESULT
EDIT_EM_SetWordBreakProc(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
239 static LRESULT
EDIT_EM_Undo(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
241 static LRESULT
EDIT_WM_Char(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
242 static LRESULT
EDIT_WM_Clear(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
243 static LRESULT
EDIT_WM_Command(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
244 static LRESULT
EDIT_WM_ContextMenu(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
245 static LRESULT
EDIT_WM_Copy(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
246 static LRESULT
EDIT_WM_Cut(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
247 static LRESULT
EDIT_WM_Create(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
248 static LRESULT
EDIT_WM_Destroy(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
249 static LRESULT
EDIT_WM_Enable(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
250 static LRESULT
EDIT_WM_EraseBkGnd(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
251 static LRESULT
EDIT_WM_GetDlgCode(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
252 static LRESULT
EDIT_WM_GetFont(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
253 static LRESULT
EDIT_WM_GetText(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
254 static LRESULT
EDIT_WM_GetTextLength(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
255 static LRESULT
EDIT_WM_HScroll(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
256 static LRESULT
EDIT_WM_InitMenuPopup(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
257 static LRESULT
EDIT_WM_KeyDown(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
258 static LRESULT
EDIT_WM_KillFocus(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
259 static LRESULT
EDIT_WM_LButtonDblClk(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
260 static LRESULT
EDIT_WM_LButtonDown(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
261 static LRESULT
EDIT_WM_LButtonUp(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
262 static LRESULT
EDIT_WM_MouseMove(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
263 static LRESULT
EDIT_WM_Paint(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
264 static LRESULT
EDIT_WM_Paste(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
265 static LRESULT
EDIT_WM_SetCursor(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
266 static LRESULT
EDIT_WM_SetFocus(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
267 static LRESULT
EDIT_WM_SetFont(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
268 static LRESULT
EDIT_WM_SetRedraw(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
269 static LRESULT
EDIT_WM_SetText(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
270 static LRESULT
EDIT_WM_Size(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
271 static LRESULT
EDIT_WM_SysKeyDown(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
272 static LRESULT
EDIT_WM_Timer(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
273 static LRESULT
EDIT_WM_VScroll(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
276 /*********************************************************************
278 * General shortcuts for variable names:
282 * INT32 s; offset of selection start
283 * INT32 e; offset of selection end
284 * INT32 sl; line on which the selection starts
285 * INT32 el; line on which the selection ends
286 * INT32 sc; column on which the selection starts
287 * INT32 ec; column on which the selection ends
288 * INT32 li; line index (offset)
289 * INT32 fv; first visible line
290 * INT32 vlc; vissible line count
291 * INT32 lc; line count
292 * INT32 lh; line height (in pixels)
293 * INT32 tw; text width (in pixels)
294 * INT32 ww; window width (in pixels)
295 * INT32 cw; character width (average, in pixels)
300 /*********************************************************************
304 * The messages are in the order of the actual integer values
305 * (which can be found in include/windows.h)
306 * Whereever possible the 16 bit versions are converted to
307 * the 32 bit ones, so that we can 'fall through' to the
308 * helper functions. These are mostly 32 bit (with a few
309 * exceptions, clearly indicated by a '16' extension to their
313 LRESULT
EditWndProc(HWND32 hwnd
, UINT32 msg
, WPARAM32 wParam
, LPARAM lParam
)
316 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
318 if ((!EDITSTATEPTR(wndPtr
)) && (msg
!= WM_CREATE
))
319 return DefWindowProc32A(hwnd
, msg
, wParam
, lParam
);
323 DPRINTF_EDIT_MSG16("EM_GETSEL");
328 DPRINTF_EDIT_MSG32("EM_GETSEL");
329 lResult
= EDIT_EM_GetSel(wndPtr
, wParam
, lParam
);
333 DPRINTF_EDIT_MSG16("EM_SETSEL");
334 lResult
= EDIT_EM_SetSel16(wndPtr
, wParam
, lParam
);
337 DPRINTF_EDIT_MSG32("EM_SETSEL");
338 lResult
= EDIT_EM_SetSel(wndPtr
, wParam
, lParam
);
342 DPRINTF_EDIT_MSG16("EM_GETRECT");
343 lResult
= EDIT_EM_GetRect16(wndPtr
, wParam
, lParam
);
346 DPRINTF_EDIT_MSG32("EM_GETRECT");
347 lResult
= EDIT_EM_GetRect(wndPtr
, wParam
, lParam
);
351 DPRINTF_EDIT_MSG16("EM_SETRECT");
354 DPRINTF_EDIT_MSG32("EM_SETRECT");
355 lResult
= EDIT_EM_SetRect(wndPtr
, wParam
, lParam
);
359 DPRINTF_EDIT_MSG16("EM_SETRECTNP");
362 DPRINTF_EDIT_MSG32("EM_SETRECTNP");
363 lResult
= EDIT_EM_SetRectNP(wndPtr
, wParam
, lParam
);
367 DPRINTF_EDIT_MSG16("EM_SCROLL");
370 DPRINTF_EDIT_MSG32("EM_SCROLL");
371 lResult
= EDIT_EM_Scroll(wndPtr
, wParam
, lParam
);
374 case EM_LINESCROLL16
:
375 DPRINTF_EDIT_MSG16("EM_LINESCROLL");
376 wParam
= (WPARAM32
)(INT32
)(INT16
)HIWORD(lParam
);
377 lParam
= (LPARAM
)(INT32
)(INT16
)LOWORD(lParam
);
379 case EM_LINESCROLL32
:
380 DPRINTF_EDIT_MSG32("EM_LINESCROLL");
381 lResult
= EDIT_EM_LineScroll(wndPtr
, wParam
, lParam
);
384 case EM_SCROLLCARET16
:
385 DPRINTF_EDIT_MSG16("EM_SCROLLCARET");
387 case EM_SCROLLCARET32
:
388 DPRINTF_EDIT_MSG32("EM_SCROLLCARET");
389 lResult
= EDIT_EM_ScrollCaret(wndPtr
, wParam
, lParam
);
393 DPRINTF_EDIT_MSG16("EM_GETMODIFY");
396 DPRINTF_EDIT_MSG32("EM_GETMODIFY");
397 lResult
= EDIT_EM_GetModify(wndPtr
, wParam
, lParam
);
401 DPRINTF_EDIT_MSG16("EM_SETMODIFY");
404 DPRINTF_EDIT_MSG32("EM_SETMODIFY");
405 lResult
= EDIT_EM_SetModify(wndPtr
, wParam
, lParam
);
408 case EM_GETLINECOUNT16
:
409 DPRINTF_EDIT_MSG16("EM_GETLINECOUNT");
411 case EM_GETLINECOUNT32
:
412 DPRINTF_EDIT_MSG32("EM_GETLINECOUNT");
413 lResult
= EDIT_EM_GetLineCount(wndPtr
, wParam
, lParam
);
417 DPRINTF_EDIT_MSG16("EM_LINEINDEX");
420 DPRINTF_EDIT_MSG32("EM_LINEINDEX");
421 lResult
= EDIT_EM_LineIndex(wndPtr
, wParam
, lParam
);
425 DPRINTF_EDIT_MSG16("EM_SETHANDLE");
426 lResult
= EDIT_EM_SetHandle16(wndPtr
, wParam
, lParam
);
429 DPRINTF_EDIT_MSG32("EM_SETHANDLE");
430 lResult
= EDIT_EM_SetHandle(wndPtr
, wParam
, lParam
);
434 DPRINTF_EDIT_MSG16("EM_GETHANDLE");
435 lResult
= EDIT_EM_GetHandle16(wndPtr
, wParam
, lParam
);
438 DPRINTF_EDIT_MSG32("EM_GETHANDLE");
439 lResult
= EDIT_EM_GetHandle(wndPtr
, wParam
, lParam
);
443 DPRINTF_EDIT_MSG16("EM_GETTHUMB");
446 DPRINTF_EDIT_MSG32("EM_GETTHUMB");
447 lResult
= EDIT_EM_GetThumb(wndPtr
, wParam
, lParam
);
450 /* messages 0x00bf and 0x00c0 missing from specs */
453 DPRINTF_EDIT_MSG16("undocumented WM_USER+15, please report");
456 DPRINTF_EDIT_MSG32("undocumented 0x00bf, please report");
457 lResult
= DefWindowProc32A(hwnd
, msg
, wParam
, lParam
);
461 DPRINTF_EDIT_MSG16("undocumented WM_USER+16, please report");
464 DPRINTF_EDIT_MSG32("undocumented 0x00c0, please report");
465 lResult
= DefWindowProc32A(hwnd
, msg
, wParam
, lParam
);
468 case EM_LINELENGTH16
:
469 DPRINTF_EDIT_MSG16("EM_LINELENGTH");
471 case EM_LINELENGTH32
:
472 DPRINTF_EDIT_MSG32("EM_LINELENGTH");
473 lResult
= EDIT_EM_LineLength(wndPtr
, wParam
, lParam
);
476 case EM_REPLACESEL16
:
477 DPRINTF_EDIT_MSG16("EM_REPLACESEL");
478 lParam
= (LPARAM
)PTR_SEG_TO_LIN((SEGPTR
)lParam
);
480 case EM_REPLACESEL32
:
481 DPRINTF_EDIT_MSG32("EM_REPLACESEL");
482 lResult
= EDIT_EM_ReplaceSel(wndPtr
, wParam
, lParam
);
485 /* message 0x00c3 missing from specs */
488 DPRINTF_EDIT_MSG16("undocumented WM_USER+19, please report");
491 DPRINTF_EDIT_MSG32("undocumented 0x00c3, please report");
492 lResult
= DefWindowProc32A(hwnd
, msg
, wParam
, lParam
);
496 DPRINTF_EDIT_MSG16("EM_GETLINE");
497 lParam
= (LPARAM
)PTR_SEG_TO_LIN((SEGPTR
)lParam
);
500 DPRINTF_EDIT_MSG32("EM_GETLINE");
501 lResult
= EDIT_EM_GetLine(wndPtr
, wParam
, lParam
);
505 DPRINTF_EDIT_MSG16("EM_LIMITTEXT");
507 case EM_SETLIMITTEXT32
:
508 DPRINTF_EDIT_MSG32("EM_SETLIMITTEXT");
509 lResult
= EDIT_EM_SetLimitText(wndPtr
, wParam
, lParam
);
513 DPRINTF_EDIT_MSG16("EM_CANUNDO");
516 DPRINTF_EDIT_MSG32("EM_CANUNDO");
517 lResult
= EDIT_EM_CanUndo(wndPtr
, wParam
, lParam
);
521 DPRINTF_EDIT_MSG16("EM_UNDO");
526 DPRINTF_EDIT_MSG32("EM_UNDO / WM_UNDO");
527 lResult
= EDIT_EM_Undo(wndPtr
, wParam
, lParam
);
531 DPRINTF_EDIT_MSG16("EM_FMTLINES");
534 DPRINTF_EDIT_MSG32("EM_FMTLINES");
535 lResult
= EDIT_EM_FmtLines(wndPtr
, wParam
, lParam
);
538 case EM_LINEFROMCHAR16
:
539 DPRINTF_EDIT_MSG16("EM_LINEFROMCHAR");
541 case EM_LINEFROMCHAR32
:
542 DPRINTF_EDIT_MSG32("EM_LINEFROMCHAR");
543 lResult
= EDIT_EM_LineFromChar(wndPtr
, wParam
, lParam
);
546 /* message 0x00ca missing from specs */
549 DPRINTF_EDIT_MSG16("undocumented WM_USER+26, please report");
552 DPRINTF_EDIT_MSG32("undocumented 0x00ca, please report");
553 lResult
= DefWindowProc32A(hwnd
, msg
, wParam
, lParam
);
556 case EM_SETTABSTOPS16
:
557 DPRINTF_EDIT_MSG16("EM_SETTABSTOPS");
558 lResult
= EDIT_EM_SetTabStops16(wndPtr
, wParam
, lParam
);
560 case EM_SETTABSTOPS32
:
561 DPRINTF_EDIT_MSG32("EM_SETTABSTOPS");
562 lResult
= EDIT_EM_SetTabStops(wndPtr
, wParam
, lParam
);
565 case EM_SETPASSWORDCHAR16
:
566 DPRINTF_EDIT_MSG16("EM_SETPASSWORDCHAR");
568 case EM_SETPASSWORDCHAR32
:
569 DPRINTF_EDIT_MSG32("EM_SETPASSWORDCHAR");
570 lResult
= EDIT_EM_SetPasswordChar(wndPtr
, wParam
, lParam
);
573 case EM_EMPTYUNDOBUFFER16
:
574 DPRINTF_EDIT_MSG16("EM_EMPTYUNDOBUFFER");
576 case EM_EMPTYUNDOBUFFER32
:
577 DPRINTF_EDIT_MSG32("EM_EMPTYUNDOBUFFER");
578 lResult
= EDIT_EM_EmptyUndoBuffer(wndPtr
, wParam
, lParam
);
581 case EM_GETFIRSTVISIBLELINE16
:
582 DPRINTF_EDIT_MSG16("EM_GETFIRSTVISIBLELINE");
584 case EM_GETFIRSTVISIBLELINE32
:
585 DPRINTF_EDIT_MSG32("EM_GETFIRSTVISIBLELINE");
586 lResult
= EDIT_EM_GetFirstVisibleLine(wndPtr
, wParam
, lParam
);
589 case EM_SETREADONLY16
:
590 DPRINTF_EDIT_MSG16("EM_SETREADONLY");
592 case EM_SETREADONLY32
:
593 DPRINTF_EDIT_MSG32("EM_SETREADONLY");
594 lResult
= EDIT_EM_SetReadOnly(wndPtr
, wParam
, lParam
);
597 case EM_SETWORDBREAKPROC16
:
598 DPRINTF_EDIT_MSG16("EM_SETWORDBREAKPROC");
600 case EM_SETWORDBREAKPROC32
:
601 DPRINTF_EDIT_MSG32("EM_SETWORDBREAKPROC");
602 lResult
= EDIT_EM_SetWordBreakProc(wndPtr
, wParam
, lParam
);
605 case EM_GETWORDBREAKPROC16
:
606 DPRINTF_EDIT_MSG16("EM_GETWORDBREAKPROC");
608 case EM_GETWORDBREAKPROC32
:
609 DPRINTF_EDIT_MSG32("EM_GETWORDBREAKPROC");
610 lResult
= EDIT_EM_GetWordBreakProc(wndPtr
, wParam
, lParam
);
613 case EM_GETPASSWORDCHAR16
:
614 DPRINTF_EDIT_MSG16("EM_GETPASSWORDCHAR");
616 case EM_GETPASSWORDCHAR32
:
617 DPRINTF_EDIT_MSG32("EM_GETPASSWORDCHAR");
618 lResult
= EDIT_EM_GetPasswordChar(wndPtr
, wParam
, lParam
);
621 /* The following EM_xxx are new to win95 and don't exist for 16 bit */
623 case EM_SETMARGINS32
:
624 DPRINTF_EDIT_MSG16("EM_SETMARGINS");
625 lResult
= EDIT_EM_SetMargins(wndPtr
, wParam
, lParam
);
628 case EM_GETMARGINS32
:
629 DPRINTF_EDIT_MSG16("EM_GETMARGINS");
630 lResult
= EDIT_EM_GetMargins(wndPtr
, wParam
, lParam
);
633 case EM_GETLIMITTEXT32
:
634 DPRINTF_EDIT_MSG16("EM_GETLIMITTEXT");
635 lResult
= EDIT_EM_GetLimitText(wndPtr
, wParam
, lParam
);
638 case EM_POSFROMCHAR32
:
639 DPRINTF_EDIT_MSG16("EM_POSFROMCHAR");
640 lResult
= EDIT_EM_PosFromChar(wndPtr
, wParam
, lParam
);
643 case EM_CHARFROMPOS32
:
644 DPRINTF_EDIT_MSG16("EM_CHARFROMPOS");
645 lResult
= EDIT_EM_CharFromPos(wndPtr
, wParam
, lParam
);
649 DPRINTF_EDIT_MSG32("WM_GETDLGCODE");
650 lResult
= EDIT_WM_GetDlgCode(wndPtr
, wParam
, lParam
);
654 DPRINTF_EDIT_MSG32("WM_CHAR");
655 lResult
= EDIT_WM_Char(wndPtr
, wParam
, lParam
);
659 DPRINTF_EDIT_MSG32("WM_CLEAR");
660 lResult
= EDIT_WM_Clear(wndPtr
, wParam
, lParam
);
664 DPRINTF_EDIT_MSG32("WM_COMMAND");
665 lResult
= EDIT_WM_Command(wndPtr
, wParam
, lParam
);
669 DPRINTF_EDIT_MSG32("WM_CONTEXTMENU");
670 lResult
= EDIT_WM_ContextMenu(wndPtr
, wParam
, lParam
);
674 DPRINTF_EDIT_MSG32("WM_COPY");
675 lResult
= EDIT_WM_Copy(wndPtr
, wParam
, lParam
);
679 DPRINTF_EDIT_MSG32("WM_CREATE");
680 lResult
= EDIT_WM_Create(wndPtr
, wParam
, lParam
);
684 DPRINTF_EDIT_MSG32("WM_CUT");
685 lResult
= EDIT_WM_Cut(wndPtr
, wParam
, lParam
);
689 DPRINTF_EDIT_MSG32("WM_DESTROY");
690 lResult
= EDIT_WM_Destroy(wndPtr
, wParam
, lParam
);
694 DPRINTF_EDIT_MSG32("WM_ENABLE");
695 lResult
= EDIT_WM_Enable(wndPtr
, wParam
, lParam
);
699 DPRINTF_EDIT_MSG32("WM_ERASEBKGND");
700 lResult
= EDIT_WM_EraseBkGnd(wndPtr
, wParam
, lParam
);
704 DPRINTF_EDIT_MSG32("WM_GETFONT");
705 lResult
= EDIT_WM_GetFont(wndPtr
, wParam
, lParam
);
709 DPRINTF_EDIT_MSG32("WM_GETTEXT");
710 lResult
= EDIT_WM_GetText(wndPtr
, wParam
, lParam
);
713 case WM_GETTEXTLENGTH
:
714 DPRINTF_EDIT_MSG32("WM_GETTEXTLENGTH");
715 lResult
= EDIT_WM_GetTextLength(wndPtr
, wParam
, lParam
);
719 DPRINTF_EDIT_MSG32("WM_HSCROLL");
720 lResult
= EDIT_WM_HScroll(wndPtr
, wParam
, lParam
);
723 case WM_INITMENUPOPUP
:
724 DPRINTF_EDIT_MSG32("WM_INITMENUPOPUP");
725 lResult
= EDIT_WM_InitMenuPopup(wndPtr
, wParam
, lParam
);
729 DPRINTF_EDIT_MSG32("WM_KEYDOWN");
730 lResult
= EDIT_WM_KeyDown(wndPtr
, wParam
, lParam
);
734 DPRINTF_EDIT_MSG32("WM_KILLFOCUS");
735 lResult
= EDIT_WM_KillFocus(wndPtr
, wParam
, lParam
);
738 case WM_LBUTTONDBLCLK
:
739 DPRINTF_EDIT_MSG32("WM_LBUTTONDBLCLK");
740 lResult
= EDIT_WM_LButtonDblClk(wndPtr
, wParam
, lParam
);
744 DPRINTF_EDIT_MSG32("WM_LBUTTONDOWN");
745 lResult
= EDIT_WM_LButtonDown(wndPtr
, wParam
, lParam
);
749 DPRINTF_EDIT_MSG32("WM_LBUTTONUP");
750 lResult
= EDIT_WM_LButtonUp(wndPtr
, wParam
, lParam
);
755 * DPRINTF_EDIT_MSG32("WM_MOUSEMOVE");
757 lResult
= EDIT_WM_MouseMove(wndPtr
, wParam
, lParam
);
761 DPRINTF_EDIT_MSG32("WM_PAINT");
762 lResult
= EDIT_WM_Paint(wndPtr
, wParam
, lParam
);
766 DPRINTF_EDIT_MSG32("WM_PASTE");
767 lResult
= EDIT_WM_Paste(wndPtr
, wParam
, lParam
);
772 * DPRINTF_EDIT_MSG32("WM_SETCURSOR");
774 lResult
= EDIT_WM_SetCursor(wndPtr
, wParam
, lParam
);
778 DPRINTF_EDIT_MSG32("WM_SETFOCUS");
779 lResult
= EDIT_WM_SetFocus(wndPtr
, wParam
, lParam
);
783 DPRINTF_EDIT_MSG32("WM_SETFONT");
784 lResult
= EDIT_WM_SetFont(wndPtr
, wParam
, lParam
);
788 DPRINTF_EDIT_MSG32("WM_SETREDRAW");
789 lResult
= EDIT_WM_SetRedraw(wndPtr
, wParam
, lParam
);
793 DPRINTF_EDIT_MSG32("WM_SETTEXT");
794 lResult
= EDIT_WM_SetText(wndPtr
, wParam
, lParam
);
798 DPRINTF_EDIT_MSG32("WM_SIZE");
799 lResult
= EDIT_WM_Size(wndPtr
, wParam
, lParam
);
803 DPRINTF_EDIT_MSG32("WM_SYSKEYDOWN");
804 lResult
= EDIT_WM_SysKeyDown(wndPtr
, wParam
, lParam
);
808 DPRINTF_EDIT_MSG32("WM_TIMER");
809 lResult
= EDIT_WM_Timer(wndPtr
, wParam
, lParam
);
813 DPRINTF_EDIT_MSG32("WM_VSCROLL");
814 lResult
= EDIT_WM_VScroll(wndPtr
, wParam
, lParam
);
818 lResult
= DefWindowProc32A(hwnd
, msg
, wParam
, lParam
);
821 EDIT_ReleasePointer(wndPtr
);
826 /*********************************************************************
830 * Build array of pointers to text lines.
831 * Lines can end with '\0' (last line), nothing (if it is too long),
832 * a delimiter (usually ' '), a soft return '\r\r\n' or a hard return '\r\n'
835 static void EDIT_BuildLineDefs(WND
*wndPtr
)
837 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
838 LPSTR text
= EDIT_GetPasswordPointer(wndPtr
);
839 INT32 ww
= EDIT_GetWndWidth(wndPtr
);
849 hdc
= GetDC32(wndPtr
->hwndSelf
);
850 hFont
= (HFONT32
)EDIT_WM_GetFont(wndPtr
, 0, 0);
851 if (hFont
) oldFont
= SelectObject32(hdc
, hFont
);
853 if (!IsMultiLine(wndPtr
)) {
855 es
->LineDefs
= xrealloc(es
->LineDefs
, sizeof(LINEDEF
));
856 es
->LineDefs
[0].offset
= 0;
857 es
->LineDefs
[0].length
= EDIT_WM_GetTextLength(wndPtr
, 0, 0);
858 es
->LineDefs
[0].ending
= END_0
;
859 es
->TextWidth
= (INT32
)LOWORD(GetTabbedTextExtent32A(hdc
, text
,
860 es
->LineDefs
[0].length
,
861 es
->NumTabStops
, es
->TabStops
));
866 if (!(cp
= strstr(start
, "\r\n"))) {
868 length
= lstrlen32A(start
);
869 } else if ((cp
> start
) && (*(cp
- 1) == '\r')) {
871 length
= cp
- start
- 1;
876 width
= (INT32
)LOWORD(GetTabbedTextExtent32A(hdc
, start
, length
,
877 es
->NumTabStops
, es
->TabStops
));
879 if (IsWordWrap(wndPtr
) && (width
> ww
)) {
883 next
= EDIT_CallWordBreakProc(wndPtr
, start
,
884 prev
+ 1, length
, WB_RIGHT
);
885 width
= (INT32
)LOWORD(GetTabbedTextExtent32A(hdc
, start
, next
,
886 es
->NumTabStops
, es
->TabStops
));
887 } while (width
<= ww
);
893 width
= (INT32
)LOWORD(GetTabbedTextExtent32A(hdc
, start
, next
,
894 es
->NumTabStops
, es
->TabStops
));
895 } while (width
<= ww
);
899 if (EDIT_CallWordBreakProc(wndPtr
, start
, length
- 1,
900 length
, WB_ISDELIMITER
)) {
902 ending
= END_DELIMIT
;
905 width
= (INT32
)LOWORD(GetTabbedTextExtent32A(hdc
, start
, length
,
906 es
->NumTabStops
, es
->TabStops
));
909 es
->LineDefs
= xrealloc(es
->LineDefs
, (es
->LineCount
+ 1) * sizeof(LINEDEF
));
910 es
->LineDefs
[es
->LineCount
].offset
= start
- text
;
911 es
->LineDefs
[es
->LineCount
].length
= length
;
912 es
->LineDefs
[es
->LineCount
].ending
= ending
;
914 es
->TextWidth
= MAX(es
->TextWidth
, width
);
930 } while (*start
|| (ending
== END_SOFT
) || (ending
== END_HARD
));
932 if (hFont
) SelectObject32(hdc
, oldFont
);
933 ReleaseDC32(wndPtr
->hwndSelf
, hdc
);
939 /*********************************************************************
941 * EDIT_CallWordBreakProc
943 * Call appropriate WordBreakProc (internal or external).
945 * FIXME: Heavily broken now that we have a LOCAL32 buffer.
946 * External wordbreak functions have been disabled in
947 * EM_SETWORDBREAKPROC.
950 static INT32
EDIT_CallWordBreakProc(WND
*wndPtr
, LPSTR s
, INT32 index
, INT32 count
, INT32 action
)
952 return EDIT_WordBreakProc(s
, index
, count
, action
);
954 * EDITWORDBREAKPROC wbp = (EDITWORDBREAKPROC)EDIT_EM_GetWordBreakProc(wndPtr, 0, 0);
956 * if (!wbp) return EDIT_WordBreakProc(s, index, count, action);
958 * EDITSTATE *es = EDITSTATEPTR(wndPtr);
959 * SEGPTR ptr = LOCAL_LockSegptr( wndPtr->hInstance, es->hBuf16 ) +
960 * (INT16)(s - EDIT_GetPointer(wndPtr));
961 * INT ret = CallWordBreakProc( (FARPROC16)wbp, ptr,
962 * index, count, action);
963 * LOCAL_Unlock( wndPtr->hInstance, es->hBuf16 );
970 /*********************************************************************
974 * Calculates, for a given line and X-coordinate on the screen, the column.
977 static INT32
EDIT_ColFromWndX(WND
*wndPtr
, INT32 line
, INT32 x
)
979 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, 0, 0);
980 INT32 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, line
, 0);
981 INT32 ll
= (INT32
)EDIT_EM_LineLength(wndPtr
, li
, 0);
984 line
= MAX(0, MIN(line
, lc
- 1));
985 for (i
= 0 ; i
< ll
; i
++)
986 if (EDIT_WndXFromCol(wndPtr
, line
, i
) >= x
)
992 /*********************************************************************
996 * Delete all characters on this line to right of cursor.
999 static void EDIT_DelEnd(WND
*wndPtr
)
1001 EDIT_EM_SetSel(wndPtr
, -1, 0);
1002 EDIT_MoveEnd(wndPtr
, TRUE
);
1003 EDIT_WM_Clear(wndPtr
, 0, 0);
1007 /*********************************************************************
1011 * Delete character to left of cursor.
1014 static void EDIT_DelLeft(WND
*wndPtr
)
1016 EDIT_EM_SetSel(wndPtr
, -1, 0);
1017 EDIT_MoveBackward(wndPtr
, TRUE
);
1018 EDIT_WM_Clear(wndPtr
, 0, 0);
1022 /*********************************************************************
1026 * Delete character to right of cursor.
1029 static void EDIT_DelRight(WND
*wndPtr
)
1031 EDIT_EM_SetSel(wndPtr
, -1, 0);
1032 EDIT_MoveForward(wndPtr
, TRUE
);
1033 EDIT_WM_Clear(wndPtr
, 0, 0);
1037 /*********************************************************************
1039 * EDIT_GetAveCharWidth
1042 static INT32
EDIT_GetAveCharWidth(WND
*wndPtr
)
1044 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1046 return es
->AveCharWidth
;
1050 /*********************************************************************
1052 * EDIT_GetLineHeight
1055 static INT32
EDIT_GetLineHeight(WND
*wndPtr
)
1057 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1059 return es
->LineHeight
;
1063 /*********************************************************************
1067 * Calculates the bounding rectangle for a line from a starting
1068 * column to an ending column.
1071 static void EDIT_GetLineRect(WND
*wndPtr
, INT32 line
, INT32 scol
, INT32 ecol
, LPRECT32 rc
)
1073 rc
->top
= EDIT_WndYFromLine(wndPtr
, line
);
1074 rc
->bottom
= rc
->top
+ EDIT_GetLineHeight(wndPtr
);
1075 rc
->left
= EDIT_WndXFromCol(wndPtr
, line
, scol
);
1076 rc
->right
= (ecol
== -1) ? EDIT_GetWndWidth(wndPtr
) :
1077 EDIT_WndXFromCol(wndPtr
, line
, ecol
);
1081 /*********************************************************************
1085 * This acts as a LOCAL_Lock(), but it locks only once. This way
1086 * you can call it whenever you like, without unlocking.
1089 static LPSTR
EDIT_GetPointer(WND
*wndPtr
)
1091 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1093 if (!es
->text
&& (es
->hBuf32
|| es
->hBuf16
)) {
1095 es
->text
= (LPSTR
)LocalLock32(es
->hBuf32
);
1097 es
->text
= LOCAL_Lock(wndPtr
->hInstance
, es
->hBuf16
);
1103 /*********************************************************************
1105 * EDIT_GetPasswordPointer
1109 static LPSTR
EDIT_GetPasswordPointer(WND
*wndPtr
)
1111 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1112 LPSTR text
= xstrdup(EDIT_GetPointer(wndPtr
));
1115 if(es
->PasswordChar
) {
1118 if(*p
!= '\r' && *p
!= '\n')
1119 *p
= es
->PasswordChar
;
1127 /*********************************************************************
1132 static BOOL32
EDIT_GetRedraw(WND
*wndPtr
)
1134 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1140 /*********************************************************************
1144 * Beware: This is not the function called on EM_GETSEL.
1145 * This is the unordered version used internally
1146 * (s can be > e). No return value either.
1149 static void EDIT_GetSel(WND
*wndPtr
, LPINT32 s
, LPINT32 e
)
1151 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1160 /*********************************************************************
1165 static INT32
EDIT_GetTextWidth(WND
*wndPtr
)
1167 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1169 return es
->TextWidth
;
1173 /*********************************************************************
1175 * EDIT_GetUndoPointer
1177 * This acts as a LocalLock32(), but it locks only once. This way
1178 * you can call it whenever you like, without unlocking.
1181 static LPSTR
EDIT_GetUndoPointer(WND
*wndPtr
)
1183 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1185 if (!es
->UndoText
&& es
->hUndoBuf
)
1186 es
->UndoText
= (LPSTR
)LocalLock32(es
->hUndoBuf
);
1187 return es
->UndoText
;
1191 /*********************************************************************
1193 * EDIT_GetVisibleLineCount
1196 static INT32
EDIT_GetVisibleLineCount(WND
*wndPtr
)
1200 EDIT_EM_GetRect(wndPtr
, 0, (LPARAM
)&rc
);
1201 return MAX(1, MAX(rc
.bottom
- rc
.top
, 0) / EDIT_GetLineHeight(wndPtr
));
1205 /*********************************************************************
1210 static INT32
EDIT_GetWndWidth(WND
*wndPtr
)
1214 EDIT_EM_GetRect(wndPtr
, 0, (LPARAM
)&rc
);
1215 return rc
.right
- rc
.left
;
1219 /*********************************************************************
1224 static INT32
EDIT_GetXOffset(WND
*wndPtr
)
1226 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1232 /*********************************************************************
1234 * EDIT_InvalidateText
1236 * Invalidate the text from offset start upto, but not including,
1237 * offset end. Useful for (re)painting the selection.
1238 * Regions outside the linewidth are not invalidated.
1239 * end == -1 means end == TextLength.
1240 * start and end need not be ordered.
1243 static void EDIT_InvalidateText(WND
*wndPtr
, INT32 start
, INT32 end
)
1245 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0);
1246 INT32 vlc
= EDIT_GetVisibleLineCount(wndPtr
);
1260 end
= (INT32
)EDIT_WM_GetTextLength(wndPtr
, 0, 0);
1261 ORDER_INT32(start
, end
);
1262 sl
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, start
, 0);
1263 el
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, end
, 0);
1264 if ((el
< fv
) || (sl
> fv
+ vlc
))
1267 sc
= start
- (INT32
)EDIT_EM_LineIndex(wndPtr
, sl
, 0);
1268 ec
= end
- (INT32
)EDIT_EM_LineIndex(wndPtr
, el
, 0);
1273 if (el
> fv
+ vlc
) {
1275 ec
= (INT32
)EDIT_EM_LineLength(wndPtr
,
1276 (INT32
)EDIT_EM_LineIndex(wndPtr
, el
, 0), 0);
1278 EDIT_EM_GetRect(wndPtr
, 0, (LPARAM
)&rcWnd
);
1280 EDIT_GetLineRect(wndPtr
, sl
, sc
, ec
, &rcLine
);
1281 if (IntersectRect32(&rcUpdate
, &rcWnd
, &rcLine
))
1282 InvalidateRect32( wndPtr
->hwndSelf
, &rcUpdate
, FALSE
);
1284 EDIT_GetLineRect(wndPtr
, sl
, sc
,
1285 (INT32
)EDIT_EM_LineLength(wndPtr
,
1286 (INT32
)EDIT_EM_LineIndex(wndPtr
, sl
, 0), 0),
1288 if (IntersectRect32(&rcUpdate
, &rcWnd
, &rcLine
))
1289 InvalidateRect32( wndPtr
->hwndSelf
, &rcUpdate
, FALSE
);
1290 for (l
= sl
+ 1 ; l
< el
; l
++) {
1291 EDIT_GetLineRect(wndPtr
, l
, 0,
1292 (INT32
)EDIT_EM_LineLength(wndPtr
,
1293 (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0), 0),
1295 if (IntersectRect32(&rcUpdate
, &rcWnd
, &rcLine
))
1296 InvalidateRect32(wndPtr
->hwndSelf
, &rcUpdate
, FALSE
);
1298 EDIT_GetLineRect(wndPtr
, el
, 0, ec
, &rcLine
);
1299 if (IntersectRect32(&rcUpdate
, &rcWnd
, &rcLine
))
1300 InvalidateRect32( wndPtr
->hwndSelf
, &rcUpdate
, FALSE
);
1305 /*********************************************************************
1309 * Calculates, for a given Y-coordinate on the screen, the line.
1312 static INT32
EDIT_LineFromWndY(WND
*wndPtr
, INT32 y
)
1314 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0);
1315 INT32 lh
= EDIT_GetLineHeight(wndPtr
);
1316 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, 0, 0);
1318 return MAX(0, MIN(lc
- 1, y
/ lh
+ fv
));
1322 /*********************************************************************
1326 * Try to fit size + 1 bytes in the buffer. Constrain to limits.
1329 static BOOL32
EDIT_MakeFit(WND
*wndPtr
, INT32 size
)
1331 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1335 if (size
<= es
->BufSize
)
1337 if (size
> es
->BufLimit
) {
1338 dprintf_edit(stddeb
, "edit: notification EN_MAXTEXT sent\n");
1339 EDIT_NOTIFY_PARENT(wndPtr
, EN_MAXTEXT
);
1342 size
= ((size
/ GROWLENGTH
) + 1) * GROWLENGTH
;
1343 if (size
> es
->BufLimit
)
1344 size
= es
->BufLimit
;
1346 dprintf_edit(stddeb
, "edit: EDIT_MakeFit: trying to ReAlloc to %d+1\n", size
);
1348 EDIT_ReleasePointer(wndPtr
);
1350 if ((hNew32
= LocalReAlloc32(es
->hBuf32
, size
+ 1, 0))) {
1351 dprintf_edit(stddeb
, "edit: EDIT_MakeFit: Old 32 bit handle %08x, new handle %08x\n", es
->hBuf32
, hNew32
);
1352 es
->hBuf32
= hNew32
;
1353 es
->BufSize
= MIN(LocalSize32(es
->hBuf32
) - 1, es
->BufLimit
);
1354 if (es
->BufSize
< size
) {
1355 dprintf_edit(stddeb
, "edit: EDIT_MakeFit: FAILED ! We now have %d+1\n", es
->BufSize
);
1356 dprintf_edit(stddeb
, "edit: notification EN_ERRSPACE sent\n");
1357 EDIT_NOTIFY_PARENT(wndPtr
, EN_ERRSPACE
);
1360 dprintf_edit(stddeb
, "edit: EDIT_MakeFit: We now have %d+1\n", es
->BufSize
);
1364 if ((hNew16
= LOCAL_ReAlloc(wndPtr
->hInstance
, es
->hBuf16
, size
+ 1, LMEM_MOVEABLE
))) {
1365 dprintf_edit(stddeb
, "edit: EDIT_MakeFit: Old 16 bit handle %08x, new handle %08x\n", es
->hBuf16
, hNew16
);
1366 es
->hBuf16
= hNew16
;
1367 es
->BufSize
= MIN(LOCAL_Size(wndPtr
->hInstance
, es
->hBuf16
) - 1, es
->BufLimit
);
1368 if (es
->BufSize
< size
) {
1369 dprintf_edit(stddeb
, "edit: EDIT_MakeFit: FAILED ! We now have %d+1\n", es
->BufSize
);
1370 dprintf_edit(stddeb
, "edit: notification EN_ERRSPACE sent\n");
1371 EDIT_NOTIFY_PARENT(wndPtr
, EN_ERRSPACE
);
1374 dprintf_edit(stddeb
, "edit: EDIT_MakeFit: We now have %d+1\n", es
->BufSize
);
1378 dprintf_edit(stddeb
, "edit: EDIT_MakeFit: Reallocation failed\n");
1379 dprintf_edit(stddeb
, "edit: notification EN_ERRSPACE sent\n");
1380 EDIT_NOTIFY_PARENT(wndPtr
, EN_ERRSPACE
);
1385 /*********************************************************************
1389 * Try to fit size + 1 bytes in the undo buffer.
1392 static BOOL32
EDIT_MakeUndoFit(WND
*wndPtr
, INT32 size
)
1394 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1397 if (size
<= es
->UndoBufSize
)
1399 size
= ((size
/ GROWLENGTH
) + 1) * GROWLENGTH
;
1401 dprintf_edit(stddeb
, "edit: EDIT_MakeUndoFit: trying to ReAlloc to %d+1\n", size
);
1403 EDIT_ReleaseUndoPointer(wndPtr
);
1404 if ((hNew
= LocalReAlloc32(es
->hUndoBuf
, size
+ 1, 0))) {
1405 dprintf_edit(stddeb
, "edit: EDIT_MakeUndoFit: Old handle %08x, new handle %08x\n", es
->hUndoBuf
, hNew
);
1406 es
->hUndoBuf
= hNew
;
1407 es
->UndoBufSize
= LocalSize32(es
->hUndoBuf
) - 1;
1408 if (es
->UndoBufSize
< size
) {
1409 dprintf_edit(stddeb
, "edit: EDIT_MakeUndoFit: FAILED ! We now have %d+1\n", es
->UndoBufSize
);
1412 dprintf_edit(stddeb
, "edit: EDIT_MakeUndoFit: We now have %d+1\n", es
->UndoBufSize
);
1419 /*********************************************************************
1424 static void EDIT_MoveBackward(WND
*wndPtr
, BOOL32 extend
)
1431 EDIT_GetSel(wndPtr
, &s
, &e
);
1432 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
1433 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
1436 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
- 1, 0);
1437 e
= li
+ (INT32
)EDIT_EM_LineLength(wndPtr
, li
, 0);
1443 EDIT_SetSel(wndPtr
, s
, e
);
1444 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
1448 /*********************************************************************
1453 static void EDIT_MoveDownward(WND
*wndPtr
, BOOL32 extend
)
1462 EDIT_GetSel(wndPtr
, &s
, &e
);
1463 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
1464 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, e
, 0);
1465 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
1467 x
= EDIT_WndXFromCol(wndPtr
, l
, e
- li
);
1469 e
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0) +
1470 EDIT_ColFromWndX(wndPtr
, l
, x
);
1474 EDIT_SetSel(wndPtr
, s
, e
);
1475 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
1479 /*********************************************************************
1484 static void EDIT_MoveEnd(WND
*wndPtr
, BOOL32 extend
)
1492 EDIT_GetSel(wndPtr
, &s
, &e
);
1493 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
1494 ll
= (INT32
)EDIT_EM_LineLength(wndPtr
, e
, 0);
1495 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
1499 EDIT_SetSel(wndPtr
, s
, e
);
1500 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
1504 /*********************************************************************
1509 static void EDIT_MoveForward(WND
*wndPtr
, BOOL32 extend
)
1518 EDIT_GetSel(wndPtr
, &s
, &e
);
1519 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
1520 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, e
, 0);
1521 ll
= (INT32
)EDIT_EM_LineLength(wndPtr
, e
, 0);
1522 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
1525 e
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
+ 1, 0);
1530 EDIT_SetSel(wndPtr
, s
, e
);
1531 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
1535 /*********************************************************************
1539 * Home key: move to beginning of line.
1542 static void EDIT_MoveHome(WND
*wndPtr
, BOOL32 extend
)
1549 EDIT_GetSel(wndPtr
, &s
, &e
);
1550 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
1551 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
1555 EDIT_SetSel(wndPtr
, s
, e
);
1556 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
1560 /*********************************************************************
1565 static void EDIT_MovePageDown(WND
*wndPtr
, BOOL32 extend
)
1574 EDIT_GetSel(wndPtr
, &s
, &e
);
1575 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
1576 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, e
, 0);
1577 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
1579 x
= EDIT_WndXFromCol(wndPtr
, l
, e
- li
);
1580 l
= MIN(lc
- 1, l
+ EDIT_GetVisibleLineCount(wndPtr
));
1581 e
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0) +
1582 EDIT_ColFromWndX(wndPtr
, l
, x
);
1586 EDIT_SetSel(wndPtr
, s
, e
);
1587 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
1591 /*********************************************************************
1596 static void EDIT_MovePageUp(WND
*wndPtr
, BOOL32 extend
)
1604 EDIT_GetSel(wndPtr
, &s
, &e
);
1605 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
1606 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
1608 x
= EDIT_WndXFromCol(wndPtr
, l
, e
- li
);
1609 l
= MAX(0, l
- EDIT_GetVisibleLineCount(wndPtr
));
1610 e
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0) +
1611 EDIT_ColFromWndX(wndPtr
, l
, x
);
1615 EDIT_SetSel(wndPtr
, s
, e
);
1616 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
1620 /*********************************************************************
1625 static void EDIT_MoveUpward(WND
*wndPtr
, BOOL32 extend
)
1633 EDIT_GetSel(wndPtr
, &s
, &e
);
1634 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
1635 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
1637 x
= EDIT_WndXFromCol(wndPtr
, l
, e
- li
);
1639 e
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0) +
1640 EDIT_ColFromWndX(wndPtr
, l
, x
);
1644 EDIT_SetSel(wndPtr
, s
, e
);
1645 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
1649 /*********************************************************************
1651 * EDIT_MoveWordBackward
1654 static void EDIT_MoveWordBackward(WND
*wndPtr
, BOOL32 extend
)
1663 EDIT_GetSel(wndPtr
, &s
, &e
);
1664 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
1665 ll
= (INT32
)EDIT_EM_LineLength(wndPtr
, e
, 0);
1666 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
1669 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
- 1, 0);
1670 e
= li
+ (INT32
)EDIT_EM_LineLength(wndPtr
, li
, 0);
1673 text
= EDIT_GetPointer(wndPtr
);
1674 e
= li
+ (INT32
)EDIT_CallWordBreakProc(wndPtr
,
1675 text
+ li
, e
- li
, ll
, WB_LEFT
);
1679 EDIT_SetSel(wndPtr
, s
, e
);
1680 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
1684 /*********************************************************************
1686 * EDIT_MoveWordForward
1689 static void EDIT_MoveWordForward(WND
*wndPtr
, BOOL32 extend
)
1699 EDIT_GetSel(wndPtr
, &s
, &e
);
1700 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
1701 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, e
, 0);
1702 ll
= (INT32
)EDIT_EM_LineLength(wndPtr
, e
, 0);
1703 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
1706 e
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
+ 1, 0);
1708 text
= EDIT_GetPointer(wndPtr
);
1709 e
= li
+ EDIT_CallWordBreakProc(wndPtr
,
1710 text
+ li
, e
- li
+ 1, ll
, WB_RIGHT
);
1714 EDIT_SetSel(wndPtr
, s
, e
);
1715 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
1719 /*********************************************************************
1724 static void EDIT_PaintLine(WND
*wndPtr
, HDC32 hdc
, INT32 line
, BOOL32 rev
)
1726 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0);
1727 INT32 vlc
= EDIT_GetVisibleLineCount(wndPtr
);
1728 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, 0, 0);
1736 if ((line
< fv
) || (line
> fv
+ vlc
) || (line
>= lc
))
1739 dprintf_edit(stddeb
, "edit: EDIT_PaintLine: line=%d\n", line
);
1741 x
= EDIT_WndXFromCol(wndPtr
, line
, 0);
1742 y
= EDIT_WndYFromLine(wndPtr
, line
);
1743 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, line
, 0);
1744 ll
= (INT32
)EDIT_EM_LineLength(wndPtr
, li
, 0);
1745 EDIT_GetSel(wndPtr
, &s
, &e
);
1747 s
= MIN(li
+ ll
, MAX(li
, s
));
1748 e
= MIN(li
+ ll
, MAX(li
, e
));
1749 if (rev
&& (s
!= e
) &&
1750 ((GetFocus32() == wndPtr
->hwndSelf
) ||
1751 (wndPtr
->dwStyle
& ES_NOHIDESEL
))) {
1752 x
+= EDIT_PaintText(wndPtr
, hdc
, x
, y
, line
, 0, s
- li
, FALSE
);
1753 x
+= EDIT_PaintText(wndPtr
, hdc
, x
, y
, line
, s
- li
, e
- s
, TRUE
);
1754 x
+= EDIT_PaintText(wndPtr
, hdc
, x
, y
, line
, e
- li
, li
+ ll
- e
, FALSE
);
1756 x
+= EDIT_PaintText(wndPtr
, hdc
, x
, y
, line
, 0, ll
, FALSE
);
1760 /*********************************************************************
1765 static INT32
EDIT_PaintText(WND
*wndPtr
, HDC32 hdc
, INT32 x
, INT32 y
, INT32 line
, INT32 col
, INT32 count
, BOOL32 rev
)
1767 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1777 BkColor
= GetBkColor32(hdc
);
1778 TextColor
= GetTextColor32(hdc
);
1781 SetBkColor32(hdc
, GetSysColor32(COLOR_HIGHLIGHT
));
1782 SetTextColor32(hdc
, GetSysColor32(COLOR_HIGHLIGHTTEXT
));
1784 text
= EDIT_GetPasswordPointer(wndPtr
);
1785 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, line
, 0);
1786 xoff
= EDIT_GetXOffset(wndPtr
);
1787 ret
= (INT32
)LOWORD(TabbedTextOut32A(hdc
, x
, y
, text
+ li
+ col
, count
,
1788 es
->NumTabStops
, es
->TabStops
, -xoff
));
1792 SetBkColor32(hdc
, BkColor
);
1793 SetTextColor32(hdc
, TextColor
);
1799 /*********************************************************************
1801 * EDIT_ReleasePointer
1803 * This is the only helper function that can be called with es = NULL.
1804 * It is called at the end of EditWndProc() to unlock the buffer.
1807 static void EDIT_ReleasePointer(WND
*wndPtr
)
1809 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1813 if (es
->text
&& (es
->hBuf32
|| es
->hBuf16
)) {
1815 LocalUnlock32(es
->hBuf32
);
1817 LOCAL_Unlock(wndPtr
->hInstance
, es
->hBuf16
);
1823 /*********************************************************************
1825 * EDIT_ReleaseUndoPointer
1827 * This is the only helper function that can be called with es = NULL.
1828 * It is called at the end of EditWndProc() to unlock the buffer.
1831 static void EDIT_ReleaseUndoPointer(WND
*wndPtr
)
1833 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1837 if (es
->UndoText
&& es
->hUndoBuf
)
1838 LocalUnlock32(es
->hUndoBuf
);
1839 es
->UndoText
= NULL
;
1843 /*********************************************************************
1847 * Beware: This is not the function called on EM_SETSEL.
1848 * This is the unordered version used internally
1849 * (s can be > e). Doesn't accept -1 parameters either.
1850 * No range checking.
1853 static void EDIT_SetSel(WND
*wndPtr
, INT32 ns
, INT32 ne
)
1855 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1860 EDIT_EM_GetSel(wndPtr
, (WPARAM32
)&s
, (LPARAM
)&e
);
1863 if (EDIT_GetRedraw(wndPtr
)) {
1864 if (wndPtr
->hwndSelf
== GetFocus32()) {
1865 pos
= EDIT_EM_PosFromChar(wndPtr
, ne
, 0);
1866 SetCaretPos16((INT16
)LOWORD(pos
), (INT16
)HIWORD(pos
));
1872 ORDER_INT32(ns
, ne
);
1874 EDIT_InvalidateText(wndPtr
, s
, e
);
1875 EDIT_InvalidateText(wndPtr
, ns
, ne
);
1877 EDIT_InvalidateText(wndPtr
, s
, ne
);
1882 /*********************************************************************
1886 * Calculates, for a given line and column, the X-coordinate on the screen.
1889 static INT32
EDIT_WndXFromCol(WND
*wndPtr
, INT32 line
, INT32 col
)
1891 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1892 LPSTR text
= EDIT_GetPasswordPointer(wndPtr
);
1896 HFONT32 oldFont
= 0;
1897 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, 0, 0);
1898 INT32 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, line
, 0);
1899 INT32 ll
= (INT32
)EDIT_EM_LineLength(wndPtr
, li
, 0);
1900 INT32 xoff
= EDIT_GetXOffset(wndPtr
);
1902 hdc
= GetDC32(wndPtr
->hwndSelf
);
1903 hFont
= (HFONT32
)EDIT_WM_GetFont(wndPtr
, 0, 0);
1904 if (hFont
) oldFont
= SelectObject32(hdc
, hFont
);
1905 line
= MAX(0, MIN(line
, lc
- 1));
1907 ret
= (INT32
)LOWORD(GetTabbedTextExtent32A(hdc
,
1909 es
->NumTabStops
, es
->TabStops
)) - xoff
;
1910 if (hFont
) SelectObject32(hdc
, oldFont
);
1911 ReleaseDC32(wndPtr
->hwndSelf
, hdc
);
1917 /*********************************************************************
1921 * Calculates, for a given line, the Y-coordinate on the screen.
1924 static INT32
EDIT_WndYFromLine(WND
*wndPtr
, INT32 line
)
1926 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0);
1927 INT32 lh
= EDIT_GetLineHeight(wndPtr
);
1929 return (line
- fv
) * lh
;
1933 /*********************************************************************
1935 * EDIT_WordBreakProc
1937 * Find the beginning of words.
1938 * Note: unlike the specs for a WordBreakProc, this function only
1939 * allows to be called without linebreaks between s[0] upto
1940 * s[count - 1]. Remember it is only called
1941 * internally, so we can decide this for ourselves.
1944 static INT32
EDIT_WordBreakProc(LPSTR s
, INT32 index
, INT32 count
, INT32 action
)
1948 dprintf_edit(stddeb
, "edit: EDIT_WordBreakProc: s=%p, index=%u"
1949 ", count=%u, action=%d\n", s
, index
, count
, action
);
1957 if (s
[index
] == ' ') {
1958 while (index
&& (s
[index
] == ' '))
1961 while (index
&& (s
[index
] != ' '))
1963 if (s
[index
] == ' ')
1967 while (index
&& (s
[index
] != ' '))
1969 if (s
[index
] == ' ')
1979 if (s
[index
] == ' ')
1980 while ((index
< count
) && (s
[index
] == ' ')) index
++;
1982 while (s
[index
] && (s
[index
] != ' ') && (index
< count
))
1984 while ((s
[index
] == ' ') && (index
< count
)) index
++;
1988 case WB_ISDELIMITER
:
1989 ret
= (s
[index
] == ' ');
1992 fprintf(stderr
, "edit: EDIT_WordBreakProc: unknown action code, please report !\n");
1999 /*********************************************************************
2004 static LRESULT
EDIT_EM_CanUndo(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2006 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2008 return (LRESULT
)(es
->UndoInsertLen
|| lstrlen32A(EDIT_GetUndoPointer(wndPtr
)));
2012 /*********************************************************************
2016 * FIXME: do the specs mean LineIndex or LineNumber (li v.s. l) ???
2018 static LRESULT
EDIT_EM_CharFromPos(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2026 pt
.x
= LOWORD(lParam
);
2027 pt
.y
= HIWORD(lParam
);
2028 GetClientRect32(wndPtr
->hwndSelf
, &rc
);
2030 if (!PtInRect32(&rc
, pt
))
2033 l
= EDIT_LineFromWndY(wndPtr
, pt
.y
);
2034 li
= EDIT_EM_LineIndex(wndPtr
, l
, 0);
2035 c
= EDIT_ColFromWndX(wndPtr
, l
, pt
.x
);
2037 return (LRESULT
)MAKELONG(li
+ c
, li
);
2041 /*********************************************************************
2043 * EM_EMPTYUNDOBUFFER
2046 static LRESULT
EDIT_EM_EmptyUndoBuffer(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2048 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2050 es
->UndoInsertLen
= 0;
2051 *EDIT_GetUndoPointer(wndPtr
) = '\0';
2056 /*********************************************************************
2061 static LRESULT
EDIT_EM_FmtLines(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2063 fprintf(stdnimp
, "edit: EM_FMTLINES: message not implemented\n");
2064 return wParam
? TRUE
: FALSE
;
2068 /*********************************************************************
2070 * EM_GETFIRSTVISIBLELINE
2073 static LRESULT
EDIT_EM_GetFirstVisibleLine(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2075 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2077 if (IsMultiLine(wndPtr
))
2078 return (LRESULT
)es
->FirstVisibleLine
;
2080 return (LRESULT
)EDIT_ColFromWndX(wndPtr
, 0, 0);
2084 /*********************************************************************
2089 static LRESULT
EDIT_EM_GetHandle(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2091 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2093 if (!IsMultiLine(wndPtr
))
2097 return (LRESULT
)es
->hBuf32
;
2099 return (LRESULT
)es
->hBuf16
;
2103 /*********************************************************************
2107 * Hopefully this won't fire back at us.
2108 * We always start with a buffer in 32 bit linear memory.
2109 * However, with this message a 16 bit application requests
2110 * a handle of 16 bit local heap memory, where it expects to find
2112 * It's a pitty that from this moment on we have to use this
2113 * local heap, because applications may rely on the handle
2116 * In this function we'll try to switch to local heap.
2118 static LRESULT
EDIT_EM_GetHandle16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2120 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2126 if (!IsMultiLine(wndPtr
))
2130 return (LRESULT
)es
->hBuf16
;
2132 if (!LOCAL_HeapSize(wndPtr
->hInstance
)) {
2133 if (!LocalInit(wndPtr
->hInstance
, 0,
2134 GlobalSize16(wndPtr
->hInstance
))) {
2135 fprintf(stderr
, "edit: EM_GETHANDLE: could not initialize local heap\n");
2138 dprintf_edit(stddeb
, "edit: EM_GETHANDLE: local heap initialized\n");
2140 if (!(newBuf
= LOCAL_Alloc(wndPtr
->hInstance
, LMEM_MOVEABLE
,
2141 EDIT_WM_GetTextLength(wndPtr
, 0, 0) + 1)))
2143 fprintf(stderr
, "edit: EM_GETHANDLE: could not allocate new 16 bit buffer\n");
2146 newSize
= MIN(LOCAL_Size(wndPtr
->hInstance
, newBuf
) - 1, es
->BufLimit
);
2147 if (!(newText
= LOCAL_Lock(wndPtr
->hInstance
, newBuf
))) {
2148 fprintf(stderr
, "edit: EM_GETHANDLE: could not lock new 16 bit buffer\n");
2149 LOCAL_Free(wndPtr
->hInstance
, newBuf
);
2152 text
= EDIT_GetPointer(wndPtr
);
2153 lstrcpy32A(newText
, text
);
2154 EDIT_ReleasePointer(wndPtr
);
2155 GlobalFree32(es
->hBuf32
);
2156 es
->hBuf32
= (HLOCAL32
)NULL
;
2157 es
->hBuf16
= newBuf
;
2158 es
->BufSize
= newSize
;
2160 dprintf_edit(stddeb
, "edit: EM_GETHANDLE: switched to 16 bit buffer\n");
2162 return (LRESULT
)es
->hBuf16
;
2166 /*********************************************************************
2171 static LRESULT
EDIT_EM_GetLimitText(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2173 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2175 return es
->BufLimit
;
2179 /*********************************************************************
2184 static LRESULT
EDIT_EM_GetLine(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2191 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, 0, 0);
2193 if (!IsMultiLine(wndPtr
))
2195 if ((INT32
)wParam
>= lc
)
2197 text
= EDIT_GetPointer(wndPtr
);
2198 src
= text
+ (INT32
)EDIT_EM_LineIndex(wndPtr
, wParam
, 0);
2199 dst
= (LPSTR
)lParam
;
2200 len
= MIN(*(WORD
*)dst
, (INT32
)EDIT_EM_LineLength(wndPtr
, wParam
, 0));
2201 for (i
= 0 ; i
< len
; i
++) {
2206 return (LRESULT
)len
;
2210 /*********************************************************************
2215 static LRESULT
EDIT_EM_GetLineCount(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2217 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2219 return (LRESULT
)es
->LineCount
;
2223 /*********************************************************************
2228 static LRESULT
EDIT_EM_GetMargins(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2230 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2232 return (LRESULT
)MAKELONG(es
->LeftMargin
, es
->RightMargin
);
2236 /*********************************************************************
2241 static LRESULT
EDIT_EM_GetModify(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2243 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2245 return (LRESULT
)es
->TextChanged
;
2249 /*********************************************************************
2251 * EM_GETPASSWORDCHAR
2254 static LRESULT
EDIT_EM_GetPasswordChar(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2256 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2258 return (LRESULT
)es
->PasswordChar
;
2262 /*********************************************************************
2267 static LRESULT
EDIT_EM_GetRect(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2269 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2271 CopyRect32((LPRECT32
)lParam
, &es
->FormatRect
);
2276 /*********************************************************************
2281 static LRESULT
EDIT_EM_GetRect16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2283 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2285 CONV_RECT32TO16(&es
->FormatRect
, (LPRECT16
)PTR_SEG_TO_LIN((SEGPTR
)lParam
));
2290 /*********************************************************************
2294 * Returns the ordered selection range so that
2295 * LOWORD(result) < HIWORD(result)
2298 static LRESULT
EDIT_EM_GetSel(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2303 EDIT_GetSel(wndPtr
, &s
, &e
);
2306 *(LPINT32
)wParam
= s
;
2308 *(LPINT32
)lParam
= e
;
2309 return MAKELONG((INT16
)s
, (INT16
)e
);
2313 /*********************************************************************
2317 * FIXME: is this right ? (or should it be only HSCROLL)
2318 * (and maybe only for edit controls that really have their
2319 * own scrollbars) (and maybe only for multiline controls ?)
2320 * All in all: very poorly documented
2323 static LRESULT
EDIT_EM_GetThumb(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2325 return MAKELONG(EDIT_WM_VScroll(wndPtr
, EM_GETTHUMB16
, 0),
2326 EDIT_WM_HScroll(wndPtr
, EM_GETTHUMB16
, 0));
2330 /*********************************************************************
2332 * EM_GETWORDBREAKPROC
2334 * FIXME: Application defined WordBreakProc should be returned
2337 static LRESULT
EDIT_EM_GetWordBreakProc(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2340 EDITSTATE *es = EDITSTATEPTR(wndPtr);
2342 return (LRESULT)es->WordBreakProc;
2348 /*********************************************************************
2353 static LRESULT
EDIT_EM_LineFromChar(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2357 if (!IsMultiLine(wndPtr
))
2359 if ((INT32
)wParam
== -1)
2360 EDIT_EM_GetSel(wndPtr
, (WPARAM32
)&wParam
, 0); /* intentional (looks weird, doesn't it ?) */
2361 l
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, 0, 0) - 1;
2362 while ((INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0) > (INT32
)wParam
)
2368 /*********************************************************************
2373 static LRESULT
EDIT_EM_LineIndex(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2375 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2378 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, 0, 0);
2380 if ((INT32
)wParam
== -1) {
2381 EDIT_GetSel(wndPtr
, NULL
, &e
);
2383 while (es
->LineDefs
[l
].offset
> e
)
2385 return (LRESULT
)es
->LineDefs
[l
].offset
;
2387 if ((INT32
)wParam
>= lc
)
2389 return (LRESULT
)es
->LineDefs
[(INT32
)wParam
].offset
;
2393 /*********************************************************************
2398 static LRESULT
EDIT_EM_LineLength(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2400 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2406 if (!IsMultiLine(wndPtr
))
2407 return (LRESULT
)es
->LineDefs
[0].length
;
2408 if ((INT32
)wParam
== -1) {
2409 EDIT_GetSel(wndPtr
, &s
, &e
);
2410 sl
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, s
, 0);
2411 el
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
2412 return (LRESULT
)(s
- es
->LineDefs
[sl
].offset
+
2413 es
->LineDefs
[el
].offset
+
2414 es
->LineDefs
[el
].length
- e
);
2416 return (LRESULT
)es
->LineDefs
[(INT32
)EDIT_EM_LineFromChar(wndPtr
, wParam
, 0)].length
;
2420 /*********************************************************************
2424 * FIXME: is wParam in pixels or in average character widths ???
2425 * FIXME: we use this internally to scroll single line controls as well
2426 * (specs are vague about whether this message is valid or not for
2427 * single line controls)
2430 static LRESULT
EDIT_EM_LineScroll(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2432 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2433 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, 0, 0);
2434 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0);
2435 INT32 nfv
= MAX(0, fv
+ (INT32
)lParam
);
2436 INT32 xoff
= EDIT_GetXOffset(wndPtr
);
2437 INT32 nxoff
= MAX(0, xoff
+ (INT32
)wParam
);
2438 INT32 tw
= EDIT_GetTextWidth(wndPtr
);
2448 dy
= EDIT_WndYFromLine(wndPtr
, fv
) - EDIT_WndYFromLine(wndPtr
, nfv
);
2450 if (EDIT_GetRedraw(wndPtr
))
2451 ScrollWindow32(wndPtr
->hwndSelf
, dx
, dy
, NULL
, NULL
);
2452 es
->FirstVisibleLine
= nfv
;
2453 es
->XOffset
= nxoff
;
2454 if (IsVScrollBar(wndPtr
))
2455 SetScrollPos32(wndPtr
->hwndSelf
, SB_VERT
,
2456 EDIT_WM_VScroll(wndPtr
, EM_GETTHUMB16
, 0), TRUE
);
2457 if (IsHScrollBar(wndPtr
))
2458 SetScrollPos32(wndPtr
->hwndSelf
, SB_HORZ
,
2459 EDIT_WM_HScroll(wndPtr
, EM_GETTHUMB16
, 0), TRUE
);
2461 if (IsMultiLine(wndPtr
))
2468 /*********************************************************************
2473 static LRESULT
EDIT_EM_PosFromChar(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2475 INT32 len
= (INT32
)EDIT_WM_GetTextLength(wndPtr
, 0, 0);
2479 wParam
= MIN(wParam
, len
);
2480 l
= EDIT_EM_LineFromChar(wndPtr
, wParam
, 0);
2481 li
= EDIT_EM_LineIndex(wndPtr
, l
, 0);
2482 return (LRESULT
)MAKELONG(EDIT_WndXFromCol(wndPtr
, l
, wParam
- li
),
2483 EDIT_WndYFromLine(wndPtr
, l
));
2487 /*********************************************************************
2492 static LRESULT
EDIT_EM_ReplaceSel(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2494 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2495 LPCSTR str
= (LPCSTR
)lParam
;
2496 INT32 strl
= lstrlen32A(str
);
2497 INT32 tl
= (INT32
)EDIT_WM_GetTextLength(wndPtr
, 0, 0);
2507 EDIT_EM_GetSel(wndPtr
, (WPARAM32
)&s
, (LPARAM
)&e
);
2509 if ((s
== e
) && !strl
)
2512 if (!EDIT_MakeFit(wndPtr
, tl
- (e
- s
) + strl
))
2515 text
= EDIT_GetPointer(wndPtr
);
2516 utext
= EDIT_GetUndoPointer(wndPtr
);
2518 /* there is something to be deleted */
2519 if ((BOOL32
)wParam
) {
2520 /* we have to be able to undo */
2521 utl
= lstrlen32A(utext
);
2522 if (!es
->UndoInsertLen
&& (*utext
&& (s
== es
->UndoPos
))) {
2523 /* undo-buffer is extended to the right */
2524 EDIT_MakeUndoFit(wndPtr
, utl
+ e
- s
);
2525 lstrcpyn32A(utext
+ utl
, text
+ s
, e
- s
+ 1);
2526 } else if (!es
->UndoInsertLen
&& (*utext
&& (e
== es
->UndoPos
))) {
2527 /* undo-buffer is extended to the left */
2528 EDIT_MakeUndoFit(wndPtr
, utl
+ e
- s
);
2529 for (p
= utext
+ utl
; p
>= utext
; p
--)
2531 for (i
= 0 , p
= utext
; i
< e
- s
; i
++)
2532 p
[i
] = (text
+ s
)[i
];
2535 /* new undo-buffer */
2536 EDIT_MakeUndoFit(wndPtr
, e
- s
);
2537 lstrcpyn32A(utext
, text
+ s
, e
- s
+ 1);
2540 /* any deletion makes the old insertion-undo invalid */
2541 es
->UndoInsertLen
= 0;
2543 EDIT_EM_EmptyUndoBuffer(wndPtr
, 0, 0);
2546 lstrcpy32A(text
+ s
, text
+ e
);
2549 /* there is an insertion */
2550 if ((BOOL32
)wParam
) {
2551 /* we have to be able to undo */
2552 if ((s
== es
->UndoPos
) ||
2553 ((es
->UndoInsertLen
) &&
2554 (s
== es
->UndoPos
+ es
->UndoInsertLen
)))
2556 * insertion is new and at delete position or
2557 * an extension to either left or right
2559 es
->UndoInsertLen
+= strl
;
2561 /* new insertion undo */
2563 es
->UndoInsertLen
= strl
;
2564 /* new insertion makes old delete-buffer invalid */
2568 EDIT_EM_EmptyUndoBuffer(wndPtr
, 0, 0);
2571 tl
= lstrlen32A(text
);
2572 for (p
= text
+ tl
; p
>= text
+ s
; p
--)
2574 for (i
= 0 , p
= text
+ s
; i
< strl
; i
++)
2577 CharUpperBuff32A(p
, strl
);
2578 else if(IsLower(wndPtr
))
2579 CharLowerBuff32A(p
, strl
);
2582 redraw
= EDIT_GetRedraw(wndPtr
);
2583 EDIT_WM_SetRedraw(wndPtr
, FALSE
, 0);
2584 EDIT_BuildLineDefs(wndPtr
);
2585 EDIT_EM_SetSel(wndPtr
, s
, s
);
2586 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
2587 EDIT_EM_SetModify(wndPtr
, TRUE
, 0);
2588 dprintf_edit(stddeb
, "edit: notification EN_UPDATE sent\n");
2589 EDIT_NOTIFY_PARENT(wndPtr
, EN_UPDATE
);
2590 EDIT_WM_SetRedraw(wndPtr
, redraw
, 0);
2592 InvalidateRect32( wndPtr
->hwndSelf
, NULL
, TRUE
);
2593 dprintf_edit(stddeb
, "edit: notification EN_CHANGE sent\n");
2594 EDIT_NOTIFY_PARENT(wndPtr
, EN_CHANGE
);
2600 /*********************************************************************
2604 * FIXME: Scroll what ??? And where ???
2607 static LRESULT
EDIT_EM_Scroll(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2609 fprintf(stdnimp
, "edit: EM_SCROLL: message not implemented\n");
2614 /*********************************************************************
2618 * Makes sure the caret is visible.
2619 * FIXME: We use EM_LINESCROLL, but may we do that for single line
2623 static LRESULT
EDIT_EM_ScrollCaret(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2628 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0);
2629 INT32 vlc
= EDIT_GetVisibleLineCount(wndPtr
);
2630 INT32 ww
= EDIT_GetWndWidth(wndPtr
);
2631 INT32 cw
= EDIT_GetAveCharWidth(wndPtr
);
2636 EDIT_GetSel(wndPtr
, NULL
, &e
);
2637 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
2638 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
2639 x
= EDIT_WndXFromCol(wndPtr
, l
, e
- li
);
2641 dy
= l
- vlc
+ 1 - fv
;
2645 dx
= x
- ww
/ HSCROLL_FRACTION
/ cw
* cw
;
2647 dx
= x
- (HSCROLL_FRACTION
- 1) * ww
/ HSCROLL_FRACTION
/ cw
* cw
;
2649 EDIT_EM_LineScroll(wndPtr
, dx
, dy
);
2651 dprintf_edit(stddeb
, "edit: notification EN_VSCROLL sent\n");
2652 EDIT_NOTIFY_PARENT(wndPtr
, EN_VSCROLL
);
2655 dprintf_edit(stddeb
, "edit: notification EN_HSCROLL sent\n");
2656 EDIT_NOTIFY_PARENT(wndPtr
, EN_HSCROLL
);
2663 /*********************************************************************
2668 static LRESULT
EDIT_EM_SetHandle(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2670 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2672 if (IsMultiLine(wndPtr
)) {
2673 EDIT_ReleasePointer(wndPtr
);
2675 * old buffer is freed by caller
2677 es
->hBuf16
= (HLOCAL16
)NULL
;
2678 es
->hBuf32
= (HLOCAL32
)wParam
;
2679 es
->BufSize
= LocalSize32(es
->hBuf32
) - 1;
2681 es
->FirstVisibleLine
= 0;
2682 es
->SelStart
= es
->SelEnd
= 0;
2683 EDIT_EM_EmptyUndoBuffer(wndPtr
, 0, 0);
2684 EDIT_EM_SetModify(wndPtr
, FALSE
, 0);
2685 EDIT_BuildLineDefs(wndPtr
);
2686 if (EDIT_GetRedraw(wndPtr
))
2687 InvalidateRect32( wndPtr
->hwndSelf
, NULL
, TRUE
);
2688 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
2694 /*********************************************************************
2699 static LRESULT
EDIT_EM_SetHandle16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2701 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2703 if (IsMultiLine(wndPtr
)) {
2704 EDIT_ReleasePointer(wndPtr
);
2706 * old buffer is freed by caller
2708 es
->hBuf16
= (HLOCAL16
)wParam
;
2709 es
->hBuf32
= (HLOCAL32
)NULL
;
2710 es
->BufSize
= LOCAL_Size(wndPtr
->hInstance
, es
->hBuf16
) - 1;
2712 es
->FirstVisibleLine
= 0;
2713 es
->SelStart
= es
->SelEnd
= 0;
2714 EDIT_EM_EmptyUndoBuffer(wndPtr
, 0, 0);
2715 EDIT_EM_SetModify(wndPtr
, FALSE
, 0);
2716 EDIT_BuildLineDefs(wndPtr
);
2717 if (EDIT_GetRedraw(wndPtr
))
2718 InvalidateRect32( wndPtr
->hwndSelf
, NULL
, TRUE
);
2719 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
2725 /*********************************************************************
2729 * FIXME: in WinNT maxsize is 0x7FFFFFFF / 0xFFFFFFFF
2730 * However, the windows version is not complied to yet in all of edit.c
2733 static LRESULT
EDIT_EM_SetLimitText(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2735 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2737 if (IsMultiLine(wndPtr
)) {
2739 es
->BufLimit
= MIN((INT32
)wParam
, BUFLIMIT_MULTI
);
2741 es
->BufLimit
= BUFLIMIT_MULTI
;
2744 es
->BufLimit
= MIN((INT32
)wParam
, BUFLIMIT_SINGLE
);
2746 es
->BufLimit
= BUFLIMIT_SINGLE
;
2752 /*********************************************************************
2756 * FIXME: We let the margins be set, but we don't use them yet !?!
2759 static LRESULT
EDIT_EM_SetMargins(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2761 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2763 if (wParam
& EC_USEFONTINFO
) {
2764 if (IsMultiLine(wndPtr
)) {
2766 * FIXME: do some GetABCCharWidth, or so
2767 * This is just preliminary
2769 es
->LeftMargin
= es
->RightMargin
= EDIT_GetAveCharWidth(wndPtr
);
2771 es
->LeftMargin
= es
->RightMargin
= EDIT_GetAveCharWidth(wndPtr
);
2774 if (wParam
& EC_LEFTMARGIN
)
2775 es
->LeftMargin
= LOWORD(lParam
);
2776 if (wParam
& EC_RIGHTMARGIN
)
2777 es
->RightMargin
= HIWORD(lParam
);
2782 /*********************************************************************
2787 static LRESULT
EDIT_EM_SetModify(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2789 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2791 es
->TextChanged
= (BOOL32
)wParam
;
2796 /*********************************************************************
2798 * EM_SETPASSWORDCHAR
2800 * FIXME: This imlementation is way too simple
2803 static LRESULT
EDIT_EM_SetPasswordChar(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2805 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2807 es
->PasswordChar
= (CHAR
)wParam
;
2812 /*********************************************************************
2817 static LRESULT
EDIT_EM_SetReadOnly(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2820 wndPtr
->dwStyle
|= ES_READONLY
;
2822 wndPtr
->dwStyle
&= ~(DWORD
)ES_READONLY
;
2827 /*********************************************************************
2832 static LRESULT
EDIT_EM_SetRect(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2834 fprintf(stdnimp
,"edit: EM_SETRECT: message not implemented\n");
2839 /*********************************************************************
2844 static LRESULT
EDIT_EM_SetRectNP(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2846 fprintf(stdnimp
,"edit: EM_SETRECTNP: message not implemented\n");
2851 /*********************************************************************
2856 static LRESULT
EDIT_EM_SetSel(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2858 INT32 ns
= (INT32
)wParam
;
2859 INT32 ne
= (INT32
)lParam
;
2860 INT32 tl
= (INT32
)EDIT_WM_GetTextLength(wndPtr
, 0, 0);
2863 EDIT_GetSel(wndPtr
, NULL
, &ne
);
2865 } else if ((!ns
) && (ne
== -1))
2868 ns
= MAX(0, MIN(ns
, tl
));
2869 ne
= MAX(0, MIN(ne
, tl
));
2870 ORDER_INT32(ns
, ne
);
2872 EDIT_SetSel(wndPtr
, ns
, ne
);
2877 /*********************************************************************
2882 static LRESULT
EDIT_EM_SetSel16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2884 INT32 ns
= (INT32
)LOWORD(lParam
);
2885 INT32 ne
= (INT32
)HIWORD(lParam
);
2887 if ((INT16
)LOWORD(lParam
) == -1)
2889 if ((!ns
) && ((INT16
)HIWORD(lParam
) == -1))
2891 EDIT_EM_SetSel(wndPtr
, ns
, ne
);
2893 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
2898 /*********************************************************************
2903 static LRESULT
EDIT_EM_SetTabStops(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2905 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2907 if (!IsMultiLine(wndPtr
))
2911 es
->NumTabStops
= (INT32
)wParam
;
2913 es
->TabStops
= NULL
;
2915 es
->TabStops
= (LPINT32
)xmalloc(wParam
* sizeof(INT32
));
2916 memcpy( es
->TabStops
, (LPINT32
)lParam
,
2917 (INT32
)wParam
* sizeof(INT32
) );
2923 /*********************************************************************
2928 static LRESULT
EDIT_EM_SetTabStops16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2930 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2933 if (!IsMultiLine(wndPtr
))
2937 es
->NumTabStops
= (INT32
)wParam
;
2939 es
->TabStops
= NULL
;
2942 LPINT16 p
= (LPINT16
)PTR_SEG_TO_LIN(lParam
);
2943 es
->TabStops
= (LPINT32
)xmalloc(wParam
* sizeof(INT32
));
2944 for ( i
= 0 ; i
< (INT32
)wParam
; i
++) es
->TabStops
[i
] = *p
++;
2950 /*********************************************************************
2952 * EM_SETWORDBREAKPROC
2955 static LRESULT
EDIT_EM_SetWordBreakProc(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2958 EDITSTATE *es = EDITSTATEPTR(wndPtr);
2960 es->WordBreakProc = (EDITWORDBREAKPROC)lParam;
2966 /*********************************************************************
2971 static LRESULT
EDIT_EM_Undo(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2973 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2974 LPSTR utext
= xstrdup(EDIT_GetUndoPointer(wndPtr
));
2976 dprintf_edit(stddeb
, "edit: before UNDO:insertion length = %d, deletion buffer = %s\n",
2977 es
->UndoInsertLen
, utext
);
2979 EDIT_EM_SetSel(wndPtr
, es
->UndoPos
, es
->UndoPos
+ es
->UndoInsertLen
);
2980 EDIT_EM_EmptyUndoBuffer(wndPtr
, 0, 0);
2981 EDIT_EM_ReplaceSel(wndPtr
, TRUE
, (LPARAM
)utext
);
2982 EDIT_EM_SetSel(wndPtr
, es
->UndoPos
, es
->UndoPos
+ es
->UndoInsertLen
);
2985 dprintf_edit(stddeb
, "edit: after UNDO: insertion length = %d, deletion buffer = %s\n",
2986 es
->UndoInsertLen
, EDIT_GetUndoPointer(wndPtr
));
2992 /*********************************************************************
2997 static LRESULT
EDIT_WM_Char(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3000 unsigned char c
= (unsigned char)wParam
;
3005 if (IsMultiLine(wndPtr
)) {
3006 if (IsReadOnly(wndPtr
)) {
3007 EDIT_MoveHome(wndPtr
, FALSE
);
3008 EDIT_MoveDownward(wndPtr
, FALSE
);
3010 EDIT_EM_ReplaceSel(wndPtr
, (WPARAM32
)TRUE
, (LPARAM
)"\r\n");
3014 if (IsMultiLine(wndPtr
) && !IsReadOnly(wndPtr
))
3015 EDIT_EM_ReplaceSel(wndPtr
, (WPARAM32
)TRUE
, (LPARAM
)"\t");
3018 if (!IsReadOnly(wndPtr
) && (c
>= ' ') && (c
!= 127)) {
3021 EDIT_EM_ReplaceSel(wndPtr
, (WPARAM32
)TRUE
, (LPARAM
)str
);
3029 /*********************************************************************
3034 static LRESULT
EDIT_WM_Clear(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3036 EDIT_EM_ReplaceSel(wndPtr
, TRUE
, (LPARAM
)"");
3042 /*********************************************************************
3047 static LRESULT
EDIT_WM_Command(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3052 switch (LOWORD(wParam
)) {
3054 EDIT_EM_Undo(wndPtr
, 0, 0);
3057 EDIT_WM_Cut(wndPtr
, 0, 0);
3060 EDIT_WM_Copy(wndPtr
, 0, 0);
3063 EDIT_WM_Paste(wndPtr
, 0, 0);
3066 EDIT_WM_Clear(wndPtr
, 0, 0);
3069 EDIT_EM_SetSel(wndPtr
, 0, -1);
3070 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
3073 dprintf_edit(stddeb
, "edit: unknown menu item, please report\n");
3080 /*********************************************************************
3084 * Note: the resource files resource/sysres_??.rc cannot define a
3085 * single popup menu. Hence we use a (dummy) menubar
3086 * containing the single popup menu as its first item.
3089 static LRESULT
EDIT_WM_ContextMenu(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3091 HMENU32 hMenu
= LoadMenuIndirect32A(SYSRES_GetResPtr(SYSRES_MENU_EDITMENU
));
3092 HMENU32 hPopup
= GetSubMenu32(hMenu
, 0);
3094 TrackPopupMenu32(hPopup
, TPM_LEFTALIGN
| TPM_RIGHTBUTTON
, LOWORD(lParam
),
3095 HIWORD(lParam
), 0, wndPtr
->hwndSelf
, NULL
);
3096 DestroyMenu32(hMenu
);
3101 /*********************************************************************
3106 static LRESULT
EDIT_WM_Copy(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3114 EDIT_GetSel(wndPtr
, &s
, &e
);
3118 hdst
= GlobalAlloc16(GMEM_MOVEABLE
, (DWORD
)(e
- s
+ 1));
3119 dst
= GlobalLock16(hdst
);
3120 text
= EDIT_GetPointer(wndPtr
);
3121 lstrcpyn32A(dst
, text
+ s
, e
- s
+ 1);
3122 GlobalUnlock16(hdst
);
3123 OpenClipboard32(wndPtr
->hwndSelf
);
3125 SetClipboardData16(CF_TEXT
, hdst
);
3131 /*********************************************************************
3136 static LRESULT
EDIT_WM_Create(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3138 CREATESTRUCT32A
*cs
= (CREATESTRUCT32A
*)lParam
;
3142 es
= xmalloc(sizeof(EDITSTATE
));
3143 memset(es
, 0, sizeof(EDITSTATE
));
3144 *(EDITSTATE
**)wndPtr
->wExtra
= es
;
3146 if (cs
->style
& WS_VSCROLL
)
3147 cs
->style
|= ES_AUTOVSCROLL
;
3148 if (cs
->style
& WS_HSCROLL
)
3149 cs
->style
|= ES_AUTOHSCROLL
;
3151 /* remove the WS_CAPTION style if it has been set - this is really a */
3152 /* pseudo option made from a combination of WS_BORDER and WS_DLGFRAME */
3153 if ((cs
->style
& WS_BORDER
) && (cs
->style
& WS_DLGFRAME
))
3154 cs
->style
^= WS_DLGFRAME
;
3156 if (IsMultiLine(wndPtr
)) {
3157 es
->BufSize
= BUFSTART_MULTI
;
3158 es
->BufLimit
= BUFLIMIT_MULTI
;
3159 es
->PasswordChar
= '\0';
3161 es
->BufSize
= BUFSTART_SINGLE
;
3162 es
->BufLimit
= BUFLIMIT_SINGLE
;
3163 es
->PasswordChar
= (cs
->style
& ES_PASSWORD
) ? '*' : '\0';
3165 if (!(es
->hBuf32
= LocalAlloc32(LMEM_MOVEABLE
, es
->BufSize
+ 1))) {
3166 fprintf(stderr
, "edit: WM_CREATE: unable to allocate buffer\n");
3169 if (!(es
->hUndoBuf
= LocalAlloc32(LMEM_MOVEABLE
, es
->BufSize
+ 1))) {
3170 fprintf(stderr
, "edit: WM_CREATE: unable to allocate undo buffer\n");
3171 LocalFree32(es
->hBuf32
);
3172 es
->hBuf32
= (HLOCAL32
)NULL
;
3175 es
->BufSize
= LocalSize32(es
->hBuf32
) - 1;
3176 es
->UndoBufSize
= LocalSize32(es
->hUndoBuf
) - 1;
3177 EDIT_EM_EmptyUndoBuffer(wndPtr
, 0, 0);
3178 text
= EDIT_GetPointer(wndPtr
);
3180 EDIT_BuildLineDefs(wndPtr
);
3181 EDIT_WM_SetFont(wndPtr
, 0, 0);
3182 if (cs
->lpszName
&& *(cs
->lpszName
) != '\0')
3183 EDIT_EM_ReplaceSel(wndPtr
, (WPARAM32
)FALSE
, (LPARAM
)cs
->lpszName
);
3184 EDIT_WM_SetRedraw(wndPtr
, TRUE
, 0);
3189 /*********************************************************************
3194 static LRESULT
EDIT_WM_Cut(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3196 EDIT_WM_Copy(wndPtr
, 0, 0);
3197 EDIT_WM_Clear(wndPtr
, 0, 0);
3202 /*********************************************************************
3207 static LRESULT
EDIT_WM_Destroy(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3209 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
3214 EDIT_ReleaseUndoPointer(wndPtr
);
3215 LocalFree32(es
->hUndoBuf
);
3216 EDIT_ReleasePointer(wndPtr
);
3218 LocalFree32(es
->hBuf32
);
3220 LOCAL_Free(wndPtr
->hInstance
, es
->hBuf16
);
3222 *(EDITSTATE
**)&wndPtr
->wExtra
= NULL
;
3227 /*********************************************************************
3232 static LRESULT
EDIT_WM_Enable(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3234 EDIT_InvalidateText(wndPtr
, 0, -1);
3239 /*********************************************************************
3244 static LRESULT
EDIT_WM_EraseBkGnd(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3249 hBrush
= (HBRUSH32
)EDIT_SEND_CTLCOLOR(wndPtr
, wParam
);
3250 if (!hBrush
) hBrush
= (HBRUSH32
)GetStockObject32(WHITE_BRUSH
);
3252 GetClientRect32(wndPtr
->hwndSelf
, &rc
);
3253 IntersectClipRect32((HDC32
)wParam
, rc
.left
, rc
.top
,
3254 rc
.right
, rc
.bottom
);
3255 GetClipBox32((HDC32
)wParam
, &rc
);
3257 * FIXME: specs say that we should UnrealizeObject() the brush,
3258 * but the specs of UnrealizeObject() say that we shouldn't
3259 * unrealize a stock object. The default brush that
3260 * DefWndProc() returns is ... a stock object.
3262 FillRect32((HDC32
)wParam
, &rc
, hBrush
);
3267 /*********************************************************************
3272 static LRESULT
EDIT_WM_GetDlgCode(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3274 return DLGC_HASSETSEL
| DLGC_WANTCHARS
| DLGC_WANTARROWS
;
3278 /*********************************************************************
3283 static LRESULT
EDIT_WM_GetFont(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3285 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
3287 return (LRESULT
)es
->hFont
;
3291 /*********************************************************************
3296 static LRESULT
EDIT_WM_GetText(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3298 LPSTR text
= EDIT_GetPointer(wndPtr
);
3300 LRESULT lResult
= 0;
3302 len
= lstrlen32A(text
);
3303 if ((INT32
)wParam
> len
) {
3304 lstrcpy32A((LPSTR
)lParam
, text
);
3305 lResult
= (LRESULT
)len
+ 1;
3311 /*********************************************************************
3316 static LRESULT
EDIT_WM_GetTextLength(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3318 LPSTR text
= EDIT_GetPointer(wndPtr
);
3320 return (LRESULT
)lstrlen32A(text
);
3324 /*********************************************************************
3328 * FIXME: scrollbar code itself is broken, so this one is a hack.
3331 static LRESULT
EDIT_WM_HScroll(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3333 INT32 ww
= EDIT_GetWndWidth(wndPtr
);
3334 INT32 tw
= EDIT_GetTextWidth(wndPtr
);
3335 INT32 cw
= EDIT_GetAveCharWidth(wndPtr
);
3336 INT32 xoff
= EDIT_GetXOffset(wndPtr
);
3349 dx
= -ww
/ HSCROLL_FRACTION
/ cw
* cw
;
3352 dx
= ww
/ HSCROLL_FRACTION
/ cw
* cw
;
3364 case SB_THUMBPOSITION
:
3365 dx
= HIWORD(wParam
) * tw
/ 100 - xoff
;
3367 /* The next two are undocumented ! */
3369 ret
= tw
? xoff
* 100 / tw
: 0;
3371 case EM_LINESCROLL16
:
3372 dx
= (INT16
)HIWORD(wParam
);
3379 EDIT_EM_LineScroll(wndPtr
, dx
, 0);
3381 dprintf_edit(stddeb
, "edit: notification EN_HSCROLL sent\n");
3382 EDIT_NOTIFY_PARENT(wndPtr
, EN_HSCROLL
);
3389 /*********************************************************************
3393 * FIXME: the message identifiers have been chosen arbitrarily,
3394 * hence we use MF_BYPOSITION.
3395 * We might as well use the "real" values (anybody knows ?)
3396 * The menu definition is in resources/sysres_??.rc.
3397 * Once these are OK, we better use MF_BYCOMMAND here
3398 * (as we do in EDIT_WM_Command()).
3401 static LRESULT
EDIT_WM_InitMenuPopup(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3403 HMENU32 hPopup
= (HMENU32
)wParam
;
3407 EDIT_EM_GetSel(wndPtr
, (WPARAM32
)&s
, (LPARAM
)&e
);
3410 EnableMenuItem32(hPopup
, 0, MF_BYPOSITION
|
3411 (EDIT_EM_CanUndo(wndPtr
, 0, 0) ? MF_ENABLED
: MF_GRAYED
));
3413 EnableMenuItem32(hPopup
, 2, MF_BYPOSITION
|
3414 ((e
- s
) && !IsPassword(wndPtr
) ? MF_ENABLED
: MF_GRAYED
));
3416 EnableMenuItem32(hPopup
, 3, MF_BYPOSITION
|
3417 ((e
- s
) && !IsPassword(wndPtr
) ? MF_ENABLED
: MF_GRAYED
));
3419 EnableMenuItem32(hPopup
, 4, MF_BYPOSITION
|
3420 (IsClipboardFormatAvailable32(CF_TEXT
) ? MF_ENABLED
: MF_GRAYED
));
3422 EnableMenuItem32(hPopup
, 5, MF_BYPOSITION
|
3423 ((e
- s
) ? MF_ENABLED
: MF_GRAYED
));
3425 EnableMenuItem32(hPopup
, 7, MF_BYPOSITION
|
3426 (s
|| (e
!= EDIT_WM_GetTextLength(wndPtr
, 0, 0)) ? MF_ENABLED
: MF_GRAYED
));
3432 /*********************************************************************
3436 * Handling of special keys that don't produce a WM_CHAR
3437 * (i.e. non-printable keys) & Backspace & Delete
3440 static LRESULT
EDIT_WM_KeyDown(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3447 if (GetKeyState32(VK_MENU
) & 0x8000)
3450 shift
= GetKeyState32(VK_SHIFT
) & 0x8000;
3451 control
= GetKeyState32(VK_CONTROL
) & 0x8000;
3453 EDIT_GetSel(wndPtr
, &s
, &e
);
3457 if (IsMultiLine(wndPtr
) && (wParam
== VK_UP
))
3458 EDIT_MoveUpward(wndPtr
, shift
);
3461 EDIT_MoveWordBackward(wndPtr
, shift
);
3463 EDIT_MoveBackward(wndPtr
, shift
);
3467 if (IsMultiLine(wndPtr
) && (wParam
== VK_DOWN
))
3468 EDIT_MoveDownward(wndPtr
, shift
);
3470 EDIT_MoveWordForward(wndPtr
, shift
);
3472 EDIT_MoveForward(wndPtr
, shift
);
3475 EDIT_MoveHome(wndPtr
, shift
);
3478 EDIT_MoveEnd(wndPtr
, shift
);
3481 if (IsMultiLine(wndPtr
))
3482 EDIT_MovePageUp(wndPtr
, shift
);
3485 if (IsMultiLine(wndPtr
))
3486 EDIT_MovePageDown(wndPtr
, shift
);
3489 if (!IsReadOnly(wndPtr
) && !control
)
3491 EDIT_WM_Clear(wndPtr
, 0, 0);
3493 EDIT_DelLeft(wndPtr
);
3496 if (!IsReadOnly(wndPtr
) && !(shift
&& control
))
3499 EDIT_WM_Cut(wndPtr
, 0, 0);
3501 EDIT_WM_Clear(wndPtr
, 0, 0);
3504 EDIT_DelLeft(wndPtr
);
3506 EDIT_DelEnd(wndPtr
);
3508 EDIT_DelRight(wndPtr
);
3513 if (!IsReadOnly(wndPtr
))
3514 EDIT_WM_Paste(wndPtr
, 0, 0);
3516 EDIT_WM_Copy(wndPtr
, 0, 0);
3523 /*********************************************************************
3528 static LRESULT
EDIT_WM_KillFocus(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3534 if(!(wndPtr
->dwStyle
& ES_NOHIDESEL
)) {
3535 EDIT_EM_GetSel(wndPtr
, (WPARAM32
)&s
, (LPARAM
)&e
);
3536 EDIT_InvalidateText(wndPtr
, s
, e
);
3538 dprintf_edit(stddeb
, "edit: notification EN_KILLFOCUS sent\n");
3539 EDIT_NOTIFY_PARENT(wndPtr
, EN_KILLFOCUS
);
3544 /*********************************************************************
3548 * The caret position has been set on the WM_LBUTTONDOWN message
3551 static LRESULT
EDIT_WM_LButtonDblClk(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3558 LPSTR text
= EDIT_GetPointer(wndPtr
);
3560 EDIT_GetSel(wndPtr
, NULL
, &e
);
3561 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
, 0);
3562 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
3563 ll
= (INT32
)EDIT_EM_LineLength(wndPtr
, e
, 0);
3564 s
= li
+ EDIT_CallWordBreakProc (wndPtr
, text
+ li
, e
- li
, ll
, WB_LEFT
);
3565 e
= li
+ EDIT_CallWordBreakProc(wndPtr
, text
+ li
, e
- li
, ll
, WB_RIGHT
);
3566 EDIT_EM_SetSel(wndPtr
, s
, e
);
3567 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
3572 /*********************************************************************
3577 static LRESULT
EDIT_WM_LButtonDown(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3579 INT32 x
= (INT32
)(INT16
)LOWORD(lParam
);
3580 INT32 y
= (INT32
)(INT16
)HIWORD(lParam
);
3581 INT32 l
= EDIT_LineFromWndY(wndPtr
, y
);
3585 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0);
3586 INT32 vlc
= EDIT_GetVisibleLineCount(wndPtr
);
3589 SetFocus32(wndPtr
->hwndSelf
);
3590 SetCapture32(wndPtr
->hwndSelf
);
3591 l
= MIN(fv
+ vlc
- 1, MAX(fv
, l
));
3592 x
= MIN(EDIT_GetWndWidth(wndPtr
), MAX(0, x
));
3593 c
= EDIT_ColFromWndX(wndPtr
, l
, x
);
3594 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
3596 if (GetKeyState32(VK_SHIFT
) & 0x8000)
3597 EDIT_GetSel(wndPtr
, &s
, NULL
);
3600 EDIT_SetSel(wndPtr
, s
, e
);
3601 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
3602 SetTimer32(wndPtr
->hwndSelf
, 0, 100, NULL
);
3607 /*********************************************************************
3612 static LRESULT
EDIT_WM_LButtonUp(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3614 if (GetCapture32() == wndPtr
->hwndSelf
) {
3615 KillTimer32(wndPtr
->hwndSelf
, 0);
3622 /*********************************************************************
3627 static LRESULT
EDIT_WM_MouseMove(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3638 if (GetCapture32() == wndPtr
->hwndSelf
) {
3639 x
= (INT32
)(INT16
)LOWORD(lParam
);
3640 y
= (INT32
)(INT16
)HIWORD(lParam
);
3641 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0);
3642 vlc
= EDIT_GetVisibleLineCount(wndPtr
);
3643 l
= EDIT_LineFromWndY(wndPtr
, y
);
3644 l
= MIN(fv
+ vlc
- 1, MAX(fv
, l
));
3645 x
= MIN(EDIT_GetWndWidth(wndPtr
), MAX(0, x
));
3646 c
= EDIT_ColFromWndX(wndPtr
, l
, x
);
3647 EDIT_GetSel(wndPtr
, &s
, NULL
);
3648 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
, 0);
3649 EDIT_SetSel(wndPtr
, s
, li
+ c
);
3652 * FIXME: gotta do some scrolling if outside client (format ?)
3653 * area. Maybe reset the timer ?
3659 /*********************************************************************
3664 static LRESULT
EDIT_WM_Paint(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3668 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0);
3669 INT32 vlc
= EDIT_GetVisibleLineCount(wndPtr
);
3670 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, 0, 0);
3673 HFONT32 oldFont
= 0;
3679 BOOL32 rev
= IsWindowEnabled32(wndPtr
->hwndSelf
) &&
3680 ((GetFocus32() == wndPtr
->hwndSelf
) ||
3681 (wndPtr
->dwStyle
& ES_NOHIDESEL
));
3683 hdc
= BeginPaint32(wndPtr
->hwndSelf
, &ps
);
3684 GetClientRect32(wndPtr
->hwndSelf
, &rc
);
3685 IntersectClipRect32( hdc
, rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
3686 hFont
= (HFONT32
)EDIT_WM_GetFont(wndPtr
, 0, 0);
3688 oldFont
= (HFONT32
)SelectObject32(hdc
, hFont
);
3689 EDIT_SEND_CTLCOLOR(wndPtr
, hdc
);
3690 if (!IsWindowEnabled32(wndPtr
->hwndSelf
))
3691 SetTextColor32(hdc
, GetSysColor32(COLOR_GRAYTEXT
));
3692 GetClipBox32(hdc
, &rcRgn
);
3693 for (i
= fv
; i
<= MIN(fv
+ vlc
, fv
+ lc
- 1) ; i
++ ) {
3694 EDIT_GetLineRect(wndPtr
, i
, 0, -1, &rcLine
);
3695 if (IntersectRect32(&rc
, &rcRgn
, &rcLine
))
3696 EDIT_PaintLine(wndPtr
, hdc
, i
, rev
);
3698 if (hFont
) SelectObject32(hdc
, oldFont
);
3699 if (wndPtr
->hwndSelf
== GetFocus32()) {
3700 EDIT_GetSel(wndPtr
, NULL
, &e
);
3701 pos
= EDIT_EM_PosFromChar(wndPtr
, e
, 0);
3702 SetCaretPos16( (INT16
)LOWORD(pos
), (INT16
)HIWORD(pos
) );
3704 EndPaint32(wndPtr
->hwndSelf
, &ps
);
3709 /*********************************************************************
3714 static LRESULT
EDIT_WM_Paste(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3719 OpenClipboard32(wndPtr
->hwndSelf
);
3720 if ((hsrc
= GetClipboardData16(CF_TEXT
)))
3722 src
= (LPSTR
)GlobalLock16(hsrc
);
3723 EDIT_EM_ReplaceSel(wndPtr
, (WPARAM32
)TRUE
, (LPARAM
)src
);
3724 GlobalUnlock16(hsrc
);
3731 /*********************************************************************
3736 static LRESULT
EDIT_WM_SetCursor(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3738 if (LOWORD(lParam
) == HTCLIENT
) {
3739 SetCursor16(LoadCursor16(0, IDC_IBEAM
));
3746 /*********************************************************************
3751 static LRESULT
EDIT_WM_SetFocus(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3756 EDIT_GetSel(wndPtr
, &s
, &e
);
3757 CreateCaret32( wndPtr
->hwndSelf
, 0, 2, EDIT_GetLineHeight(wndPtr
) );
3758 EDIT_SetSel(wndPtr
, s
, e
);
3759 if(!(wndPtr
->dwStyle
& ES_NOHIDESEL
))
3760 EDIT_InvalidateText(wndPtr
, s
, e
);
3761 ShowCaret32(wndPtr
->hwndSelf
);
3762 dprintf_edit(stddeb
, "edit: notification EN_SETFOCUS sent\n");
3763 EDIT_NOTIFY_PARENT(wndPtr
, EN_SETFOCUS
);
3768 /*********************************************************************
3773 static LRESULT
EDIT_WM_SetFont(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3776 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
3780 HFONT32 oldFont
= 0;
3782 EDIT_GetSel(wndPtr
, &s
, &e
);
3783 es
->hFont
= (HFONT32
)wParam
;
3784 hdc
= GetDC32(wndPtr
->hwndSelf
);
3785 if (es
->hFont
) oldFont
= SelectObject32(hdc
, es
->hFont
);
3786 GetTextMetrics32A(hdc
, &tm
);
3787 es
->LineHeight
= tm
.tmHeight
;
3788 es
->AveCharWidth
= tm
.tmAveCharWidth
;
3789 if (es
->hFont
) SelectObject32(hdc
, oldFont
);
3790 ReleaseDC32(wndPtr
->hwndSelf
, hdc
);
3791 EDIT_BuildLineDefs(wndPtr
);
3792 if ((BOOL32
)lParam
&& EDIT_GetRedraw(wndPtr
))
3793 InvalidateRect32( wndPtr
->hwndSelf
, NULL
, TRUE
);
3794 if (wndPtr
->hwndSelf
== GetFocus32()) {
3796 CreateCaret32( wndPtr
->hwndSelf
, 0,
3797 2, EDIT_GetLineHeight(wndPtr
) );
3798 EDIT_SetSel(wndPtr
, s
, e
);
3799 ShowCaret32(wndPtr
->hwndSelf
);
3805 /*********************************************************************
3810 static LRESULT
EDIT_WM_SetRedraw(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3812 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
3814 es
->Redraw
= (BOOL32
)wParam
;
3819 /*********************************************************************
3824 static LRESULT
EDIT_WM_SetText(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3826 EDIT_EM_SetSel(wndPtr
, 0, -1);
3828 EDIT_EM_ReplaceSel(wndPtr
, (WPARAM32
)FALSE
, lParam
);
3829 EDIT_EM_SetModify(wndPtr
, TRUE
, 0);
3830 EDIT_EM_ScrollCaret(wndPtr
, 0, 0);
3835 /*********************************************************************
3839 * FIXME: What about that FormatRect ???
3842 static LRESULT
EDIT_WM_Size(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3844 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
3847 EDIT_GetSel(wndPtr
, 0, &e
);
3848 GetClientRect32(wndPtr
->hwndSelf
, &es
->FormatRect
);
3849 if (EDIT_GetRedraw(wndPtr
) &&
3850 ((wParam
== SIZE_MAXIMIZED
) ||
3851 (wParam
== SIZE_RESTORED
))) {
3852 if (IsMultiLine(wndPtr
) && IsWordWrap(wndPtr
))
3853 EDIT_BuildLineDefs(wndPtr
);
3854 InvalidateRect32( wndPtr
->hwndSelf
, NULL
, TRUE
);
3860 /*********************************************************************
3865 static LRESULT
EDIT_WM_SysKeyDown(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3867 if ((wParam
== VK_BACK
) && (lParam
& 0x2000) &&
3868 (BOOL32
)EDIT_EM_CanUndo(wndPtr
, 0, 0))
3869 EDIT_EM_Undo(wndPtr
, 0, 0);
3874 /*********************************************************************
3879 static LRESULT
EDIT_WM_Timer(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3882 * FIXME: gotta do some scrolling here, like
3883 * EDIT_EM_LineScroll(wndPtr, 0, 1);
3889 /*********************************************************************
3893 * FIXME: scrollbar code itself is broken, so this one is a hack.
3896 static LRESULT
EDIT_WM_VScroll(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3898 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
, 0, 0);
3899 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
, 0, 0);
3900 INT32 vlc
= EDIT_GetVisibleLineCount(wndPtr
);
3927 case SB_THUMBPOSITION
:
3928 dy
= HIWORD(wParam
) * (lc
- 1) / 100 - fv
;
3930 /* The next two are undocumented ! */
3932 ret
= (lc
> 1) ? MAKELONG(fv
* 100 / (lc
- 1), 0) : 0;
3934 case EM_LINESCROLL16
:
3935 dy
= (INT16
)LOWORD(lParam
);
3942 EDIT_EM_LineScroll(wndPtr
, 0, dy
);
3944 dprintf_edit(stddeb
, "edit: notification EN_VSCROLL sent\n");
3945 EDIT_NOTIFY_PARENT(wndPtr
, EN_VSCROLL
);