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.
32 #define BUFLIMIT_MULTI 65534 /* maximum text buffer length (not including '\0') */
33 /* FIXME: BTW, new specs say 65535 (do you dare ???) */
34 #define BUFLIMIT_SINGLE 32766
35 #define BUFSTART_MULTI 1024 /* starting length for multi-line control */
36 #define BUFSTART_SINGLE 256 /* starting length for single line control */
37 #define GROWLENGTH 64 /* buffers grow by this much */
38 #define HSCROLL_FRACTION 3 /* scroll window by 1/3 width */
40 #define EF_TEXTCHANGED 0x0001
41 #define EF_FOCUSED 0x0002
60 HLOCAL16 hBuf16
; /* For when a 16-bit multiline edit
61 * control gets a EM_GETHANDLE (which
62 * should return 16-bit local heap).
63 * From that point on we _have_ to keep
64 * using 16-bit local heap (apps rely
65 * on that ... bummer).
67 HLOCAL32 hBuf32
; /* Don't worry about 'LOCAL'. LOCAL32 is
68 * identical to GLOBAL32, which is
69 * essentially a HANDLE32 created with
70 * HeapAlloc(GetProcessHeap(), ...) plus
71 * a global32 (and thus local32)
72 * descriptor, which we can return upon
74 * It is 32-bit linear addressing, so
77 LPSTR text
; /* Depending on the fact that we are a
78 * 16 or 32 bit control, this is the
79 * pointer that we get after
80 * LocalLock32(hBuf23) (which is a typecast :-)
81 * or LOCAL_Lock(hBuf16).
82 * This is always a 32-bit linear pointer.
85 LINEDEF
*LineDefs
; /* Internal table for (soft) linebreaks */
86 INT32 TextWidth
; /* width of the widest line in pixels */
87 INT32 XOffset
; /* offset of the viewport in pixels */
88 INT32 FirstVisibleLine
;
90 INT32 LineHeight
; /* height of a screen line in pixels */
91 INT32 AveCharWidth
; /* average character width in pixels */
94 UINT32 eState
; /* EF flags */
100 INT32 SelStart
; /* offset of selection start, == SelEnd if no selection */
101 INT32 SelEnd
; /* offset of selection end == current caret position */
105 * FIXME: The following should probably be a (VOID *) that is
106 * typecast to either 16- or 32-bit callback when used,
107 * depending on the type of edit control (16 or 32 bit).
109 * EDITWORDBREAKPROC WordBreakProc;
111 * For now: no more application specific wordbreaking.
112 * (Internal wordbreak function still works)
121 #define SWAP_INT32(x,y) do { INT32 temp = (INT32)(x); (x) = (INT32)(y); (y) = temp; } while(0)
122 #define ORDER_INT32(x,y) do { if ((INT32)(y) < (INT32)(x)) SWAP_INT32((x),(y)); } while(0)
124 /* macros to access window styles */
125 #define IsMultiLine(wndPtr) ((wndPtr)->dwStyle & ES_MULTILINE)
126 #define IsVScrollBar(wndPtr) ((wndPtr)->dwStyle & WS_VSCROLL)
127 #define IsHScrollBar(wndPtr) ((wndPtr)->dwStyle & WS_HSCROLL)
128 #define IsReadOnly(wndPtr) ((wndPtr)->dwStyle & ES_READONLY)
129 #define IsWordWrap(wndPtr) (((wndPtr)->dwStyle & ES_AUTOHSCROLL) == 0)
130 #define IsPassword(wndPtr) ((wndPtr)->dwStyle & ES_PASSWORD)
131 #define IsLower(wndPtr) ((wndPtr)->dwStyle & ES_LOWERCASE)
132 #define IsUpper(wndPtr) ((wndPtr)->dwStyle & ES_UPPERCASE)
133 #define IsNoRedraw(wndPtr) ((wndPtr)->flags & WIN_NO_REDRAW)
135 #define EDITSTATEPTR(wndPtr) (*(EDITSTATE **)((wndPtr)->wExtra))
137 #define EDIT_SEND_CTLCOLOR(wndPtr,hdc) \
138 (SendMessage32A((wndPtr)->parent->hwndSelf, WM_CTLCOLOREDIT, \
139 (WPARAM32)(hdc), (LPARAM)(wndPtr)->hwndSelf ))
140 #define EDIT_NOTIFY_PARENT(wndPtr, wNotifyCode) \
141 (SendMessage32A((wndPtr)->parent->hwndSelf, WM_COMMAND, \
142 MAKEWPARAM((wndPtr)->wIDmenu, wNotifyCode), \
143 (LPARAM)(wndPtr)->hwndSelf ))
144 #define DPRINTF_EDIT_MSG16(str) \
145 dprintf_edit(stddeb, \
146 "edit: 16 bit : " str ": hwnd=%08x, wParam=%08x, lParam=%08x\n", \
147 (UINT32)hwnd, (UINT32)wParam, (UINT32)lParam)
148 #define DPRINTF_EDIT_MSG32(str) \
149 dprintf_edit(stddeb, \
150 "edit: 32 bit : " str ": hwnd=%08x, wParam=%08x, lParam=%08x\n", \
151 (UINT32)hwnd, (UINT32)wParam, (UINT32)lParam)
153 /*********************************************************************
157 * Files like these should really be kept in alphabetical order.
160 LRESULT
EditWndProc(HWND32 hwnd
, UINT32 msg
, WPARAM32 wParam
, LPARAM lParam
);
162 static void EDIT_BuildLineDefs(WND
*wndPtr
);
163 static INT32
EDIT_CallWordBreakProc(WND
*wndPtr
, LPSTR s
, INT32 index
, INT32 count
, INT32 action
);
164 static INT32
EDIT_ColFromWndX(WND
*wndPtr
, INT32 line
, INT32 x
);
165 static void EDIT_DelEnd(WND
*wndPtr
);
166 static void EDIT_DelLeft(WND
*wndPtr
);
167 static void EDIT_DelRight(WND
*wndPtr
);
168 static INT32
EDIT_GetAveCharWidth(WND
*wndPtr
);
169 static INT32
EDIT_GetLineHeight(WND
*wndPtr
);
170 static void EDIT_GetLineRect(WND
*wndPtr
, INT32 line
, INT32 scol
, INT32 ecol
, LPRECT32 rc
);
171 static LPSTR
EDIT_GetPointer(WND
*wndPtr
);
172 static LPSTR
EDIT_GetPasswordPointer(WND
*wndPtr
);
173 static void EDIT_GetSel(WND
*wndPtr
, LPINT32 s
, LPINT32 e
);
174 static INT32
EDIT_GetTextWidth(WND
*wndPtr
);
175 static LPSTR
EDIT_GetUndoPointer(WND
*wndPtr
);
176 static INT32
EDIT_GetVisibleLineCount(WND
*wndPtr
);
177 static INT32
EDIT_GetWndWidth(WND
*wndPtr
);
178 static INT32
EDIT_GetXOffset(WND
*wndPtr
);
179 static void EDIT_InvalidateText(WND
*wndPtr
, INT32 start
, INT32 end
);
180 static INT32
EDIT_LineFromWndY(WND
*wndPtr
, INT32 y
);
181 static BOOL32
EDIT_MakeFit(WND
*wndPtr
, INT32 size
);
182 static BOOL32
EDIT_MakeUndoFit(WND
*wndPtr
, INT32 size
);
183 static void EDIT_MoveBackward(WND
*wndPtr
, BOOL32 extend
);
184 static void EDIT_MoveDownward(WND
*wndPtr
, BOOL32 extend
);
185 static void EDIT_MoveEnd(WND
*wndPtr
, BOOL32 extend
);
186 static void EDIT_MoveForward(WND
*wndPtr
, BOOL32 extend
);
187 static void EDIT_MoveHome(WND
*wndPtr
, BOOL32 extend
);
188 static void EDIT_MovePageDown(WND
*wndPtr
, BOOL32 extend
);
189 static void EDIT_MovePageUp(WND
*wndPtr
, BOOL32 extend
);
190 static void EDIT_MoveUpward(WND
*wndPtr
, BOOL32 extend
);
191 static void EDIT_MoveWordBackward(WND
*wndPtr
, BOOL32 extend
);
192 static void EDIT_MoveWordForward(WND
*wndPtr
, BOOL32 extend
);
193 static void EDIT_PaintLine(WND
*wndPtr
, HDC32 hdc
, INT32 line
, BOOL32 rev
);
194 static INT32
EDIT_PaintText(WND
*wndPtr
, HDC32 hdc
, INT32 x
, INT32 y
, INT32 line
, INT32 col
, INT32 count
, BOOL32 rev
);
195 static void EDIT_ReleasePointer(WND
*wndPtr
);
196 static void EDIT_ReleaseUndoPointer(WND
*wndPtr
);
197 static void EDIT_SetSel(WND
*wndPtr
, INT32 ns
, INT32 ne
);
198 static INT32
EDIT_WndXFromCol(WND
*wndPtr
, INT32 line
, INT32 col
);
199 static INT32
EDIT_WndYFromLine(WND
*wndPtr
, INT32 line
);
200 static INT32
EDIT_WordBreakProc(LPSTR s
, INT32 index
, INT32 count
, INT32 action
);
202 static LRESULT
EDIT_EM_CanUndo(WND
*wndPtr
);
203 static LRESULT
EDIT_EM_CharFromPos(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
204 static LRESULT
EDIT_EM_EmptyUndoBuffer(WND
*wndPtr
);
205 static LRESULT
EDIT_EM_FmtLines(WND
*wndPtr
, WPARAM32 wParam
);
206 static LRESULT
EDIT_EM_GetFirstVisibleLine(WND
*wndPtr
);
207 static LRESULT
EDIT_EM_GetHandle(WND
*wndPtr
);
208 static LRESULT
EDIT_EM_GetHandle16(WND
*wndPtr
);
209 static LRESULT
EDIT_EM_GetLimitText(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
210 static LRESULT
EDIT_EM_GetLine(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
211 static LRESULT
EDIT_EM_GetLineCount(WND
*wndPtr
);
212 static LRESULT
EDIT_EM_GetMargins(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
213 static LRESULT
EDIT_EM_GetModify(WND
*wndPtr
);
214 static LRESULT
EDIT_EM_GetPasswordChar(WND
*wndPtr
);
215 static LRESULT
EDIT_EM_GetRect(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
216 static LRESULT
EDIT_EM_GetRect16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
217 static LRESULT
EDIT_EM_GetSel(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
218 static LRESULT
EDIT_EM_GetThumb(WND
*wndPtr
);
219 static LRESULT
EDIT_EM_GetWordBreakProc(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
220 static LRESULT
EDIT_EM_LineFromChar(WND
*wndPtr
, WPARAM32 wParam
);
221 static LRESULT
EDIT_EM_LineIndex(WND
*wndPtr
, WPARAM32 wParam
);
222 static LRESULT
EDIT_EM_LineLength(WND
*wndPtr
, WPARAM32 wParam
);
223 static LRESULT
EDIT_EM_LineScroll(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
224 static LRESULT
EDIT_EM_PosFromChar(WND
*wndPtr
, WPARAM32 wParam
);
225 static LRESULT
EDIT_EM_ReplaceSel(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
226 static LRESULT
EDIT_EM_Scroll(WND
*wndPtr
, WPARAM32 wParam
);
227 static LRESULT
EDIT_EM_ScrollCaret(WND
*wndPtr
);
228 static LRESULT
EDIT_EM_SetHandle(WND
*wndPtr
, WPARAM32 wParam
);
229 static LRESULT
EDIT_EM_SetHandle16(WND
*wndPtr
, WPARAM32 wParam
);
230 static LRESULT
EDIT_EM_SetLimitText(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
231 static LRESULT
EDIT_EM_SetMargins(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
232 static LRESULT
EDIT_EM_SetModify(WND
*wndPtr
, WPARAM32 wParam
);
233 static LRESULT
EDIT_EM_SetPasswordChar(WND
*wndPtr
, WPARAM32 wParam
);
234 static LRESULT
EDIT_EM_SetReadOnly(WND
*wndPtr
, WPARAM32 wParam
);
235 static LRESULT
EDIT_EM_SetRect(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
236 static LRESULT
EDIT_EM_SetRectNP(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
237 static LRESULT
EDIT_EM_SetSel(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
238 static LRESULT
EDIT_EM_SetSel16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
239 static LRESULT
EDIT_EM_SetTabStops(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
240 static LRESULT
EDIT_EM_SetTabStops16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
241 static LRESULT
EDIT_EM_SetWordBreakProc(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
242 static LRESULT
EDIT_EM_Undo(WND
*wndPtr
);
244 static LRESULT
EDIT_WM_Char(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
245 static LRESULT
EDIT_WM_Clear(WND
*wndPtr
);
246 static LRESULT
EDIT_WM_Command(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
247 static LRESULT
EDIT_WM_ContextMenu(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
248 static LRESULT
EDIT_WM_Copy(WND
*wndPtr
);
249 static LRESULT
EDIT_WM_Cut(WND
*wndPtr
);
250 static LRESULT
EDIT_WM_Create(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
251 static LRESULT
EDIT_WM_Destroy(WND
*wndPtr
);
252 static LRESULT
EDIT_WM_Enable(WND
*wndPtr
, WPARAM32 wParam
);
253 static LRESULT
EDIT_WM_EraseBkGnd(WND
*wndPtr
, WPARAM32 wParam
);
254 static LRESULT
EDIT_WM_GetDlgCode(WND
*wndPtr
);
255 static LRESULT
EDIT_WM_GetFont(WND
*wndPtr
);
256 static LRESULT
EDIT_WM_GetText(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
257 static LRESULT
EDIT_WM_GetTextLength(WND
*wndPtr
);
258 static LRESULT
EDIT_WM_HScroll(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
259 static LRESULT
EDIT_WM_InitMenuPopup(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
260 static LRESULT
EDIT_WM_KeyDown(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
261 static LRESULT
EDIT_WM_KillFocus(WND
*wndPtr
, WPARAM32 wParam
);
262 static LRESULT
EDIT_WM_LButtonDblClk(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
263 static LRESULT
EDIT_WM_LButtonDown(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
264 static LRESULT
EDIT_WM_LButtonUp(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
265 static LRESULT
EDIT_WM_MouseMove(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
266 static LRESULT
EDIT_WM_Paint(WND
*wndPtr
, WPARAM32 wParam
);
267 static LRESULT
EDIT_WM_Paste(WND
*wndPtr
);
268 static LRESULT
EDIT_WM_SetCursor(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
269 static LRESULT
EDIT_WM_SetFocus(WND
*wndPtr
, WPARAM32 wParam
);
270 static LRESULT
EDIT_WM_SetFont(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
271 static LRESULT
EDIT_WM_SetRedraw(WND
*wndPtr
, WPARAM32 wParam
);
272 static LRESULT
EDIT_WM_SetText(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
273 static LRESULT
EDIT_WM_Size(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
274 static LRESULT
EDIT_WM_SysKeyDown(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
275 static LRESULT
EDIT_WM_Timer(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
276 static LRESULT
EDIT_WM_VScroll(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
);
279 /*********************************************************************
281 * General shortcuts for variable names:
285 * INT32 s; offset of selection start
286 * INT32 e; offset of selection end
287 * INT32 sl; line on which the selection starts
288 * INT32 el; line on which the selection ends
289 * INT32 sc; column on which the selection starts
290 * INT32 ec; column on which the selection ends
291 * INT32 li; line index (offset)
292 * INT32 fv; first visible line
293 * INT32 vlc; vissible line count
294 * INT32 lc; line count
295 * INT32 lh; line height (in pixels)
296 * INT32 tw; text width (in pixels)
297 * INT32 ww; window width (in pixels)
298 * INT32 cw; character width (average, in pixels)
303 /*********************************************************************
307 * The messages are in the order of the actual integer values
308 * (which can be found in include/windows.h)
309 * Whereever possible the 16 bit versions are converted to
310 * the 32 bit ones, so that we can 'fall through' to the
311 * helper functions. These are mostly 32 bit (with a few
312 * exceptions, clearly indicated by a '16' extension to their
316 LRESULT
EditWndProc(HWND32 hwnd
, UINT32 msg
, WPARAM32 wParam
, LPARAM lParam
)
319 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
321 if ((!EDITSTATEPTR(wndPtr
)) && (msg
!= WM_CREATE
))
322 return DefWindowProc32A(hwnd
, msg
, wParam
, lParam
);
326 DPRINTF_EDIT_MSG16("EM_GETSEL");
331 DPRINTF_EDIT_MSG32("EM_GETSEL");
332 lResult
= EDIT_EM_GetSel(wndPtr
, wParam
, lParam
);
336 DPRINTF_EDIT_MSG16("EM_SETSEL");
337 lResult
= EDIT_EM_SetSel16(wndPtr
, wParam
, lParam
);
340 DPRINTF_EDIT_MSG32("EM_SETSEL");
341 lResult
= EDIT_EM_SetSel(wndPtr
, wParam
, lParam
);
345 DPRINTF_EDIT_MSG16("EM_GETRECT");
346 lResult
= EDIT_EM_GetRect16(wndPtr
, wParam
, lParam
);
349 DPRINTF_EDIT_MSG32("EM_GETRECT");
350 lResult
= EDIT_EM_GetRect(wndPtr
, wParam
, lParam
);
354 DPRINTF_EDIT_MSG16("EM_SETRECT");
357 DPRINTF_EDIT_MSG32("EM_SETRECT");
358 lResult
= EDIT_EM_SetRect(wndPtr
, wParam
, lParam
);
362 DPRINTF_EDIT_MSG16("EM_SETRECTNP");
365 DPRINTF_EDIT_MSG32("EM_SETRECTNP");
366 lResult
= EDIT_EM_SetRectNP(wndPtr
, wParam
, lParam
);
370 DPRINTF_EDIT_MSG16("EM_SCROLL");
373 DPRINTF_EDIT_MSG32("EM_SCROLL");
374 lResult
= EDIT_EM_Scroll(wndPtr
, wParam
);
377 case EM_LINESCROLL16
:
378 DPRINTF_EDIT_MSG16("EM_LINESCROLL");
379 wParam
= (WPARAM32
)(INT32
)(INT16
)HIWORD(lParam
);
380 lParam
= (LPARAM
)(INT32
)(INT16
)LOWORD(lParam
);
382 case EM_LINESCROLL32
:
383 DPRINTF_EDIT_MSG32("EM_LINESCROLL");
384 lResult
= EDIT_EM_LineScroll(wndPtr
, wParam
, lParam
);
387 case EM_SCROLLCARET16
:
388 DPRINTF_EDIT_MSG16("EM_SCROLLCARET");
390 case EM_SCROLLCARET32
:
391 DPRINTF_EDIT_MSG32("EM_SCROLLCARET");
392 lResult
= EDIT_EM_ScrollCaret(wndPtr
);
396 DPRINTF_EDIT_MSG16("EM_GETMODIFY");
399 DPRINTF_EDIT_MSG32("EM_GETMODIFY");
400 lResult
= EDIT_EM_GetModify(wndPtr
);
404 DPRINTF_EDIT_MSG16("EM_SETMODIFY");
407 DPRINTF_EDIT_MSG32("EM_SETMODIFY");
408 lResult
= EDIT_EM_SetModify(wndPtr
, wParam
);
411 case EM_GETLINECOUNT16
:
412 DPRINTF_EDIT_MSG16("EM_GETLINECOUNT");
414 case EM_GETLINECOUNT32
:
415 DPRINTF_EDIT_MSG32("EM_GETLINECOUNT");
416 lResult
= EDIT_EM_GetLineCount(wndPtr
);
420 DPRINTF_EDIT_MSG16("EM_LINEINDEX");
423 DPRINTF_EDIT_MSG32("EM_LINEINDEX");
424 lResult
= EDIT_EM_LineIndex(wndPtr
, wParam
);
428 DPRINTF_EDIT_MSG16("EM_SETHANDLE");
429 lResult
= EDIT_EM_SetHandle16(wndPtr
, wParam
);
432 DPRINTF_EDIT_MSG32("EM_SETHANDLE");
433 lResult
= EDIT_EM_SetHandle(wndPtr
, wParam
);
437 DPRINTF_EDIT_MSG16("EM_GETHANDLE");
438 lResult
= EDIT_EM_GetHandle16(wndPtr
);
441 DPRINTF_EDIT_MSG32("EM_GETHANDLE");
442 lResult
= EDIT_EM_GetHandle(wndPtr
);
446 DPRINTF_EDIT_MSG16("EM_GETTHUMB");
449 DPRINTF_EDIT_MSG32("EM_GETTHUMB");
450 lResult
= EDIT_EM_GetThumb(wndPtr
);
453 /* messages 0x00bf and 0x00c0 missing from specs */
456 DPRINTF_EDIT_MSG16("undocumented WM_USER+15, please report");
459 DPRINTF_EDIT_MSG32("undocumented 0x00bf, please report");
460 lResult
= DefWindowProc32A(hwnd
, msg
, wParam
, lParam
);
464 DPRINTF_EDIT_MSG16("undocumented WM_USER+16, please report");
467 DPRINTF_EDIT_MSG32("undocumented 0x00c0, please report");
468 lResult
= DefWindowProc32A(hwnd
, msg
, wParam
, lParam
);
471 case EM_LINELENGTH16
:
472 DPRINTF_EDIT_MSG16("EM_LINELENGTH");
474 case EM_LINELENGTH32
:
475 DPRINTF_EDIT_MSG32("EM_LINELENGTH");
476 lResult
= EDIT_EM_LineLength(wndPtr
, wParam
);
479 case EM_REPLACESEL16
:
480 DPRINTF_EDIT_MSG16("EM_REPLACESEL");
481 lParam
= (LPARAM
)PTR_SEG_TO_LIN((SEGPTR
)lParam
);
483 case EM_REPLACESEL32
:
484 DPRINTF_EDIT_MSG32("EM_REPLACESEL");
485 lResult
= EDIT_EM_ReplaceSel(wndPtr
, wParam
, lParam
);
488 /* message 0x00c3 missing from specs */
491 DPRINTF_EDIT_MSG16("undocumented WM_USER+19, please report");
494 DPRINTF_EDIT_MSG32("undocumented 0x00c3, please report");
495 lResult
= DefWindowProc32A(hwnd
, msg
, wParam
, lParam
);
499 DPRINTF_EDIT_MSG16("EM_GETLINE");
500 lParam
= (LPARAM
)PTR_SEG_TO_LIN((SEGPTR
)lParam
);
503 DPRINTF_EDIT_MSG32("EM_GETLINE");
504 lResult
= EDIT_EM_GetLine(wndPtr
, wParam
, lParam
);
508 DPRINTF_EDIT_MSG16("EM_LIMITTEXT");
510 case EM_SETLIMITTEXT32
:
511 DPRINTF_EDIT_MSG32("EM_SETLIMITTEXT");
512 lResult
= EDIT_EM_SetLimitText(wndPtr
, wParam
, lParam
);
516 DPRINTF_EDIT_MSG16("EM_CANUNDO");
519 DPRINTF_EDIT_MSG32("EM_CANUNDO");
520 lResult
= EDIT_EM_CanUndo(wndPtr
);
524 DPRINTF_EDIT_MSG16("EM_UNDO");
529 DPRINTF_EDIT_MSG32("EM_UNDO / WM_UNDO");
530 lResult
= EDIT_EM_Undo(wndPtr
);
534 DPRINTF_EDIT_MSG16("EM_FMTLINES");
537 DPRINTF_EDIT_MSG32("EM_FMTLINES");
538 lResult
= EDIT_EM_FmtLines(wndPtr
, wParam
);
541 case EM_LINEFROMCHAR16
:
542 DPRINTF_EDIT_MSG16("EM_LINEFROMCHAR");
544 case EM_LINEFROMCHAR32
:
545 DPRINTF_EDIT_MSG32("EM_LINEFROMCHAR");
546 lResult
= EDIT_EM_LineFromChar(wndPtr
, wParam
);
549 /* message 0x00ca missing from specs */
552 DPRINTF_EDIT_MSG16("undocumented WM_USER+26, please report");
555 DPRINTF_EDIT_MSG32("undocumented 0x00ca, please report");
556 lResult
= DefWindowProc32A(hwnd
, msg
, wParam
, lParam
);
559 case EM_SETTABSTOPS16
:
560 DPRINTF_EDIT_MSG16("EM_SETTABSTOPS");
561 lResult
= EDIT_EM_SetTabStops16(wndPtr
, wParam
, lParam
);
563 case EM_SETTABSTOPS32
:
564 DPRINTF_EDIT_MSG32("EM_SETTABSTOPS");
565 lResult
= EDIT_EM_SetTabStops(wndPtr
, wParam
, lParam
);
568 case EM_SETPASSWORDCHAR16
:
569 DPRINTF_EDIT_MSG16("EM_SETPASSWORDCHAR");
571 case EM_SETPASSWORDCHAR32
:
572 DPRINTF_EDIT_MSG32("EM_SETPASSWORDCHAR");
573 lResult
= EDIT_EM_SetPasswordChar(wndPtr
, wParam
);
576 case EM_EMPTYUNDOBUFFER16
:
577 DPRINTF_EDIT_MSG16("EM_EMPTYUNDOBUFFER");
579 case EM_EMPTYUNDOBUFFER32
:
580 DPRINTF_EDIT_MSG32("EM_EMPTYUNDOBUFFER");
581 lResult
= EDIT_EM_EmptyUndoBuffer(wndPtr
);
584 case EM_GETFIRSTVISIBLELINE16
:
585 DPRINTF_EDIT_MSG16("EM_GETFIRSTVISIBLELINE");
587 case EM_GETFIRSTVISIBLELINE32
:
588 DPRINTF_EDIT_MSG32("EM_GETFIRSTVISIBLELINE");
589 lResult
= EDIT_EM_GetFirstVisibleLine(wndPtr
);
592 case EM_SETREADONLY16
:
593 DPRINTF_EDIT_MSG16("EM_SETREADONLY");
595 case EM_SETREADONLY32
:
596 DPRINTF_EDIT_MSG32("EM_SETREADONLY");
597 lResult
= EDIT_EM_SetReadOnly(wndPtr
, wParam
);
600 case EM_SETWORDBREAKPROC16
:
601 DPRINTF_EDIT_MSG16("EM_SETWORDBREAKPROC");
603 case EM_SETWORDBREAKPROC32
:
604 DPRINTF_EDIT_MSG32("EM_SETWORDBREAKPROC");
605 lResult
= EDIT_EM_SetWordBreakProc(wndPtr
, wParam
, lParam
);
608 case EM_GETWORDBREAKPROC16
:
609 DPRINTF_EDIT_MSG16("EM_GETWORDBREAKPROC");
611 case EM_GETWORDBREAKPROC32
:
612 DPRINTF_EDIT_MSG32("EM_GETWORDBREAKPROC");
613 lResult
= EDIT_EM_GetWordBreakProc(wndPtr
, wParam
, lParam
);
616 case EM_GETPASSWORDCHAR16
:
617 DPRINTF_EDIT_MSG16("EM_GETPASSWORDCHAR");
619 case EM_GETPASSWORDCHAR32
:
620 DPRINTF_EDIT_MSG32("EM_GETPASSWORDCHAR");
621 lResult
= EDIT_EM_GetPasswordChar(wndPtr
);
624 /* The following EM_xxx are new to win95 and don't exist for 16 bit */
626 case EM_SETMARGINS32
:
627 DPRINTF_EDIT_MSG16("EM_SETMARGINS");
628 lResult
= EDIT_EM_SetMargins(wndPtr
, wParam
, lParam
);
631 case EM_GETMARGINS32
:
632 DPRINTF_EDIT_MSG16("EM_GETMARGINS");
633 lResult
= EDIT_EM_GetMargins(wndPtr
, wParam
, lParam
);
636 case EM_GETLIMITTEXT32
:
637 DPRINTF_EDIT_MSG16("EM_GETLIMITTEXT");
638 lResult
= EDIT_EM_GetLimitText(wndPtr
, wParam
, lParam
);
641 case EM_POSFROMCHAR32
:
642 DPRINTF_EDIT_MSG16("EM_POSFROMCHAR");
643 lResult
= EDIT_EM_PosFromChar(wndPtr
, wParam
);
646 case EM_CHARFROMPOS32
:
647 DPRINTF_EDIT_MSG16("EM_CHARFROMPOS");
648 lResult
= EDIT_EM_CharFromPos(wndPtr
, wParam
, lParam
);
652 DPRINTF_EDIT_MSG32("WM_GETDLGCODE");
653 lResult
= EDIT_WM_GetDlgCode(wndPtr
);
657 DPRINTF_EDIT_MSG32("WM_CHAR");
658 lResult
= EDIT_WM_Char(wndPtr
, wParam
, lParam
);
662 DPRINTF_EDIT_MSG32("WM_CLEAR");
663 lResult
= EDIT_WM_Clear(wndPtr
);
667 DPRINTF_EDIT_MSG32("WM_COMMAND");
668 lResult
= EDIT_WM_Command(wndPtr
, wParam
, lParam
);
672 DPRINTF_EDIT_MSG32("WM_CONTEXTMENU");
673 lResult
= EDIT_WM_ContextMenu(wndPtr
, wParam
, lParam
);
677 DPRINTF_EDIT_MSG32("WM_COPY");
678 lResult
= EDIT_WM_Copy(wndPtr
);
682 DPRINTF_EDIT_MSG32("WM_CREATE");
683 lResult
= EDIT_WM_Create(wndPtr
, wParam
, lParam
);
687 DPRINTF_EDIT_MSG32("WM_CUT");
688 lResult
= EDIT_WM_Cut(wndPtr
);
692 DPRINTF_EDIT_MSG32("WM_DESTROY");
693 lResult
= EDIT_WM_Destroy(wndPtr
);
697 DPRINTF_EDIT_MSG32("WM_ENABLE");
698 lResult
= EDIT_WM_Enable(wndPtr
, wParam
);
702 DPRINTF_EDIT_MSG32("WM_ERASEBKGND");
703 lResult
= EDIT_WM_EraseBkGnd(wndPtr
, wParam
);
707 DPRINTF_EDIT_MSG32("WM_GETFONT");
708 lResult
= EDIT_WM_GetFont(wndPtr
);
712 DPRINTF_EDIT_MSG32("WM_GETTEXT");
713 lResult
= EDIT_WM_GetText(wndPtr
, wParam
, lParam
);
716 case WM_GETTEXTLENGTH
:
717 DPRINTF_EDIT_MSG32("WM_GETTEXTLENGTH");
718 lResult
= EDIT_WM_GetTextLength(wndPtr
);
722 DPRINTF_EDIT_MSG32("WM_HSCROLL");
723 lResult
= EDIT_WM_HScroll(wndPtr
, wParam
, lParam
);
726 case WM_INITMENUPOPUP
:
727 DPRINTF_EDIT_MSG32("WM_INITMENUPOPUP");
728 lResult
= EDIT_WM_InitMenuPopup(wndPtr
, wParam
, lParam
);
732 DPRINTF_EDIT_MSG32("WM_KEYDOWN");
733 lResult
= EDIT_WM_KeyDown(wndPtr
, wParam
, lParam
);
737 DPRINTF_EDIT_MSG32("WM_KILLFOCUS");
738 lResult
= EDIT_WM_KillFocus(wndPtr
, wParam
);
741 case WM_LBUTTONDBLCLK
:
742 DPRINTF_EDIT_MSG32("WM_LBUTTONDBLCLK");
743 lResult
= EDIT_WM_LButtonDblClk(wndPtr
, wParam
, lParam
);
747 DPRINTF_EDIT_MSG32("WM_LBUTTONDOWN");
748 lResult
= EDIT_WM_LButtonDown(wndPtr
, wParam
, lParam
);
752 DPRINTF_EDIT_MSG32("WM_LBUTTONUP");
753 lResult
= EDIT_WM_LButtonUp(wndPtr
, wParam
, lParam
);
758 * DPRINTF_EDIT_MSG32("WM_MOUSEMOVE");
760 lResult
= EDIT_WM_MouseMove(wndPtr
, wParam
, lParam
);
764 DPRINTF_EDIT_MSG32("WM_PAINT");
765 lResult
= EDIT_WM_Paint(wndPtr
, wParam
);
769 DPRINTF_EDIT_MSG32("WM_PASTE");
770 lResult
= EDIT_WM_Paste(wndPtr
);
775 * DPRINTF_EDIT_MSG32("WM_SETCURSOR");
777 lResult
= EDIT_WM_SetCursor(wndPtr
, wParam
, lParam
);
781 DPRINTF_EDIT_MSG32("WM_SETFOCUS");
782 lResult
= EDIT_WM_SetFocus(wndPtr
, wParam
);
786 DPRINTF_EDIT_MSG32("WM_SETFONT");
787 lResult
= EDIT_WM_SetFont(wndPtr
, wParam
, lParam
);
791 DPRINTF_EDIT_MSG32("WM_SETREDRAW");
792 lResult
= EDIT_WM_SetRedraw(wndPtr
, wParam
);
796 DPRINTF_EDIT_MSG32("WM_SETTEXT");
797 lResult
= EDIT_WM_SetText(wndPtr
, wParam
, lParam
);
801 DPRINTF_EDIT_MSG32("WM_SIZE");
802 lResult
= EDIT_WM_Size(wndPtr
, wParam
, lParam
);
806 DPRINTF_EDIT_MSG32("WM_SYSKEYDOWN");
807 lResult
= EDIT_WM_SysKeyDown(wndPtr
, wParam
, lParam
);
811 DPRINTF_EDIT_MSG32("WM_TIMER");
812 lResult
= EDIT_WM_Timer(wndPtr
, wParam
, lParam
);
816 DPRINTF_EDIT_MSG32("WM_VSCROLL");
817 lResult
= EDIT_WM_VScroll(wndPtr
, wParam
, lParam
);
821 lResult
= DefWindowProc32A(hwnd
, msg
, wParam
, lParam
);
824 EDIT_ReleasePointer(wndPtr
);
829 /*********************************************************************
833 * Build array of pointers to text lines.
834 * Lines can end with '\0' (last line), nothing (if it is too long),
835 * a delimiter (usually ' '), a soft return '\r\r\n' or a hard return '\r\n'
838 static void EDIT_BuildLineDefs(WND
*wndPtr
)
840 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
841 LPSTR text
= EDIT_GetPasswordPointer(wndPtr
);
842 INT32 ww
= EDIT_GetWndWidth(wndPtr
);
852 hdc
= GetDC32(wndPtr
->hwndSelf
);
853 hFont
= (HFONT32
)EDIT_WM_GetFont(wndPtr
);
854 if (hFont
) oldFont
= SelectObject32(hdc
, hFont
);
856 if (!IsMultiLine(wndPtr
)) {
858 es
->LineDefs
= xrealloc(es
->LineDefs
, sizeof(LINEDEF
));
859 es
->LineDefs
[0].offset
= 0;
860 es
->LineDefs
[0].length
= EDIT_WM_GetTextLength(wndPtr
);
861 es
->LineDefs
[0].ending
= END_0
;
862 es
->TextWidth
= (INT32
)LOWORD(GetTabbedTextExtent32A(hdc
, text
,
863 es
->LineDefs
[0].length
,
864 es
->NumTabStops
, es
->TabStops
));
869 if (!(cp
= strstr(start
, "\r\n"))) {
871 length
= lstrlen32A(start
);
872 } else if ((cp
> start
) && (*(cp
- 1) == '\r')) {
874 length
= cp
- start
- 1;
879 width
= (INT32
)LOWORD(GetTabbedTextExtent32A(hdc
, start
, length
,
880 es
->NumTabStops
, es
->TabStops
));
882 if (IsWordWrap(wndPtr
) && (width
> ww
)) {
886 next
= EDIT_CallWordBreakProc(wndPtr
, start
,
887 prev
+ 1, length
, WB_RIGHT
);
888 width
= (INT32
)LOWORD(GetTabbedTextExtent32A(hdc
, start
, next
,
889 es
->NumTabStops
, es
->TabStops
));
890 } while (width
<= ww
);
896 width
= (INT32
)LOWORD(GetTabbedTextExtent32A(hdc
, start
, next
,
897 es
->NumTabStops
, es
->TabStops
));
898 } while (width
<= ww
);
902 if (EDIT_CallWordBreakProc(wndPtr
, start
, length
- 1,
903 length
, WB_ISDELIMITER
)) {
905 ending
= END_DELIMIT
;
908 width
= (INT32
)LOWORD(GetTabbedTextExtent32A(hdc
, start
, length
,
909 es
->NumTabStops
, es
->TabStops
));
912 es
->LineDefs
= xrealloc(es
->LineDefs
, (es
->LineCount
+ 1) * sizeof(LINEDEF
));
913 es
->LineDefs
[es
->LineCount
].offset
= start
- text
;
914 es
->LineDefs
[es
->LineCount
].length
= length
;
915 es
->LineDefs
[es
->LineCount
].ending
= ending
;
917 es
->TextWidth
= MAX(es
->TextWidth
, width
);
933 } while (*start
|| (ending
== END_SOFT
) || (ending
== END_HARD
));
935 if (hFont
) SelectObject32(hdc
, oldFont
);
936 ReleaseDC32(wndPtr
->hwndSelf
, hdc
);
942 /*********************************************************************
944 * EDIT_CallWordBreakProc
946 * Call appropriate WordBreakProc (internal or external).
948 * FIXME: Heavily broken now that we have a LOCAL32 buffer.
949 * External wordbreak functions have been disabled in
950 * EM_SETWORDBREAKPROC.
953 static INT32
EDIT_CallWordBreakProc(WND
*wndPtr
, LPSTR s
, INT32 index
, INT32 count
, INT32 action
)
955 return EDIT_WordBreakProc(s
, index
, count
, action
);
957 * EDITWORDBREAKPROC wbp = (EDITWORDBREAKPROC)EDIT_EM_GetWordBreakProc(wndPtr, 0, 0);
959 * if (!wbp) return EDIT_WordBreakProc(s, index, count, action);
961 * EDITSTATE *es = EDITSTATEPTR(wndPtr);
962 * SEGPTR ptr = LOCAL_LockSegptr( wndPtr->hInstance, es->hBuf16 ) +
963 * (INT16)(s - EDIT_GetPointer(wndPtr));
964 * INT ret = CallWordBreakProc( (FARPROC16)wbp, ptr,
965 * index, count, action);
966 * LOCAL_Unlock( wndPtr->hInstance, es->hBuf16 );
973 /*********************************************************************
977 * Calculates, for a given line and X-coordinate on the screen, the column.
980 static INT32
EDIT_ColFromWndX(WND
*wndPtr
, INT32 line
, INT32 x
)
982 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
);
983 INT32 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, line
);
984 INT32 ll
= (INT32
)EDIT_EM_LineLength(wndPtr
, li
);
987 line
= MAX(0, MIN(line
, lc
- 1));
988 for (i
= 0 ; i
< ll
; i
++)
989 if (EDIT_WndXFromCol(wndPtr
, line
, i
) >= x
)
995 /*********************************************************************
999 * Delete all characters on this line to right of cursor.
1002 static void EDIT_DelEnd(WND
*wndPtr
)
1004 EDIT_EM_SetSel(wndPtr
, -1, 0);
1005 EDIT_MoveEnd(wndPtr
, TRUE
);
1006 EDIT_WM_Clear(wndPtr
);
1010 /*********************************************************************
1014 * Delete character to left of cursor.
1017 static void EDIT_DelLeft(WND
*wndPtr
)
1019 EDIT_EM_SetSel(wndPtr
, -1, 0);
1020 EDIT_MoveBackward(wndPtr
, TRUE
);
1021 EDIT_WM_Clear(wndPtr
);
1025 /*********************************************************************
1029 * Delete character to right of cursor.
1032 static void EDIT_DelRight(WND
*wndPtr
)
1034 EDIT_EM_SetSel(wndPtr
, -1, 0);
1035 EDIT_MoveForward(wndPtr
, TRUE
);
1036 EDIT_WM_Clear(wndPtr
);
1040 /*********************************************************************
1042 * EDIT_GetAveCharWidth
1045 static INT32
EDIT_GetAveCharWidth(WND
*wndPtr
)
1047 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1049 return es
->AveCharWidth
;
1053 /*********************************************************************
1055 * EDIT_GetLineHeight
1058 static INT32
EDIT_GetLineHeight(WND
*wndPtr
)
1060 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1062 return es
->LineHeight
;
1066 /*********************************************************************
1070 * Calculates the bounding rectangle for a line from a starting
1071 * column to an ending column.
1074 static void EDIT_GetLineRect(WND
*wndPtr
, INT32 line
, INT32 scol
, INT32 ecol
, LPRECT32 rc
)
1076 rc
->top
= EDIT_WndYFromLine(wndPtr
, line
);
1077 rc
->bottom
= rc
->top
+ EDIT_GetLineHeight(wndPtr
);
1078 rc
->left
= EDIT_WndXFromCol(wndPtr
, line
, scol
);
1079 rc
->right
= (ecol
== -1) ? EDIT_GetWndWidth(wndPtr
) :
1080 EDIT_WndXFromCol(wndPtr
, line
, ecol
);
1084 /*********************************************************************
1088 * This acts as a LOCAL_Lock(), but it locks only once. This way
1089 * you can call it whenever you like, without unlocking.
1092 static LPSTR
EDIT_GetPointer(WND
*wndPtr
)
1094 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1096 if (!es
->text
&& (es
->hBuf32
|| es
->hBuf16
)) {
1098 es
->text
= (LPSTR
)LocalLock32(es
->hBuf32
);
1100 es
->text
= LOCAL_Lock(wndPtr
->hInstance
, es
->hBuf16
);
1106 /*********************************************************************
1108 * EDIT_GetPasswordPointer
1112 static LPSTR
EDIT_GetPasswordPointer(WND
*wndPtr
)
1114 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1115 LPSTR text
= xstrdup(EDIT_GetPointer(wndPtr
));
1118 if(es
->PasswordChar
) {
1121 if(*p
!= '\r' && *p
!= '\n')
1122 *p
= es
->PasswordChar
;
1130 /*********************************************************************
1134 * Beware: This is not the function called on EM_GETSEL.
1135 * This is the unordered version used internally
1136 * (s can be > e). No return value either.
1139 static void EDIT_GetSel(WND
*wndPtr
, LPINT32 s
, LPINT32 e
)
1141 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1150 /*********************************************************************
1155 static INT32
EDIT_GetTextWidth(WND
*wndPtr
)
1157 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1159 return es
->TextWidth
;
1163 /*********************************************************************
1165 * EDIT_GetUndoPointer
1167 * This acts as a LocalLock32(), but it locks only once. This way
1168 * you can call it whenever you like, without unlocking.
1171 static LPSTR
EDIT_GetUndoPointer(WND
*wndPtr
)
1173 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1175 if (!es
->UndoText
&& es
->hUndoBuf
)
1176 es
->UndoText
= (LPSTR
)LocalLock32(es
->hUndoBuf
);
1177 return es
->UndoText
;
1181 /*********************************************************************
1183 * EDIT_GetVisibleLineCount
1186 static INT32
EDIT_GetVisibleLineCount(WND
*wndPtr
)
1190 EDIT_EM_GetRect(wndPtr
, 0, (LPARAM
)&rc
);
1191 return MAX(1, MAX(rc
.bottom
- rc
.top
, 0) / EDIT_GetLineHeight(wndPtr
));
1195 /*********************************************************************
1200 static INT32
EDIT_GetWndWidth(WND
*wndPtr
)
1204 EDIT_EM_GetRect(wndPtr
, 0, (LPARAM
)&rc
);
1205 return rc
.right
- rc
.left
;
1209 /*********************************************************************
1214 static INT32
EDIT_GetXOffset(WND
*wndPtr
)
1216 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1222 /*********************************************************************
1224 * EDIT_InvalidateText
1226 * Invalidate the text from offset start upto, but not including,
1227 * offset end. Useful for (re)painting the selection.
1228 * Regions outside the linewidth are not invalidated.
1229 * end == -1 means end == TextLength.
1230 * start and end need not be ordered.
1233 static void EDIT_InvalidateText(WND
*wndPtr
, INT32 start
, INT32 end
)
1235 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
);
1236 INT32 vlc
= EDIT_GetVisibleLineCount(wndPtr
);
1250 end
= (INT32
)EDIT_WM_GetTextLength(wndPtr
);
1251 ORDER_INT32(start
, end
);
1252 sl
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, start
);
1253 el
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, end
);
1254 if ((el
< fv
) || (sl
> fv
+ vlc
))
1257 sc
= start
- (INT32
)EDIT_EM_LineIndex(wndPtr
, sl
);
1258 ec
= end
- (INT32
)EDIT_EM_LineIndex(wndPtr
, el
);
1263 if (el
> fv
+ vlc
) {
1265 ec
= (INT32
)EDIT_EM_LineLength(wndPtr
,
1266 (INT32
)EDIT_EM_LineIndex(wndPtr
, el
));
1268 EDIT_EM_GetRect(wndPtr
, 0, (LPARAM
)&rcWnd
);
1270 EDIT_GetLineRect(wndPtr
, sl
, sc
, ec
, &rcLine
);
1271 if (IntersectRect32(&rcUpdate
, &rcWnd
, &rcLine
))
1272 InvalidateRect32( wndPtr
->hwndSelf
, &rcUpdate
, FALSE
);
1274 EDIT_GetLineRect(wndPtr
, sl
, sc
,
1275 (INT32
)EDIT_EM_LineLength(wndPtr
,
1276 (INT32
)EDIT_EM_LineIndex(wndPtr
, sl
)),
1278 if (IntersectRect32(&rcUpdate
, &rcWnd
, &rcLine
))
1279 InvalidateRect32( wndPtr
->hwndSelf
, &rcUpdate
, FALSE
);
1280 for (l
= sl
+ 1 ; l
< el
; l
++) {
1281 EDIT_GetLineRect(wndPtr
, l
, 0,
1282 (INT32
)EDIT_EM_LineLength(wndPtr
,
1283 (INT32
)EDIT_EM_LineIndex(wndPtr
, l
)),
1285 if (IntersectRect32(&rcUpdate
, &rcWnd
, &rcLine
))
1286 InvalidateRect32(wndPtr
->hwndSelf
, &rcUpdate
, FALSE
);
1288 EDIT_GetLineRect(wndPtr
, el
, 0, ec
, &rcLine
);
1289 if (IntersectRect32(&rcUpdate
, &rcWnd
, &rcLine
))
1290 InvalidateRect32( wndPtr
->hwndSelf
, &rcUpdate
, FALSE
);
1295 /*********************************************************************
1299 * Calculates, for a given Y-coordinate on the screen, the line.
1302 static INT32
EDIT_LineFromWndY(WND
*wndPtr
, INT32 y
)
1304 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
);
1305 INT32 lh
= EDIT_GetLineHeight(wndPtr
);
1306 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
);
1308 return MAX(0, MIN(lc
- 1, y
/ lh
+ fv
));
1312 /*********************************************************************
1316 * Try to fit size + 1 bytes in the buffer. Constrain to limits.
1319 static BOOL32
EDIT_MakeFit(WND
*wndPtr
, INT32 size
)
1321 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1325 if (size
<= es
->BufSize
)
1327 if (size
> es
->BufLimit
) {
1328 dprintf_edit(stddeb
, "edit: notification EN_MAXTEXT sent\n");
1329 EDIT_NOTIFY_PARENT(wndPtr
, EN_MAXTEXT
);
1332 size
= ((size
/ GROWLENGTH
) + 1) * GROWLENGTH
;
1333 if (size
> es
->BufLimit
)
1334 size
= es
->BufLimit
;
1336 dprintf_edit(stddeb
, "edit: EDIT_MakeFit: trying to ReAlloc to %d+1\n", size
);
1338 EDIT_ReleasePointer(wndPtr
);
1340 if ((hNew32
= LocalReAlloc32(es
->hBuf32
, size
+ 1, 0))) {
1341 dprintf_edit(stddeb
, "edit: EDIT_MakeFit: Old 32 bit handle %08x, new handle %08x\n", es
->hBuf32
, hNew32
);
1342 es
->hBuf32
= hNew32
;
1343 es
->BufSize
= MIN(LocalSize32(es
->hBuf32
) - 1, es
->BufLimit
);
1344 if (es
->BufSize
< size
) {
1345 dprintf_edit(stddeb
, "edit: EDIT_MakeFit: FAILED ! We now have %d+1\n", es
->BufSize
);
1346 dprintf_edit(stddeb
, "edit: notification EN_ERRSPACE sent\n");
1347 EDIT_NOTIFY_PARENT(wndPtr
, EN_ERRSPACE
);
1350 dprintf_edit(stddeb
, "edit: EDIT_MakeFit: We now have %d+1\n", es
->BufSize
);
1354 if ((hNew16
= LOCAL_ReAlloc(wndPtr
->hInstance
, es
->hBuf16
, size
+ 1, LMEM_MOVEABLE
))) {
1355 dprintf_edit(stddeb
, "edit: EDIT_MakeFit: Old 16 bit handle %08x, new handle %08x\n", es
->hBuf16
, hNew16
);
1356 es
->hBuf16
= hNew16
;
1357 es
->BufSize
= MIN(LOCAL_Size(wndPtr
->hInstance
, es
->hBuf16
) - 1, es
->BufLimit
);
1358 if (es
->BufSize
< size
) {
1359 dprintf_edit(stddeb
, "edit: EDIT_MakeFit: FAILED ! We now have %d+1\n", es
->BufSize
);
1360 dprintf_edit(stddeb
, "edit: notification EN_ERRSPACE sent\n");
1361 EDIT_NOTIFY_PARENT(wndPtr
, EN_ERRSPACE
);
1364 dprintf_edit(stddeb
, "edit: EDIT_MakeFit: We now have %d+1\n", es
->BufSize
);
1368 dprintf_edit(stddeb
, "edit: EDIT_MakeFit: Reallocation failed\n");
1369 dprintf_edit(stddeb
, "edit: notification EN_ERRSPACE sent\n");
1370 EDIT_NOTIFY_PARENT(wndPtr
, EN_ERRSPACE
);
1375 /*********************************************************************
1379 * Try to fit size + 1 bytes in the undo buffer.
1382 static BOOL32
EDIT_MakeUndoFit(WND
*wndPtr
, INT32 size
)
1384 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1387 if (size
<= es
->UndoBufSize
)
1389 size
= ((size
/ GROWLENGTH
) + 1) * GROWLENGTH
;
1391 dprintf_edit(stddeb
, "edit: EDIT_MakeUndoFit: trying to ReAlloc to %d+1\n", size
);
1393 EDIT_ReleaseUndoPointer(wndPtr
);
1394 if ((hNew
= LocalReAlloc32(es
->hUndoBuf
, size
+ 1, 0))) {
1395 dprintf_edit(stddeb
, "edit: EDIT_MakeUndoFit: Old handle %08x, new handle %08x\n", es
->hUndoBuf
, hNew
);
1396 es
->hUndoBuf
= hNew
;
1397 es
->UndoBufSize
= LocalSize32(es
->hUndoBuf
) - 1;
1398 if (es
->UndoBufSize
< size
) {
1399 dprintf_edit(stddeb
, "edit: EDIT_MakeUndoFit: FAILED ! We now have %d+1\n", es
->UndoBufSize
);
1402 dprintf_edit(stddeb
, "edit: EDIT_MakeUndoFit: We now have %d+1\n", es
->UndoBufSize
);
1409 /*********************************************************************
1414 static void EDIT_MoveBackward(WND
*wndPtr
, BOOL32 extend
)
1421 EDIT_GetSel(wndPtr
, &s
, &e
);
1422 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
);
1423 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
);
1426 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
- 1);
1427 e
= li
+ (INT32
)EDIT_EM_LineLength(wndPtr
, li
);
1433 EDIT_SetSel(wndPtr
, s
, e
);
1434 EDIT_EM_ScrollCaret(wndPtr
);
1438 /*********************************************************************
1443 static void EDIT_MoveDownward(WND
*wndPtr
, BOOL32 extend
)
1452 EDIT_GetSel(wndPtr
, &s
, &e
);
1453 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
);
1454 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
);
1455 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
);
1457 x
= EDIT_WndXFromCol(wndPtr
, l
, e
- li
);
1459 e
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
) +
1460 EDIT_ColFromWndX(wndPtr
, l
, x
);
1464 EDIT_SetSel(wndPtr
, s
, e
);
1465 EDIT_EM_ScrollCaret(wndPtr
);
1469 /*********************************************************************
1474 static void EDIT_MoveEnd(WND
*wndPtr
, BOOL32 extend
)
1482 EDIT_GetSel(wndPtr
, &s
, &e
);
1483 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
);
1484 ll
= (INT32
)EDIT_EM_LineLength(wndPtr
, e
);
1485 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
);
1489 EDIT_SetSel(wndPtr
, s
, e
);
1490 EDIT_EM_ScrollCaret(wndPtr
);
1494 /*********************************************************************
1499 static void EDIT_MoveForward(WND
*wndPtr
, BOOL32 extend
)
1508 EDIT_GetSel(wndPtr
, &s
, &e
);
1509 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
);
1510 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
);
1511 ll
= (INT32
)EDIT_EM_LineLength(wndPtr
, e
);
1512 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
);
1515 e
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
+ 1);
1520 EDIT_SetSel(wndPtr
, s
, e
);
1521 EDIT_EM_ScrollCaret(wndPtr
);
1525 /*********************************************************************
1529 * Home key: move to beginning of line.
1532 static void EDIT_MoveHome(WND
*wndPtr
, BOOL32 extend
)
1539 EDIT_GetSel(wndPtr
, &s
, &e
);
1540 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
);
1541 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
);
1545 EDIT_SetSel(wndPtr
, s
, e
);
1546 EDIT_EM_ScrollCaret(wndPtr
);
1550 /*********************************************************************
1555 static void EDIT_MovePageDown(WND
*wndPtr
, BOOL32 extend
)
1564 EDIT_GetSel(wndPtr
, &s
, &e
);
1565 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
);
1566 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
);
1567 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
);
1569 x
= EDIT_WndXFromCol(wndPtr
, l
, e
- li
);
1570 l
= MIN(lc
- 1, l
+ EDIT_GetVisibleLineCount(wndPtr
));
1571 e
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
) +
1572 EDIT_ColFromWndX(wndPtr
, l
, x
);
1576 EDIT_SetSel(wndPtr
, s
, e
);
1577 EDIT_EM_ScrollCaret(wndPtr
);
1581 /*********************************************************************
1586 static void EDIT_MovePageUp(WND
*wndPtr
, BOOL32 extend
)
1594 EDIT_GetSel(wndPtr
, &s
, &e
);
1595 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
);
1596 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
);
1598 x
= EDIT_WndXFromCol(wndPtr
, l
, e
- li
);
1599 l
= MAX(0, l
- EDIT_GetVisibleLineCount(wndPtr
));
1600 e
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
) +
1601 EDIT_ColFromWndX(wndPtr
, l
, x
);
1605 EDIT_SetSel(wndPtr
, s
, e
);
1606 EDIT_EM_ScrollCaret(wndPtr
);
1610 /*********************************************************************
1615 static void EDIT_MoveUpward(WND
*wndPtr
, BOOL32 extend
)
1623 EDIT_GetSel(wndPtr
, &s
, &e
);
1624 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
);
1625 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
);
1627 x
= EDIT_WndXFromCol(wndPtr
, l
, e
- li
);
1629 e
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
) +
1630 EDIT_ColFromWndX(wndPtr
, l
, x
);
1634 EDIT_SetSel(wndPtr
, s
, e
);
1635 EDIT_EM_ScrollCaret(wndPtr
);
1639 /*********************************************************************
1641 * EDIT_MoveWordBackward
1644 static void EDIT_MoveWordBackward(WND
*wndPtr
, BOOL32 extend
)
1653 EDIT_GetSel(wndPtr
, &s
, &e
);
1654 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
);
1655 ll
= (INT32
)EDIT_EM_LineLength(wndPtr
, e
);
1656 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
);
1659 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
- 1);
1660 e
= li
+ (INT32
)EDIT_EM_LineLength(wndPtr
, li
);
1663 text
= EDIT_GetPointer(wndPtr
);
1664 e
= li
+ (INT32
)EDIT_CallWordBreakProc(wndPtr
,
1665 text
+ li
, e
- li
, ll
, WB_LEFT
);
1669 EDIT_SetSel(wndPtr
, s
, e
);
1670 EDIT_EM_ScrollCaret(wndPtr
);
1674 /*********************************************************************
1676 * EDIT_MoveWordForward
1679 static void EDIT_MoveWordForward(WND
*wndPtr
, BOOL32 extend
)
1689 EDIT_GetSel(wndPtr
, &s
, &e
);
1690 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
);
1691 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
);
1692 ll
= (INT32
)EDIT_EM_LineLength(wndPtr
, e
);
1693 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
);
1696 e
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
+ 1);
1698 text
= EDIT_GetPointer(wndPtr
);
1699 e
= li
+ EDIT_CallWordBreakProc(wndPtr
,
1700 text
+ li
, e
- li
+ 1, ll
, WB_RIGHT
);
1704 EDIT_SetSel(wndPtr
, s
, e
);
1705 EDIT_EM_ScrollCaret(wndPtr
);
1709 /*********************************************************************
1714 static void EDIT_PaintLine(WND
*wndPtr
, HDC32 hdc
, INT32 line
, BOOL32 rev
)
1716 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
);
1717 INT32 vlc
= EDIT_GetVisibleLineCount(wndPtr
);
1718 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
);
1725 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1727 if ((line
< fv
) || (line
> fv
+ vlc
) || (line
>= lc
))
1730 dprintf_edit(stddeb
, "edit: EDIT_PaintLine: line=%d\n", line
);
1732 x
= EDIT_WndXFromCol(wndPtr
, line
, 0);
1733 y
= EDIT_WndYFromLine(wndPtr
, line
);
1734 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, line
);
1735 ll
= (INT32
)EDIT_EM_LineLength(wndPtr
, li
);
1736 EDIT_GetSel(wndPtr
, &s
, &e
);
1738 s
= MIN(li
+ ll
, MAX(li
, s
));
1739 e
= MIN(li
+ ll
, MAX(li
, e
));
1740 if (rev
&& (s
!= e
) &&
1741 ((es
->eState
& EF_FOCUSED
) || (wndPtr
->dwStyle
& ES_NOHIDESEL
)) ) {
1742 x
+= EDIT_PaintText(wndPtr
, hdc
, x
, y
, line
, 0, s
- li
, FALSE
);
1743 x
+= EDIT_PaintText(wndPtr
, hdc
, x
, y
, line
, s
- li
, e
- s
, TRUE
);
1744 x
+= EDIT_PaintText(wndPtr
, hdc
, x
, y
, line
, e
- li
, li
+ ll
- e
, FALSE
);
1746 x
+= EDIT_PaintText(wndPtr
, hdc
, x
, y
, line
, 0, ll
, FALSE
);
1750 /*********************************************************************
1755 static INT32
EDIT_PaintText(WND
*wndPtr
, HDC32 hdc
, INT32 x
, INT32 y
, INT32 line
, INT32 col
, INT32 count
, BOOL32 rev
)
1757 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1767 BkColor
= GetBkColor32(hdc
);
1768 TextColor
= GetTextColor32(hdc
);
1770 SetBkColor32(hdc
, GetSysColor32(COLOR_HIGHLIGHT
));
1771 SetTextColor32(hdc
, GetSysColor32(COLOR_HIGHLIGHTTEXT
));
1773 text
= EDIT_GetPasswordPointer(wndPtr
);
1774 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, line
);
1775 xoff
= EDIT_GetXOffset(wndPtr
);
1776 ret
= (INT32
)LOWORD(TabbedTextOut32A(hdc
, x
, y
, text
+ li
+ col
, count
,
1777 es
->NumTabStops
, es
->TabStops
, -xoff
));
1780 SetBkColor32(hdc
, BkColor
);
1781 SetTextColor32(hdc
, TextColor
);
1787 /*********************************************************************
1789 * EDIT_ReleasePointer
1791 * This is the only helper function that can be called with es = NULL.
1792 * It is called at the end of EditWndProc() to unlock the buffer.
1795 static void EDIT_ReleasePointer(WND
*wndPtr
)
1797 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1801 if (es
->text
&& (es
->hBuf32
|| es
->hBuf16
)) {
1803 LocalUnlock32(es
->hBuf32
);
1805 LOCAL_Unlock(wndPtr
->hInstance
, es
->hBuf16
);
1811 /*********************************************************************
1813 * EDIT_ReleaseUndoPointer
1815 * This is the only helper function that can be called with es = NULL.
1816 * It is called at the end of EditWndProc() to unlock the buffer.
1819 static void EDIT_ReleaseUndoPointer(WND
*wndPtr
)
1821 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1825 if (es
->UndoText
&& es
->hUndoBuf
)
1826 LocalUnlock32(es
->hUndoBuf
);
1827 es
->UndoText
= NULL
;
1831 /*********************************************************************
1835 * Beware: This is not the function called on EM_SETSEL.
1836 * This is the unordered version used internally
1837 * (s can be > e). Doesn't accept -1 parameters either.
1838 * No range checking.
1841 static void EDIT_SetSel(WND
*wndPtr
, INT32 ns
, INT32 ne
)
1843 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1848 EDIT_EM_GetSel(wndPtr
, (WPARAM32
)&s
, (LPARAM
)&e
);
1851 if (!IsNoRedraw(wndPtr
)) {
1852 if (es
->eState
& EF_FOCUSED
) {
1853 pos
= EDIT_EM_PosFromChar(wndPtr
, ne
);
1854 SetCaretPos16((INT16
)LOWORD(pos
), (INT16
)HIWORD(pos
));
1860 ORDER_INT32(ns
, ne
);
1862 EDIT_InvalidateText(wndPtr
, s
, e
);
1863 EDIT_InvalidateText(wndPtr
, ns
, ne
);
1865 EDIT_InvalidateText(wndPtr
, s
, ne
);
1870 /*********************************************************************
1874 * Calculates, for a given line and column, the X-coordinate on the screen.
1877 static INT32
EDIT_WndXFromCol(WND
*wndPtr
, INT32 line
, INT32 col
)
1879 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1880 LPSTR text
= EDIT_GetPasswordPointer(wndPtr
);
1884 HFONT32 oldFont
= 0;
1885 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
);
1886 INT32 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, line
);
1887 INT32 ll
= (INT32
)EDIT_EM_LineLength(wndPtr
, li
);
1888 INT32 xoff
= EDIT_GetXOffset(wndPtr
);
1890 hdc
= GetDC32(wndPtr
->hwndSelf
);
1891 hFont
= (HFONT32
)EDIT_WM_GetFont(wndPtr
);
1892 if (hFont
) oldFont
= SelectObject32(hdc
, hFont
);
1893 line
= MAX(0, MIN(line
, lc
- 1));
1895 ret
= (INT32
)LOWORD(GetTabbedTextExtent32A(hdc
,
1897 es
->NumTabStops
, es
->TabStops
)) - xoff
;
1898 if (hFont
) SelectObject32(hdc
, oldFont
);
1899 ReleaseDC32(wndPtr
->hwndSelf
, hdc
);
1905 /*********************************************************************
1909 * Calculates, for a given line, the Y-coordinate on the screen.
1912 static INT32
EDIT_WndYFromLine(WND
*wndPtr
, INT32 line
)
1914 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
);
1915 INT32 lh
= EDIT_GetLineHeight(wndPtr
);
1917 return (line
- fv
) * lh
;
1921 /*********************************************************************
1923 * EDIT_WordBreakProc
1925 * Find the beginning of words.
1926 * Note: unlike the specs for a WordBreakProc, this function only
1927 * allows to be called without linebreaks between s[0] upto
1928 * s[count - 1]. Remember it is only called
1929 * internally, so we can decide this for ourselves.
1932 static INT32
EDIT_WordBreakProc(LPSTR s
, INT32 index
, INT32 count
, INT32 action
)
1936 dprintf_edit(stddeb
, "edit: EDIT_WordBreakProc: s=%p, index=%u"
1937 ", count=%u, action=%d\n", s
, index
, count
, action
);
1945 if (s
[index
] == ' ') {
1946 while (index
&& (s
[index
] == ' '))
1949 while (index
&& (s
[index
] != ' '))
1951 if (s
[index
] == ' ')
1955 while (index
&& (s
[index
] != ' '))
1957 if (s
[index
] == ' ')
1967 if (s
[index
] == ' ')
1968 while ((index
< count
) && (s
[index
] == ' ')) index
++;
1970 while (s
[index
] && (s
[index
] != ' ') && (index
< count
))
1972 while ((s
[index
] == ' ') && (index
< count
)) index
++;
1976 case WB_ISDELIMITER
:
1977 ret
= (s
[index
] == ' ');
1980 fprintf(stderr
, "edit: EDIT_WordBreakProc: unknown action code, please report !\n");
1987 /*********************************************************************
1992 static LRESULT
EDIT_EM_CanUndo(WND
*wndPtr
)
1994 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
1996 return (LRESULT
)(es
->UndoInsertLen
|| lstrlen32A(EDIT_GetUndoPointer(wndPtr
)));
2000 /*********************************************************************
2004 * FIXME: do the specs mean LineIndex or LineNumber (li v.s. l) ???
2006 static LRESULT
EDIT_EM_CharFromPos(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2014 pt
.x
= LOWORD(lParam
);
2015 pt
.y
= HIWORD(lParam
);
2016 GetClientRect32(wndPtr
->hwndSelf
, &rc
);
2018 if (!PtInRect32(&rc
, pt
))
2021 l
= EDIT_LineFromWndY(wndPtr
, pt
.y
);
2022 li
= EDIT_EM_LineIndex(wndPtr
, l
);
2023 c
= EDIT_ColFromWndX(wndPtr
, l
, pt
.x
);
2025 return (LRESULT
)MAKELONG(li
+ c
, li
);
2029 /*********************************************************************
2031 * EM_EMPTYUNDOBUFFER
2034 static LRESULT
EDIT_EM_EmptyUndoBuffer(WND
*wndPtr
)
2036 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2038 es
->UndoInsertLen
= 0;
2039 *EDIT_GetUndoPointer(wndPtr
) = '\0';
2044 /*********************************************************************
2049 static LRESULT
EDIT_EM_FmtLines(WND
*wndPtr
, WPARAM32 wParam
)
2051 fprintf(stdnimp
, "edit: EM_FMTLINES: message not implemented\n");
2052 return wParam
? TRUE
: FALSE
;
2056 /*********************************************************************
2058 * EM_GETFIRSTVISIBLELINE
2061 static LRESULT
EDIT_EM_GetFirstVisibleLine(WND
*wndPtr
)
2063 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2065 if (IsMultiLine(wndPtr
))
2066 return (LRESULT
)es
->FirstVisibleLine
;
2068 return (LRESULT
)EDIT_ColFromWndX(wndPtr
, 0, 0);
2072 /*********************************************************************
2077 static LRESULT
EDIT_EM_GetHandle(WND
*wndPtr
)
2079 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2081 if (!IsMultiLine(wndPtr
))
2085 return (LRESULT
)es
->hBuf32
;
2087 return (LRESULT
)es
->hBuf16
;
2091 /*********************************************************************
2095 * Hopefully this won't fire back at us.
2096 * We always start with a buffer in 32 bit linear memory.
2097 * However, with this message a 16 bit application requests
2098 * a handle of 16 bit local heap memory, where it expects to find
2100 * It's a pitty that from this moment on we have to use this
2101 * local heap, because applications may rely on the handle
2104 * In this function we'll try to switch to local heap.
2106 static LRESULT
EDIT_EM_GetHandle16(WND
*wndPtr
)
2108 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2114 if (!IsMultiLine(wndPtr
))
2118 return (LRESULT
)es
->hBuf16
;
2120 if (!LOCAL_HeapSize(wndPtr
->hInstance
)) {
2121 if (!LocalInit(wndPtr
->hInstance
, 0,
2122 GlobalSize16(wndPtr
->hInstance
))) {
2123 fprintf(stderr
, "edit: EM_GETHANDLE: could not initialize local heap\n");
2126 dprintf_edit(stddeb
, "edit: EM_GETHANDLE: local heap initialized\n");
2128 if (!(newBuf
= LOCAL_Alloc(wndPtr
->hInstance
, LMEM_MOVEABLE
,
2129 EDIT_WM_GetTextLength(wndPtr
) + 1))) {
2130 fprintf(stderr
, "edit: EM_GETHANDLE: could not allocate new 16 bit buffer\n");
2133 newSize
= MIN(LOCAL_Size(wndPtr
->hInstance
, newBuf
) - 1, es
->BufLimit
);
2134 if (!(newText
= LOCAL_Lock(wndPtr
->hInstance
, newBuf
))) {
2135 fprintf(stderr
, "edit: EM_GETHANDLE: could not lock new 16 bit buffer\n");
2136 LOCAL_Free(wndPtr
->hInstance
, newBuf
);
2139 text
= EDIT_GetPointer(wndPtr
);
2140 lstrcpy32A(newText
, text
);
2141 EDIT_ReleasePointer(wndPtr
);
2142 GlobalFree32(es
->hBuf32
);
2143 es
->hBuf32
= (HLOCAL32
)NULL
;
2144 es
->hBuf16
= newBuf
;
2145 es
->BufSize
= newSize
;
2147 dprintf_edit(stddeb
, "edit: EM_GETHANDLE: switched to 16 bit buffer\n");
2149 return (LRESULT
)es
->hBuf16
;
2153 /*********************************************************************
2158 static LRESULT
EDIT_EM_GetLimitText(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2160 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2162 return es
->BufLimit
;
2166 /*********************************************************************
2171 static LRESULT
EDIT_EM_GetLine(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2178 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
);
2180 if (!IsMultiLine(wndPtr
))
2182 if ((INT32
)wParam
>= lc
)
2184 text
= EDIT_GetPointer(wndPtr
);
2185 src
= text
+ (INT32
)EDIT_EM_LineIndex(wndPtr
, wParam
);
2186 dst
= (LPSTR
)lParam
;
2187 len
= MIN(*(WORD
*)dst
, (INT32
)EDIT_EM_LineLength(wndPtr
, wParam
));
2188 for (i
= 0 ; i
< len
; i
++) {
2193 return (LRESULT
)len
;
2197 /*********************************************************************
2202 static LRESULT
EDIT_EM_GetLineCount(WND
*wndPtr
)
2204 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2206 return (LRESULT
)es
->LineCount
;
2210 /*********************************************************************
2215 static LRESULT
EDIT_EM_GetMargins(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2217 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2219 return (LRESULT
)MAKELONG(es
->LeftMargin
, es
->RightMargin
);
2223 /*********************************************************************
2228 static LRESULT
EDIT_EM_GetModify(WND
*wndPtr
)
2230 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2232 return (LRESULT
)((es
->eState
& EF_TEXTCHANGED
) != 0);
2236 /*********************************************************************
2238 * EM_GETPASSWORDCHAR
2241 static LRESULT
EDIT_EM_GetPasswordChar(WND
*wndPtr
)
2243 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2245 return (LRESULT
)es
->PasswordChar
;
2249 /*********************************************************************
2254 static LRESULT
EDIT_EM_GetRect(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2256 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2258 CopyRect32((LPRECT32
)lParam
, &es
->FormatRect
);
2263 /*********************************************************************
2268 static LRESULT
EDIT_EM_GetRect16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2270 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2272 CONV_RECT32TO16(&es
->FormatRect
, (LPRECT16
)PTR_SEG_TO_LIN((SEGPTR
)lParam
));
2277 /*********************************************************************
2281 * Returns the ordered selection range so that
2282 * LOWORD(result) < HIWORD(result)
2285 static LRESULT
EDIT_EM_GetSel(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2290 EDIT_GetSel(wndPtr
, &s
, &e
);
2293 *(LPINT32
)wParam
= s
;
2295 *(LPINT32
)lParam
= e
;
2296 return MAKELONG((INT16
)s
, (INT16
)e
);
2300 /*********************************************************************
2304 * FIXME: is this right ? (or should it be only HSCROLL)
2305 * (and maybe only for edit controls that really have their
2306 * own scrollbars) (and maybe only for multiline controls ?)
2307 * All in all: very poorly documented
2310 static LRESULT
EDIT_EM_GetThumb(WND
*wndPtr
)
2312 return MAKELONG(EDIT_WM_VScroll(wndPtr
, EM_GETTHUMB16
, 0),
2313 EDIT_WM_HScroll(wndPtr
, EM_GETTHUMB16
, 0));
2317 /*********************************************************************
2319 * EM_GETWORDBREAKPROC
2321 * FIXME: Application defined WordBreakProc should be returned
2324 static LRESULT
EDIT_EM_GetWordBreakProc(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2327 EDITSTATE *es = EDITSTATEPTR(wndPtr);
2329 return (LRESULT)es->WordBreakProc;
2335 /*********************************************************************
2340 static LRESULT
EDIT_EM_LineFromChar(WND
*wndPtr
, WPARAM32 wParam
)
2344 if (!IsMultiLine(wndPtr
))
2346 if ((INT32
)wParam
== -1)
2347 EDIT_EM_GetSel(wndPtr
, (WPARAM32
)&wParam
, 0); /* intentional (looks weird, doesn't it ?) */
2348 l
= (INT32
)EDIT_EM_GetLineCount(wndPtr
) - 1;
2349 while ((INT32
)EDIT_EM_LineIndex(wndPtr
, l
) > (INT32
)wParam
)
2355 /*********************************************************************
2360 static LRESULT
EDIT_EM_LineIndex(WND
*wndPtr
, WPARAM32 wParam
)
2362 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2365 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
);
2367 if ((INT32
)wParam
== -1) {
2368 EDIT_GetSel(wndPtr
, NULL
, &e
);
2370 while (es
->LineDefs
[l
].offset
> e
)
2372 return (LRESULT
)es
->LineDefs
[l
].offset
;
2374 if ((INT32
)wParam
>= lc
)
2376 return (LRESULT
)es
->LineDefs
[(INT32
)wParam
].offset
;
2380 /*********************************************************************
2385 static LRESULT
EDIT_EM_LineLength(WND
*wndPtr
, WPARAM32 wParam
)
2387 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2393 if (!IsMultiLine(wndPtr
))
2394 return (LRESULT
)es
->LineDefs
[0].length
;
2395 if ((INT32
)wParam
== -1) {
2396 EDIT_GetSel(wndPtr
, &s
, &e
);
2397 sl
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, s
);
2398 el
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
);
2399 return (LRESULT
)(s
- es
->LineDefs
[sl
].offset
+
2400 es
->LineDefs
[el
].offset
+
2401 es
->LineDefs
[el
].length
- e
);
2403 return (LRESULT
)es
->LineDefs
[(INT32
)EDIT_EM_LineFromChar(wndPtr
, wParam
)].length
;
2407 /*********************************************************************
2411 * FIXME: is wParam in pixels or in average character widths ???
2412 * FIXME: we use this internally to scroll single line controls as well
2413 * (specs are vague about whether this message is valid or not for
2414 * single line controls)
2417 static LRESULT
EDIT_EM_LineScroll(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2419 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2420 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
);
2421 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
);
2422 INT32 nfv
= MAX(0, fv
+ (INT32
)lParam
);
2423 INT32 xoff
= EDIT_GetXOffset(wndPtr
);
2424 INT32 nxoff
= MAX(0, xoff
+ (INT32
)wParam
);
2425 INT32 tw
= EDIT_GetTextWidth(wndPtr
);
2435 dy
= EDIT_WndYFromLine(wndPtr
, fv
) - EDIT_WndYFromLine(wndPtr
, nfv
);
2437 if (!IsNoRedraw(wndPtr
))
2438 ScrollWindowEx32(wndPtr
->hwndSelf
, dx
, dy
,
2439 NULL
, NULL
, 0, NULL
, (SW_INVALIDATE
| SW_ERASE
));
2440 es
->FirstVisibleLine
= nfv
;
2441 es
->XOffset
= nxoff
;
2442 if (IsVScrollBar(wndPtr
))
2443 SetScrollPos32(wndPtr
->hwndSelf
, SB_VERT
,
2444 EDIT_WM_VScroll(wndPtr
, EM_GETTHUMB16
, 0), TRUE
);
2445 if (IsHScrollBar(wndPtr
))
2446 SetScrollPos32(wndPtr
->hwndSelf
, SB_HORZ
,
2447 EDIT_WM_HScroll(wndPtr
, EM_GETTHUMB16
, 0), TRUE
);
2449 if (IsMultiLine(wndPtr
))
2456 /*********************************************************************
2461 static LRESULT
EDIT_EM_PosFromChar(WND
*wndPtr
, WPARAM32 wParam
)
2463 INT32 len
= (INT32
)EDIT_WM_GetTextLength(wndPtr
);
2467 wParam
= MIN(wParam
, len
);
2468 l
= EDIT_EM_LineFromChar(wndPtr
, wParam
);
2469 li
= EDIT_EM_LineIndex(wndPtr
, l
);
2470 return (LRESULT
)MAKELONG(EDIT_WndXFromCol(wndPtr
, l
, wParam
- li
),
2471 EDIT_WndYFromLine(wndPtr
, l
));
2475 /*********************************************************************
2480 static LRESULT
EDIT_EM_ReplaceSel(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2482 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2483 LPCSTR str
= (LPCSTR
)lParam
;
2484 INT32 strl
= lstrlen32A(str
);
2485 INT32 tl
= (INT32
)EDIT_WM_GetTextLength(wndPtr
);
2495 EDIT_EM_GetSel(wndPtr
, (WPARAM32
)&s
, (LPARAM
)&e
);
2497 if ((s
== e
) && !strl
)
2500 if (!EDIT_MakeFit(wndPtr
, tl
- (e
- s
) + strl
))
2503 text
= EDIT_GetPointer(wndPtr
);
2504 utext
= EDIT_GetUndoPointer(wndPtr
);
2506 /* there is something to be deleted */
2507 if ((BOOL32
)wParam
) {
2508 /* we have to be able to undo */
2509 utl
= lstrlen32A(utext
);
2510 if (!es
->UndoInsertLen
&& (*utext
&& (s
== es
->UndoPos
))) {
2511 /* undo-buffer is extended to the right */
2512 EDIT_MakeUndoFit(wndPtr
, utl
+ e
- s
);
2513 lstrcpyn32A(utext
+ utl
, text
+ s
, e
- s
+ 1);
2514 } else if (!es
->UndoInsertLen
&& (*utext
&& (e
== es
->UndoPos
))) {
2515 /* undo-buffer is extended to the left */
2516 EDIT_MakeUndoFit(wndPtr
, utl
+ e
- s
);
2517 for (p
= utext
+ utl
; p
>= utext
; p
--)
2519 for (i
= 0 , p
= utext
; i
< e
- s
; i
++)
2520 p
[i
] = (text
+ s
)[i
];
2523 /* new undo-buffer */
2524 EDIT_MakeUndoFit(wndPtr
, e
- s
);
2525 lstrcpyn32A(utext
, text
+ s
, e
- s
+ 1);
2528 /* any deletion makes the old insertion-undo invalid */
2529 es
->UndoInsertLen
= 0;
2531 EDIT_EM_EmptyUndoBuffer(wndPtr
);
2534 lstrcpy32A(text
+ s
, text
+ e
);
2537 /* there is an insertion */
2538 if ((BOOL32
)wParam
) {
2539 /* we have to be able to undo */
2540 if ((s
== es
->UndoPos
) ||
2541 ((es
->UndoInsertLen
) &&
2542 (s
== es
->UndoPos
+ es
->UndoInsertLen
)))
2544 * insertion is new and at delete position or
2545 * an extension to either left or right
2547 es
->UndoInsertLen
+= strl
;
2549 /* new insertion undo */
2551 es
->UndoInsertLen
= strl
;
2552 /* new insertion makes old delete-buffer invalid */
2556 EDIT_EM_EmptyUndoBuffer(wndPtr
);
2559 tl
= lstrlen32A(text
);
2560 for (p
= text
+ tl
; p
>= text
+ s
; p
--)
2562 for (i
= 0 , p
= text
+ s
; i
< strl
; i
++)
2565 CharUpperBuff32A(p
, strl
);
2566 else if(IsLower(wndPtr
))
2567 CharLowerBuff32A(p
, strl
);
2570 redraw
= !IsNoRedraw(wndPtr
);
2571 EDIT_WM_SetRedraw(wndPtr
, FALSE
);
2572 EDIT_BuildLineDefs(wndPtr
);
2573 EDIT_EM_SetSel(wndPtr
, s
, s
);
2574 EDIT_EM_ScrollCaret(wndPtr
);
2575 EDIT_EM_SetModify(wndPtr
, TRUE
);
2576 dprintf_edit(stddeb
, "edit: notification EN_UPDATE sent\n");
2577 EDIT_NOTIFY_PARENT(wndPtr
, EN_UPDATE
);
2578 EDIT_WM_SetRedraw(wndPtr
, redraw
);
2580 InvalidateRect32( wndPtr
->hwndSelf
, NULL
, TRUE
);
2581 dprintf_edit(stddeb
, "edit: notification EN_CHANGE sent\n");
2582 EDIT_NOTIFY_PARENT(wndPtr
, EN_CHANGE
);
2588 /*********************************************************************
2592 static LRESULT
EDIT_EM_Scroll(WND
*wndPtr
, WPARAM32 wParam
)
2605 dy
= EDIT_GetVisibleLineCount(wndPtr
);
2606 if( wParam
== SB_PAGEUP
) dy
= -dy
;
2612 EDIT_EM_LineScroll(wndPtr
, 0, dy
);
2613 dprintf_edit(stddeb
, "edit: notification EN_VSCROLL sent\n");
2614 EDIT_NOTIFY_PARENT(wndPtr
, EN_VSCROLL
);
2616 return MAKELONG( ((UINT16
)(INT16
)dy
), TRUE
);
2620 /*********************************************************************
2624 * Makes sure the caret is visible.
2625 * FIXME: We use EM_LINESCROLL, but may we do that for single line
2629 static LRESULT
EDIT_EM_ScrollCaret(WND
*wndPtr
)
2634 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
);
2635 INT32 vlc
= EDIT_GetVisibleLineCount(wndPtr
);
2636 INT32 ww
= EDIT_GetWndWidth(wndPtr
);
2637 INT32 cw
= EDIT_GetAveCharWidth(wndPtr
);
2642 EDIT_GetSel(wndPtr
, NULL
, &e
);
2643 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
);
2644 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
);
2645 x
= EDIT_WndXFromCol(wndPtr
, l
, e
- li
);
2647 dy
= l
- vlc
+ 1 - fv
;
2651 dx
= x
- ww
/ HSCROLL_FRACTION
/ cw
* cw
;
2653 dx
= x
- (HSCROLL_FRACTION
- 1) * ww
/ HSCROLL_FRACTION
/ cw
* cw
;
2655 EDIT_EM_LineScroll(wndPtr
, dx
, dy
);
2657 dprintf_edit(stddeb
, "edit: notification EN_VSCROLL sent\n");
2658 EDIT_NOTIFY_PARENT(wndPtr
, EN_VSCROLL
);
2661 dprintf_edit(stddeb
, "edit: notification EN_HSCROLL sent\n");
2662 EDIT_NOTIFY_PARENT(wndPtr
, EN_HSCROLL
);
2669 /*********************************************************************
2674 static LRESULT
EDIT_EM_SetHandle(WND
*wndPtr
, WPARAM32 wParam
)
2676 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2678 if (IsMultiLine(wndPtr
)) {
2679 EDIT_ReleasePointer(wndPtr
);
2681 * old buffer is freed by caller
2683 es
->hBuf16
= (HLOCAL16
)NULL
;
2684 es
->hBuf32
= (HLOCAL32
)wParam
;
2685 es
->BufSize
= LocalSize32(es
->hBuf32
) - 1;
2687 es
->FirstVisibleLine
= 0;
2688 es
->SelStart
= es
->SelEnd
= 0;
2689 EDIT_EM_EmptyUndoBuffer(wndPtr
);
2690 EDIT_EM_SetModify(wndPtr
, FALSE
);
2691 EDIT_BuildLineDefs(wndPtr
);
2692 if (!IsNoRedraw(wndPtr
))
2693 InvalidateRect32( wndPtr
->hwndSelf
, NULL
, TRUE
);
2694 EDIT_EM_ScrollCaret(wndPtr
);
2700 /*********************************************************************
2705 static LRESULT
EDIT_EM_SetHandle16(WND
*wndPtr
, WPARAM32 wParam
)
2707 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2709 if (IsMultiLine(wndPtr
)) {
2710 EDIT_ReleasePointer(wndPtr
);
2712 * old buffer is freed by caller
2714 es
->hBuf16
= (HLOCAL16
)wParam
;
2715 es
->hBuf32
= (HLOCAL32
)NULL
;
2716 es
->BufSize
= LOCAL_Size(wndPtr
->hInstance
, es
->hBuf16
) - 1;
2718 es
->FirstVisibleLine
= 0;
2719 es
->SelStart
= es
->SelEnd
= 0;
2720 EDIT_EM_EmptyUndoBuffer(wndPtr
);
2721 EDIT_EM_SetModify(wndPtr
, FALSE
);
2722 EDIT_BuildLineDefs(wndPtr
);
2723 if (!IsNoRedraw(wndPtr
))
2724 InvalidateRect32( wndPtr
->hwndSelf
, NULL
, TRUE
);
2725 EDIT_EM_ScrollCaret(wndPtr
);
2731 /*********************************************************************
2735 * FIXME: in WinNT maxsize is 0x7FFFFFFF / 0xFFFFFFFF
2736 * However, the windows version is not complied to yet in all of edit.c
2739 static LRESULT
EDIT_EM_SetLimitText(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2741 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2743 if (IsMultiLine(wndPtr
)) {
2745 es
->BufLimit
= MIN((INT32
)wParam
, BUFLIMIT_MULTI
);
2747 es
->BufLimit
= BUFLIMIT_MULTI
;
2750 es
->BufLimit
= MIN((INT32
)wParam
, BUFLIMIT_SINGLE
);
2752 es
->BufLimit
= BUFLIMIT_SINGLE
;
2758 /*********************************************************************
2762 * FIXME: We let the margins be set, but we don't use them yet !?!
2765 static LRESULT
EDIT_EM_SetMargins(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2767 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2769 if (wParam
& EC_USEFONTINFO
) {
2770 if (IsMultiLine(wndPtr
)) {
2772 * FIXME: do some GetABCCharWidth, or so
2773 * This is just preliminary
2775 es
->LeftMargin
= es
->RightMargin
= EDIT_GetAveCharWidth(wndPtr
);
2777 es
->LeftMargin
= es
->RightMargin
= EDIT_GetAveCharWidth(wndPtr
);
2780 if (wParam
& EC_LEFTMARGIN
)
2781 es
->LeftMargin
= LOWORD(lParam
);
2782 if (wParam
& EC_RIGHTMARGIN
)
2783 es
->RightMargin
= HIWORD(lParam
);
2788 /*********************************************************************
2793 static LRESULT
EDIT_EM_SetModify(WND
*wndPtr
, WPARAM32 wParam
)
2795 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2798 es
->eState
|= EF_TEXTCHANGED
;
2800 es
->eState
&= ~EF_TEXTCHANGED
;
2805 /*********************************************************************
2807 * EM_SETPASSWORDCHAR
2809 * FIXME: This imlementation is way too simple
2812 static LRESULT
EDIT_EM_SetPasswordChar(WND
*wndPtr
, WPARAM32 wParam
)
2814 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2816 es
->PasswordChar
= (CHAR
)wParam
;
2821 /*********************************************************************
2826 static LRESULT
EDIT_EM_SetReadOnly(WND
*wndPtr
, WPARAM32 wParam
)
2829 wndPtr
->dwStyle
|= ES_READONLY
;
2831 wndPtr
->dwStyle
&= ~(DWORD
)ES_READONLY
;
2836 /*********************************************************************
2841 static LRESULT
EDIT_EM_SetRect(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2843 fprintf(stdnimp
,"edit: EM_SETRECT: message not implemented\n");
2848 /*********************************************************************
2853 static LRESULT
EDIT_EM_SetRectNP(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2855 fprintf(stdnimp
,"edit: EM_SETRECTNP: message not implemented\n");
2860 /*********************************************************************
2865 static LRESULT
EDIT_EM_SetSel(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2867 INT32 ns
= (INT32
)wParam
;
2868 INT32 ne
= (INT32
)lParam
;
2869 INT32 tl
= (INT32
)EDIT_WM_GetTextLength(wndPtr
);
2872 EDIT_GetSel(wndPtr
, NULL
, &ne
);
2874 } else if ((!ns
) && (ne
== -1))
2877 ns
= MAX(0, MIN(ns
, tl
));
2878 ne
= MAX(0, MIN(ne
, tl
));
2879 ORDER_INT32(ns
, ne
);
2881 EDIT_SetSel(wndPtr
, ns
, ne
);
2886 /*********************************************************************
2891 static LRESULT
EDIT_EM_SetSel16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2893 INT32 ns
= (INT32
)LOWORD(lParam
);
2894 INT32 ne
= (INT32
)HIWORD(lParam
);
2896 if ((INT16
)LOWORD(lParam
) == -1)
2898 if ((!ns
) && ((INT16
)HIWORD(lParam
) == -1))
2900 EDIT_EM_SetSel(wndPtr
, ns
, ne
);
2902 EDIT_EM_ScrollCaret(wndPtr
);
2907 /*********************************************************************
2912 static LRESULT
EDIT_EM_SetTabStops(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2914 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2916 if (!IsMultiLine(wndPtr
))
2920 es
->NumTabStops
= (INT32
)wParam
;
2922 es
->TabStops
= NULL
;
2924 es
->TabStops
= (LPINT32
)xmalloc(wParam
* sizeof(INT32
));
2925 memcpy( es
->TabStops
, (LPINT32
)lParam
,
2926 (INT32
)wParam
* sizeof(INT32
) );
2932 /*********************************************************************
2937 static LRESULT
EDIT_EM_SetTabStops16(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2939 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2942 if (!IsMultiLine(wndPtr
))
2946 es
->NumTabStops
= (INT32
)wParam
;
2948 es
->TabStops
= NULL
;
2951 LPINT16 p
= (LPINT16
)PTR_SEG_TO_LIN(lParam
);
2952 es
->TabStops
= (LPINT32
)xmalloc(wParam
* sizeof(INT32
));
2953 for ( i
= 0 ; i
< (INT32
)wParam
; i
++) es
->TabStops
[i
] = *p
++;
2959 /*********************************************************************
2961 * EM_SETWORDBREAKPROC
2964 static LRESULT
EDIT_EM_SetWordBreakProc(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
2967 EDITSTATE *es = EDITSTATEPTR(wndPtr);
2969 es->WordBreakProc = (EDITWORDBREAKPROC)lParam;
2975 /*********************************************************************
2980 static LRESULT
EDIT_EM_Undo(WND
*wndPtr
)
2982 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
2983 LPSTR utext
= xstrdup(EDIT_GetUndoPointer(wndPtr
));
2985 dprintf_edit(stddeb
, "edit: before UNDO:insertion length = %d, deletion buffer = %s\n",
2986 es
->UndoInsertLen
, utext
);
2988 EDIT_EM_SetSel(wndPtr
, es
->UndoPos
, es
->UndoPos
+ es
->UndoInsertLen
);
2989 EDIT_EM_EmptyUndoBuffer(wndPtr
);
2990 EDIT_EM_ReplaceSel(wndPtr
, TRUE
, (LPARAM
)utext
);
2991 EDIT_EM_SetSel(wndPtr
, es
->UndoPos
, es
->UndoPos
+ es
->UndoInsertLen
);
2994 dprintf_edit(stddeb
, "edit: after UNDO: insertion length = %d, deletion buffer = %s\n",
2995 es
->UndoInsertLen
, EDIT_GetUndoPointer(wndPtr
));
3001 /*********************************************************************
3006 static LRESULT
EDIT_WM_Char(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3009 unsigned char c
= (unsigned char)wParam
;
3014 if (IsMultiLine(wndPtr
)) {
3015 if (IsReadOnly(wndPtr
)) {
3016 EDIT_MoveHome(wndPtr
, FALSE
);
3017 EDIT_MoveDownward(wndPtr
, FALSE
);
3019 EDIT_EM_ReplaceSel(wndPtr
, (WPARAM32
)TRUE
, (LPARAM
)"\r\n");
3023 if (IsMultiLine(wndPtr
) && !IsReadOnly(wndPtr
))
3024 EDIT_EM_ReplaceSel(wndPtr
, (WPARAM32
)TRUE
, (LPARAM
)"\t");
3027 if (!IsReadOnly(wndPtr
) && (c
>= ' ') && (c
!= 127)) {
3030 EDIT_EM_ReplaceSel(wndPtr
, (WPARAM32
)TRUE
, (LPARAM
)str
);
3038 /*********************************************************************
3043 static LRESULT
EDIT_WM_Clear(WND
*wndPtr
)
3045 EDIT_EM_ReplaceSel(wndPtr
, TRUE
, (LPARAM
)"");
3051 /*********************************************************************
3056 static LRESULT
EDIT_WM_Command(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3061 switch (LOWORD(wParam
)) {
3063 EDIT_EM_Undo(wndPtr
);
3066 EDIT_WM_Cut(wndPtr
);
3069 EDIT_WM_Copy(wndPtr
);
3072 EDIT_WM_Paste(wndPtr
);
3075 EDIT_WM_Clear(wndPtr
);
3078 EDIT_EM_SetSel(wndPtr
, 0, -1);
3079 EDIT_EM_ScrollCaret(wndPtr
);
3082 dprintf_edit(stddeb
, "edit: unknown menu item, please report\n");
3089 /*********************************************************************
3093 * Note: the resource files resource/sysres_??.rc cannot define a
3094 * single popup menu. Hence we use a (dummy) menubar
3095 * containing the single popup menu as its first item.
3098 static LRESULT
EDIT_WM_ContextMenu(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3100 HMENU32 hMenu
= LoadMenuIndirect32A(SYSRES_GetResPtr(SYSRES_MENU_EDITMENU
));
3101 HMENU32 hPopup
= GetSubMenu32(hMenu
, 0);
3103 TrackPopupMenu32(hPopup
, TPM_LEFTALIGN
| TPM_RIGHTBUTTON
, LOWORD(lParam
),
3104 HIWORD(lParam
), 0, wndPtr
->hwndSelf
, NULL
);
3105 DestroyMenu32(hMenu
);
3110 /*********************************************************************
3115 static LRESULT
EDIT_WM_Copy(WND
*wndPtr
)
3123 EDIT_GetSel(wndPtr
, &s
, &e
);
3127 hdst
= GlobalAlloc16(GMEM_MOVEABLE
, (DWORD
)(e
- s
+ 1));
3128 dst
= GlobalLock16(hdst
);
3129 text
= EDIT_GetPointer(wndPtr
);
3130 lstrcpyn32A(dst
, text
+ s
, e
- s
+ 1);
3131 GlobalUnlock16(hdst
);
3132 OpenClipboard32(wndPtr
->hwndSelf
);
3134 SetClipboardData16(CF_TEXT
, hdst
);
3140 /*********************************************************************
3145 static LRESULT
EDIT_WM_Create(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3147 CREATESTRUCT32A
*cs
= (CREATESTRUCT32A
*)lParam
;
3151 es
= xmalloc(sizeof(EDITSTATE
));
3152 memset(es
, 0, sizeof(EDITSTATE
));
3153 *(EDITSTATE
**)wndPtr
->wExtra
= es
;
3155 if (cs
->style
& WS_VSCROLL
)
3156 cs
->style
|= ES_AUTOVSCROLL
;
3157 if (cs
->style
& WS_HSCROLL
)
3158 cs
->style
|= ES_AUTOHSCROLL
;
3160 /* remove the WS_CAPTION style if it has been set - this is really a */
3161 /* pseudo option made from a combination of WS_BORDER and WS_DLGFRAME */
3162 if ((cs
->style
& WS_BORDER
) && (cs
->style
& WS_DLGFRAME
))
3163 cs
->style
^= WS_DLGFRAME
;
3165 if (IsMultiLine(wndPtr
)) {
3166 es
->BufSize
= BUFSTART_MULTI
;
3167 es
->BufLimit
= BUFLIMIT_MULTI
;
3168 es
->PasswordChar
= '\0';
3170 es
->BufSize
= BUFSTART_SINGLE
;
3171 es
->BufLimit
= BUFLIMIT_SINGLE
;
3172 es
->PasswordChar
= (cs
->style
& ES_PASSWORD
) ? '*' : '\0';
3174 if (!(es
->hBuf32
= LocalAlloc32(LMEM_MOVEABLE
, es
->BufSize
+ 1))) {
3175 fprintf(stderr
, "edit: WM_CREATE: unable to allocate buffer\n");
3178 if (!(es
->hUndoBuf
= LocalAlloc32(LMEM_MOVEABLE
, es
->BufSize
+ 1))) {
3179 fprintf(stderr
, "edit: WM_CREATE: unable to allocate undo buffer\n");
3180 LocalFree32(es
->hBuf32
);
3181 es
->hBuf32
= (HLOCAL32
)NULL
;
3184 es
->BufSize
= LocalSize32(es
->hBuf32
) - 1;
3185 es
->UndoBufSize
= LocalSize32(es
->hUndoBuf
) - 1;
3186 EDIT_EM_EmptyUndoBuffer(wndPtr
);
3187 text
= EDIT_GetPointer(wndPtr
);
3189 EDIT_BuildLineDefs(wndPtr
);
3190 EDIT_WM_SetFont(wndPtr
, 0, 0);
3191 if (cs
->lpszName
&& *(cs
->lpszName
) != '\0')
3192 EDIT_EM_ReplaceSel(wndPtr
, (WPARAM32
)FALSE
, (LPARAM
)cs
->lpszName
);
3193 EDIT_WM_SetRedraw(wndPtr
, TRUE
);
3198 /*********************************************************************
3203 static LRESULT
EDIT_WM_Cut(WND
*wndPtr
)
3205 EDIT_WM_Copy(wndPtr
);
3206 EDIT_WM_Clear(wndPtr
);
3211 /*********************************************************************
3216 static LRESULT
EDIT_WM_Destroy(WND
*wndPtr
)
3218 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
3223 EDIT_ReleaseUndoPointer(wndPtr
);
3224 LocalFree32(es
->hUndoBuf
);
3225 EDIT_ReleasePointer(wndPtr
);
3227 LocalFree32(es
->hBuf32
);
3229 LOCAL_Free(wndPtr
->hInstance
, es
->hBuf16
);
3231 wndPtr
->wExtra
[0] = 0;
3237 /*********************************************************************
3242 static LRESULT
EDIT_WM_Enable(WND
*wndPtr
, WPARAM32 wParam
)
3244 EDIT_InvalidateText(wndPtr
, 0, -1);
3249 /*********************************************************************
3254 static LRESULT
EDIT_WM_EraseBkGnd(WND
*wndPtr
, WPARAM32 wParam
)
3259 hBrush
= (HBRUSH32
)EDIT_SEND_CTLCOLOR(wndPtr
, wParam
);
3260 if (!hBrush
) hBrush
= (HBRUSH32
)GetStockObject32(WHITE_BRUSH
);
3262 GetClientRect32(wndPtr
->hwndSelf
, &rc
);
3263 IntersectClipRect32((HDC32
)wParam
, rc
.left
, rc
.top
,
3264 rc
.right
, rc
.bottom
);
3265 GetClipBox32((HDC32
)wParam
, &rc
);
3267 * FIXME: specs say that we should UnrealizeObject() the brush,
3268 * but the specs of UnrealizeObject() say that we shouldn't
3269 * unrealize a stock object. The default brush that
3270 * DefWndProc() returns is ... a stock object.
3272 FillRect32((HDC32
)wParam
, &rc
, hBrush
);
3277 /*********************************************************************
3282 static LRESULT
EDIT_WM_GetDlgCode(WND
*wndPtr
)
3284 return DLGC_HASSETSEL
| DLGC_WANTCHARS
| DLGC_WANTARROWS
;
3288 /*********************************************************************
3293 static LRESULT
EDIT_WM_GetFont(WND
*wndPtr
)
3295 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
3297 return (LRESULT
)es
->hFont
;
3301 /*********************************************************************
3306 static LRESULT
EDIT_WM_GetText(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3308 LPSTR text
= EDIT_GetPointer(wndPtr
);
3310 LRESULT lResult
= 0;
3312 len
= lstrlen32A(text
);
3313 if ((INT32
)wParam
> len
) {
3314 lstrcpy32A((LPSTR
)lParam
, text
);
3315 lResult
= (LRESULT
)len
+ 1;
3321 /*********************************************************************
3326 static LRESULT
EDIT_WM_GetTextLength(WND
*wndPtr
)
3328 LPSTR text
= EDIT_GetPointer(wndPtr
);
3330 return (LRESULT
)lstrlen32A(text
);
3334 /*********************************************************************
3338 * FIXME: scrollbar code itself is broken, so this one is a hack.
3341 static LRESULT
EDIT_WM_HScroll(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3343 INT32 ww
= EDIT_GetWndWidth(wndPtr
);
3344 INT32 tw
= EDIT_GetTextWidth(wndPtr
);
3345 INT32 cw
= EDIT_GetAveCharWidth(wndPtr
);
3346 INT32 xoff
= EDIT_GetXOffset(wndPtr
);
3359 dx
= -ww
/ HSCROLL_FRACTION
/ cw
* cw
;
3362 dx
= ww
/ HSCROLL_FRACTION
/ cw
* cw
;
3374 case SB_THUMBPOSITION
:
3375 dx
= HIWORD(wParam
) * tw
/ 100 - xoff
;
3377 /* The next two are undocumented ! */
3379 ret
= tw
? xoff
* 100 / tw
: 0;
3381 case EM_LINESCROLL16
:
3382 dx
= (INT16
)HIWORD(wParam
);
3389 EDIT_EM_LineScroll(wndPtr
, dx
, 0);
3391 dprintf_edit(stddeb
, "edit: notification EN_HSCROLL sent\n");
3392 EDIT_NOTIFY_PARENT(wndPtr
, EN_HSCROLL
);
3399 /*********************************************************************
3403 * FIXME: the message identifiers have been chosen arbitrarily,
3404 * hence we use MF_BYPOSITION.
3405 * We might as well use the "real" values (anybody knows ?)
3406 * The menu definition is in resources/sysres_??.rc.
3407 * Once these are OK, we better use MF_BYCOMMAND here
3408 * (as we do in EDIT_WM_Command()).
3411 static LRESULT
EDIT_WM_InitMenuPopup(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3413 HMENU32 hPopup
= (HMENU32
)wParam
;
3417 EDIT_EM_GetSel(wndPtr
, (WPARAM32
)&s
, (LPARAM
)&e
);
3420 EnableMenuItem32(hPopup
, 0, MF_BYPOSITION
|
3421 (EDIT_EM_CanUndo(wndPtr
) ? MF_ENABLED
: MF_GRAYED
));
3423 EnableMenuItem32(hPopup
, 2, MF_BYPOSITION
|
3424 ((e
- s
) && !IsPassword(wndPtr
) ? MF_ENABLED
: MF_GRAYED
));
3426 EnableMenuItem32(hPopup
, 3, MF_BYPOSITION
|
3427 ((e
- s
) && !IsPassword(wndPtr
) ? MF_ENABLED
: MF_GRAYED
));
3429 EnableMenuItem32(hPopup
, 4, MF_BYPOSITION
|
3430 (IsClipboardFormatAvailable32(CF_TEXT
) ? MF_ENABLED
: MF_GRAYED
));
3432 EnableMenuItem32(hPopup
, 5, MF_BYPOSITION
|
3433 ((e
- s
) ? MF_ENABLED
: MF_GRAYED
));
3435 EnableMenuItem32(hPopup
, 7, MF_BYPOSITION
|
3436 (s
|| (e
!= EDIT_WM_GetTextLength(wndPtr
)) ? MF_ENABLED
: MF_GRAYED
));
3441 /*********************************************************************
3446 static BOOL32
EDIT_CheckCombo(WND
*wndPtr
, UINT32 msg
, WPARAM32 wParam
, LPARAM lParam
)
3450 if( WIDGETS_IsControl32( wndPtr
->parent
, BIC32_COMBO
) &&
3451 (hLBox
= COMBO_GetLBWindow( wndPtr
->parent
)) )
3453 HWND32 hCombo
= wndPtr
->parent
->hwndSelf
;
3454 BOOL32 bUIFlip
= TRUE
;
3456 dprintf_combo(stddeb
, "EDIT_CheckCombo [%04x]: handling msg %04x (%04x)\n",
3457 wndPtr
->hwndSelf
, (UINT16
)msg
, (UINT16
)wParam
);
3460 case WM_KEYDOWN
: /* Handle F4 and arrow keys */
3461 if( wParam
!= VK_F4
)
3463 bUIFlip
= (BOOL32
)SendMessage32A( hCombo
, CB_GETEXTENDEDUI32
, 0, 0 );
3464 if( SendMessage32A( hCombo
, CB_GETDROPPEDSTATE32
, 0, 0 ) ) bUIFlip
= FALSE
;
3468 SendMessage32A( hLBox
, WM_KEYDOWN
, wParam
, 0 );
3471 /* make sure ComboLBox pops up */
3473 SendMessage32A( hCombo
, CB_SETEXTENDEDUI32
, 0, 0 );
3474 SendMessage32A( hLBox
, WM_KEYDOWN
, VK_F4
, 0 );
3475 SendMessage32A( hCombo
, CB_SETEXTENDEDUI32
, 1, 0 );
3479 case WM_SYSKEYDOWN
: /* Handle Alt+up/down arrows */
3480 bUIFlip
= (BOOL32
)SendMessage32A( hCombo
, CB_GETEXTENDEDUI32
, 0, 0 );
3484 bUIFlip
= (BOOL32
)SendMessage32A( hCombo
, CB_GETDROPPEDSTATE32
, 0, 0 );
3485 SendMessage32A( hCombo
, CB_SHOWDROPDOWN32
, (bUIFlip
) ? FALSE
: TRUE
, 0 );
3486 } else SendMessage32A( hLBox
, WM_KEYDOWN
, VK_F4
, 0 );
3494 /*********************************************************************
3498 * Handling of special keys that don't produce a WM_CHAR
3499 * (i.e. non-printable keys) & Backspace & Delete
3502 static LRESULT
EDIT_WM_KeyDown(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3509 if (GetKeyState32(VK_MENU
) & 0x8000)
3512 shift
= GetKeyState32(VK_SHIFT
) & 0x8000;
3513 control
= GetKeyState32(VK_CONTROL
) & 0x8000;
3515 EDIT_GetSel(wndPtr
, &s
, &e
);
3519 if( EDIT_CheckCombo(wndPtr
, WM_KEYDOWN
, wParam
, lParam
) ) break;
3520 if( wParam
== VK_F4
) break;
3523 if (IsMultiLine(wndPtr
) && (wParam
== VK_UP
))
3524 EDIT_MoveUpward(wndPtr
, shift
);
3527 EDIT_MoveWordBackward(wndPtr
, shift
);
3529 EDIT_MoveBackward(wndPtr
, shift
);
3532 if( EDIT_CheckCombo(wndPtr
, WM_KEYDOWN
, wParam
, lParam
) ) break;
3535 if (IsMultiLine(wndPtr
) && (wParam
== VK_DOWN
))
3536 EDIT_MoveDownward(wndPtr
, shift
);
3538 EDIT_MoveWordForward(wndPtr
, shift
);
3540 EDIT_MoveForward(wndPtr
, shift
);
3543 EDIT_MoveHome(wndPtr
, shift
);
3546 EDIT_MoveEnd(wndPtr
, shift
);
3549 if (IsMultiLine(wndPtr
))
3550 EDIT_MovePageUp(wndPtr
, shift
);
3553 if (IsMultiLine(wndPtr
))
3554 EDIT_MovePageDown(wndPtr
, shift
);
3557 if (!IsReadOnly(wndPtr
) && !control
)
3559 EDIT_WM_Clear(wndPtr
);
3561 EDIT_DelLeft(wndPtr
);
3564 if (!IsReadOnly(wndPtr
) && !(shift
&& control
))
3567 EDIT_WM_Cut(wndPtr
);
3569 EDIT_WM_Clear(wndPtr
);
3572 EDIT_DelLeft(wndPtr
);
3574 EDIT_DelEnd(wndPtr
);
3576 EDIT_DelRight(wndPtr
);
3581 if (!IsReadOnly(wndPtr
))
3582 EDIT_WM_Paste(wndPtr
);
3584 EDIT_WM_Copy(wndPtr
);
3591 /*********************************************************************
3596 static LRESULT
EDIT_WM_KillFocus(WND
*wndPtr
, WPARAM32 wParam
)
3600 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
3602 es
->eState
&= ~EF_FOCUSED
;
3604 if(!(wndPtr
->dwStyle
& ES_NOHIDESEL
)) {
3605 EDIT_EM_GetSel(wndPtr
, (WPARAM32
)&s
, (LPARAM
)&e
);
3606 EDIT_InvalidateText(wndPtr
, s
, e
);
3608 dprintf_edit(stddeb
, "edit: notification EN_KILLFOCUS sent\n");
3609 EDIT_NOTIFY_PARENT(wndPtr
, EN_KILLFOCUS
);
3614 /*********************************************************************
3618 * The caret position has been set on the WM_LBUTTONDOWN message
3621 static LRESULT
EDIT_WM_LButtonDblClk(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3628 LPSTR text
= EDIT_GetPointer(wndPtr
);
3630 EDIT_GetSel(wndPtr
, NULL
, &e
);
3631 l
= (INT32
)EDIT_EM_LineFromChar(wndPtr
, e
);
3632 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
);
3633 ll
= (INT32
)EDIT_EM_LineLength(wndPtr
, e
);
3634 s
= li
+ EDIT_CallWordBreakProc (wndPtr
, text
+ li
, e
- li
, ll
, WB_LEFT
);
3635 e
= li
+ EDIT_CallWordBreakProc(wndPtr
, text
+ li
, e
- li
, ll
, WB_RIGHT
);
3636 EDIT_EM_SetSel(wndPtr
, s
, e
);
3637 EDIT_EM_ScrollCaret(wndPtr
);
3642 /*********************************************************************
3647 static LRESULT
EDIT_WM_LButtonDown(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3649 INT32 x
= (INT32
)(INT16
)LOWORD(lParam
);
3650 INT32 y
= (INT32
)(INT16
)HIWORD(lParam
);
3651 INT32 l
= EDIT_LineFromWndY(wndPtr
, y
);
3655 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
);
3656 INT32 vlc
= EDIT_GetVisibleLineCount(wndPtr
);
3659 SetFocus32(wndPtr
->hwndSelf
);
3660 SetCapture32(wndPtr
->hwndSelf
);
3661 l
= MIN(fv
+ vlc
- 1, MAX(fv
, l
));
3662 x
= MIN(EDIT_GetWndWidth(wndPtr
), MAX(0, x
));
3663 c
= EDIT_ColFromWndX(wndPtr
, l
, x
);
3664 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
);
3666 if (GetKeyState32(VK_SHIFT
) & 0x8000)
3667 EDIT_GetSel(wndPtr
, &s
, NULL
);
3670 EDIT_SetSel(wndPtr
, s
, e
);
3671 EDIT_EM_ScrollCaret(wndPtr
);
3672 SetTimer32(wndPtr
->hwndSelf
, 0, 100, NULL
);
3677 /*********************************************************************
3682 static LRESULT
EDIT_WM_LButtonUp(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3684 if (GetCapture32() == wndPtr
->hwndSelf
) {
3685 KillTimer32(wndPtr
->hwndSelf
, 0);
3692 /*********************************************************************
3697 static LRESULT
EDIT_WM_MouseMove(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3708 if (GetCapture32() == wndPtr
->hwndSelf
) {
3709 x
= (INT32
)(INT16
)LOWORD(lParam
);
3710 y
= (INT32
)(INT16
)HIWORD(lParam
);
3711 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
);
3712 vlc
= EDIT_GetVisibleLineCount(wndPtr
);
3713 l
= EDIT_LineFromWndY(wndPtr
, y
);
3714 l
= MIN(fv
+ vlc
- 1, MAX(fv
, l
));
3715 x
= MIN(EDIT_GetWndWidth(wndPtr
), MAX(0, x
));
3716 c
= EDIT_ColFromWndX(wndPtr
, l
, x
);
3717 EDIT_GetSel(wndPtr
, &s
, NULL
);
3718 li
= (INT32
)EDIT_EM_LineIndex(wndPtr
, l
);
3719 EDIT_SetSel(wndPtr
, s
, li
+ c
);
3722 * FIXME: gotta do some scrolling if outside client (format ?)
3723 * area. Maybe reset the timer ?
3729 /*********************************************************************
3734 static LRESULT
EDIT_WM_Paint(WND
*wndPtr
, WPARAM32 wParam
)
3738 INT32 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
);
3739 INT32 vlc
= EDIT_GetVisibleLineCount(wndPtr
);
3740 INT32 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
);
3743 HFONT32 oldFont
= 0;
3749 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
3750 BOOL32 rev
= IsWindowEnabled32(wndPtr
->hwndSelf
) &&
3751 ((es
->eState
& EF_FOCUSED
) ||
3752 (wndPtr
->dwStyle
& ES_NOHIDESEL
));
3754 hdc
= BeginPaint32(wndPtr
->hwndSelf
, &ps
);
3755 GetClientRect32(wndPtr
->hwndSelf
, &rc
);
3756 IntersectClipRect32( hdc
, rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
3757 hFont
= (HFONT32
)EDIT_WM_GetFont(wndPtr
);
3759 oldFont
= (HFONT32
)SelectObject32(hdc
, hFont
);
3760 EDIT_SEND_CTLCOLOR(wndPtr
, hdc
);
3761 if (!IsWindowEnabled32(wndPtr
->hwndSelf
))
3762 SetTextColor32(hdc
, GetSysColor32(COLOR_GRAYTEXT
));
3763 GetClipBox32(hdc
, &rcRgn
);
3764 for (i
= fv
; i
<= MIN(fv
+ vlc
, fv
+ lc
- 1) ; i
++ ) {
3765 EDIT_GetLineRect(wndPtr
, i
, 0, -1, &rcLine
);
3766 if (IntersectRect32(&rc
, &rcRgn
, &rcLine
))
3767 EDIT_PaintLine(wndPtr
, hdc
, i
, rev
);
3769 if (hFont
) SelectObject32(hdc
, oldFont
);
3770 if (es
->eState
& EF_FOCUSED
) {
3771 EDIT_GetSel(wndPtr
, NULL
, &e
);
3772 pos
= EDIT_EM_PosFromChar(wndPtr
, e
);
3773 SetCaretPos16((INT16
)LOWORD(pos
), (INT16
)HIWORD(pos
));
3775 EndPaint32(wndPtr
->hwndSelf
, &ps
);
3780 /*********************************************************************
3785 static LRESULT
EDIT_WM_Paste(WND
*wndPtr
)
3790 OpenClipboard32(wndPtr
->hwndSelf
);
3791 if ((hsrc
= GetClipboardData16(CF_TEXT
))) {
3792 src
= (LPSTR
)GlobalLock16(hsrc
);
3793 EDIT_EM_ReplaceSel(wndPtr
, (WPARAM32
)TRUE
, (LPARAM
)src
);
3794 GlobalUnlock16(hsrc
);
3801 /*********************************************************************
3806 static LRESULT
EDIT_WM_SetCursor(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3808 if (LOWORD(lParam
) == HTCLIENT
) {
3809 SetCursor16(LoadCursor16(0, IDC_IBEAM
));
3816 /*********************************************************************
3821 static LRESULT
EDIT_WM_SetFocus(WND
*wndPtr
, WPARAM32 wParam
)
3825 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
3827 es
->eState
|= EF_FOCUSED
;
3828 EDIT_GetSel(wndPtr
, &s
, &e
);
3829 CreateCaret32(wndPtr
->hwndSelf
, 0, 2, EDIT_GetLineHeight(wndPtr
));
3830 EDIT_SetSel(wndPtr
, s
, e
);
3831 if(!(wndPtr
->dwStyle
& ES_NOHIDESEL
))
3832 EDIT_InvalidateText(wndPtr
, s
, e
);
3833 ShowCaret32(wndPtr
->hwndSelf
);
3834 dprintf_edit(stddeb
, "edit: notification EN_SETFOCUS sent\n");
3835 EDIT_NOTIFY_PARENT(wndPtr
, EN_SETFOCUS
);
3840 /*********************************************************************
3845 static LRESULT
EDIT_WM_SetFont(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3848 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
3852 HFONT32 oldFont
= 0;
3854 EDIT_GetSel(wndPtr
, &s
, &e
);
3855 es
->hFont
= (HFONT32
)wParam
;
3856 hdc
= GetDC32(wndPtr
->hwndSelf
);
3857 if (es
->hFont
) oldFont
= SelectObject32(hdc
, es
->hFont
);
3858 GetTextMetrics32A(hdc
, &tm
);
3859 es
->LineHeight
= tm
.tmHeight
;
3860 es
->AveCharWidth
= tm
.tmAveCharWidth
;
3861 if (es
->hFont
) SelectObject32(hdc
, oldFont
);
3862 ReleaseDC32(wndPtr
->hwndSelf
, hdc
);
3863 EDIT_BuildLineDefs(wndPtr
);
3864 if ((BOOL32
)lParam
&& !IsNoRedraw(wndPtr
))
3865 InvalidateRect32( wndPtr
->hwndSelf
, NULL
, TRUE
);
3866 if (es
->eState
& EF_FOCUSED
) {
3868 CreateCaret32(wndPtr
->hwndSelf
, 0, 2, EDIT_GetLineHeight(wndPtr
));
3869 EDIT_SetSel(wndPtr
, s
, e
);
3870 ShowCaret32(wndPtr
->hwndSelf
);
3876 /*********************************************************************
3881 static LRESULT
EDIT_WM_SetRedraw(WND
*wndPtr
, WPARAM32 wParam
)
3884 wndPtr
->flags
&= ~WIN_NO_REDRAW
;
3886 wndPtr
->flags
|= WIN_NO_REDRAW
;
3891 /*********************************************************************
3896 static LRESULT
EDIT_WM_SetText(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3898 EDIT_EM_SetSel(wndPtr
, 0, -1);
3901 dprintf_edit(stddeb
,"\t'%s'\n", (char*)lParam
);
3902 EDIT_EM_ReplaceSel(wndPtr
, (WPARAM32
)FALSE
, lParam
);
3904 EDIT_EM_SetModify(wndPtr
, TRUE
);
3905 EDIT_EM_ScrollCaret(wndPtr
);
3910 /*********************************************************************
3914 * FIXME: What about that FormatRect ???
3917 static LRESULT
EDIT_WM_Size(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3919 EDITSTATE
*es
= EDITSTATEPTR(wndPtr
);
3922 EDIT_GetSel(wndPtr
, 0, &e
);
3923 GetClientRect32(wndPtr
->hwndSelf
, &es
->FormatRect
);
3924 if (!IsNoRedraw(wndPtr
) &&
3925 ((wParam
== SIZE_MAXIMIZED
) ||
3926 (wParam
== SIZE_RESTORED
))) {
3927 if (IsMultiLine(wndPtr
) && IsWordWrap(wndPtr
))
3928 EDIT_BuildLineDefs(wndPtr
);
3929 InvalidateRect32( wndPtr
->hwndSelf
, NULL
, TRUE
);
3935 /*********************************************************************
3940 static LRESULT
EDIT_WM_SysKeyDown(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3942 if ((wParam
== VK_BACK
) && (lParam
& 0x2000) &&
3943 (BOOL32
)EDIT_EM_CanUndo(wndPtr
))
3944 EDIT_EM_Undo(wndPtr
);
3945 else if( wParam
== VK_UP
|| wParam
== VK_DOWN
)
3946 EDIT_CheckCombo( wndPtr
, WM_SYSKEYDOWN
, wParam
, lParam
);
3951 /*********************************************************************
3956 static LRESULT
EDIT_WM_Timer(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3959 * FIXME: gotta do some scrolling here, like
3960 * EDIT_EM_LineScroll(wndPtr, 0, 1);
3966 /*********************************************************************
3970 * FIXME: scrollbar code itself is broken, so this one is a hack.
3973 static LRESULT
EDIT_WM_VScroll(WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
3985 EDIT_EM_Scroll( wndPtr
, wParam
);
3988 lc
= (INT32
)EDIT_EM_GetLineCount(wndPtr
);
3989 fv
= (INT32
)EDIT_EM_GetFirstVisibleLine(wndPtr
);
4000 case SB_THUMBPOSITION
:
4001 dy
= HIWORD(wParam
) * (lc
- 1) / 100 - fv
;
4003 /* The next two are undocumented ! */
4005 ret
= (lc
> 1) ? MAKELONG(fv
* 100 / (lc
- 1), 0) : 0;
4007 case EM_LINESCROLL16
:
4008 dy
= (INT16
)LOWORD(lParam
);
4015 EDIT_EM_LineScroll(wndPtr
, 0, dy
);
4017 dprintf_edit(stddeb
, "edit: notification EN_VSCROLL sent\n");
4018 EDIT_NOTIFY_PARENT(wndPtr
, EN_VSCROLL
);