4 * Copyright David W. Metcalfe, 1994
5 * Copyright William Magro, 1995, 1996
6 * Copyright Frans van Dorsselaer, 1996
11 * UNDER CONSTRUCTION, please read EDIT.TODO
25 #define BUFLIMIT_MULTI 65534 /* maximum text buffer length (not including '\0') */
26 #define BUFLIMIT_SINGLE 32766
27 #define BUFSTART_MULTI 1024 /* starting length for multi-line control */
28 #define BUFSTART_SINGLE 256 /* starting length for single line control */
29 #define GROWLENGTH 64 /* buffers grow by this much */
30 #define HSCROLL_FRACTION 3 /* scroll window by 1/3 width */
49 UINT TextWidth; /* width of the widest line in pixels */
54 UINT XOffset; /* offset of the viewport in pixels */
55 UINT FirstVisibleLine;
57 UINT LineHeight; /* height of a screen line in pixels */
58 UINT AveCharWidth; /* average character width in pixels */
63 UINT SelStart; /* offset of selection start, == SelEnd if no selection */
64 UINT SelEnd; /* offset of selection end == current caret position */
67 EDITWORDBREAKPROC WordBreakProc;
72 #define SWAP_UINT(x,y) do { UINT temp = (UINT)(x); (x) = (UINT)(y); (y) = temp; } while(0)
73 #define ORDER_UINT(x,y) do { if ((UINT)(y) < (UINT)(x)) SWAP_UINT((x),(y)); } while(0)
75 /* macros to access window styles */
76 #define IsMultiLine(wndPtr) ((wndPtr)->dwStyle & ES_MULTILINE)
77 #define IsVScrollBar(wndPtr) ((wndPtr)->dwStyle & WS_VSCROLL)
78 #define IsHScrollBar(wndPtr) ((wndPtr)->dwStyle & WS_HSCROLL)
79 #define IsReadOnly(wndPtr) ((wndPtr)->dwStyle & ES_READONLY)
80 #define IsWordWrap(wndPtr) (((wndPtr)->dwStyle & ES_AUTOHSCROLL) == 0)
81 #define IsPassword(wndPtr) ((wndPtr)->dwStyle & ES_PASSWORD)
82 #define IsLower(wndPtr) ((wndPtr)->dwStyle & ES_LOWERCASE)
83 #define IsUpper(wndPtr) ((wndPtr)->dwStyle & ES_UPPERCASE)
85 #define EDITSTATEPTR(wndPtr) (*(EDITSTATE **)((wndPtr)->wExtra))
87 #define EDIT_SEND_CTLCOLOR(wndPtr,hdc) \
88 (SendMessage32A((wndPtr)->parent->hwndSelf, WM_CTLCOLOREDIT, \
89 (WPARAM32)(hdc), (LPARAM)(wndPtr)->hwndSelf ))
90 #define EDIT_NOTIFY_PARENT(wndPtr, wNotifyCode) \
91 (SendMessage32A((wndPtr)->parent->hwndSelf, WM_COMMAND, \
92 MAKEWPARAM((wndPtr)->wIDmenu, wNotifyCode), \
93 (LPARAM)(wndPtr)->hwndSelf ))
94 #define DPRINTF_EDIT_MSG(str) \
95 dprintf_edit(stddeb, \
96 "edit: " str ": hwnd=%04x, wParam=%04x, lParam=%08x\n", \
97 (UINT32)hwnd, (UINT32)wParam, (UINT32)lParam)
100 /*********************************************************************
104 * Files like these should really be kept in alphabetical order.
107 LRESULT EditWndProc(HWND hwnd, UINT msg, WPARAM16 wParam, LPARAM lParam);
109 static void EDIT_BuildLineDefs(WND *wndPtr);
110 static INT EDIT_CallWordBreakProc(WND *wndPtr, char *s, INT index, INT count, INT action);
111 static UINT EDIT_ColFromWndX(WND *wndPtr, UINT line, INT x);
112 static void EDIT_DelEnd(WND *wndPtr);
113 static void EDIT_DelLeft(WND *wndPtr);
114 static void EDIT_DelRight(WND *wndPtr);
115 static UINT EDIT_GetAveCharWidth(WND *wndPtr);
116 static UINT EDIT_GetLineHeight(WND *wndPtr);
117 static void EDIT_GetLineRect(WND *wndPtr, UINT line, UINT scol, UINT ecol, LPRECT16 rc);
118 static char * EDIT_GetPointer(WND *wndPtr);
119 static char * EDIT_GetPasswordPointer(WND *wndPtr);
120 static LRESULT EDIT_GetRect(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
121 static BOOL EDIT_GetRedraw(WND *wndPtr);
122 static LRESULT EDIT_GetSel(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
123 static UINT EDIT_GetTextWidth(WND *wndPtr);
124 static UINT EDIT_GetVisibleLineCount(WND *wndPtr);
125 static UINT EDIT_GetWndWidth(WND *wndPtr);
126 static UINT EDIT_GetXOffset(WND *wndPtr);
127 static void EDIT_InvalidateText(WND *wndPtr, UINT start, UINT end);
128 static UINT EDIT_LineFromWndY(WND *wndPtr, INT y);
129 static BOOL EDIT_MakeFit(WND *wndPtr, UINT size);
130 static void EDIT_MoveBackward(WND *wndPtr, BOOL extend);
131 static void EDIT_MoveDownward(WND *wndPtr, BOOL extend);
132 static void EDIT_MoveEnd(WND *wndPtr, BOOL extend);
133 static void EDIT_MoveForward(WND *wndPtr, BOOL extend);
134 static void EDIT_MoveHome(WND *wndPtr, BOOL extend);
135 static void EDIT_MovePageDown(WND *wndPtr, BOOL extend);
136 static void EDIT_MovePageUp(WND *wndPtr, BOOL extend);
137 static void EDIT_MoveUpward(WND *wndPtr, BOOL extend);
138 static void EDIT_MoveWordBackward(WND *wndPtr, BOOL extend);
139 static void EDIT_MoveWordForward(WND *wndPtr, BOOL extend);
140 static void EDIT_PaintLine(WND *wndPtr, HDC32 hdc, UINT line, BOOL rev);
141 static UINT EDIT_PaintText(WND *wndPtr, HDC32 hdc, INT x, INT y, UINT line, UINT col, UINT count, BOOL rev);
142 static void EDIT_ReleasePointer(WND *wndPtr);
143 static LRESULT EDIT_ReplaceSel(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
144 static void EDIT_ScrollIntoView(WND *wndPtr);
145 static INT EDIT_WndXFromCol(WND *wndPtr, UINT line, UINT col);
146 static INT EDIT_WndYFromLine(WND *wndPtr, UINT line);
147 static INT EDIT_WordBreakProc(char *s, INT index, INT count, INT action);
149 static LRESULT EDIT_EM_CanUndo(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
150 static LRESULT EDIT_EM_EmptyUndoBuffer(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
151 static LRESULT EDIT_EM_FmtLines(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
152 static LRESULT EDIT_EM_GetFirstVisibleLine(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
153 static LRESULT EDIT_EM_GetHandle(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
154 static LRESULT EDIT_EM_GetLine(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
155 static LRESULT EDIT_EM_GetLineCount(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
156 static LRESULT EDIT_EM_GetModify(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
157 static LRESULT EDIT_EM_GetPasswordChar(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
158 static LRESULT EDIT_EM_GetRect(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
159 static LRESULT EDIT_EM_GetSel(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
160 static LRESULT EDIT_EM_GetThumb(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
161 static LRESULT EDIT_EM_GetWordBreakProc(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
162 static LRESULT EDIT_EM_LimitText(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
163 static LRESULT EDIT_EM_LineFromChar(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
164 static LRESULT EDIT_EM_LineIndex(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
165 static LRESULT EDIT_EM_LineLength(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
166 static LRESULT EDIT_EM_LineScroll(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
167 static LRESULT EDIT_EM_ReplaceSel(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
168 static LRESULT EDIT_EM_Scroll(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
169 static LRESULT EDIT_EM_SetHandle(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
170 static LRESULT EDIT_EM_SetModify(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
171 static LRESULT EDIT_EM_SetPasswordChar(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
172 static LRESULT EDIT_EM_SetReadOnly(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
173 static LRESULT EDIT_EM_SetRect(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
174 static LRESULT EDIT_EM_SetRectNP(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
175 static LRESULT EDIT_EM_SetSel(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
176 static LRESULT EDIT_EM_SetTabStops(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
177 static LRESULT EDIT_EM_SetWordBreakProc(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
178 static LRESULT EDIT_EM_Undo(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
180 static LRESULT EDIT_WM_Char(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
181 static LRESULT EDIT_WM_Clear(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
182 static LRESULT EDIT_WM_Copy(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
183 static LRESULT EDIT_WM_Cut(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
184 static LRESULT EDIT_WM_Create(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
185 static LRESULT EDIT_WM_Destroy(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
186 static LRESULT EDIT_WM_Enable(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
187 static LRESULT EDIT_WM_EraseBkGnd(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
188 static LRESULT EDIT_WM_GetDlgCode(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
189 static LRESULT EDIT_WM_GetFont(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
190 static LRESULT EDIT_WM_GetText(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
191 static LRESULT EDIT_WM_GetTextLength(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
192 static LRESULT EDIT_WM_HScroll(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
193 static LRESULT EDIT_WM_KeyDown(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
194 static LRESULT EDIT_WM_KillFocus(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
195 static LRESULT EDIT_WM_LButtonDblClk(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
196 static LRESULT EDIT_WM_LButtonDown(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
197 static LRESULT EDIT_WM_LButtonUp(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
198 static LRESULT EDIT_WM_MouseMove(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
199 static LRESULT EDIT_WM_Paint(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
200 static LRESULT EDIT_WM_Paste(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
201 static LRESULT EDIT_WM_SetCursor(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
202 static LRESULT EDIT_WM_SetFocus(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
203 static LRESULT EDIT_WM_SetFont(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
204 static LRESULT EDIT_WM_SetRedraw(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
205 static LRESULT EDIT_WM_SetText(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
206 static LRESULT EDIT_WM_Size(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
207 static LRESULT EDIT_WM_VScroll(WND *wndPtr, WPARAM32 wParam, LPARAM lParam);
210 /*********************************************************************
212 * General shortcuts for variable names:
216 * UINT s; offset of selection start
217 * UINT e; offset of selection end
218 * UINT sl; line on which the selection starts
219 * UINT el; line on which the selection ends
220 * UINT sc; column on which the selection starts
221 * UINT ec; column on which the selection ends
222 * UINT li; line index (offset)
223 * UINT fv; first visible line
224 * UINT vlc; vissible line count
225 * UINT lc; line count
226 * UINT lh; line height (in pixels)
227 * UINT tw; text width (in pixels)
228 * UINT ww; window width (in pixels)
229 * UINT cw; character width (average, in pixels)
234 /*********************************************************************
239 LRESULT EditWndProc(HWND hwnd, UINT msg, WPARAM16 wParam, LPARAM lParam)
241 LRESULT lResult = 0L;
242 WND *wndPtr = WIN_FindWndPtr(hwnd);
244 if ((!EDITSTATEPTR(wndPtr)) && (msg != WM_CREATE))
245 return DefWindowProc16(hwnd, msg, wParam, lParam);
249 DPRINTF_EDIT_MSG("EM_CANUNDO");
250 lResult = EDIT_EM_CanUndo(wndPtr, wParam, lParam);
252 case EM_EMPTYUNDOBUFFER:
253 DPRINTF_EDIT_MSG("EM_EMPTYUNDOBUFFER");
254 lResult = EDIT_EM_EmptyUndoBuffer(wndPtr, wParam, lParam);
257 DPRINTF_EDIT_MSG("EM_FMTLINES");
258 lResult = EDIT_EM_FmtLines(wndPtr, wParam, lParam);
260 case EM_GETFIRSTVISIBLELINE:
261 DPRINTF_EDIT_MSG("EM_GETFIRSTVISIBLELINE");
262 lResult = EDIT_EM_GetFirstVisibleLine(wndPtr, wParam, lParam);
265 DPRINTF_EDIT_MSG("EM_GETHANDLE");
266 lResult = EDIT_EM_GetHandle(wndPtr, wParam, lParam);
269 DPRINTF_EDIT_MSG("EM_GETLINE");
270 lResult = EDIT_EM_GetLine(wndPtr, wParam, lParam);
272 case EM_GETLINECOUNT:
273 DPRINTF_EDIT_MSG("EM_GETLINECOUNT");
274 lResult = EDIT_EM_GetLineCount(wndPtr, wParam, lParam);
277 DPRINTF_EDIT_MSG("EM_GETMODIFY");
278 lResult = EDIT_EM_GetModify(wndPtr, wParam, lParam);
280 case EM_GETPASSWORDCHAR:
281 DPRINTF_EDIT_MSG("EM_GETPASSWORDCHAR");
282 lResult = EDIT_EM_GetPasswordChar(wndPtr, wParam, lParam);
285 DPRINTF_EDIT_MSG("EM_GETRECT");
286 lResult = EDIT_EM_GetRect(wndPtr, wParam, lParam);
289 DPRINTF_EDIT_MSG("EM_GETSEL");
290 lResult = EDIT_EM_GetSel(wndPtr, wParam, lParam);
293 DPRINTF_EDIT_MSG("EM_GETTHUMB");
294 lResult = EDIT_EM_GetThumb(wndPtr, wParam, lParam);
296 case EM_GETWORDBREAKPROC:
297 DPRINTF_EDIT_MSG("EM_GETWORDBREAKPROC");
298 lResult = EDIT_EM_GetWordBreakProc(wndPtr, wParam, lParam);
301 DPRINTF_EDIT_MSG("EM_LIMITTEXT");
302 lResult = EDIT_EM_LimitText(wndPtr, wParam, lParam);
304 case EM_LINEFROMCHAR:
305 DPRINTF_EDIT_MSG("EM_LINEFROMCHAR");
306 lResult = EDIT_EM_LineFromChar(wndPtr, wParam, lParam);
309 DPRINTF_EDIT_MSG("EM_LINEINDEX");
310 lResult = EDIT_EM_LineIndex(wndPtr, wParam, lParam);
313 DPRINTF_EDIT_MSG("EM_LINELENGTH");
314 lResult = EDIT_EM_LineLength(wndPtr, wParam, lParam);
317 DPRINTF_EDIT_MSG("EM_LINESCROLL");
318 lResult = EDIT_EM_LineScroll(wndPtr, wParam, lParam);
321 DPRINTF_EDIT_MSG("EM_REPLACESEL");
322 lResult = EDIT_EM_ReplaceSel(wndPtr, wParam, lParam);
325 DPRINTF_EDIT_MSG("EM_SCROLL");
326 lResult = EDIT_EM_Scroll(wndPtr, wParam, lParam);
329 DPRINTF_EDIT_MSG("EM_SETHANDLE");
330 lResult = EDIT_EM_SetHandle(wndPtr, wParam, lParam);
333 DPRINTF_EDIT_MSG("EM_SETMODIFY");
334 lResult = EDIT_EM_SetModify(wndPtr, wParam, lParam);
336 case EM_SETPASSWORDCHAR:
337 DPRINTF_EDIT_MSG("EM_SETPASSWORDCHAR");
338 lResult = EDIT_EM_SetPasswordChar(wndPtr, wParam, lParam);
341 DPRINTF_EDIT_MSG("EM_SETREADONLY");
342 lResult = EDIT_EM_SetReadOnly(wndPtr, wParam, lParam);
345 DPRINTF_EDIT_MSG("EM_SETRECT");
346 lResult = EDIT_EM_SetRect(wndPtr, wParam, lParam);
349 DPRINTF_EDIT_MSG("EM_SETRECTNP");
350 lResult = EDIT_EM_SetRectNP(wndPtr, wParam, lParam);
353 DPRINTF_EDIT_MSG("EM_SETSEL");
354 lResult = EDIT_EM_SetSel(wndPtr, wParam, lParam);
357 DPRINTF_EDIT_MSG("EM_SETTABSTOPS");
358 lResult = EDIT_EM_SetTabStops(wndPtr, wParam, lParam);
360 case EM_SETWORDBREAKPROC:
361 DPRINTF_EDIT_MSG("EM_SETWORDBREAKPROC");
362 lResult = EDIT_EM_SetWordBreakProc(wndPtr, wParam, lParam);
366 DPRINTF_EDIT_MSG("EM_UNDO / WM_UNDO");
367 lResult = EDIT_EM_Undo(wndPtr, wParam, lParam);
370 DPRINTF_EDIT_MSG("WM_GETDLGCODE");
371 lResult = EDIT_WM_GetDlgCode(wndPtr, wParam, lParam);
374 DPRINTF_EDIT_MSG("WM_CHAR");
375 lResult = EDIT_WM_Char(wndPtr, wParam, lParam);
378 DPRINTF_EDIT_MSG("WM_CLEAR");
379 lResult = EDIT_WM_Clear(wndPtr, wParam, lParam);
382 DPRINTF_EDIT_MSG("WM_COPY");
383 lResult = EDIT_WM_Copy(wndPtr, wParam, lParam);
386 DPRINTF_EDIT_MSG("WM_CREATE");
387 lResult = EDIT_WM_Create(wndPtr, wParam, lParam);
390 DPRINTF_EDIT_MSG("WM_CUT");
391 lResult = EDIT_WM_Cut(wndPtr, wParam, lParam);
394 DPRINTF_EDIT_MSG("WM_DESTROY");
395 lResult = EDIT_WM_Destroy(wndPtr, wParam, lParam);
398 DPRINTF_EDIT_MSG("WM_ENABLE");
399 lResult = EDIT_WM_Enable(wndPtr, wParam, lParam);
402 DPRINTF_EDIT_MSG("WM_ERASEBKGND");
403 lResult = EDIT_WM_EraseBkGnd(wndPtr, wParam, lParam);
406 DPRINTF_EDIT_MSG("WM_GETFONT");
407 lResult = EDIT_WM_GetFont(wndPtr, wParam, lParam);
410 DPRINTF_EDIT_MSG("WM_GETTEXT");
411 lResult = EDIT_WM_GetText(wndPtr, wParam, lParam);
413 case WM_GETTEXTLENGTH:
414 DPRINTF_EDIT_MSG("WM_GETTEXTLENGTH");
415 lResult = EDIT_WM_GetTextLength(wndPtr, wParam, lParam);
418 DPRINTF_EDIT_MSG("WM_HSCROLL");
419 lResult = EDIT_WM_HScroll(wndPtr, wParam, lParam);
422 DPRINTF_EDIT_MSG("WM_KEYDOWN");
423 lResult = EDIT_WM_KeyDown(wndPtr, wParam, lParam);
426 DPRINTF_EDIT_MSG("WM_KILLFOCUS");
427 lResult = EDIT_WM_KillFocus(wndPtr, wParam, lParam);
429 case WM_LBUTTONDBLCLK:
430 DPRINTF_EDIT_MSG("WM_LBUTTONDBLCLK");
431 lResult = EDIT_WM_LButtonDblClk(wndPtr, wParam, lParam);
434 DPRINTF_EDIT_MSG("WM_LBUTTONDOWN");
435 lResult = EDIT_WM_LButtonDown(wndPtr, wParam, lParam);
438 DPRINTF_EDIT_MSG("WM_LBUTTONUP");
439 lResult = EDIT_WM_LButtonUp(wndPtr, wParam, lParam);
443 * DPRINTF_EDIT_MSG("WM_MOUSEMOVE");
445 lResult = EDIT_WM_MouseMove(wndPtr, wParam, lParam);
448 DPRINTF_EDIT_MSG("WM_PAINT");
449 lResult = EDIT_WM_Paint(wndPtr, wParam, lParam);
452 DPRINTF_EDIT_MSG("WM_PASTE");
453 lResult = EDIT_WM_Paste(wndPtr, wParam, lParam);
457 * DPRINTF_EDIT_MSG("WM_SETCURSOR");
459 lResult = EDIT_WM_SetCursor(wndPtr, wParam, lParam);
462 DPRINTF_EDIT_MSG("WM_SETFOCUS");
463 lResult = EDIT_WM_SetFocus(wndPtr, wParam, lParam);
466 DPRINTF_EDIT_MSG("WM_SETFONT");
467 lResult = EDIT_WM_SetFont(wndPtr, wParam, lParam);
470 DPRINTF_EDIT_MSG("WM_SETREDRAW");
471 lResult = EDIT_WM_SetRedraw(wndPtr, wParam, lParam);
474 DPRINTF_EDIT_MSG("WM_SETTEXT");
475 lResult = EDIT_WM_SetText(wndPtr, wParam, lParam);
478 DPRINTF_EDIT_MSG("WM_SIZE");
479 lResult = EDIT_WM_Size(wndPtr, wParam, lParam);
482 DPRINTF_EDIT_MSG("WM_VSCROLL");
483 lResult = EDIT_WM_VScroll(wndPtr, wParam, lParam);
486 /* Some programs pass messages obtained through
487 * RegisterWindowMessage() (>= 0xc000); we just ignore them
489 if ((msg >= WM_USER) && (msg < 0xc000))
490 fprintf(stdnimp, "edit: undocumented message %d >= WM_USER, please report.\n", msg);
491 lResult = DefWindowProc16(hwnd, msg, wParam, lParam);
494 EDIT_ReleasePointer(wndPtr);
499 /*********************************************************************
503 * Build array of pointers to text lines.
504 * Lines can end with '\0' (last line), nothing (if it is too long),
505 * a delimiter (usually ' '), a soft return '\r\r\n' or a hard return '\r\n'
508 static void EDIT_BuildLineDefs(WND *wndPtr)
510 EDITSTATE *es = EDITSTATEPTR(wndPtr);
511 char *text = EDIT_GetPasswordPointer(wndPtr);
512 int ww = EDIT_GetWndWidth(wndPtr);
522 hdc = GetDC32(wndPtr->hwndSelf);
523 hFont = (HFONT16)EDIT_WM_GetFont(wndPtr, 0, 0L);
524 if (hFont) oldFont = SelectObject32(hdc, hFont);
526 if (!IsMultiLine(wndPtr)) {
528 es->LineDefs = xrealloc(es->LineDefs, sizeof(LINEDEF));
529 es->LineDefs[0].offset = 0;
530 es->LineDefs[0].length = EDIT_WM_GetTextLength(wndPtr, 0, 0L);
531 es->LineDefs[0].ending = END_0;
532 es->TextWidth = LOWORD(GetTabbedTextExtent(hdc, text,
533 es->LineDefs[0].length,
534 es->NumTabStops, es->TabStops));
539 if (!(cp = strstr(start, "\r\n"))) {
541 length = strlen(start);
542 } else if ((cp > start) && (*(cp - 1) == '\r')) {
544 length = cp - start - 1;
549 width = LOWORD(GetTabbedTextExtent(hdc, start, length,
550 es->NumTabStops, es->TabStops));
552 if (IsWordWrap(wndPtr) && (width > ww)) {
556 next = EDIT_CallWordBreakProc(wndPtr, start,
557 prev + 1, length, WB_RIGHT);
558 width = LOWORD(GetTabbedTextExtent(hdc, start, next,
559 es->NumTabStops, es->TabStops));
560 } while (width <= ww);
566 width = LOWORD(GetTabbedTextExtent(hdc, start, next,
567 es->NumTabStops, es->TabStops));
568 } while (width <= ww);
572 if (EDIT_CallWordBreakProc(wndPtr, start, length - 1,
573 length, WB_ISDELIMITER)) {
575 ending = END_DELIMIT;
578 width = LOWORD(GetTabbedTextExtent(hdc, start, length,
579 es->NumTabStops, es->TabStops));
582 es->LineDefs = xrealloc(es->LineDefs, (es->LineCount + 1) * sizeof(LINEDEF));
583 es->LineDefs[es->LineCount].offset = start - text;
584 es->LineDefs[es->LineCount].length = length;
585 es->LineDefs[es->LineCount].ending = ending;
587 es->TextWidth = MAX(es->TextWidth, width);
603 } while (*start || (ending == END_SOFT) || (ending == END_HARD));
605 if (hFont) SelectObject32(hdc, oldFont);
606 ReleaseDC32(wndPtr->hwndSelf, hdc);
612 /*********************************************************************
614 * EDIT_CallWordBreakProc
616 * Call appropriate WordBreakProc (internal or external).
619 static INT EDIT_CallWordBreakProc(WND *wndPtr, char *s, INT index, INT count, INT action)
621 EDITWORDBREAKPROC wbp = (EDITWORDBREAKPROC)EDIT_EM_GetWordBreakProc(wndPtr, 0, 0L);
623 if (!wbp) return EDIT_WordBreakProc(s, index, count, action);
626 /* We need a SEGPTR here */
628 EDITSTATE *es = EDITSTATEPTR(wndPtr);
629 SEGPTR ptr = LOCAL_LockSegptr( wndPtr->hInstance, es->hBuf ) +
630 (UINT16)(s - EDIT_GetPointer(wndPtr));
631 INT ret = CallWordBreakProc( (FARPROC16)wbp, ptr,
632 index, count, action);
633 LOCAL_Unlock( wndPtr->hInstance, es->hBuf );
639 /*********************************************************************
643 * Calculates, for a given line and X-coordinate on the screen, the column.
646 static UINT EDIT_ColFromWndX(WND *wndPtr, UINT line, INT x)
648 UINT lc = (UINT)EDIT_EM_GetLineCount(wndPtr, 0, 0L);
649 UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, line, 0L);
650 UINT ll = (UINT)EDIT_EM_LineLength(wndPtr, li, 0L);
653 line = MAX(0, MIN(line, lc - 1));
654 for (i = 0 ; i < ll ; i++)
655 if (EDIT_WndXFromCol(wndPtr, line, i) >= x)
661 /*********************************************************************
665 * Delete all characters on this line to right of cursor.
668 static void EDIT_DelEnd(WND *wndPtr)
670 EDIT_EM_SetSel(wndPtr, 1, MAKELPARAM(-1, 0));
671 EDIT_MoveEnd(wndPtr, TRUE);
672 EDIT_WM_Clear(wndPtr, 0, 0L);
676 /*********************************************************************
680 * Delete character to left of cursor.
683 static void EDIT_DelLeft(WND *wndPtr)
685 EDIT_EM_SetSel(wndPtr, 1, MAKELPARAM(-1, 0));
686 EDIT_MoveBackward(wndPtr, TRUE);
687 EDIT_WM_Clear(wndPtr, 0, 0L);
691 /*********************************************************************
695 * Delete character to right of cursor.
698 static void EDIT_DelRight(WND *wndPtr)
700 EDIT_EM_SetSel(wndPtr, 1, MAKELPARAM(-1, 0));
701 EDIT_MoveForward(wndPtr, TRUE);
702 EDIT_WM_Clear(wndPtr, 0, 0L);
706 /*********************************************************************
708 * EDIT_GetAveCharWidth
711 static UINT EDIT_GetAveCharWidth(WND *wndPtr)
713 EDITSTATE *es = EDITSTATEPTR(wndPtr);
715 return es->AveCharWidth;
719 /*********************************************************************
724 static UINT EDIT_GetLineHeight(WND *wndPtr)
726 EDITSTATE *es = EDITSTATEPTR(wndPtr);
728 return es->LineHeight;
732 /*********************************************************************
736 * Calculates the bounding rectangle for a line from a starting
737 * column to an ending column.
740 static void EDIT_GetLineRect(WND *wndPtr, UINT line, UINT scol, UINT ecol, LPRECT16 rc)
742 rc->top = EDIT_WndYFromLine(wndPtr, line);
743 rc->bottom = rc->top + EDIT_GetLineHeight(wndPtr);
744 rc->left = EDIT_WndXFromCol(wndPtr, line, scol);
745 rc->right = ((INT)ecol == -1) ? EDIT_GetWndWidth(wndPtr) :
746 EDIT_WndXFromCol(wndPtr, line, ecol);
750 /*********************************************************************
754 * This acts as a LOCAL_Lock(), but it locks only once. This way
755 * you can call it whenever you like, without unlocking.
758 static char *EDIT_GetPointer(WND *wndPtr)
760 EDITSTATE *es = EDITSTATEPTR(wndPtr);
762 if (!es->text && es->hBuf)
763 es->text = LOCAL_Lock(wndPtr->hInstance, es->hBuf);
768 /*********************************************************************
770 * EDIT_GetPasswordPointer
774 static char *EDIT_GetPasswordPointer(WND *wndPtr)
776 EDITSTATE *es = EDITSTATEPTR(wndPtr);
777 char *text = xstrdup(EDIT_GetPointer(wndPtr));
780 if(es->PasswordChar) {
783 if(*p != '\r' && *p != '\n')
784 *p = es->PasswordChar;
792 /*********************************************************************
796 * Beware: This is not the function called on EM_GETRECT.
797 * It expects a (LPRECT) in lParam, not a (SEGPTR).
798 * It is used internally, as if there were no pointer difficulties.
801 static LRESULT EDIT_GetRect(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
803 GetClientRect16( wndPtr->hwndSelf, (LPRECT16)lParam );
808 /*********************************************************************
813 static BOOL EDIT_GetRedraw(WND *wndPtr)
815 EDITSTATE *es = EDITSTATEPTR(wndPtr);
821 /*********************************************************************
825 * Beware: This is not the function called on EM_GETSEL.
826 * It returns the start in the low word and the end in the high word.
827 * NB s can be greater than e.
830 static LRESULT EDIT_GetSel(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
832 EDITSTATE *es = EDITSTATEPTR(wndPtr);
834 return MAKELONG(es->SelStart, es->SelEnd);
837 /*********************************************************************
842 static UINT EDIT_GetTextWidth(WND *wndPtr)
844 EDITSTATE *es = EDITSTATEPTR(wndPtr);
846 return es->TextWidth;
850 /*********************************************************************
852 * EDIT_GetVisibleLineCount
855 static UINT EDIT_GetVisibleLineCount(WND *wndPtr)
859 EDIT_GetRect(wndPtr, 0, (LPARAM)&rc);
860 return MAX(1, MAX(rc.bottom - rc.top, 0) / EDIT_GetLineHeight(wndPtr));
864 /*********************************************************************
869 static UINT EDIT_GetWndWidth(WND *wndPtr)
873 EDIT_GetRect(wndPtr, 0, (LPARAM)&rc);
874 return rc.right - rc.left;
878 /*********************************************************************
883 static UINT EDIT_GetXOffset(WND *wndPtr)
885 EDITSTATE *es = EDITSTATEPTR(wndPtr);
891 /*********************************************************************
893 * EDIT_InvalidateText
895 * Invalidate the text from offset start upto, but not including,
896 * offset end. Useful for (re)painting the selection.
897 * Regions outside the linewidth are not invalidated.
898 * end == -1 means end == TextLength.
899 * start and end need not be ordered.
902 static void EDIT_InvalidateText(WND *wndPtr, UINT start, UINT end)
904 UINT fv = (UINT)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L);
905 UINT vlc = EDIT_GetVisibleLineCount(wndPtr);
919 end = (UINT)EDIT_WM_GetTextLength(wndPtr, 0, 0L);
920 ORDER_UINT(start, end);
921 sl = (UINT)EDIT_EM_LineFromChar(wndPtr, start, 0L);
922 el = (UINT)EDIT_EM_LineFromChar(wndPtr, end, 0L);
923 if ((el < fv) || (sl > fv + vlc))
926 sc = start - (UINT)EDIT_EM_LineIndex(wndPtr, sl, 0L);
927 ec = end - (UINT)EDIT_EM_LineIndex(wndPtr, el, 0L);
934 ec = (UINT)EDIT_EM_LineLength(wndPtr,
935 (UINT)EDIT_EM_LineIndex(wndPtr, el, 0L), 0L);
937 EDIT_GetRect(wndPtr, 0, (LPARAM)&rcWnd);
939 EDIT_GetLineRect(wndPtr, sl, sc, ec, &rcLine);
940 if (IntersectRect16(&rcUpdate, &rcWnd, &rcLine))
941 InvalidateRect16( wndPtr->hwndSelf, &rcUpdate, FALSE );
943 EDIT_GetLineRect(wndPtr, sl, sc,
944 (UINT)EDIT_EM_LineLength(wndPtr,
945 (UINT)EDIT_EM_LineIndex(wndPtr, sl, 0L), 0L),
947 if (IntersectRect16(&rcUpdate, &rcWnd, &rcLine))
948 InvalidateRect16( wndPtr->hwndSelf, &rcUpdate, FALSE );
949 for (l = sl + 1 ; l < el ; l++) {
950 EDIT_GetLineRect(wndPtr, l, 0,
951 (UINT)EDIT_EM_LineLength(wndPtr,
952 (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L), 0L),
954 if (IntersectRect16(&rcUpdate, &rcWnd, &rcLine))
955 InvalidateRect16(wndPtr->hwndSelf, &rcUpdate, FALSE);
957 EDIT_GetLineRect(wndPtr, el, 0, ec, &rcLine);
958 if (IntersectRect16(&rcUpdate, &rcWnd, &rcLine))
959 InvalidateRect16( wndPtr->hwndSelf, &rcUpdate, FALSE );
964 /*********************************************************************
968 * Calculates, for a given Y-coordinate on the screen, the line.
971 static UINT EDIT_LineFromWndY(WND *wndPtr, INT y)
973 UINT fv = (UINT)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L);
974 UINT lh = EDIT_GetLineHeight(wndPtr);
975 UINT lc = (UINT)EDIT_EM_GetLineCount(wndPtr, 0, 0L);
977 return MAX(0, MIN(lc - 1, y / lh + fv));
981 /*********************************************************************
985 * Try to fit size + 1 bytes in the buffer. Constrain to limits.
988 static BOOL EDIT_MakeFit(WND *wndPtr, UINT size)
990 EDITSTATE *es = EDITSTATEPTR(wndPtr);
992 if (size <= es->BufSize)
994 if (size > es->BufLimit)
996 size = ((size / GROWLENGTH) + 1) * GROWLENGTH;
997 if (size > es->BufLimit)
1000 dprintf_edit(stddeb, "edit: EDIT_MakeFit: trying to ReAlloc to %d+1\n", size);
1002 if (LOCAL_ReAlloc(wndPtr->hInstance, es->hBuf, size + 1, LMEM_MOVEABLE)) {
1003 es->BufSize = MIN(LOCAL_Size(wndPtr->hInstance, es->hBuf) - 1, es->BufLimit);
1010 /*********************************************************************
1015 static void EDIT_MoveBackward(WND *wndPtr, BOOL extend)
1017 UINT s = LOWORD(EDIT_GetSel(wndPtr, 0, 0L));
1018 UINT e = HIWORD(EDIT_GetSel(wndPtr, 0, 0L));
1019 UINT l = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L);
1020 UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L);
1024 li = (UINT)EDIT_EM_LineIndex(wndPtr, l - 1, 0L);
1025 e = li + (UINT)EDIT_EM_LineLength(wndPtr, li, 0L);
1031 EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e));
1035 /*********************************************************************
1040 static void EDIT_MoveDownward(WND *wndPtr, BOOL extend)
1042 UINT s = LOWORD(EDIT_GetSel(wndPtr, 0, 0L));
1043 UINT e = HIWORD(EDIT_GetSel(wndPtr, 0, 0L));
1044 UINT l = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L);
1045 UINT lc = (UINT)EDIT_EM_GetLineCount(wndPtr, e, 0L);
1046 UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L);
1050 x = EDIT_WndXFromCol(wndPtr, l, e - li);
1052 e = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L) +
1053 EDIT_ColFromWndX(wndPtr, l, x);
1057 EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e));
1061 /*********************************************************************
1066 static void EDIT_MoveEnd(WND *wndPtr, BOOL extend)
1068 UINT s = LOWORD(EDIT_GetSel(wndPtr, 0, 0L));
1069 UINT e = HIWORD(EDIT_GetSel(wndPtr, 0, 0L));
1070 UINT l = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L);
1071 UINT ll = (UINT)EDIT_EM_LineLength(wndPtr, e, 0L);
1072 UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L);
1077 EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e));
1081 /*********************************************************************
1086 static void EDIT_MoveForward(WND *wndPtr, BOOL extend)
1088 UINT s = LOWORD(EDIT_GetSel(wndPtr, 0, 0L));
1089 UINT e = HIWORD(EDIT_GetSel(wndPtr, 0, 0L));
1090 UINT l = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L);
1091 UINT lc = (UINT)EDIT_EM_GetLineCount(wndPtr, e, 0L);
1092 UINT ll = (UINT)EDIT_EM_LineLength(wndPtr, e, 0L);
1093 UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L);
1097 e = (UINT)EDIT_EM_LineIndex(wndPtr, l + 1, 0L);
1102 EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e));
1106 /*********************************************************************
1110 * Home key: move to beginning of line.
1113 static void EDIT_MoveHome(WND *wndPtr, BOOL extend)
1115 UINT s = LOWORD(EDIT_GetSel(wndPtr, 0, 0L));
1116 UINT e = HIWORD(EDIT_GetSel(wndPtr, 0, 0L));
1117 UINT l = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L);
1118 UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L);
1123 EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e));
1127 /*********************************************************************
1132 static void EDIT_MovePageDown(WND *wndPtr, BOOL extend)
1134 UINT s = LOWORD(EDIT_GetSel(wndPtr, 0, 0L));
1135 UINT e = HIWORD(EDIT_GetSel(wndPtr, 0, 0L));
1136 UINT l = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L);
1137 UINT lc = (UINT)EDIT_EM_GetLineCount(wndPtr, e, 0L);
1138 UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L);
1142 x = EDIT_WndXFromCol(wndPtr, l, e - li);
1143 l = MIN(lc - 1, l + EDIT_GetVisibleLineCount(wndPtr));
1144 e = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L) +
1145 EDIT_ColFromWndX(wndPtr, l, x);
1149 EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e));
1153 /*********************************************************************
1158 static void EDIT_MovePageUp(WND *wndPtr, BOOL extend)
1160 UINT s = LOWORD(EDIT_GetSel(wndPtr, 0, 0L));
1161 UINT e = HIWORD(EDIT_GetSel(wndPtr, 0, 0L));
1162 UINT l = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L);
1163 UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L);
1167 x = EDIT_WndXFromCol(wndPtr, l, e - li);
1168 l = MAX(0, l - EDIT_GetVisibleLineCount(wndPtr));
1169 e = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L) +
1170 EDIT_ColFromWndX(wndPtr, l, x);
1174 EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e));
1178 /*********************************************************************
1183 static void EDIT_MoveUpward(WND *wndPtr, BOOL extend)
1185 UINT s = LOWORD(EDIT_GetSel(wndPtr, 0, 0L));
1186 UINT e = HIWORD(EDIT_GetSel(wndPtr, 0, 0L));
1187 UINT l = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L);
1188 UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L);
1192 x = EDIT_WndXFromCol(wndPtr, l, e - li);
1194 e = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L) +
1195 EDIT_ColFromWndX(wndPtr, l, x);
1199 EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e));
1203 /*********************************************************************
1205 * EDIT_MoveWordBackward
1208 static void EDIT_MoveWordBackward(WND *wndPtr, BOOL extend)
1210 UINT s = LOWORD(EDIT_GetSel(wndPtr, 0, 0L));
1211 UINT e = HIWORD(EDIT_GetSel(wndPtr, 0, 0L));
1212 UINT l = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L);
1213 UINT ll = (UINT)EDIT_EM_LineLength(wndPtr, e, 0L);
1214 UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L);
1219 li = (UINT)EDIT_EM_LineIndex(wndPtr, l - 1, 0L);
1220 e = li + (UINT)EDIT_EM_LineLength(wndPtr, li, 0L);
1223 text = EDIT_GetPointer(wndPtr);
1224 e = li + (UINT)EDIT_CallWordBreakProc(wndPtr,
1225 text + li, e - li, ll, WB_LEFT);
1229 EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e));
1233 /*********************************************************************
1235 * EDIT_MoveWordForward
1238 static void EDIT_MoveWordForward(WND *wndPtr, BOOL extend)
1240 UINT s = LOWORD(EDIT_GetSel(wndPtr, 0, 0L));
1241 UINT e = HIWORD(EDIT_GetSel(wndPtr, 0, 0L));
1242 UINT l = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L);
1243 UINT lc = (UINT)EDIT_EM_GetLineCount(wndPtr, e, 0L);
1244 UINT ll = (UINT)EDIT_EM_LineLength(wndPtr, e, 0L);
1245 UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L);
1250 e = (UINT)EDIT_EM_LineIndex(wndPtr, l + 1, 0L);
1252 text = EDIT_GetPointer(wndPtr);
1253 e = li + (UINT)EDIT_CallWordBreakProc(wndPtr,
1254 text + li, e - li + 1, ll, WB_RIGHT);
1258 EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e));
1262 /*********************************************************************
1267 static void EDIT_PaintLine(WND *wndPtr, HDC32 hdc, UINT line, BOOL rev)
1269 UINT fv = (UINT)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L);
1270 UINT vlc = EDIT_GetVisibleLineCount(wndPtr);
1271 UINT lc = (UINT)EDIT_EM_GetLineCount(wndPtr, 0, 0L);
1279 if ((line < fv) || (line > fv + vlc) || (line >= lc))
1282 dprintf_edit(stddeb, "edit: EDIT_PaintLine: line=%d\n", line);
1284 x = EDIT_WndXFromCol(wndPtr, line, 0);
1285 y = EDIT_WndYFromLine(wndPtr, line);
1286 li = (UINT)EDIT_EM_LineIndex(wndPtr, line, 0L);
1287 ll = (UINT)EDIT_EM_LineLength(wndPtr, li, 0L);
1288 s = LOWORD(EDIT_GetSel(wndPtr, 0, 0L));
1289 e = HIWORD(EDIT_GetSel(wndPtr, 0, 0L));
1291 s = MIN(li + ll, MAX(li, s));
1292 e = MIN(li + ll, MAX(li, e));
1293 if (rev && (s != e) &&
1294 ((GetFocus32() == wndPtr->hwndSelf) ||
1295 (wndPtr->dwStyle & ES_NOHIDESEL))) {
1296 x += EDIT_PaintText(wndPtr, hdc, x, y, line, 0, s - li, FALSE);
1297 x += EDIT_PaintText(wndPtr, hdc, x, y, line, s - li, e - s, TRUE);
1298 x += EDIT_PaintText(wndPtr, hdc, x, y, line, e - li, li + ll - e, FALSE);
1300 x += EDIT_PaintText(wndPtr, hdc, x, y, line, 0, ll, FALSE);
1304 /*********************************************************************
1309 static UINT EDIT_PaintText(WND *wndPtr, HDC32 hdc, INT x, INT y, UINT line, UINT col, UINT count, BOOL rev)
1311 EDITSTATE *es = EDITSTATEPTR(wndPtr);
1321 BkColor = GetBkColor(hdc);
1322 TextColor = GetTextColor(hdc);
1324 SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
1325 SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
1327 text = EDIT_GetPasswordPointer(wndPtr);
1328 li = (UINT)EDIT_EM_LineIndex(wndPtr, line, 0L);
1329 xoff = EDIT_GetXOffset(wndPtr);
1330 ret = LOWORD(TabbedTextOut(hdc, x, y, text + li + col, count,
1331 es->NumTabStops, es->TabStops, -xoff));
1334 SetBkColor(hdc, BkColor);
1335 SetTextColor(hdc, TextColor);
1341 /*********************************************************************
1343 * EDIT_ReleasePointer
1345 * This is the only helper function that can be called with es = NULL.
1346 * It is called at the end of EditWndProc() to unlock the buffer.
1349 static void EDIT_ReleasePointer(WND *wndPtr)
1351 EDITSTATE *es = EDITSTATEPTR(wndPtr);
1355 if (es->text && es->hBuf)
1356 LOCAL_Unlock(wndPtr->hInstance, es->hBuf);
1361 /*********************************************************************
1365 * Beware: This is not the function called on EM_REPLACESEL.
1366 * It expects a (char *) in lParam, not a (SEGPTR).
1367 * It is used internally, as if there were no pointer difficulties.
1370 static LRESULT EDIT_ReplaceSel(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1372 const char *str = (char *)lParam;
1373 int strl = strlen(str);
1374 UINT tl = (UINT)EDIT_WM_GetTextLength(wndPtr, 0, 0L);
1375 UINT s = LOWORD(EDIT_GetSel(wndPtr, 0, 0L));
1376 UINT e = HIWORD(EDIT_GetSel(wndPtr, 0, 0L));
1383 if (!EDIT_MakeFit(wndPtr, tl - (e - s) + strl)) {
1384 EDIT_NOTIFY_PARENT(wndPtr, EN_MAXTEXT);
1387 redraw = EDIT_GetRedraw(wndPtr);
1388 EDIT_WM_SetRedraw(wndPtr, FALSE, 0L);
1389 EDIT_WM_Clear(wndPtr, 0, 0L);
1390 tl = EDIT_WM_GetTextLength(wndPtr, 0, 0L);
1391 e = HIWORD(EDIT_GetSel(wndPtr, 0, 0L));
1392 text = EDIT_GetPointer(wndPtr);
1393 for (p = text + tl ; p >= text + e ; p--)
1395 for (i = 0 , p = text + e ; i < strl ; i++)
1398 AnsiUpperBuff(p, strl);
1399 else if(IsLower(wndPtr))
1400 AnsiLowerBuff(p, strl);
1401 EDIT_BuildLineDefs(wndPtr);
1403 EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(e, e));
1404 EDIT_EM_SetModify(wndPtr, TRUE, 0L);
1405 EDIT_NOTIFY_PARENT(wndPtr, EN_UPDATE);
1406 EDIT_WM_SetRedraw(wndPtr, redraw, 0L);
1408 InvalidateRect32( wndPtr->hwndSelf, NULL, TRUE );
1409 EDIT_NOTIFY_PARENT(wndPtr, EN_CHANGE);
1415 /*********************************************************************
1417 * EDIT_ScrollIntoView
1419 * Makes sure the caret is visible.
1422 static void EDIT_ScrollIntoView(WND *wndPtr)
1424 UINT e = HIWORD(EDIT_GetSel(wndPtr, 0, 0L));
1425 UINT l = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L);
1426 UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L);
1427 UINT fv = (UINT)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L);
1428 UINT vlc = EDIT_GetVisibleLineCount(wndPtr);
1429 UINT ww = EDIT_GetWndWidth(wndPtr);
1430 UINT cw = EDIT_GetAveCharWidth(wndPtr);
1431 INT x = EDIT_WndXFromCol(wndPtr, l, e - li);
1436 dy = l - vlc + 1 - fv;
1440 dx = x - ww / HSCROLL_FRACTION / cw * cw;
1442 dx = x - (HSCROLL_FRACTION - 1) * ww / HSCROLL_FRACTION / cw * cw;
1444 EDIT_EM_LineScroll(wndPtr, 0, MAKELPARAM(dy, dx));
1446 EDIT_NOTIFY_PARENT(wndPtr, EN_VSCROLL);
1448 EDIT_NOTIFY_PARENT(wndPtr, EN_HSCROLL);
1453 /*********************************************************************
1457 * Calculates, for a given line and column, the X-coordinate on the screen.
1460 static INT EDIT_WndXFromCol(WND *wndPtr, UINT line, UINT col)
1462 EDITSTATE *es = EDITSTATEPTR(wndPtr);
1463 char *text = EDIT_GetPasswordPointer(wndPtr);
1467 HFONT32 oldFont = 0;
1468 UINT lc = (UINT)EDIT_EM_GetLineCount(wndPtr, 0, 0L);
1469 UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, line, 0L);
1470 UINT ll = (UINT)EDIT_EM_LineLength(wndPtr, li, 0L);
1471 UINT xoff = EDIT_GetXOffset(wndPtr);
1473 hdc = GetDC32(wndPtr->hwndSelf);
1474 hFont = (HFONT16)EDIT_WM_GetFont(wndPtr, 0, 0L);
1475 if (hFont) oldFont = SelectObject32(hdc, hFont);
1476 line = MAX(0, MIN(line, lc - 1));
1478 ret = LOWORD(GetTabbedTextExtent(hdc,
1480 es->NumTabStops, es->TabStops)) - xoff;
1481 if (hFont) SelectObject32(hdc, oldFont);
1482 ReleaseDC32(wndPtr->hwndSelf, hdc);
1488 /*********************************************************************
1492 * Calculates, for a given line, the Y-coordinate on the screen.
1495 static INT EDIT_WndYFromLine(WND *wndPtr, UINT line)
1497 UINT fv = (UINT)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L);
1498 UINT lh = EDIT_GetLineHeight(wndPtr);
1500 return (line - fv) * lh;
1504 /*********************************************************************
1506 * EDIT_WordBreakProc
1508 * Find the beginning of words.
1509 * Note: unlike the specs for a WordBreakProc, this function only
1510 * allows to be called without linebreaks between s[0] upto
1511 * s[count - 1]. Remember it is only called
1512 * internally, so we can decide this for ourselves.
1515 static INT EDIT_WordBreakProc(char *s, INT index, INT count, INT action)
1519 dprintf_edit(stddeb, "edit: EDIT_WordBreakProc: s=%p, index=%d"
1520 ", count=%d, action=%d\n", s, index, count, action);
1528 if (s[index] == ' ') {
1529 while (index && (s[index] == ' '))
1532 while (index && (s[index] != ' '))
1534 if (s[index] == ' ')
1538 while (index && (s[index] != ' '))
1540 if (s[index] == ' ')
1550 if (s[index] == ' ')
1551 while ((index < count) && (s[index] == ' ')) index++;
1553 while (s[index] && (s[index] != ' ') && (index < count))
1555 while ((s[index] == ' ') && (index < count)) index++;
1559 case WB_ISDELIMITER:
1560 ret = (s[index] == ' ');
1563 fprintf(stderr, "edit: EDIT_WordBreakProc: unknown action code, please report !\n");
1570 /*********************************************************************
1575 static LRESULT EDIT_EM_CanUndo(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1581 /*********************************************************************
1583 * EM_EMPTYUNDOBUFFER
1586 static LRESULT EDIT_EM_EmptyUndoBuffer(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1592 /*********************************************************************
1597 static LRESULT EDIT_EM_FmtLines(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1599 fprintf(stdnimp, "edit: EM_FMTLINES: message not implemented.\n");
1600 return wParam ? -1L : 0L;
1604 /*********************************************************************
1606 * EM_GETFIRSTVISIBLELINE
1609 static LRESULT EDIT_EM_GetFirstVisibleLine(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1611 EDITSTATE *es = EDITSTATEPTR(wndPtr);
1613 return (LRESULT)es->FirstVisibleLine;
1617 /*********************************************************************
1622 static LRESULT EDIT_EM_GetHandle(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1624 EDITSTATE *es = EDITSTATEPTR(wndPtr);
1626 return (LRESULT)es->hBuf;
1630 /*********************************************************************
1635 static LRESULT EDIT_EM_GetLine(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1642 UINT lc = (UINT)EDIT_EM_GetLineCount(wndPtr, 0, 0L);
1644 if (!IsMultiLine(wndPtr))
1646 if ((UINT)wParam >= lc)
1648 text = EDIT_GetPointer(wndPtr);
1649 src = text + (UINT)EDIT_EM_LineIndex(wndPtr, wParam, 0L);
1650 dst = (char *)PTR_SEG_TO_LIN(lParam);
1651 len = MIN(*(WORD *)dst, (UINT)EDIT_EM_LineLength(wndPtr, wParam, 0L));
1652 for (i = 0 ; i < len ; i++) {
1657 return (LRESULT)len;
1661 /*********************************************************************
1666 static LRESULT EDIT_EM_GetLineCount(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1668 EDITSTATE *es = EDITSTATEPTR(wndPtr);
1670 return (LRESULT)es->LineCount;
1674 /*********************************************************************
1679 static LRESULT EDIT_EM_GetModify(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1681 EDITSTATE *es = EDITSTATEPTR(wndPtr);
1683 return (LRESULT)es->TextChanged;
1687 /*********************************************************************
1689 * EM_GETPASSWORDCHAR
1692 static LRESULT EDIT_EM_GetPasswordChar(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1694 EDITSTATE *es = EDITSTATEPTR(wndPtr);
1696 return (LRESULT)es->PasswordChar;
1700 /*********************************************************************
1705 static LRESULT EDIT_EM_GetRect(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1707 return EDIT_GetRect(wndPtr, wParam, (LPARAM)PTR_SEG_TO_LIN(lParam));
1711 /*********************************************************************
1715 * Returns the ordered selection range so that
1716 * LOWORD(result) < HIWORD(result)
1719 static LRESULT EDIT_EM_GetSel(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1721 UINT s = LOWORD(EDIT_GetSel(wndPtr, 0, 0L));
1722 UINT e = HIWORD(EDIT_GetSel(wndPtr, 0, 0L));
1725 return MAKELONG(s, e);
1729 /*********************************************************************
1733 * FIXME: undocumented: is this right ?
1736 static LRESULT EDIT_EM_GetThumb(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1738 return MAKELONG(EDIT_WM_VScroll(wndPtr, EM_GETTHUMB, 0L),
1739 EDIT_WM_HScroll(wndPtr, EM_GETTHUMB, 0L));
1743 /*********************************************************************
1745 * EM_GETWORDBREAKPROC
1748 static LRESULT EDIT_EM_GetWordBreakProc(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1750 EDITSTATE *es = EDITSTATEPTR(wndPtr);
1752 return (LRESULT)es->WordBreakProc;
1756 /*********************************************************************
1761 static LRESULT EDIT_EM_LimitText(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1763 EDITSTATE *es = EDITSTATEPTR(wndPtr);
1765 if (IsMultiLine(wndPtr)) {
1767 es->BufLimit = MIN((UINT)wParam, BUFLIMIT_MULTI);
1769 es->BufLimit = BUFLIMIT_MULTI;
1772 es->BufLimit = MIN((UINT)wParam, BUFLIMIT_SINGLE);
1774 es->BufLimit = BUFLIMIT_SINGLE;
1780 /*********************************************************************
1785 static LRESULT EDIT_EM_LineFromChar(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1789 if (!IsMultiLine(wndPtr))
1791 if ((INT)wParam == -1)
1792 wParam = HIWORD(EDIT_GetSel(wndPtr, 0, 0L));
1793 l = (UINT)EDIT_EM_GetLineCount(wndPtr, 0, 0L) - 1;
1794 while ((UINT)EDIT_EM_LineIndex(wndPtr, l, 0L) > (UINT)wParam)
1800 /*********************************************************************
1805 static LRESULT EDIT_EM_LineIndex(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1807 EDITSTATE *es = EDITSTATEPTR(wndPtr);
1810 UINT lc = (UINT)EDIT_EM_GetLineCount(wndPtr, 0, 0L);
1812 if ((INT)wParam == -1) {
1813 e = HIWORD(EDIT_GetSel(wndPtr, 0, 0L));
1815 while (es->LineDefs[l].offset > e)
1817 return (LRESULT)es->LineDefs[l].offset;
1819 if ((UINT)wParam >= lc)
1821 return (LRESULT)es->LineDefs[(UINT)wParam].offset;
1825 /*********************************************************************
1830 static LRESULT EDIT_EM_LineLength(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1832 EDITSTATE *es = EDITSTATEPTR(wndPtr);
1838 if (!IsMultiLine(wndPtr))
1839 return (LRESULT)es->LineDefs[0].length;
1840 if ((INT)wParam == -1) {
1841 s = LOWORD(EDIT_GetSel(wndPtr, 0, 0L));
1842 e = HIWORD(EDIT_GetSel(wndPtr, 0, 0L));
1843 sl = (UINT)EDIT_EM_LineFromChar(wndPtr, s, 0L);
1844 el = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L);
1845 return (LRESULT)(s - es->LineDefs[sl].offset +
1846 es->LineDefs[el].offset +
1847 es->LineDefs[el].length - e);
1849 return (LRESULT)es->LineDefs[(UINT)EDIT_EM_LineFromChar(wndPtr, wParam, 0L)].length;
1853 /*********************************************************************
1858 static LRESULT EDIT_EM_LineScroll(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1860 EDITSTATE *es = EDITSTATEPTR(wndPtr);
1861 UINT lc = (UINT)EDIT_EM_GetLineCount(wndPtr, 0, 0L);
1862 UINT fv = (UINT)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L);
1863 UINT nfv = MAX(0, fv + (INT)LOWORD(lParam));
1864 UINT xoff = EDIT_GetXOffset(wndPtr);
1865 UINT nxoff = MAX(0, xoff + (INT)HIWORD(lParam));
1866 UINT tw = EDIT_GetTextWidth(wndPtr);
1877 dy = EDIT_WndYFromLine(wndPtr, fv) - EDIT_WndYFromLine(wndPtr, nfv);
1879 if (wndPtr->hwndSelf == GetFocus32())
1880 HideCaret(wndPtr->hwndSelf);
1881 if (EDIT_GetRedraw(wndPtr))
1882 ScrollWindow(wndPtr->hwndSelf, dx, dy, NULL, NULL);
1883 es->FirstVisibleLine = nfv;
1884 es->XOffset = nxoff;
1885 if (IsVScrollBar(wndPtr))
1886 SetScrollPos32(wndPtr->hwndSelf, SB_VERT,
1887 EDIT_WM_VScroll(wndPtr, EM_GETTHUMB, 0L), TRUE);
1888 if (IsHScrollBar(wndPtr))
1889 SetScrollPos32(wndPtr->hwndSelf, SB_HORZ,
1890 EDIT_WM_HScroll(wndPtr, EM_GETTHUMB, 0L), TRUE);
1891 if (wndPtr->hwndSelf == GetFocus32()) {
1892 GetCaretPos16(&pos);
1893 SetCaretPos(pos.x + dx, pos.y + dy);
1894 ShowCaret(wndPtr->hwndSelf);
1901 /*********************************************************************
1906 static LRESULT EDIT_EM_ReplaceSel(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1908 return (LRESULT)EDIT_ReplaceSel(wndPtr, wParam,
1909 (LPARAM)(char *)PTR_SEG_TO_LIN(lParam));
1913 /*********************************************************************
1917 * FIXME: undocumented message.
1920 static LRESULT EDIT_EM_Scroll(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1922 fprintf(stdnimp, "edit: EM_SCROLL: message not implemented (undocumented), please report.\n");
1927 /*********************************************************************
1932 static LRESULT EDIT_EM_SetHandle(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1934 EDITSTATE *es = EDITSTATEPTR(wndPtr);
1936 if (IsMultiLine(wndPtr)) {
1937 EDIT_ReleasePointer(wndPtr);
1939 * old buffer is freed by caller
1941 es->hBuf = (HLOCAL16)wParam;
1942 es->BufSize = LOCAL_Size(wndPtr->hInstance, es->hBuf) - 1;
1944 es->FirstVisibleLine = 0;
1945 es->SelStart = es->SelEnd = 0;
1946 EDIT_EM_EmptyUndoBuffer(wndPtr, 0, 0L);
1947 EDIT_EM_SetModify(wndPtr, FALSE, 0L);
1948 EDIT_BuildLineDefs(wndPtr);
1949 if (EDIT_GetRedraw(wndPtr))
1950 InvalidateRect32( wndPtr->hwndSelf, NULL, TRUE );
1951 EDIT_ScrollIntoView(wndPtr);
1957 /*********************************************************************
1962 static LRESULT EDIT_EM_SetModify(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1964 EDITSTATE *es = EDITSTATEPTR(wndPtr);
1966 es->TextChanged = (BOOL)wParam;
1971 /*********************************************************************
1973 * EM_SETPASSWORDCHAR
1976 static LRESULT EDIT_EM_SetPasswordChar(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1978 EDITSTATE *es = EDITSTATEPTR(wndPtr);
1980 es->PasswordChar = (char)wParam;
1985 /*********************************************************************
1990 static LRESULT EDIT_EM_SetReadOnly(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1993 wndPtr->dwStyle |= ES_READONLY;
1995 wndPtr->dwStyle &= ~(DWORD)ES_READONLY;
2000 /*********************************************************************
2005 static LRESULT EDIT_EM_SetRect(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2007 fprintf(stdnimp,"edit: EM_SETRECT: message not implemented, please report.\n");
2012 /*********************************************************************
2017 static LRESULT EDIT_EM_SetRectNP(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2019 fprintf(stdnimp,"edit: EM_SETRECTNP: message not implemented, please report.\n");
2024 /*********************************************************************
2029 static LRESULT EDIT_EM_SetSel(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2031 EDITSTATE *es = EDITSTATEPTR(wndPtr);
2032 UINT ns = LOWORD(lParam);
2033 UINT ne = HIWORD(lParam);
2034 UINT s = LOWORD(EDIT_GetSel(wndPtr, 0, 0L));
2035 UINT e = HIWORD(EDIT_GetSel(wndPtr, 0, 0L));
2038 UINT tl = (UINT)EDIT_WM_GetTextLength(wndPtr, 0, 0L);
2040 if ((INT)ns == -1) {
2050 if (wndPtr->hwndSelf == GetFocus32()) {
2051 el = (UINT)EDIT_EM_LineFromChar(wndPtr, ne, 0L);
2052 eli = (UINT)EDIT_EM_LineIndex(wndPtr, el, 0L);
2053 SetCaretPos(EDIT_WndXFromCol(wndPtr, el, ne - eli),
2054 EDIT_WndYFromLine(wndPtr, el));
2057 EDIT_ScrollIntoView(wndPtr);
2058 if (EDIT_GetRedraw(wndPtr)) {
2066 EDIT_InvalidateText(wndPtr, s, e);
2067 EDIT_InvalidateText(wndPtr, ns, ne);
2069 EDIT_InvalidateText(wndPtr, s, ne);
2075 /*********************************************************************
2080 static LRESULT EDIT_EM_SetTabStops(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2082 EDITSTATE *es = EDITSTATEPTR(wndPtr);
2084 if (!IsMultiLine(wndPtr))
2088 es->NumTabStops = (UINT)wParam;
2090 es->TabStops = NULL;
2092 es->TabStops = (LPINT16)xmalloc(wParam * sizeof(INT16));
2093 memcpy(es->TabStops, (LPINT16)PTR_SEG_TO_LIN(lParam),
2094 (UINT)wParam * sizeof(INT16));
2100 /*********************************************************************
2102 * EM_SETWORDBREAKPROC
2105 static LRESULT EDIT_EM_SetWordBreakProc(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2107 EDITSTATE *es = EDITSTATEPTR(wndPtr);
2109 es->WordBreakProc = (EDITWORDBREAKPROC)lParam;
2114 /*********************************************************************
2119 static LRESULT EDIT_EM_Undo(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2125 /*********************************************************************
2130 static LRESULT EDIT_WM_Char(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2133 unsigned char c = (unsigned char)wParam;
2138 if (IsMultiLine(wndPtr)) {
2139 if (IsReadOnly(wndPtr)) {
2140 EDIT_MoveHome(wndPtr, FALSE);
2141 EDIT_MoveDownward(wndPtr, FALSE);
2143 EDIT_ReplaceSel(wndPtr, 0, (LPARAM)"\r\n");
2147 if (IsMultiLine(wndPtr) && !IsReadOnly(wndPtr))
2148 EDIT_ReplaceSel(wndPtr, 0, (LPARAM)"\t");
2151 if (!IsReadOnly(wndPtr) && (c >= ' ') && (c != 127)) {
2154 EDIT_ReplaceSel(wndPtr, 0, (LPARAM)str);
2162 /*********************************************************************
2167 static LRESULT EDIT_WM_Clear(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2169 UINT s = LOWORD(EDIT_GetSel(wndPtr, 0, 0L));
2170 UINT e = HIWORD(EDIT_GetSel(wndPtr, 0, 0L));
2175 redraw = EDIT_GetRedraw(wndPtr);
2176 EDIT_WM_SetRedraw(wndPtr, FALSE, 0L);
2178 text = EDIT_GetPointer(wndPtr);
2179 strcpy(text + s, text + e);
2180 EDIT_BuildLineDefs(wndPtr);
2181 EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, s));
2182 EDIT_EM_SetModify(wndPtr, TRUE, 0L);
2183 EDIT_NOTIFY_PARENT(wndPtr, EN_UPDATE);
2184 EDIT_WM_SetRedraw(wndPtr, redraw, 0L);
2186 InvalidateRect32( wndPtr->hwndSelf, NULL, TRUE );
2187 EDIT_NOTIFY_PARENT(wndPtr, EN_CHANGE);
2194 /*********************************************************************
2199 static LRESULT EDIT_WM_Copy(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2201 UINT s = LOWORD(EDIT_GetSel(wndPtr, 0, 0L));
2202 UINT e = HIWORD(EDIT_GetSel(wndPtr, 0, 0L));
2212 hdst = GlobalAlloc16(GMEM_MOVEABLE, (DWORD)(e - s + 1));
2213 dst = GlobalLock16(hdst);
2214 text = EDIT_GetPointer(wndPtr);
2216 for (i = 0 ; i < e - s ; i++)
2219 GlobalUnlock16(hdst);
2220 OpenClipboard(wndPtr->hwndSelf);
2222 SetClipboardData(CF_TEXT, hdst);
2228 /*********************************************************************
2233 static LRESULT EDIT_WM_Create(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2235 CREATESTRUCT16 *cs = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam);
2239 es = xmalloc(sizeof(EDITSTATE));
2240 memset(es, 0, sizeof(EDITSTATE));
2241 *(EDITSTATE **)wndPtr->wExtra = es;
2243 if (cs->style & WS_VSCROLL)
2244 cs->style |= ES_AUTOVSCROLL;
2245 if (cs->style & WS_HSCROLL)
2246 cs->style |= ES_AUTOHSCROLL;
2248 /* remove the WS_CAPTION style if it has been set - this is really a */
2249 /* pseudo option made from a combination of WS_BORDER and WS_DLGFRAME */
2250 if ((cs->style & WS_BORDER) && (cs->style & WS_DLGFRAME))
2251 cs->style ^= WS_DLGFRAME;
2253 if (IsMultiLine(wndPtr)) {
2254 es->BufSize = BUFSTART_MULTI;
2255 es->BufLimit = BUFLIMIT_MULTI;
2256 es->PasswordChar = '\0';
2258 es->BufSize = BUFSTART_SINGLE;
2259 es->BufLimit = BUFLIMIT_SINGLE;
2260 es->PasswordChar = (cs->style & ES_PASSWORD) ? '*' : '\0';
2262 if (!LOCAL_HeapSize(wndPtr->hInstance)) {
2263 if (!LocalInit(wndPtr->hInstance, 0,
2264 GlobalSize16(wndPtr->hInstance))) {
2265 fprintf(stderr, "edit: WM_CREATE: could not initialize local heap\n");
2268 dprintf_edit(stddeb, "edit: WM_CREATE: local heap initialized\n");
2270 if (!(es->hBuf = LOCAL_Alloc(wndPtr->hInstance, LMEM_MOVEABLE, es->BufSize + 1))) {
2271 fprintf(stderr, "edit: WM_CREATE: unable to allocate buffer\n");
2274 es->BufSize = LOCAL_Size(wndPtr->hInstance, es->hBuf) - 1;
2275 text = EDIT_GetPointer(wndPtr);
2277 EDIT_BuildLineDefs(wndPtr);
2278 EDIT_WM_SetFont(wndPtr, 0, 0L);
2279 if (cs->lpszName && *(char *)PTR_SEG_TO_LIN(cs->lpszName) != '\0')
2280 EDIT_EM_ReplaceSel(wndPtr, FALSE, (LPARAM)cs->lpszName);
2281 EDIT_WM_SetRedraw(wndPtr, TRUE, 0L);
2286 /*********************************************************************
2291 static LRESULT EDIT_WM_Cut(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2293 EDIT_WM_Copy(wndPtr, 0, 0L);
2294 EDIT_WM_Clear(wndPtr, 0, 0L);
2299 /*********************************************************************
2304 static LRESULT EDIT_WM_Destroy(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2306 EDITSTATE *es = EDITSTATEPTR(wndPtr);
2311 EDIT_ReleasePointer(wndPtr);
2312 LOCAL_Free(wndPtr->hInstance, es->hBuf);
2314 *(EDITSTATE **)&wndPtr->wExtra = NULL;
2319 /*********************************************************************
2324 static LRESULT EDIT_WM_Enable(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2326 EDIT_InvalidateText(wndPtr, 0, -1);
2331 /*********************************************************************
2336 static LRESULT EDIT_WM_EraseBkGnd(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2341 hBrush = (HBRUSH16)EDIT_SEND_CTLCOLOR(wndPtr, wParam);
2342 if (!hBrush) hBrush = (HBRUSH32)GetStockObject32(WHITE_BRUSH);
2344 GetClientRect16(wndPtr->hwndSelf, &rc);
2345 IntersectClipRect16( (HDC16)wParam, rc.left, rc.top,
2346 rc.right, rc.bottom);
2347 GetClipBox16((HDC16)wParam, &rc);
2349 * FIXME: specs say that we should UnrealizeObject() the brush,
2350 * but the specs of UnrealizeObject() say that we shouldn't
2351 * unrealize a stock object. The default brush that
2352 * DefWndProc() returns is ... a stock object.
2354 FillRect16((HDC16)wParam, &rc, hBrush);
2359 /*********************************************************************
2364 static LRESULT EDIT_WM_GetDlgCode(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2366 return DLGC_HASSETSEL | DLGC_WANTCHARS | DLGC_WANTARROWS;
2370 /*********************************************************************
2375 static LRESULT EDIT_WM_GetFont(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2377 EDITSTATE *es = EDITSTATEPTR(wndPtr);
2379 return (LRESULT)es->hFont;
2383 /*********************************************************************
2388 static LRESULT EDIT_WM_GetText(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2390 char *text = EDIT_GetPointer(wndPtr);
2392 LRESULT lResult = 0L;
2395 if ((UINT)wParam > len) {
2396 strcpy((char *)PTR_SEG_TO_LIN(lParam), text);
2397 lResult = (LRESULT)len ;
2403 /*********************************************************************
2408 static LRESULT EDIT_WM_GetTextLength(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2410 char *text = EDIT_GetPointer(wndPtr);
2412 return (LRESULT)strlen(text);
2416 /*********************************************************************
2420 * FIXME: scrollbar code itself is broken, so this one is a hack.
2423 static LRESULT EDIT_WM_HScroll(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2425 UINT ww = EDIT_GetWndWidth(wndPtr);
2426 UINT tw = EDIT_GetTextWidth(wndPtr);
2427 UINT cw = EDIT_GetAveCharWidth(wndPtr);
2428 UINT xoff = EDIT_GetXOffset(wndPtr);
2441 dx = -ww / HSCROLL_FRACTION / cw * cw;
2444 dx = ww / HSCROLL_FRACTION / cw * cw;
2456 case SB_THUMBPOSITION:
2457 dx = LOWORD(lParam) * tw / 100 - xoff;
2459 /* The next two are undocumented ! */
2461 ret = tw ? MAKELONG(xoff * 100 / tw, 0) : 0;
2464 dx = LOWORD(lParam);
2471 EDIT_EM_LineScroll(wndPtr, 0, MAKELPARAM(0, dx));
2473 EDIT_NOTIFY_PARENT(wndPtr, EN_HSCROLL);
2479 /*********************************************************************
2483 * Handling of special keys that don't produce a WM_CHAR
2484 * (i.e. non-printable keys) & Backspace & Delete
2487 static LRESULT EDIT_WM_KeyDown(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2489 UINT s = LOWORD(EDIT_GetSel(wndPtr, 0, 0L));
2490 UINT e = HIWORD(EDIT_GetSel(wndPtr, 0, 0L));
2494 if (GetKeyState(VK_MENU) & 0x8000)
2497 shift = GetKeyState(VK_SHIFT) & 0x8000;
2498 control = GetKeyState(VK_CONTROL) & 0x8000;
2503 if (IsMultiLine(wndPtr) && (wParam == VK_UP))
2504 EDIT_MoveUpward(wndPtr, shift);
2507 EDIT_MoveWordBackward(wndPtr, shift);
2509 EDIT_MoveBackward(wndPtr, shift);
2513 if (IsMultiLine(wndPtr) && (wParam == VK_DOWN))
2514 EDIT_MoveDownward(wndPtr, shift);
2516 EDIT_MoveWordForward(wndPtr, shift);
2518 EDIT_MoveForward(wndPtr, shift);
2521 EDIT_MoveHome(wndPtr, shift);
2524 EDIT_MoveEnd(wndPtr, shift);
2527 if (IsMultiLine(wndPtr))
2528 EDIT_MovePageUp(wndPtr, shift);
2531 if (IsMultiLine(wndPtr))
2532 EDIT_MovePageDown(wndPtr, shift);
2535 if (!IsReadOnly(wndPtr) && !control)
2537 EDIT_WM_Clear(wndPtr, 0, 0L);
2539 EDIT_DelLeft(wndPtr);
2542 if (!IsReadOnly(wndPtr) && !(shift && control))
2545 EDIT_WM_Cut(wndPtr, 0, 0L);
2547 EDIT_WM_Clear(wndPtr, 0, 0L);
2550 EDIT_DelLeft(wndPtr);
2552 EDIT_DelEnd(wndPtr);
2554 EDIT_DelRight(wndPtr);
2559 if (!IsReadOnly(wndPtr))
2560 EDIT_WM_Paste(wndPtr, 0, 0L);
2562 EDIT_WM_Copy(wndPtr, 0, 0L);
2569 /*********************************************************************
2574 static LRESULT EDIT_WM_KillFocus(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2580 if(!(wndPtr->dwStyle & ES_NOHIDESEL)) {
2581 s = LOWORD(EDIT_GetSel(wndPtr, 0, 0L));
2582 e = HIWORD(EDIT_GetSel(wndPtr, 0, 0L));
2583 EDIT_InvalidateText(wndPtr, s, e);
2585 EDIT_NOTIFY_PARENT(wndPtr, EN_KILLFOCUS);
2590 /*********************************************************************
2594 * The caret position has been set on the WM_LBUTTONDOWN message
2597 static LRESULT EDIT_WM_LButtonDblClk(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2600 UINT e = HIWORD(EDIT_GetSel(wndPtr, 0, 0L));
2601 UINT l = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L);
2602 UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L);
2603 UINT ll = (UINT)EDIT_EM_LineLength(wndPtr, e, 0L);
2604 char *text = EDIT_GetPointer(wndPtr);
2606 s = li + EDIT_CallWordBreakProc (wndPtr, text + li, e - li, ll, WB_LEFT);
2607 e = li + EDIT_CallWordBreakProc(wndPtr, text + li, e - li, ll, WB_RIGHT);
2608 EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e));
2613 /*********************************************************************
2618 static LRESULT EDIT_WM_LButtonDown(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2620 INT x = (INT)LOWORD(lParam);
2621 INT y = (INT)HIWORD(lParam);
2622 UINT l = EDIT_LineFromWndY(wndPtr, y);
2626 UINT fv = (UINT)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L);
2627 UINT vlc = EDIT_GetVisibleLineCount(wndPtr);
2630 SetFocus32(wndPtr->hwndSelf);
2631 SetCapture32(wndPtr->hwndSelf);
2632 l = MIN(fv + vlc - 1, MAX(fv, l));
2633 x = MIN(EDIT_GetWndWidth(wndPtr), MAX(0, x));
2634 c = EDIT_ColFromWndX(wndPtr, l, x);
2635 li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L);
2637 if (GetKeyState(VK_SHIFT) & 0x8000)
2638 s = LOWORD(EDIT_GetSel(wndPtr, 0, 0L));
2641 EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e));
2646 /*********************************************************************
2651 static LRESULT EDIT_WM_LButtonUp(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2653 if (GetCapture32() == wndPtr->hwndSelf)
2659 /*********************************************************************
2664 static LRESULT EDIT_WM_MouseMove(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2675 if (GetCapture32() == wndPtr->hwndSelf) {
2676 x = (INT)LOWORD(lParam);
2677 y = (INT)HIWORD(lParam);
2678 fv = (UINT)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L);
2679 vlc = EDIT_GetVisibleLineCount(wndPtr);
2680 l = EDIT_LineFromWndY(wndPtr, y);
2681 l = MIN(fv + vlc - 1, MAX(fv, l));
2682 x = MIN(EDIT_GetWndWidth(wndPtr), MAX(0, x));
2683 c = EDIT_ColFromWndX(wndPtr, l, x);
2684 s = LOWORD(EDIT_GetSel(wndPtr, 0, 0L));
2685 li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L);
2686 EDIT_EM_SetSel(wndPtr, 1, MAKELPARAM(s, li + c));
2692 /*********************************************************************
2697 static LRESULT EDIT_WM_Paint(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2701 UINT fv = (UINT)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L);
2702 UINT vlc = EDIT_GetVisibleLineCount(wndPtr);
2703 UINT lc = (UINT)EDIT_EM_GetLineCount(wndPtr, 0, 0L);
2706 HFONT32 oldFont = 0;
2710 BOOL rev = IsWindowEnabled(wndPtr->hwndSelf) &&
2711 ((GetFocus32() == wndPtr->hwndSelf) ||
2712 (wndPtr->dwStyle & ES_NOHIDESEL));
2714 hdc = BeginPaint16(wndPtr->hwndSelf, &ps);
2715 GetClientRect16(wndPtr->hwndSelf, &rc);
2716 IntersectClipRect16( hdc, rc.left, rc.top, rc.right, rc.bottom );
2717 hFont = EDIT_WM_GetFont(wndPtr, 0, 0L);
2718 if (hFont) oldFont = SelectObject32(hdc, hFont);
2719 EDIT_SEND_CTLCOLOR(wndPtr, hdc);
2720 if (!IsWindowEnabled(wndPtr->hwndSelf))
2721 SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT));
2722 GetClipBox16(hdc, &rcRgn);
2723 for (i = fv ; i <= MIN(fv + vlc, fv + lc - 1) ; i++ ) {
2724 EDIT_GetLineRect(wndPtr, i, 0, -1, &rcLine);
2725 if (IntersectRect16(&rc, &rcRgn, &rcLine))
2726 EDIT_PaintLine(wndPtr, hdc, i, rev);
2728 if (hFont) SelectObject32(hdc, oldFont);
2729 EndPaint16(wndPtr->hwndSelf, &ps);
2734 /*********************************************************************
2739 static LRESULT EDIT_WM_Paste(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2744 OpenClipboard(wndPtr->hwndSelf);
2745 if ((hsrc = GetClipboardData(CF_TEXT))) {
2746 src = (char *)GlobalLock16(hsrc);
2747 EDIT_ReplaceSel(wndPtr, 0, (LPARAM)src);
2748 GlobalUnlock16(hsrc);
2755 /*********************************************************************
2760 static LRESULT EDIT_WM_SetCursor(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2762 if (LOWORD(lParam) == HTCLIENT) {
2763 SetCursor(LoadCursor16(0, IDC_IBEAM));
2770 /*********************************************************************
2775 static LRESULT EDIT_WM_SetFocus(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2777 UINT s = LOWORD(EDIT_GetSel(wndPtr, 0, 0L));
2778 UINT e = HIWORD(EDIT_GetSel(wndPtr, 0, 0L));
2780 CreateCaret(wndPtr->hwndSelf, 0, 2, EDIT_GetLineHeight(wndPtr));
2781 EDIT_EM_SetSel(wndPtr, 1, MAKELPARAM(s, e));
2782 if(!(wndPtr->dwStyle & ES_NOHIDESEL))
2783 EDIT_InvalidateText(wndPtr, s, e);
2784 ShowCaret(wndPtr->hwndSelf);
2785 EDIT_NOTIFY_PARENT(wndPtr, EN_SETFOCUS);
2790 /*********************************************************************
2795 static LRESULT EDIT_WM_SetFont(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2798 EDITSTATE *es = EDITSTATEPTR(wndPtr);
2799 LPARAM sel = EDIT_GetSel(wndPtr, 0, 0L);
2801 HFONT32 oldFont = 0;
2803 es->hFont = (HFONT16)wParam;
2804 hdc = GetDC32(wndPtr->hwndSelf);
2805 if (es->hFont) oldFont = SelectObject32(hdc, es->hFont);
2806 GetTextMetrics16(hdc, &tm);
2807 es->LineHeight = HIWORD(GetTextExtent(hdc, "X", 1));
2808 es->AveCharWidth = tm.tmAveCharWidth;
2809 if (es->hFont) SelectObject32(hdc, oldFont);
2810 ReleaseDC32(wndPtr->hwndSelf, hdc);
2811 EDIT_BuildLineDefs(wndPtr);
2812 if ((BOOL)lParam && EDIT_GetRedraw(wndPtr))
2813 InvalidateRect32( wndPtr->hwndSelf, NULL, TRUE );
2814 if (wndPtr->hwndSelf == GetFocus32()) {
2816 CreateCaret(wndPtr->hwndSelf, 0, 2, EDIT_GetLineHeight(wndPtr));
2817 EDIT_EM_SetSel(wndPtr, 1, sel);
2818 ShowCaret(wndPtr->hwndSelf);
2824 /*********************************************************************
2829 static LRESULT EDIT_WM_SetRedraw(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2831 EDITSTATE *es = EDITSTATEPTR(wndPtr);
2833 es->Redraw = (BOOL)wParam;
2838 /*********************************************************************
2843 static LRESULT EDIT_WM_SetText(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2845 EDIT_EM_SetSel(wndPtr, 1, MAKELPARAM(0, -1));
2846 EDIT_WM_Clear(wndPtr, 0, 0L);
2848 EDIT_EM_ReplaceSel(wndPtr, 0, lParam);
2849 EDIT_EM_EmptyUndoBuffer(wndPtr, 0, 0L);
2850 EDIT_EM_SetModify(wndPtr, TRUE, 0L);
2851 EDIT_ScrollIntoView(wndPtr);
2856 /*********************************************************************
2861 static LRESULT EDIT_WM_Size(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2863 if (EDIT_GetRedraw(wndPtr) &&
2864 ((wParam == SIZE_MAXIMIZED) ||
2865 (wParam == SIZE_RESTORED))) {
2866 if (IsMultiLine(wndPtr) && IsWordWrap(wndPtr))
2867 EDIT_BuildLineDefs(wndPtr);
2868 InvalidateRect32( wndPtr->hwndSelf, NULL, TRUE );
2874 /*********************************************************************
2878 * FIXME: scrollbar code itself is broken, so this one is a hack.
2881 static LRESULT EDIT_WM_VScroll(WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2883 UINT lc = (UINT)EDIT_EM_GetLineCount(wndPtr, 0, 0L);
2884 UINT fv = (UINT)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L);
2885 UINT vlc = EDIT_GetVisibleLineCount(wndPtr);
2913 case SB_THUMBPOSITION:
2914 dy = LOWORD(lParam) * (lc - 1) / 100 - fv;
2916 /* The next two are undocumented ! */
2918 ret = (lc > 1) ? MAKELONG(fv * 100 / (lc - 1), 0) : 0L;
2921 dy = LOWORD(lParam);
2928 EDIT_EM_LineScroll(wndPtr, 0, MAKELPARAM(dy, 0));
2930 EDIT_NOTIFY_PARENT(wndPtr, EN_VSCROLL);