Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 1 | /* |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2 | * Edit control |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 3 | * |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4 | * Copyright David W. Metcalfe, 1994 |
| 5 | * Copyright William Magro, 1995, 1996 |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 6 | * Copyright Frans van Dorsselaer, 1996, 1997 |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 7 | * |
Alexandre Julliard | 0799c1a | 2002-03-09 23:29:33 +0000 | [diff] [blame] | 8 | * |
| 9 | * This library is free software; you can redistribute it and/or |
| 10 | * modify it under the terms of the GNU Lesser General Public |
| 11 | * License as published by the Free Software Foundation; either |
| 12 | * version 2.1 of the License, or (at your option) any later version. |
| 13 | * |
| 14 | * This library is distributed in the hope that it will be useful, |
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 17 | * Lesser General Public License for more details. |
| 18 | * |
| 19 | * You should have received a copy of the GNU Lesser General Public |
| 20 | * License along with this library; if not, write to the Free Software |
| 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 22 | * |
| 23 | * TODO: |
| 24 | * - ES_CENTER |
| 25 | * - ES_RIGHT |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 26 | * - ES_OEMCONVERT |
| 27 | * -!ES_AUTOVSCROLL (every multi line control *is* auto vscroll) |
| 28 | * -!ES_AUTOHSCROLL (every single line control *is* auto hscroll) |
| 29 | * |
| 30 | * When there is no autoscrolling, the control should first check whether |
| 31 | * the new text would fit. If not, an EN_MAXTEXT should be sent. |
| 32 | * However, currently this would require the actual change to be made, |
| 33 | * then call EDIT_BuildLineDefs() and then find out that the new text doesn't |
| 34 | * fit. After all this, things should be put back in the state before the |
| 35 | * changes. Note that for multi line controls !ES_AUTOHSCROLL works : wordwrap. |
| 36 | * |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 37 | */ |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 38 | |
Patrik Stridvall | 1bb9403 | 1999-05-08 15:47:44 +0000 | [diff] [blame] | 39 | #include "config.h" |
| 40 | |
Alexandre Julliard | e37c6e1 | 2003-09-05 23:08:26 +0000 | [diff] [blame] | 41 | #include <stdarg.h> |
Jeff Garzik | c3e1f72 | 1999-02-19 15:42:11 +0000 | [diff] [blame] | 42 | #include <string.h> |
Alexandre Julliard | 908464d | 2000-11-01 03:11:12 +0000 | [diff] [blame] | 43 | #include <stdlib.h> |
Patrik Stridvall | 6cc47d4 | 2000-03-08 18:26:56 +0000 | [diff] [blame] | 44 | |
Alexandre Julliard | e37c6e1 | 2003-09-05 23:08:26 +0000 | [diff] [blame] | 45 | #include "windef.h" |
Patrik Stridvall | 6cc47d4 | 2000-03-08 18:26:56 +0000 | [diff] [blame] | 46 | #include "winbase.h" |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 47 | #include "winnt.h" |
Alexandre Julliard | 7e92c9a | 2003-02-27 21:09:45 +0000 | [diff] [blame] | 48 | #include "wownt32.h" |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 49 | #include "win.h" |
Marcus Meissner | 317af32 | 1999-02-17 13:51:06 +0000 | [diff] [blame] | 50 | #include "wine/winbase16.h" |
Alexandre Julliard | 198746d | 2000-08-14 14:29:22 +0000 | [diff] [blame] | 51 | #include "wine/winuser16.h" |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 52 | #include "wine/unicode.h" |
Alexandre Julliard | 91222da | 2000-12-10 23:01:33 +0000 | [diff] [blame] | 53 | #include "controls.h" |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 54 | #include "local.h" |
Lionel Ulmer | 28d9aaf | 2004-03-29 22:54:05 +0000 | [diff] [blame] | 55 | #include "message.h" |
Alexandre Julliard | a41b2cf | 2001-01-15 20:12:55 +0000 | [diff] [blame] | 56 | #include "user.h" |
Alexandre Julliard | 0799c1a | 2002-03-09 23:29:33 +0000 | [diff] [blame] | 57 | #include "wine/debug.h" |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 58 | |
Alexandre Julliard | 0799c1a | 2002-03-09 23:29:33 +0000 | [diff] [blame] | 59 | WINE_DEFAULT_DEBUG_CHANNEL(edit); |
| 60 | WINE_DECLARE_DEBUG_CHANNEL(combo); |
| 61 | WINE_DECLARE_DEBUG_CHANNEL(relay); |
Patrik Stridvall | b4b9fae | 1999-04-19 14:56:29 +0000 | [diff] [blame] | 62 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 63 | #define BUFLIMIT_MULTI 65534 /* maximum buffer size (not including '\0') |
| 64 | FIXME: BTW, new specs say 65535 (do you dare ???) */ |
| 65 | #define BUFLIMIT_SINGLE 32766 /* maximum buffer size (not including '\0') */ |
Dmitry Timoshkov | f8b96e2 | 2000-12-20 18:39:14 +0000 | [diff] [blame] | 66 | #define GROWLENGTH 32 /* buffers granularity in bytes: must be power of 2 */ |
Dmitry Timoshkov | df793bc | 2001-01-15 20:20:31 +0000 | [diff] [blame] | 67 | #define ROUND_TO_GROW(size) (((size) + (GROWLENGTH - 1)) & ~(GROWLENGTH - 1)) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 68 | #define HSCROLL_FRACTION 3 /* scroll window by 1/3 width */ |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 69 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 70 | /* |
| 71 | * extra flags for EDITSTATE.flags field |
| 72 | */ |
| 73 | #define EF_MODIFIED 0x0001 /* text has been modified */ |
| 74 | #define EF_FOCUSED 0x0002 /* we have input focus */ |
Dmitry Timoshkov | a62f06d | 2001-03-13 23:31:08 +0000 | [diff] [blame] | 75 | #define EF_UPDATE 0x0004 /* notify parent of changed state */ |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 76 | #define EF_VSCROLL_TRACK 0x0008 /* don't SetScrollPos() since we are tracking the thumb */ |
| 77 | #define EF_HSCROLL_TRACK 0x0010 /* don't SetScrollPos() since we are tracking the thumb */ |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 78 | #define EF_AFTER_WRAP 0x0080 /* the caret is displayed after the last character of a |
| 79 | wrapped line, instead of in front of the next character */ |
Alexandre Julliard | a845b88 | 1998-06-01 10:44:35 +0000 | [diff] [blame] | 80 | #define EF_USE_SOFTBRK 0x0100 /* Enable soft breaks in text. */ |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 81 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 82 | typedef enum |
| 83 | { |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 84 | END_0 = 0, /* line ends with terminating '\0' character */ |
| 85 | END_WRAP, /* line is wrapped */ |
| 86 | END_HARD, /* line ends with a hard return '\r\n' */ |
| 87 | END_SOFT, /* line ends with a soft return '\r\r\n' */ |
| 88 | END_RICH /* line ends with a single '\n' */ |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 89 | } LINE_END; |
| 90 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 91 | typedef struct tagLINEDEF { |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 92 | INT length; /* bruto length of a line in bytes */ |
| 93 | INT net_length; /* netto length of a line in visible characters */ |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 94 | LINE_END ending; |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 95 | INT width; /* width of the line in pixels */ |
| 96 | INT index; /* line index into the buffer */ |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 97 | struct tagLINEDEF *next; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 98 | } LINEDEF; |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 99 | |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 100 | typedef struct |
| 101 | { |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 102 | BOOL is_unicode; /* how the control was created */ |
| 103 | LPWSTR text; /* the actual contents of the control */ |
| 104 | UINT buffer_size; /* the size of the buffer in characters */ |
| 105 | UINT buffer_limit; /* the maximum size to which the buffer may grow in characters */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 106 | HFONT font; /* NULL means standard system font */ |
| 107 | INT x_offset; /* scroll offset for multi lines this is in pixels |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 108 | for single lines it's in characters */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 109 | INT line_height; /* height of a screen line in pixels */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 110 | INT char_width; /* average character width in pixels */ |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 111 | DWORD style; /* sane version of wnd->dwStyle */ |
| 112 | WORD flags; /* flags that are not in es->style or wnd->flags (EF_XXX) */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 113 | INT undo_insert_count; /* number of characters inserted in sequence */ |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 114 | UINT undo_position; /* character index of the insertion and deletion */ |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 115 | LPWSTR undo_text; /* deleted text */ |
Dmitry Timoshkov | 366c0a1 | 2000-12-22 20:28:05 +0000 | [diff] [blame] | 116 | UINT undo_buffer_size; /* size of the deleted text buffer */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 117 | INT selection_start; /* == selection_end if no selection */ |
| 118 | INT selection_end; /* == current caret position */ |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 119 | WCHAR password_char; /* == 0 if no password char, and for multi line controls */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 120 | INT left_margin; /* in pixels */ |
| 121 | INT right_margin; /* in pixels */ |
| 122 | RECT format_rect; |
Dmitry Timoshkov | 11dbda6 | 2001-01-05 03:40:35 +0000 | [diff] [blame] | 123 | INT text_width; /* width of the widest line in pixels for multi line controls |
| 124 | and just line width for single line controls */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 125 | INT region_posx; /* Position of cursor relative to region: */ |
| 126 | INT region_posy; /* -1: to left, 0: within, 1: to right */ |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 127 | EDITWORDBREAKPROC16 word_break_proc16; |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 128 | void *word_break_proc; /* 32-bit word break proc: ANSI or Unicode */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 129 | INT line_count; /* number of lines */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 130 | INT y_offset; /* scroll offset in number of lines */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 131 | BOOL bCaptureState; /* flag indicating whether mouse was captured */ |
| 132 | BOOL bEnableState; /* flag keeping the enable state */ |
| 133 | HWND hwndSelf; /* the our window handle */ |
| 134 | HWND hwndParent; /* Handle of parent for sending EN_* messages. |
| 135 | Even if parent will change, EN_* messages |
| 136 | should be sent to the first parent. */ |
| 137 | HWND hwndListBox; /* handle of ComboBox's listbox or NULL */ |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 138 | /* |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 139 | * only for multi line controls |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 140 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 141 | INT lock_count; /* amount of re-entries in the EditWndProc */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 142 | INT tabs_count; |
| 143 | LPINT tabs; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 144 | LINEDEF *first_line_def; /* linked list of (soft) linebreaks */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 145 | HLOCAL hloc32W; /* our unicode local memory block */ |
| 146 | HLOCAL16 hloc16; /* alias for 16-bit control receiving EM_GETHANDLE16 |
| 147 | or EM_SETHANDLE16 */ |
| 148 | HLOCAL hloc32A; /* alias for ANSI control receiving EM_GETHANDLE |
| 149 | or EM_SETHANDLE */ |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 150 | } EDITSTATE; |
| 151 | |
Alexandre Julliard | 02ed4c2 | 1996-03-02 19:34:10 +0000 | [diff] [blame] | 152 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 153 | #define SWAP_UINT32(x,y) do { UINT temp = (UINT)(x); (x) = (UINT)(y); (y) = temp; } while(0) |
| 154 | #define ORDER_UINT(x,y) do { if ((UINT)(y) < (UINT)(x)) SWAP_UINT32((x),(y)); } while(0) |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 155 | |
Luc Tourangeau | df5fbc7 | 1999-04-03 11:14:30 +0000 | [diff] [blame] | 156 | /* used for disabled or read-only edit control */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 157 | #define EDIT_NOTIFY_PARENT(es, wNotifyCode, str) \ |
Dmitry Timoshkov | 87880c5 | 2001-03-10 19:16:46 +0000 | [diff] [blame] | 158 | do \ |
Dmitry Timoshkov | a62f06d | 2001-03-13 23:31:08 +0000 | [diff] [blame] | 159 | { /* Notify parent which has created this edit control */ \ |
Alexandre Julliard | aff7dda | 2002-11-22 21:22:14 +0000 | [diff] [blame] | 160 | TRACE("notification " str " sent to hwnd=%p\n", es->hwndParent); \ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 161 | SendMessageW(es->hwndParent, WM_COMMAND, \ |
Robert Shearman | 2e9436c | 2004-08-17 22:29:29 +0000 | [diff] [blame] | 162 | MAKEWPARAM(GetWindowLongPtrW((es->hwndSelf),GWLP_ID), wNotifyCode), \ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 163 | (LPARAM)(es->hwndSelf)); \ |
Dmitry Timoshkov | 87880c5 | 2001-03-10 19:16:46 +0000 | [diff] [blame] | 164 | } while(0) |
Alexandre Julliard | ca22b33 | 1996-07-12 19:02:39 +0000 | [diff] [blame] | 165 | |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 166 | /********************************************************************* |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 167 | * |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 168 | * Declarations |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 169 | * |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 170 | */ |
| 171 | |
| 172 | /* |
| 173 | * These functions have trivial implementations |
| 174 | * We still like to call them internally |
Patrik Stridvall | 1bb9403 | 1999-05-08 15:47:44 +0000 | [diff] [blame] | 175 | * "static inline" makes them more like macro's |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 176 | */ |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 177 | static inline BOOL EDIT_EM_CanUndo(EDITSTATE *es); |
| 178 | static inline void EDIT_EM_EmptyUndoBuffer(EDITSTATE *es); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 179 | static inline void EDIT_WM_Clear(EDITSTATE *es); |
| 180 | static inline void EDIT_WM_Cut(EDITSTATE *es); |
Patrik Stridvall | 1ed4ecf | 1999-06-26 14:58:24 +0000 | [diff] [blame] | 181 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 182 | /* |
| 183 | * Helper functions only valid for one type of control |
| 184 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 185 | static void EDIT_BuildLineDefs_ML(EDITSTATE *es, INT iStart, INT iEnd, INT delta, HRGN hrgn); |
| 186 | static void EDIT_CalcLineWidth_SL(EDITSTATE *es); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 187 | static LPWSTR EDIT_GetPasswordPointer_SL(EDITSTATE *es); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 188 | static void EDIT_MoveDown_ML(EDITSTATE *es, BOOL extend); |
| 189 | static void EDIT_MovePageDown_ML(EDITSTATE *es, BOOL extend); |
| 190 | static void EDIT_MovePageUp_ML(EDITSTATE *es, BOOL extend); |
| 191 | static void EDIT_MoveUp_ML(EDITSTATE *es, BOOL extend); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 192 | /* |
| 193 | * Helper functions valid for both single line _and_ multi line controls |
| 194 | */ |
Dmitry Timoshkov | 8058ead | 2000-12-21 20:19:21 +0000 | [diff] [blame] | 195 | static INT EDIT_CallWordBreakProc(EDITSTATE *es, INT start, INT index, INT count, INT action); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 196 | static INT EDIT_CharFromPos(EDITSTATE *es, INT x, INT y, LPBOOL after_wrap); |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 197 | static void EDIT_ConfinePoint(EDITSTATE *es, LPINT x, LPINT y); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 198 | static void EDIT_GetLineRect(EDITSTATE *es, INT line, INT scol, INT ecol, LPRECT rc); |
| 199 | static void EDIT_InvalidateText(EDITSTATE *es, INT start, INT end); |
| 200 | static void EDIT_LockBuffer(EDITSTATE *es); |
Krishna Murthy | 4af4ba4 | 2004-05-29 00:21:51 +0000 | [diff] [blame] | 201 | static BOOL EDIT_MakeFit(EDITSTATE *es, UINT size); |
Dmitry Timoshkov | 366c0a1 | 2000-12-22 20:28:05 +0000 | [diff] [blame] | 202 | static BOOL EDIT_MakeUndoFit(EDITSTATE *es, UINT size); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 203 | static void EDIT_MoveBackward(EDITSTATE *es, BOOL extend); |
| 204 | static void EDIT_MoveEnd(EDITSTATE *es, BOOL extend); |
| 205 | static void EDIT_MoveForward(EDITSTATE *es, BOOL extend); |
| 206 | static void EDIT_MoveHome(EDITSTATE *es, BOOL extend); |
| 207 | static void EDIT_MoveWordBackward(EDITSTATE *es, BOOL extend); |
| 208 | static void EDIT_MoveWordForward(EDITSTATE *es, BOOL extend); |
| 209 | static void EDIT_PaintLine(EDITSTATE *es, HDC hdc, INT line, BOOL rev); |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 210 | static INT EDIT_PaintText(EDITSTATE *es, HDC hdc, INT x, INT y, INT line, INT col, INT count, BOOL rev); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 211 | static void EDIT_SetCaretPos(EDITSTATE *es, INT pos, BOOL after_wrap); |
| 212 | static void EDIT_SetRectNP(EDITSTATE *es, LPRECT lprc); |
| 213 | static void EDIT_UnlockBuffer(EDITSTATE *es, BOOL force); |
| 214 | static void EDIT_UpdateScrollInfo(EDITSTATE *es); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 215 | static INT CALLBACK EDIT_WordBreakProc(LPWSTR s, INT index, INT count, INT action); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 216 | /* |
| 217 | * EM_XXX message handlers |
| 218 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 219 | static LRESULT EDIT_EM_CharFromPos(EDITSTATE *es, INT x, INT y); |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 220 | static BOOL EDIT_EM_FmtLines(EDITSTATE *es, BOOL add_eol); |
Dmitry Timoshkov | 8058ead | 2000-12-21 20:19:21 +0000 | [diff] [blame] | 221 | static HLOCAL EDIT_EM_GetHandle(EDITSTATE *es); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 222 | static HLOCAL16 EDIT_EM_GetHandle16(EDITSTATE *es); |
Dmitry Timoshkov | bf60453 | 2001-02-12 19:15:33 +0000 | [diff] [blame] | 223 | static INT EDIT_EM_GetLine(EDITSTATE *es, INT line, LPARAM lParam, BOOL unicode); |
Francois Gouget | bba4bb1 | 2002-09-17 01:35:09 +0000 | [diff] [blame] | 224 | static LRESULT EDIT_EM_GetSel(EDITSTATE *es, PUINT start, PUINT end); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 225 | static LRESULT EDIT_EM_GetThumb(EDITSTATE *es); |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 226 | static INT EDIT_EM_LineFromChar(EDITSTATE *es, INT index); |
| 227 | static INT EDIT_EM_LineIndex(EDITSTATE *es, INT line); |
| 228 | static INT EDIT_EM_LineLength(EDITSTATE *es, INT index); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 229 | static BOOL EDIT_EM_LineScroll(EDITSTATE *es, INT dx, INT dy); |
| 230 | static BOOL EDIT_EM_LineScroll_internal(EDITSTATE *es, INT dx, INT dy); |
| 231 | static LRESULT EDIT_EM_PosFromChar(EDITSTATE *es, INT index, BOOL after_wrap); |
Carl Sopchak | 23b88ef | 2002-11-21 03:57:05 +0000 | [diff] [blame] | 232 | static void EDIT_EM_ReplaceSel(EDITSTATE *es, BOOL can_undo, LPCWSTR lpsz_replace, BOOL send_update, BOOL honor_limit); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 233 | static LRESULT EDIT_EM_Scroll(EDITSTATE *es, INT action); |
| 234 | static void EDIT_EM_ScrollCaret(EDITSTATE *es); |
| 235 | static void EDIT_EM_SetHandle(EDITSTATE *es, HLOCAL hloc); |
| 236 | static void EDIT_EM_SetHandle16(EDITSTATE *es, HLOCAL16 hloc); |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 237 | static void EDIT_EM_SetLimitText(EDITSTATE *es, INT limit); |
| 238 | static void EDIT_EM_SetMargins(EDITSTATE *es, INT action, INT left, INT right); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 239 | static void EDIT_EM_SetPasswordChar(EDITSTATE *es, WCHAR c); |
| 240 | static void EDIT_EM_SetSel(EDITSTATE *es, UINT start, UINT end, BOOL after_wrap); |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 241 | static BOOL EDIT_EM_SetTabStops(EDITSTATE *es, INT count, LPINT tabs); |
| 242 | static BOOL EDIT_EM_SetTabStops16(EDITSTATE *es, INT count, LPINT16 tabs); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 243 | static void EDIT_EM_SetWordBreakProc(EDITSTATE *es, LPARAM lParam); |
| 244 | static void EDIT_EM_SetWordBreakProc16(EDITSTATE *es, EDITWORDBREAKPROC16 wbp); |
| 245 | static BOOL EDIT_EM_Undo(EDITSTATE *es); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 246 | /* |
| 247 | * WM_XXX message handlers |
| 248 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 249 | static void EDIT_WM_Char(EDITSTATE *es, WCHAR c); |
| 250 | static void EDIT_WM_Command(EDITSTATE *es, INT code, INT id, HWND conrtol); |
| 251 | static void EDIT_WM_ContextMenu(EDITSTATE *es, INT x, INT y); |
| 252 | static void EDIT_WM_Copy(EDITSTATE *es); |
| 253 | static LRESULT EDIT_WM_Create(EDITSTATE *es, LPCWSTR name); |
| 254 | static LRESULT EDIT_WM_Destroy(EDITSTATE *es); |
| 255 | static LRESULT EDIT_WM_EraseBkGnd(EDITSTATE *es, HDC dc); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 256 | static INT EDIT_WM_GetText(EDITSTATE *es, INT count, LPARAM lParam, BOOL unicode); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 257 | static LRESULT EDIT_WM_HScroll(EDITSTATE *es, INT action, INT pos); |
| 258 | static LRESULT EDIT_WM_KeyDown(EDITSTATE *es, INT key); |
| 259 | static LRESULT EDIT_WM_KillFocus(EDITSTATE *es); |
| 260 | static LRESULT EDIT_WM_LButtonDblClk(EDITSTATE *es); |
| 261 | static LRESULT EDIT_WM_LButtonDown(EDITSTATE *es, DWORD keys, INT x, INT y); |
| 262 | static LRESULT EDIT_WM_LButtonUp(EDITSTATE *es); |
| 263 | static LRESULT EDIT_WM_MButtonDown(EDITSTATE *es); |
| 264 | static LRESULT EDIT_WM_MouseMove(EDITSTATE *es, INT x, INT y); |
| 265 | static LRESULT EDIT_WM_NCCreate(HWND hwnd, LPCREATESTRUCTW lpcs, BOOL unicode); |
| 266 | static void EDIT_WM_Paint(EDITSTATE *es, WPARAM wParam); |
| 267 | static void EDIT_WM_Paste(EDITSTATE *es); |
| 268 | static void EDIT_WM_SetFocus(EDITSTATE *es); |
| 269 | static void EDIT_WM_SetFont(EDITSTATE *es, HFONT font, BOOL redraw); |
| 270 | static void EDIT_WM_SetText(EDITSTATE *es, LPARAM lParam, BOOL unicode); |
| 271 | static void EDIT_WM_Size(EDITSTATE *es, UINT action, INT width, INT height); |
| 272 | static LRESULT EDIT_WM_StyleChanged(EDITSTATE *es, WPARAM which, const STYLESTRUCT *style); |
| 273 | static LRESULT EDIT_WM_SysKeyDown(EDITSTATE *es, INT key, DWORD key_data); |
| 274 | static void EDIT_WM_Timer(EDITSTATE *es); |
| 275 | static LRESULT EDIT_WM_VScroll(EDITSTATE *es, INT action, INT pos); |
| 276 | static void EDIT_UpdateText(EDITSTATE *es, LPRECT rc, BOOL bErase); |
| 277 | static void EDIT_UpdateTextRegion(EDITSTATE *es, HRGN hrgn, BOOL bErase); |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 278 | |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 279 | LRESULT WINAPI EditWndProcA(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); |
| 280 | LRESULT WINAPI EditWndProcW(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); |
Alexandre Julliard | 91222da | 2000-12-10 23:01:33 +0000 | [diff] [blame] | 281 | |
| 282 | /********************************************************************* |
| 283 | * edit class descriptor |
| 284 | */ |
| 285 | const struct builtin_class_descr EDIT_builtin_class = |
| 286 | { |
| 287 | "Edit", /* name */ |
Alexandre Julliard | b062210 | 2003-12-10 04:14:35 +0000 | [diff] [blame] | 288 | CS_DBLCLKS | CS_PARENTDC, /* style */ |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 289 | EditWndProcA, /* procA */ |
| 290 | EditWndProcW, /* procW */ |
Alexandre Julliard | 91222da | 2000-12-10 23:01:33 +0000 | [diff] [blame] | 291 | sizeof(EDITSTATE *), /* extra */ |
Alexandre Julliard | cf52644 | 2003-09-10 03:56:47 +0000 | [diff] [blame] | 292 | IDC_IBEAM, /* cursor */ |
Alexandre Julliard | 91222da | 2000-12-10 23:01:33 +0000 | [diff] [blame] | 293 | 0 /* brush */ |
| 294 | }; |
| 295 | |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 296 | |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 297 | /********************************************************************* |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 298 | * |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 299 | * EM_CANUNDO |
Alexandre Julliard | cdcdede | 1996-04-21 14:57:41 +0000 | [diff] [blame] | 300 | * |
| 301 | */ |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 302 | static inline BOOL EDIT_EM_CanUndo(EDITSTATE *es) |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 303 | { |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 304 | return (es->undo_insert_count || strlenW(es->undo_text)); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 305 | } |
| 306 | |
| 307 | |
| 308 | /********************************************************************* |
| 309 | * |
| 310 | * EM_EMPTYUNDOBUFFER |
| 311 | * |
| 312 | */ |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 313 | static inline void EDIT_EM_EmptyUndoBuffer(EDITSTATE *es) |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 314 | { |
| 315 | es->undo_insert_count = 0; |
| 316 | *es->undo_text = '\0'; |
| 317 | } |
| 318 | |
| 319 | |
| 320 | /********************************************************************* |
| 321 | * |
| 322 | * WM_CLEAR |
| 323 | * |
| 324 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 325 | static inline void EDIT_WM_Clear(EDITSTATE *es) |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 326 | { |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 327 | static const WCHAR empty_stringW[] = {0}; |
| 328 | |
Dmitry Timoshkov | 9c446a1 | 2001-01-22 19:28:27 +0000 | [diff] [blame] | 329 | /* Protect read-only edit control from modification */ |
| 330 | if(es->style & ES_READONLY) |
| 331 | return; |
| 332 | |
Carl Sopchak | 23b88ef | 2002-11-21 03:57:05 +0000 | [diff] [blame] | 333 | EDIT_EM_ReplaceSel(es, TRUE, empty_stringW, TRUE, TRUE); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 334 | } |
| 335 | |
| 336 | |
| 337 | /********************************************************************* |
| 338 | * |
| 339 | * WM_CUT |
| 340 | * |
| 341 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 342 | static inline void EDIT_WM_Cut(EDITSTATE *es) |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 343 | { |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 344 | EDIT_WM_Copy(es); |
| 345 | EDIT_WM_Clear(es); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 346 | } |
Alexandre Julliard | cdcdede | 1996-04-21 14:57:41 +0000 | [diff] [blame] | 347 | |
| 348 | |
Alexandre Julliard | 198746d | 2000-08-14 14:29:22 +0000 | [diff] [blame] | 349 | /********************************************************************** |
| 350 | * get_app_version |
| 351 | * |
| 352 | * Returns the window version in case Wine emulates a later version |
Francois Gouget | 61aac4e | 2003-06-04 20:29:05 +0000 | [diff] [blame] | 353 | * of windows than the application expects. |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 354 | * |
Alexandre Julliard | 198746d | 2000-08-14 14:29:22 +0000 | [diff] [blame] | 355 | * In a number of cases when windows runs an application that was |
| 356 | * designed for an earlier windows version, windows reverts |
| 357 | * to "old" behaviour of that earlier version. |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 358 | * |
| 359 | * An example is a disabled edit control that needs to be painted. |
| 360 | * Old style behaviour is to send a WM_CTLCOLOREDIT message. This was |
| 361 | * changed in Win95, NT4.0 by a WM_CTLCOLORSTATIC message _only_ for |
Alexandre Julliard | 198746d | 2000-08-14 14:29:22 +0000 | [diff] [blame] | 362 | * applications with an expected version 0f 4.0 or higher. |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 363 | * |
Alexandre Julliard | 198746d | 2000-08-14 14:29:22 +0000 | [diff] [blame] | 364 | */ |
| 365 | static DWORD get_app_version(void) |
| 366 | { |
| 367 | static DWORD version; |
| 368 | if (!version) |
| 369 | { |
| 370 | DWORD dwEmulatedVersion; |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 371 | OSVERSIONINFOW info; |
Alexandre Julliard | 198746d | 2000-08-14 14:29:22 +0000 | [diff] [blame] | 372 | DWORD dwProcVersion = GetProcessVersion(0); |
| 373 | |
James Juran | 75c525c | 2001-05-18 20:56:37 +0000 | [diff] [blame] | 374 | info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 375 | GetVersionExW( &info ); |
Alexandre Julliard | 198746d | 2000-08-14 14:29:22 +0000 | [diff] [blame] | 376 | dwEmulatedVersion = MAKELONG( info.dwMinorVersion, info.dwMajorVersion ); |
Dimitrie O. Paun | 693cca5 | 2002-01-29 03:12:19 +0000 | [diff] [blame] | 377 | /* FIXME: this may not be 100% correct; see discussion on the |
Alexandre Julliard | 198746d | 2000-08-14 14:29:22 +0000 | [diff] [blame] | 378 | * wine developer list in Nov 1999 */ |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 379 | version = dwProcVersion < dwEmulatedVersion ? dwProcVersion : dwEmulatedVersion; |
Alexandre Julliard | 198746d | 2000-08-14 14:29:22 +0000 | [diff] [blame] | 380 | } |
| 381 | return version; |
| 382 | } |
| 383 | |
| 384 | |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 385 | static HBRUSH EDIT_NotifyCtlColor(EDITSTATE *es, HDC hdc) |
| 386 | { |
| 387 | UINT msg; |
| 388 | |
| 389 | if ( get_app_version() >= 0x40000 && (!es->bEnableState || (es->style & ES_READONLY))) |
| 390 | msg = WM_CTLCOLORSTATIC; |
| 391 | else |
| 392 | msg = WM_CTLCOLOREDIT; |
| 393 | |
| 394 | /* why do we notify to es->hwndParent, and we send this one to GetParent()? */ |
| 395 | return (HBRUSH)SendMessageW(GetParent(es->hwndSelf), msg, (WPARAM)hdc, (LPARAM)es->hwndSelf); |
| 396 | } |
| 397 | |
| 398 | static inline LRESULT DefWindowProcT(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL unicode) |
| 399 | { |
| 400 | if(unicode) |
| 401 | return DefWindowProcW(hwnd, msg, wParam, lParam); |
| 402 | else |
| 403 | return DefWindowProcA(hwnd, msg, wParam, lParam); |
| 404 | } |
| 405 | |
Alexandre Julliard | cdcdede | 1996-04-21 14:57:41 +0000 | [diff] [blame] | 406 | /********************************************************************* |
| 407 | * |
Alexandre Julliard | de42428 | 2001-08-10 22:51:42 +0000 | [diff] [blame] | 408 | * EditWndProc_common |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 409 | * |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 410 | * The messages are in the order of the actual integer values |
| 411 | * (which can be found in include/windows.h) |
Bill Medland | 86bfa4c | 2001-06-28 18:01:00 +0000 | [diff] [blame] | 412 | * Wherever possible the 16 bit versions are converted to |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 413 | * the 32 bit ones, so that we can 'fall through' to the |
| 414 | * helper functions. These are mostly 32 bit (with a few |
| 415 | * exceptions, clearly indicated by a '16' extension to their |
| 416 | * names). |
| 417 | * |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 418 | */ |
Alexandre Julliard | de42428 | 2001-08-10 22:51:42 +0000 | [diff] [blame] | 419 | static LRESULT WINAPI EditWndProc_common( HWND hwnd, UINT msg, |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 420 | WPARAM wParam, LPARAM lParam, BOOL unicode ) |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 421 | { |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 422 | EDITSTATE *es = (EDITSTATE *)GetWindowLongW( hwnd, 0 ); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 423 | LRESULT result = 0; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 424 | |
Lionel Ulmer | 28d9aaf | 2004-03-29 22:54:05 +0000 | [diff] [blame] | 425 | TRACE("hwnd=%p msg=%x (%s) wparam=%x lparam=%lx\n", hwnd, msg, SPY_GetMsgName(msg, hwnd), wParam, lParam); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 426 | |
| 427 | if (!es && msg != WM_NCCREATE) |
| 428 | return DefWindowProcT(hwnd, msg, wParam, lParam, unicode); |
| 429 | else if (msg == WM_NCCREATE) |
| 430 | return EDIT_WM_NCCreate(hwnd, (LPCREATESTRUCTW)lParam, unicode); |
| 431 | else if (msg == WM_DESTROY) |
| 432 | return EDIT_WM_Destroy(es); |
Francois Boisvert | 6b1b41c | 1999-03-14 17:25:32 +0000 | [diff] [blame] | 433 | |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 434 | |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 435 | if (es) EDIT_LockBuffer(es); |
| 436 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 437 | switch (msg) { |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 438 | case EM_GETSEL16: |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 439 | wParam = 0; |
| 440 | lParam = 0; |
| 441 | /* fall through */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 442 | case EM_GETSEL: |
Francois Gouget | bba4bb1 | 2002-09-17 01:35:09 +0000 | [diff] [blame] | 443 | result = EDIT_EM_GetSel(es, (PUINT)wParam, (PUINT)lParam); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 444 | break; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 445 | |
| 446 | case EM_SETSEL16: |
Alexandre Julliard | 9d61596 | 2003-09-17 04:28:28 +0000 | [diff] [blame] | 447 | if ((short)LOWORD(lParam) == -1) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 448 | EDIT_EM_SetSel(es, (UINT)-1, 0, FALSE); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 449 | else |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 450 | EDIT_EM_SetSel(es, LOWORD(lParam), HIWORD(lParam), FALSE); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 451 | if (!wParam) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 452 | EDIT_EM_ScrollCaret(es); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 453 | result = 1; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 454 | break; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 455 | case EM_SETSEL: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 456 | EDIT_EM_SetSel(es, wParam, lParam, FALSE); |
| 457 | EDIT_EM_ScrollCaret(es); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 458 | result = 1; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 459 | break; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 460 | |
| 461 | case EM_GETRECT16: |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 462 | if (lParam) |
Alexandre Julliard | 3c39a99 | 2004-08-31 00:02:02 +0000 | [diff] [blame^] | 463 | { |
| 464 | RECT16 *r16 = MapSL(lParam); |
| 465 | r16->left = es->format_rect.left; |
| 466 | r16->top = es->format_rect.top; |
| 467 | r16->right = es->format_rect.right; |
| 468 | r16->bottom = es->format_rect.bottom; |
| 469 | } |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 470 | break; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 471 | case EM_GETRECT: |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 472 | if (lParam) |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 473 | CopyRect((LPRECT)lParam, &es->format_rect); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 474 | break; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 475 | |
| 476 | case EM_SETRECT16: |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 477 | if ((es->style & ES_MULTILINE) && lParam) { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 478 | RECT rc; |
Alexandre Julliard | 3c39a99 | 2004-08-31 00:02:02 +0000 | [diff] [blame^] | 479 | RECT16 *r16 = MapSL(lParam); |
| 480 | rc.left = r16->left; |
| 481 | rc.top = r16->top; |
| 482 | rc.right = r16->right; |
| 483 | rc.bottom = r16->bottom; |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 484 | EDIT_SetRectNP(es, &rc); |
| 485 | EDIT_UpdateText(es, NULL, TRUE); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 486 | } |
| 487 | break; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 488 | case EM_SETRECT: |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 489 | if ((es->style & ES_MULTILINE) && lParam) { |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 490 | EDIT_SetRectNP(es, (LPRECT)lParam); |
| 491 | EDIT_UpdateText(es, NULL, TRUE); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 492 | } |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 493 | break; |
| 494 | |
| 495 | case EM_SETRECTNP16: |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 496 | if ((es->style & ES_MULTILINE) && lParam) { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 497 | RECT rc; |
Alexandre Julliard | 3c39a99 | 2004-08-31 00:02:02 +0000 | [diff] [blame^] | 498 | RECT16 *r16 = MapSL(lParam); |
| 499 | rc.left = r16->left; |
| 500 | rc.top = r16->top; |
| 501 | rc.right = r16->right; |
| 502 | rc.bottom = r16->bottom; |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 503 | EDIT_SetRectNP(es, &rc); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 504 | } |
| 505 | break; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 506 | case EM_SETRECTNP: |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 507 | if ((es->style & ES_MULTILINE) && lParam) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 508 | EDIT_SetRectNP(es, (LPRECT)lParam); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 509 | break; |
| 510 | |
| 511 | case EM_SCROLL16: |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 512 | case EM_SCROLL: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 513 | result = EDIT_EM_Scroll(es, (INT)wParam); |
Alexandre Julliard | 9d61596 | 2003-09-17 04:28:28 +0000 | [diff] [blame] | 514 | break; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 515 | |
| 516 | case EM_LINESCROLL16: |
Alexandre Julliard | 9d61596 | 2003-09-17 04:28:28 +0000 | [diff] [blame] | 517 | wParam = (WPARAM)(INT)(SHORT)HIWORD(lParam); |
| 518 | lParam = (LPARAM)(INT)(SHORT)LOWORD(lParam); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 519 | /* fall through */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 520 | case EM_LINESCROLL: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 521 | result = (LRESULT)EDIT_EM_LineScroll(es, (INT)wParam, (INT)lParam); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 522 | break; |
| 523 | |
| 524 | case EM_SCROLLCARET16: |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 525 | case EM_SCROLLCARET: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 526 | EDIT_EM_ScrollCaret(es); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 527 | result = 1; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 528 | break; |
| 529 | |
| 530 | case EM_GETMODIFY16: |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 531 | case EM_GETMODIFY: |
Eric Pouech | 8dde5a4 | 1999-04-25 10:58:04 +0000 | [diff] [blame] | 532 | result = ((es->flags & EF_MODIFIED) != 0); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 533 | break; |
| 534 | |
| 535 | case EM_SETMODIFY16: |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 536 | case EM_SETMODIFY: |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 537 | if (wParam) |
| 538 | es->flags |= EF_MODIFIED; |
| 539 | else |
Gerard Patel | 40ed511 | 1999-07-03 15:47:50 +0000 | [diff] [blame] | 540 | es->flags &= ~(EF_MODIFIED | EF_UPDATE); /* reset pending updates */ |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 541 | break; |
| 542 | |
| 543 | case EM_GETLINECOUNT16: |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 544 | case EM_GETLINECOUNT: |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 545 | result = (es->style & ES_MULTILINE) ? es->line_count : 1; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 546 | break; |
| 547 | |
| 548 | case EM_LINEINDEX16: |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 549 | if ((INT16)wParam == -1) |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 550 | wParam = (WPARAM)-1; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 551 | /* fall through */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 552 | case EM_LINEINDEX: |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 553 | result = (LRESULT)EDIT_EM_LineIndex(es, (INT)wParam); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 554 | break; |
| 555 | |
| 556 | case EM_SETHANDLE16: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 557 | EDIT_EM_SetHandle16(es, (HLOCAL16)wParam); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 558 | break; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 559 | case EM_SETHANDLE: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 560 | EDIT_EM_SetHandle(es, (HLOCAL)wParam); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 561 | break; |
| 562 | |
| 563 | case EM_GETHANDLE16: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 564 | result = (LRESULT)EDIT_EM_GetHandle16(es); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 565 | break; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 566 | case EM_GETHANDLE: |
Dmitry Timoshkov | 8058ead | 2000-12-21 20:19:21 +0000 | [diff] [blame] | 567 | result = (LRESULT)EDIT_EM_GetHandle(es); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 568 | break; |
| 569 | |
| 570 | case EM_GETTHUMB16: |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 571 | case EM_GETTHUMB: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 572 | result = EDIT_EM_GetThumb(es); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 573 | break; |
| 574 | |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 575 | /* these messages missing from specs */ |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 576 | case WM_USER+15: |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 577 | case 0x00bf: |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 578 | case WM_USER+16: |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 579 | case 0x00c0: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 580 | case WM_USER+19: |
| 581 | case 0x00c3: |
| 582 | case WM_USER+26: |
| 583 | case 0x00ca: |
| 584 | FIXME("undocumented message 0x%x, please report\n", msg); |
Alexandre Julliard | de42428 | 2001-08-10 22:51:42 +0000 | [diff] [blame] | 585 | result = DefWindowProcW(hwnd, msg, wParam, lParam); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 586 | break; |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 587 | |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 588 | case EM_LINELENGTH16: |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 589 | case EM_LINELENGTH: |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 590 | result = (LRESULT)EDIT_EM_LineLength(es, (INT)wParam); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 591 | break; |
| 592 | |
| 593 | case EM_REPLACESEL16: |
Alexandre Julliard | 982a223 | 2000-12-13 20:20:09 +0000 | [diff] [blame] | 594 | lParam = (LPARAM)MapSL(lParam); |
Alexandre Julliard | c9e1139 | 2001-04-10 21:46:27 +0000 | [diff] [blame] | 595 | unicode = FALSE; /* 16-bit message is always ascii */ |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 596 | /* fall through */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 597 | case EM_REPLACESEL: |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 598 | { |
| 599 | LPWSTR textW; |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 600 | |
| 601 | if(unicode) |
| 602 | textW = (LPWSTR)lParam; |
| 603 | else |
| 604 | { |
| 605 | LPSTR textA = (LPSTR)lParam; |
| 606 | INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0); |
| 607 | if((textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR)))) |
| 608 | MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW); |
| 609 | } |
| 610 | |
Carl Sopchak | 23b88ef | 2002-11-21 03:57:05 +0000 | [diff] [blame] | 611 | EDIT_EM_ReplaceSel(es, (BOOL)wParam, textW, TRUE, TRUE); |
Alexandre Julliard | a0d7731 | 1998-09-13 16:32:00 +0000 | [diff] [blame] | 612 | result = 1; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 613 | |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 614 | if(!unicode) |
| 615 | HeapFree(GetProcessHeap(), 0, textW); |
| 616 | break; |
| 617 | } |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 618 | |
| 619 | case EM_GETLINE16: |
Alexandre Julliard | 982a223 | 2000-12-13 20:20:09 +0000 | [diff] [blame] | 620 | lParam = (LPARAM)MapSL(lParam); |
Alexandre Julliard | c9e1139 | 2001-04-10 21:46:27 +0000 | [diff] [blame] | 621 | unicode = FALSE; /* 16-bit message is always ascii */ |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 622 | /* fall through */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 623 | case EM_GETLINE: |
Dmitry Timoshkov | bf60453 | 2001-02-12 19:15:33 +0000 | [diff] [blame] | 624 | result = (LRESULT)EDIT_EM_GetLine(es, (INT)wParam, lParam, unicode); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 625 | break; |
| 626 | |
| 627 | case EM_LIMITTEXT16: |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 628 | case EM_SETLIMITTEXT: |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 629 | EDIT_EM_SetLimitText(es, (INT)wParam); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 630 | break; |
| 631 | |
| 632 | case EM_CANUNDO16: |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 633 | case EM_CANUNDO: |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 634 | result = (LRESULT)EDIT_EM_CanUndo(es); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 635 | break; |
| 636 | |
| 637 | case EM_UNDO16: |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 638 | case EM_UNDO: |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 639 | case WM_UNDO: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 640 | result = (LRESULT)EDIT_EM_Undo(es); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 641 | break; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 642 | |
| 643 | case EM_FMTLINES16: |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 644 | case EM_FMTLINES: |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 645 | result = (LRESULT)EDIT_EM_FmtLines(es, (BOOL)wParam); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 646 | break; |
| 647 | |
| 648 | case EM_LINEFROMCHAR16: |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 649 | case EM_LINEFROMCHAR: |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 650 | result = (LRESULT)EDIT_EM_LineFromChar(es, (INT)wParam); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 651 | break; |
| 652 | |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 653 | case EM_SETTABSTOPS16: |
Alexandre Julliard | 982a223 | 2000-12-13 20:20:09 +0000 | [diff] [blame] | 654 | result = (LRESULT)EDIT_EM_SetTabStops16(es, (INT)wParam, MapSL(lParam)); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 655 | break; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 656 | case EM_SETTABSTOPS: |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 657 | result = (LRESULT)EDIT_EM_SetTabStops(es, (INT)wParam, (LPINT)lParam); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 658 | break; |
| 659 | |
| 660 | case EM_SETPASSWORDCHAR16: |
Alexandre Julliard | c9e1139 | 2001-04-10 21:46:27 +0000 | [diff] [blame] | 661 | unicode = FALSE; /* 16-bit message is always ascii */ |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 662 | /* fall through */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 663 | case EM_SETPASSWORDCHAR: |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 664 | { |
| 665 | WCHAR charW = 0; |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 666 | |
| 667 | if(unicode) |
| 668 | charW = (WCHAR)wParam; |
| 669 | else |
| 670 | { |
| 671 | CHAR charA = wParam; |
| 672 | MultiByteToWideChar(CP_ACP, 0, &charA, 1, &charW, 1); |
| 673 | } |
| 674 | |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 675 | EDIT_EM_SetPasswordChar(es, charW); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 676 | break; |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 677 | } |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 678 | |
| 679 | case EM_EMPTYUNDOBUFFER16: |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 680 | case EM_EMPTYUNDOBUFFER: |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 681 | EDIT_EM_EmptyUndoBuffer(es); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 682 | break; |
| 683 | |
| 684 | case EM_GETFIRSTVISIBLELINE16: |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 685 | result = es->y_offset; |
| 686 | break; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 687 | case EM_GETFIRSTVISIBLELINE: |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 688 | result = (es->style & ES_MULTILINE) ? es->y_offset : es->x_offset; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 689 | break; |
| 690 | |
| 691 | case EM_SETREADONLY16: |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 692 | case EM_SETREADONLY: |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 693 | if (wParam) { |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 694 | SetWindowLongW( hwnd, GWL_STYLE, |
| 695 | GetWindowLongW( hwnd, GWL_STYLE ) | ES_READONLY ); |
Alexandre Julliard | de42428 | 2001-08-10 22:51:42 +0000 | [diff] [blame] | 696 | es->style |= ES_READONLY; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 697 | } else { |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 698 | SetWindowLongW( hwnd, GWL_STYLE, |
| 699 | GetWindowLongW( hwnd, GWL_STYLE ) & ~ES_READONLY ); |
Alexandre Julliard | de42428 | 2001-08-10 22:51:42 +0000 | [diff] [blame] | 700 | es->style &= ~ES_READONLY; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 701 | } |
Francois Boisvert | 6b1b41c | 1999-03-14 17:25:32 +0000 | [diff] [blame] | 702 | result = 1; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 703 | break; |
| 704 | |
| 705 | case EM_SETWORDBREAKPROC16: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 706 | EDIT_EM_SetWordBreakProc16(es, (EDITWORDBREAKPROC16)lParam); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 707 | break; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 708 | case EM_SETWORDBREAKPROC: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 709 | EDIT_EM_SetWordBreakProc(es, lParam); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 710 | break; |
| 711 | |
| 712 | case EM_GETWORDBREAKPROC16: |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 713 | result = (LRESULT)es->word_break_proc16; |
| 714 | break; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 715 | case EM_GETWORDBREAKPROC: |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 716 | result = (LRESULT)es->word_break_proc; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 717 | break; |
| 718 | |
| 719 | case EM_GETPASSWORDCHAR16: |
Alexandre Julliard | c9e1139 | 2001-04-10 21:46:27 +0000 | [diff] [blame] | 720 | unicode = FALSE; /* 16-bit message is always ascii */ |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 721 | /* fall through */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 722 | case EM_GETPASSWORDCHAR: |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 723 | { |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 724 | if(unicode) |
| 725 | result = es->password_char; |
| 726 | else |
| 727 | { |
| 728 | WCHAR charW = es->password_char; |
| 729 | CHAR charA = 0; |
| 730 | WideCharToMultiByte(CP_ACP, 0, &charW, 1, &charA, 1, NULL, NULL); |
| 731 | result = charA; |
| 732 | } |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 733 | break; |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 734 | } |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 735 | |
| 736 | /* The following EM_xxx are new to win95 and don't exist for 16 bit */ |
| 737 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 738 | case EM_SETMARGINS: |
Alexandre Julliard | 9d61596 | 2003-09-17 04:28:28 +0000 | [diff] [blame] | 739 | EDIT_EM_SetMargins(es, (INT)wParam, (short)LOWORD(lParam), (short)HIWORD(lParam)); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 740 | break; |
| 741 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 742 | case EM_GETMARGINS: |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 743 | result = MAKELONG(es->left_margin, es->right_margin); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 744 | break; |
| 745 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 746 | case EM_GETLIMITTEXT: |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 747 | result = es->buffer_limit; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 748 | break; |
| 749 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 750 | case EM_POSFROMCHAR: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 751 | result = EDIT_EM_PosFromChar(es, (INT)wParam, FALSE); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 752 | break; |
| 753 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 754 | case EM_CHARFROMPOS: |
Alexandre Julliard | 9d61596 | 2003-09-17 04:28:28 +0000 | [diff] [blame] | 755 | result = EDIT_EM_CharFromPos(es, (short)LOWORD(lParam), (short)HIWORD(lParam)); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 756 | break; |
| 757 | |
Bill Medland | 86bfa4c | 2001-06-28 18:01:00 +0000 | [diff] [blame] | 758 | /* End of the EM_ messages which were in numerical order; what order |
| 759 | * are these in? vaguely alphabetical? |
| 760 | */ |
| 761 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 762 | case WM_GETDLGCODE: |
Rein Klazes | eb359e2 | 2003-05-15 04:14:53 +0000 | [diff] [blame] | 763 | result = DLGC_HASSETSEL | DLGC_WANTCHARS | DLGC_WANTARROWS; |
Rein Klazes | a762b4c | 2003-05-19 21:40:31 +0000 | [diff] [blame] | 764 | |
| 765 | if (lParam && (((LPMSG)lParam)->message == WM_KEYDOWN)) |
| 766 | { |
| 767 | int vk = (int)((LPMSG)lParam)->wParam; |
| 768 | |
| 769 | if (vk == VK_RETURN && (GetWindowLongW( hwnd, GWL_STYLE ) & ES_WANTRETURN)) |
| 770 | { |
| 771 | result |= DLGC_WANTMESSAGE; |
| 772 | } |
| 773 | else if (es->hwndListBox && (vk == VK_RETURN || vk == VK_ESCAPE)) |
| 774 | { |
| 775 | if (SendMessageW(GetParent(hwnd), CB_GETDROPPEDSTATE, 0, 0)) |
| 776 | result |= DLGC_WANTMESSAGE; |
| 777 | } |
| 778 | } |
Rein Klazes | eb359e2 | 2003-05-15 04:14:53 +0000 | [diff] [blame] | 779 | break; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 780 | |
Aric Stewart | 199449d | 2003-05-12 03:24:10 +0000 | [diff] [blame] | 781 | case WM_IME_CHAR: |
| 782 | if (!unicode) |
| 783 | { |
| 784 | WCHAR charW; |
| 785 | CHAR strng[2]; |
| 786 | |
| 787 | strng[0] = wParam >> 8; |
| 788 | strng[1] = wParam & 0xff; |
Yoshiro Takeno | c91d9f0 | 2004-01-26 20:20:07 +0000 | [diff] [blame] | 789 | if (strng[0]) MultiByteToWideChar(CP_ACP, 0, strng, 2, &charW, 1); |
| 790 | else MultiByteToWideChar(CP_ACP, 0, &strng[1], 1, &charW, 1); |
Aric Stewart | 199449d | 2003-05-12 03:24:10 +0000 | [diff] [blame] | 791 | EDIT_WM_Char(es, charW); |
| 792 | break; |
| 793 | } |
| 794 | /* fall through */ |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 795 | case WM_CHAR: |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 796 | { |
| 797 | WCHAR charW; |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 798 | |
| 799 | if(unicode) |
| 800 | charW = wParam; |
| 801 | else |
Serge Ivanov | 9eedcf5 | 2000-06-07 03:47:34 +0000 | [diff] [blame] | 802 | { |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 803 | CHAR charA = wParam; |
| 804 | MultiByteToWideChar(CP_ACP, 0, &charA, 1, &charW, 1); |
| 805 | } |
| 806 | |
| 807 | if ((charW == VK_RETURN || charW == VK_ESCAPE) && es->hwndListBox) |
| 808 | { |
Alexandre Julliard | de42428 | 2001-08-10 22:51:42 +0000 | [diff] [blame] | 809 | if (SendMessageW(GetParent(hwnd), CB_GETDROPPEDSTATE, 0, 0)) |
| 810 | SendMessageW(GetParent(hwnd), WM_KEYDOWN, charW, 0); |
Serge Ivanov | 9eedcf5 | 2000-06-07 03:47:34 +0000 | [diff] [blame] | 811 | break; |
| 812 | } |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 813 | EDIT_WM_Char(es, charW); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 814 | break; |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 815 | } |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 816 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 817 | case WM_CLEAR: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 818 | EDIT_WM_Clear(es); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 819 | break; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 820 | |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 821 | case WM_COMMAND: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 822 | EDIT_WM_Command(es, HIWORD(wParam), LOWORD(wParam), (HWND)lParam); |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 823 | break; |
| 824 | |
Alexandre Julliard | 9d61596 | 2003-09-17 04:28:28 +0000 | [diff] [blame] | 825 | case WM_CONTEXTMENU: |
| 826 | EDIT_WM_ContextMenu(es, (short)LOWORD(lParam), (short)HIWORD(lParam)); |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 827 | break; |
| 828 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 829 | case WM_COPY: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 830 | EDIT_WM_Copy(es); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 831 | break; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 832 | |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 833 | case WM_CREATE: |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 834 | if(unicode) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 835 | result = EDIT_WM_Create(es, ((LPCREATESTRUCTW)lParam)->lpszName); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 836 | else |
| 837 | { |
| 838 | LPCSTR nameA = ((LPCREATESTRUCTA)lParam)->lpszName; |
| 839 | LPWSTR nameW = NULL; |
| 840 | if(nameA) |
| 841 | { |
| 842 | INT countW = MultiByteToWideChar(CP_ACP, 0, nameA, -1, NULL, 0); |
| 843 | if((nameW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR)))) |
| 844 | MultiByteToWideChar(CP_ACP, 0, nameA, -1, nameW, countW); |
| 845 | } |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 846 | result = EDIT_WM_Create(es, nameW); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 847 | if(nameW) |
| 848 | HeapFree(GetProcessHeap(), 0, nameW); |
| 849 | } |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 850 | break; |
| 851 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 852 | case WM_CUT: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 853 | EDIT_WM_Cut(es); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 854 | break; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 855 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 856 | case WM_ENABLE: |
Stephane Lussier | 9380534 | 1999-09-03 16:37:00 +0000 | [diff] [blame] | 857 | es->bEnableState = (BOOL) wParam; |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 858 | EDIT_UpdateText(es, NULL, TRUE); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 859 | break; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 860 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 861 | case WM_ERASEBKGND: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 862 | result = EDIT_WM_EraseBkGnd(es, (HDC)wParam); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 863 | break; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 864 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 865 | case WM_GETFONT: |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 866 | result = (LRESULT)es->font; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 867 | break; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 868 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 869 | case WM_GETTEXT: |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 870 | result = (LRESULT)EDIT_WM_GetText(es, (INT)wParam, lParam, unicode); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 871 | break; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 872 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 873 | case WM_GETTEXTLENGTH: |
Alexandre Julliard | 741325b | 2002-06-13 19:20:43 +0000 | [diff] [blame] | 874 | if (unicode) result = strlenW(es->text); |
| 875 | else result = WideCharToMultiByte( CP_ACP, 0, es->text, strlenW(es->text), |
| 876 | NULL, 0, NULL, NULL ); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 877 | break; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 878 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 879 | case WM_HSCROLL: |
Alexandre Julliard | 9d61596 | 2003-09-17 04:28:28 +0000 | [diff] [blame] | 880 | result = EDIT_WM_HScroll(es, LOWORD(wParam), (short)HIWORD(wParam)); |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 881 | break; |
| 882 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 883 | case WM_KEYDOWN: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 884 | result = EDIT_WM_KeyDown(es, (INT)wParam); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 885 | break; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 886 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 887 | case WM_KILLFOCUS: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 888 | result = EDIT_WM_KillFocus(es); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 889 | break; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 890 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 891 | case WM_LBUTTONDBLCLK: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 892 | result = EDIT_WM_LButtonDblClk(es); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 893 | break; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 894 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 895 | case WM_LBUTTONDOWN: |
Alexandre Julliard | 9d61596 | 2003-09-17 04:28:28 +0000 | [diff] [blame] | 896 | result = EDIT_WM_LButtonDown(es, wParam, (short)LOWORD(lParam), (short)HIWORD(lParam)); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 897 | break; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 898 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 899 | case WM_LBUTTONUP: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 900 | result = EDIT_WM_LButtonUp(es); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 901 | break; |
| 902 | |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 903 | case WM_MBUTTONDOWN: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 904 | result = EDIT_WM_MButtonDown(es); |
Alexandre Julliard | c616625 | 2000-05-25 23:01:39 +0000 | [diff] [blame] | 905 | break; |
| 906 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 907 | case WM_MOUSEACTIVATE: |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 908 | result = MA_ACTIVATE; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 909 | break; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 910 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 911 | case WM_MOUSEMOVE: |
Alexandre Julliard | 9d61596 | 2003-09-17 04:28:28 +0000 | [diff] [blame] | 912 | result = EDIT_WM_MouseMove(es, (short)LOWORD(lParam), (short)HIWORD(lParam)); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 913 | break; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 914 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 915 | case WM_PAINT: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 916 | EDIT_WM_Paint(es, wParam); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 917 | break; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 918 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 919 | case WM_PASTE: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 920 | EDIT_WM_Paste(es); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 921 | break; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 922 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 923 | case WM_SETFOCUS: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 924 | EDIT_WM_SetFocus(es); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 925 | break; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 926 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 927 | case WM_SETFONT: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 928 | EDIT_WM_SetFont(es, (HFONT)wParam, LOWORD(lParam) != 0); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 929 | break; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 930 | |
Dmitry Timoshkov | a234db8 | 2001-01-19 20:49:54 +0000 | [diff] [blame] | 931 | case WM_SETREDRAW: |
| 932 | /* FIXME: actually set an internal flag and behave accordingly */ |
| 933 | break; |
| 934 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 935 | case WM_SETTEXT: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 936 | EDIT_WM_SetText(es, lParam, unicode); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 937 | result = TRUE; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 938 | break; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 939 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 940 | case WM_SIZE: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 941 | EDIT_WM_Size(es, (UINT)wParam, LOWORD(lParam), HIWORD(lParam)); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 942 | break; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 943 | |
Bill Medland | 86bfa4c | 2001-06-28 18:01:00 +0000 | [diff] [blame] | 944 | case WM_STYLECHANGED: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 945 | result = EDIT_WM_StyleChanged(es, wParam, (const STYLESTRUCT *)lParam); |
Bill Medland | 86bfa4c | 2001-06-28 18:01:00 +0000 | [diff] [blame] | 946 | break; |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 947 | |
Bill Medland | 86bfa4c | 2001-06-28 18:01:00 +0000 | [diff] [blame] | 948 | case WM_STYLECHANGING: |
Bill Medland | 86bfa4c | 2001-06-28 18:01:00 +0000 | [diff] [blame] | 949 | result = 0; /* See EDIT_WM_StyleChanged */ |
| 950 | break; |
| 951 | |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 952 | case WM_SYSKEYDOWN: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 953 | result = EDIT_WM_SysKeyDown(es, (INT)wParam, (DWORD)lParam); |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 954 | break; |
| 955 | |
| 956 | case WM_TIMER: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 957 | EDIT_WM_Timer(es); |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 958 | break; |
| 959 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 960 | case WM_VSCROLL: |
Alexandre Julliard | 9d61596 | 2003-09-17 04:28:28 +0000 | [diff] [blame] | 961 | result = EDIT_WM_VScroll(es, LOWORD(wParam), (short)HIWORD(wParam)); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 962 | break; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 963 | |
Stephane Lussier | 4bdf4af | 2000-04-18 11:56:33 +0000 | [diff] [blame] | 964 | case WM_MOUSEWHEEL: |
| 965 | { |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 966 | int gcWheelDelta = 0; |
Stephane Lussier | 4bdf4af | 2000-04-18 11:56:33 +0000 | [diff] [blame] | 967 | UINT pulScrollLines = 3; |
| 968 | SystemParametersInfoW(SPI_GETWHEELSCROLLLINES,0, &pulScrollLines, 0); |
| 969 | |
| 970 | if (wParam & (MK_SHIFT | MK_CONTROL)) { |
Alexandre Julliard | de42428 | 2001-08-10 22:51:42 +0000 | [diff] [blame] | 971 | result = DefWindowProcW(hwnd, msg, wParam, lParam); |
Stephane Lussier | 4bdf4af | 2000-04-18 11:56:33 +0000 | [diff] [blame] | 972 | break; |
| 973 | } |
Alexandre Julliard | 9d61596 | 2003-09-17 04:28:28 +0000 | [diff] [blame] | 974 | gcWheelDelta -= GET_WHEEL_DELTA_WPARAM(wParam); |
Stephane Lussier | 4bdf4af | 2000-04-18 11:56:33 +0000 | [diff] [blame] | 975 | if (abs(gcWheelDelta) >= WHEEL_DELTA && pulScrollLines) |
| 976 | { |
| 977 | int cLineScroll= (int) min((UINT) es->line_count, pulScrollLines); |
| 978 | cLineScroll *= (gcWheelDelta / WHEEL_DELTA); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 979 | result = EDIT_EM_LineScroll(es, 0, cLineScroll); |
Stephane Lussier | 4bdf4af | 2000-04-18 11:56:33 +0000 | [diff] [blame] | 980 | } |
| 981 | } |
| 982 | break; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 983 | default: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 984 | result = DefWindowProcT(hwnd, msg, wParam, lParam, unicode); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 985 | break; |
| 986 | } |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 987 | |
| 988 | if (es) EDIT_UnlockBuffer(es, FALSE); |
Robert Shearman | 8570328 | 2004-08-17 22:09:16 +0000 | [diff] [blame] | 989 | |
| 990 | TRACE("hwnd=%p msg=%x (%s) -- 0x%08lx\n", hwnd, msg, SPY_GetMsgName(msg, hwnd), result); |
| 991 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 992 | return result; |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 993 | } |
| 994 | |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 995 | /********************************************************************* |
| 996 | * |
| 997 | * EditWndProcW (USER32.@) |
| 998 | */ |
| 999 | LRESULT WINAPI EditWndProcW(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) |
| 1000 | { |
Alexandre Julliard | de42428 | 2001-08-10 22:51:42 +0000 | [diff] [blame] | 1001 | return EditWndProc_common(hWnd, uMsg, wParam, lParam, TRUE); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1002 | } |
| 1003 | |
| 1004 | /********************************************************************* |
| 1005 | * |
Patrik Stridvall | 15a3b74 | 2001-04-27 18:03:51 +0000 | [diff] [blame] | 1006 | * EditWndProc (USER32.@) |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1007 | */ |
| 1008 | LRESULT WINAPI EditWndProcA(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) |
| 1009 | { |
Alexandre Julliard | de42428 | 2001-08-10 22:51:42 +0000 | [diff] [blame] | 1010 | return EditWndProc_common(hWnd, uMsg, wParam, lParam, FALSE); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1011 | } |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 1012 | |
| 1013 | /********************************************************************* |
Alexandre Julliard | 02ed4c2 | 1996-03-02 19:34:10 +0000 | [diff] [blame] | 1014 | * |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1015 | * EDIT_BuildLineDefs_ML |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1016 | * |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1017 | * Build linked list of text lines. |
| 1018 | * Lines can end with '\0' (last line), a character (if it is wrapped), |
| 1019 | * a soft return '\r\r\n' or a hard return '\r\n' |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1020 | * |
Alexandre Julliard | 02ed4c2 | 1996-03-02 19:34:10 +0000 | [diff] [blame] | 1021 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1022 | static void EDIT_BuildLineDefs_ML(EDITSTATE *es, INT istart, INT iend, INT delta, HRGN hrgn) |
Alexandre Julliard | 02ed4c2 | 1996-03-02 19:34:10 +0000 | [diff] [blame] | 1023 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1024 | HDC dc; |
| 1025 | HFONT old_font = 0; |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 1026 | LPWSTR current_position, cp; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1027 | INT fw; |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 1028 | LINEDEF *current_line; |
| 1029 | LINEDEF *previous_line; |
| 1030 | LINEDEF *start_line; |
| 1031 | INT line_index = 0, nstart_line = 0, nstart_index = 0; |
| 1032 | INT line_count = es->line_count; |
| 1033 | INT orig_net_length; |
| 1034 | RECT rc; |
Alexandre Julliard | 02ed4c2 | 1996-03-02 19:34:10 +0000 | [diff] [blame] | 1035 | |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 1036 | if (istart == iend && delta == 0) |
| 1037 | return; |
Alexandre Julliard | 02ed4c2 | 1996-03-02 19:34:10 +0000 | [diff] [blame] | 1038 | |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1039 | dc = GetDC(es->hwndSelf); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1040 | if (es->font) |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1041 | old_font = SelectObject(dc, es->font); |
Alexandre Julliard | 02ed4c2 | 1996-03-02 19:34:10 +0000 | [diff] [blame] | 1042 | |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 1043 | previous_line = NULL; |
| 1044 | current_line = es->first_line_def; |
| 1045 | |
| 1046 | /* Find starting line. istart must lie inside an existing line or |
| 1047 | * at the end of buffer */ |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1048 | do { |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1049 | if (istart < current_line->index + current_line->length || |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 1050 | current_line->ending == END_0) |
| 1051 | break; |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1052 | |
| 1053 | previous_line = current_line; |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 1054 | current_line = current_line->next; |
| 1055 | line_index++; |
| 1056 | } while (current_line); |
| 1057 | |
| 1058 | if (!current_line) /* Error occurred start is not inside previous buffer */ |
| 1059 | { |
| 1060 | FIXME(" modification occurred outside buffer\n"); |
Christian Costa | 6e7d78e | 2003-05-11 03:27:23 +0000 | [diff] [blame] | 1061 | ReleaseDC(es->hwndSelf, dc); |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 1062 | return; |
| 1063 | } |
| 1064 | |
| 1065 | /* Remember start of modifications in order to calculate update region */ |
| 1066 | nstart_line = line_index; |
| 1067 | nstart_index = current_line->index; |
| 1068 | |
| 1069 | /* We must start to reformat from the previous line since the modifications |
| 1070 | * may have caused the line to wrap upwards. */ |
| 1071 | if (!(es->style & ES_AUTOHSCROLL) && line_index > 0) |
| 1072 | { |
| 1073 | line_index--; |
| 1074 | current_line = previous_line; |
| 1075 | } |
| 1076 | start_line = current_line; |
| 1077 | |
| 1078 | fw = es->format_rect.right - es->format_rect.left; |
| 1079 | current_position = es->text + current_line->index; |
| 1080 | do { |
| 1081 | if (current_line != start_line) |
| 1082 | { |
| 1083 | if (!current_line || current_line->index + delta > current_position - es->text) |
| 1084 | { |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1085 | /* The buffer has been expanded, create a new line and |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 1086 | insert it into the link list */ |
| 1087 | LINEDEF *new_line = HeapAlloc(GetProcessHeap(), 0, sizeof(LINEDEF)); |
| 1088 | new_line->next = previous_line->next; |
| 1089 | previous_line->next = new_line; |
| 1090 | current_line = new_line; |
| 1091 | es->line_count++; |
| 1092 | } |
| 1093 | else if (current_line->index + delta < current_position - es->text) |
| 1094 | { |
| 1095 | /* The previous line merged with this line so we delete this extra entry */ |
| 1096 | previous_line->next = current_line->next; |
| 1097 | HeapFree(GetProcessHeap(), 0, current_line); |
| 1098 | current_line = previous_line->next; |
| 1099 | es->line_count--; |
| 1100 | continue; |
| 1101 | } |
| 1102 | else /* current_line->index + delta == current_position */ |
| 1103 | { |
| 1104 | if (current_position - es->text > iend) |
| 1105 | break; /* We reached end of line modifications */ |
| 1106 | /* else recalulate this line */ |
| 1107 | } |
| 1108 | } |
| 1109 | |
| 1110 | current_line->index = current_position - es->text; |
| 1111 | orig_net_length = current_line->net_length; |
| 1112 | |
| 1113 | /* Find end of line */ |
| 1114 | cp = current_position; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1115 | while (*cp) { |
Chuck Crayne | ce2024c | 2002-04-22 23:08:19 +0000 | [diff] [blame] | 1116 | if (*cp == '\n') break; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1117 | if ((*cp == '\r') && (*(cp + 1) == '\n')) |
| 1118 | break; |
| 1119 | cp++; |
| 1120 | } |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 1121 | |
| 1122 | /* Mark type of line termination */ |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1123 | if (!(*cp)) { |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 1124 | current_line->ending = END_0; |
| 1125 | current_line->net_length = strlenW(current_position); |
| 1126 | } else if ((cp > current_position) && (*(cp - 1) == '\r')) { |
| 1127 | current_line->ending = END_SOFT; |
| 1128 | current_line->net_length = cp - current_position - 1; |
Chuck Crayne | ce2024c | 2002-04-22 23:08:19 +0000 | [diff] [blame] | 1129 | } else if (*cp == '\n') { |
| 1130 | current_line->ending = END_RICH; |
| 1131 | current_line->net_length = cp - current_position; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1132 | } else { |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 1133 | current_line->ending = END_HARD; |
| 1134 | current_line->net_length = cp - current_position; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1135 | } |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 1136 | |
| 1137 | /* Calculate line width */ |
| 1138 | current_line->width = (INT)LOWORD(GetTabbedTextExtentW(dc, |
| 1139 | current_position, current_line->net_length, |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1140 | es->tabs_count, es->tabs)); |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 1141 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1142 | /* FIXME: check here for lines that are too wide even in AUTOHSCROLL (> 32767 ???) */ |
Ulrich Czekalla | a935c2a | 2004-05-25 18:04:48 +0000 | [diff] [blame] | 1143 | if (!(es->style & ES_AUTOHSCROLL)) { |
| 1144 | if (current_line->width > fw) { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1145 | INT next = 0; |
| 1146 | INT prev; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1147 | do { |
| 1148 | prev = next; |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 1149 | next = EDIT_CallWordBreakProc(es, current_position - es->text, |
| 1150 | prev + 1, current_line->net_length, WB_RIGHT); |
| 1151 | current_line->width = (INT)LOWORD(GetTabbedTextExtentW(dc, |
| 1152 | current_position, next, es->tabs_count, es->tabs)); |
| 1153 | } while (current_line->width <= fw); |
| 1154 | if (!prev) { /* Didn't find a line break so force a break */ |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1155 | next = 0; |
| 1156 | do { |
| 1157 | prev = next; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1158 | next++; |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 1159 | current_line->width = (INT)LOWORD(GetTabbedTextExtentW(dc, |
| 1160 | current_position, next, es->tabs_count, es->tabs)); |
| 1161 | } while (current_line->width <= fw); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1162 | if (!prev) |
| 1163 | prev = 1; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1164 | } |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 1165 | |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1166 | /* If the first line we are calculating, wrapped before istart, we must |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 1167 | * adjust istart in order for this to be reflected in the update region. */ |
| 1168 | if (current_line->index == nstart_index && istart > current_line->index + prev) |
| 1169 | istart = current_line->index + prev; |
| 1170 | /* else if we are updating the previous line before the first line we |
Andreas Mohr | 07216db | 2001-11-13 21:29:38 +0000 | [diff] [blame] | 1171 | * are re-calculating and it expanded */ |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1172 | else if (current_line == start_line && |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 1173 | current_line->index != nstart_index && orig_net_length < prev) |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1174 | { |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 1175 | /* Line expanded due to an upwards line wrap so we must partially include |
| 1176 | * previous line in update region */ |
| 1177 | nstart_line = line_index; |
| 1178 | nstart_index = current_line->index; |
| 1179 | istart = current_line->index + orig_net_length; |
| 1180 | } |
| 1181 | |
| 1182 | current_line->net_length = prev; |
| 1183 | current_line->ending = END_WRAP; |
| 1184 | current_line->width = (INT)LOWORD(GetTabbedTextExtentW(dc, current_position, |
| 1185 | current_line->net_length, es->tabs_count, es->tabs)); |
Ulrich Czekalla | a935c2a | 2004-05-25 18:04:48 +0000 | [diff] [blame] | 1186 | } |
| 1187 | else if (orig_net_length < current_line->net_length && |
| 1188 | current_line == start_line && |
| 1189 | current_line->index != nstart_index) { |
| 1190 | /* The previous line expanded but it's still not as wide as the client rect */ |
| 1191 | /* The expansion is due to an upwards line wrap so we must partially include |
| 1192 | it in the update region */ |
| 1193 | nstart_line = line_index; |
| 1194 | nstart_index = current_line->index; |
| 1195 | istart = current_line->index + orig_net_length; |
| 1196 | } |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1197 | } |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 1198 | |
| 1199 | |
| 1200 | /* Adjust length to include line termination */ |
| 1201 | switch (current_line->ending) { |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1202 | case END_SOFT: |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 1203 | current_line->length = current_line->net_length + 3; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1204 | break; |
Chuck Crayne | ce2024c | 2002-04-22 23:08:19 +0000 | [diff] [blame] | 1205 | case END_RICH: |
| 1206 | current_line->length = current_line->net_length + 1; |
| 1207 | break; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1208 | case END_HARD: |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 1209 | current_line->length = current_line->net_length + 2; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1210 | break; |
| 1211 | case END_WRAP: |
| 1212 | case END_0: |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 1213 | current_line->length = current_line->net_length; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1214 | break; |
| 1215 | } |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 1216 | es->text_width = max(es->text_width, current_line->width); |
| 1217 | current_position += current_line->length; |
| 1218 | previous_line = current_line; |
| 1219 | current_line = current_line->next; |
| 1220 | line_index++; |
| 1221 | } while (previous_line->ending != END_0); |
| 1222 | |
Andreas Mohr | 07216db | 2001-11-13 21:29:38 +0000 | [diff] [blame] | 1223 | /* Finish adjusting line indexes by delta or remove hanging lines */ |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 1224 | if (previous_line->ending == END_0) |
| 1225 | { |
| 1226 | LINEDEF *pnext = NULL; |
| 1227 | |
| 1228 | previous_line->next = NULL; |
| 1229 | while (current_line) |
| 1230 | { |
| 1231 | pnext = current_line->next; |
| 1232 | HeapFree(GetProcessHeap(), 0, current_line); |
| 1233 | current_line = pnext; |
| 1234 | es->line_count--; |
| 1235 | } |
| 1236 | } |
| 1237 | else |
| 1238 | { |
| 1239 | while (current_line) |
| 1240 | { |
| 1241 | current_line->index += delta; |
| 1242 | current_line = current_line->next; |
| 1243 | } |
| 1244 | } |
| 1245 | |
| 1246 | /* Calculate rest of modification rectangle */ |
| 1247 | if (hrgn) |
| 1248 | { |
| 1249 | HRGN tmphrgn; |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1250 | /* |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 1251 | * We calculate two rectangles. One for the first line which may have |
| 1252 | * an indent with respect to the format rect. The other is a format-width |
| 1253 | * rectangle that spans the rest of the lines that changed or moved. |
| 1254 | */ |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1255 | rc.top = es->format_rect.top + nstart_line * es->line_height - |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 1256 | (es->y_offset * es->line_height); /* Adjust for vertical scrollbar */ |
| 1257 | rc.bottom = rc.top + es->line_height; |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1258 | rc.left = es->format_rect.left + (INT)LOWORD(GetTabbedTextExtentW(dc, |
| 1259 | es->text + nstart_index, istart - nstart_index, |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 1260 | es->tabs_count, es->tabs)) - es->x_offset; /* Adjust for horz scroll */ |
| 1261 | rc.right = es->format_rect.right; |
| 1262 | SetRectRgn(hrgn, rc.left, rc.top, rc.right, rc.bottom); |
| 1263 | |
| 1264 | rc.top = rc.bottom; |
| 1265 | rc.left = es->format_rect.left; |
| 1266 | rc.right = es->format_rect.right; |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1267 | /* |
| 1268 | * If lines were added or removed we must re-paint the remainder of the |
| 1269 | * lines since the remaining lines were either shifted up or down. |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 1270 | */ |
| 1271 | if (line_count < es->line_count) /* We added lines */ |
| 1272 | rc.bottom = es->line_count * es->line_height; |
| 1273 | else if (line_count > es->line_count) /* We removed lines */ |
| 1274 | rc.bottom = line_count * es->line_height; |
| 1275 | else |
| 1276 | rc.bottom = line_index * es->line_height; |
| 1277 | rc.bottom -= (es->y_offset * es->line_height); /* Adjust for vertical scrollbar */ |
| 1278 | tmphrgn = CreateRectRgn(rc.left, rc.top, rc.right, rc.bottom); |
| 1279 | CombineRgn(hrgn, hrgn, tmphrgn, RGN_OR); |
| 1280 | DeleteObject(tmphrgn); |
| 1281 | } |
| 1282 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1283 | if (es->font) |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1284 | SelectObject(dc, old_font); |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 1285 | |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1286 | ReleaseDC(es->hwndSelf, dc); |
Alexandre Julliard | 02ed4c2 | 1996-03-02 19:34:10 +0000 | [diff] [blame] | 1287 | } |
| 1288 | |
Dmitry Timoshkov | 11dbda6 | 2001-01-05 03:40:35 +0000 | [diff] [blame] | 1289 | /********************************************************************* |
| 1290 | * |
| 1291 | * EDIT_CalcLineWidth_SL |
| 1292 | * |
| 1293 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1294 | static void EDIT_CalcLineWidth_SL(EDITSTATE *es) |
Dmitry Timoshkov | 11dbda6 | 2001-01-05 03:40:35 +0000 | [diff] [blame] | 1295 | { |
Alexandre Julliard | 9d61596 | 2003-09-17 04:28:28 +0000 | [diff] [blame] | 1296 | es->text_width = (short)LOWORD(EDIT_EM_PosFromChar(es, strlenW(es->text), FALSE)); |
Dmitry Timoshkov | 11dbda6 | 2001-01-05 03:40:35 +0000 | [diff] [blame] | 1297 | } |
Alexandre Julliard | 02ed4c2 | 1996-03-02 19:34:10 +0000 | [diff] [blame] | 1298 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1299 | /********************************************************************* |
| 1300 | * |
| 1301 | * EDIT_CallWordBreakProc |
| 1302 | * |
| 1303 | * Call appropriate WordBreakProc (internal or external). |
| 1304 | * |
Andreas Mohr | 07216db | 2001-11-13 21:29:38 +0000 | [diff] [blame] | 1305 | * Note: The "start" argument should always be an index referring |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1306 | * to es->text. The actual wordbreak proc might be |
| 1307 | * 16 bit, so we can't always pass any 32 bit LPSTR. |
| 1308 | * Hence we assume that es->text is the buffer that holds |
| 1309 | * the string under examination (we can decide this for ourselves). |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 1310 | * |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1311 | */ |
Dmitry Timoshkov | 8058ead | 2000-12-21 20:19:21 +0000 | [diff] [blame] | 1312 | static INT EDIT_CallWordBreakProc(EDITSTATE *es, INT start, INT index, INT count, INT action) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1313 | { |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1314 | INT ret, iWndsLocks; |
| 1315 | |
Andreas Mohr | 07216db | 2001-11-13 21:29:38 +0000 | [diff] [blame] | 1316 | /* To avoid any deadlocks, all the locks on the window structures |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1317 | must be suspended before the control is passed to the application */ |
| 1318 | iWndsLocks = WIN_SuspendWndsLock(); |
| 1319 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1320 | if (es->word_break_proc16) { |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1321 | HGLOBAL16 hglob16; |
| 1322 | SEGPTR segptr; |
| 1323 | INT countA; |
Alexandre Julliard | 7e92c9a | 2003-02-27 21:09:45 +0000 | [diff] [blame] | 1324 | WORD args[5]; |
| 1325 | DWORD result; |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1326 | |
| 1327 | countA = WideCharToMultiByte(CP_ACP, 0, es->text + start, count, NULL, 0, NULL, NULL); |
| 1328 | hglob16 = GlobalAlloc16(GMEM_MOVEABLE | GMEM_ZEROINIT, countA); |
Alexandre Julliard | 5801723 | 2000-12-22 01:09:26 +0000 | [diff] [blame] | 1329 | segptr = K32WOWGlobalLock16(hglob16); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1330 | WideCharToMultiByte(CP_ACP, 0, es->text + start, count, MapSL(segptr), countA, NULL, NULL); |
Alexandre Julliard | 7e92c9a | 2003-02-27 21:09:45 +0000 | [diff] [blame] | 1331 | args[4] = SELECTOROF(segptr); |
| 1332 | args[3] = OFFSETOF(segptr); |
| 1333 | args[2] = index; |
| 1334 | args[1] = countA; |
| 1335 | args[0] = action; |
| 1336 | WOWCallback16Ex((DWORD)es->word_break_proc16, WCB16_PASCAL, sizeof(args), args, &result); |
| 1337 | ret = LOWORD(result); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1338 | GlobalUnlock16(hglob16); |
| 1339 | GlobalFree16(hglob16); |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1340 | } |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1341 | else if (es->word_break_proc) |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1342 | { |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1343 | if(es->is_unicode) |
| 1344 | { |
| 1345 | EDITWORDBREAKPROCW wbpW = (EDITWORDBREAKPROCW)es->word_break_proc; |
| 1346 | |
| 1347 | TRACE_(relay)("(UNICODE wordbrk=%p,str=%s,idx=%d,cnt=%d,act=%d)\n", |
| 1348 | es->word_break_proc, debugstr_wn(es->text + start, count), index, count, action); |
| 1349 | ret = wbpW(es->text + start, index, count, action); |
| 1350 | } |
| 1351 | else |
| 1352 | { |
| 1353 | EDITWORDBREAKPROCA wbpA = (EDITWORDBREAKPROCA)es->word_break_proc; |
| 1354 | INT countA; |
| 1355 | CHAR *textA; |
| 1356 | |
| 1357 | countA = WideCharToMultiByte(CP_ACP, 0, es->text + start, count, NULL, 0, NULL, NULL); |
| 1358 | textA = HeapAlloc(GetProcessHeap(), 0, countA); |
| 1359 | WideCharToMultiByte(CP_ACP, 0, es->text + start, count, textA, countA, NULL, NULL); |
| 1360 | TRACE_(relay)("(ANSI wordbrk=%p,str=%s,idx=%d,cnt=%d,act=%d)\n", |
| 1361 | es->word_break_proc, debugstr_an(textA, countA), index, countA, action); |
| 1362 | ret = wbpA(textA, index, countA, action); |
| 1363 | HeapFree(GetProcessHeap(), 0, textA); |
| 1364 | } |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1365 | } |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1366 | else |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1367 | ret = EDIT_WordBreakProc(es->text + start, index, count, action); |
| 1368 | |
| 1369 | WIN_RestoreWndsLock(iWndsLocks); |
| 1370 | return ret; |
Alexandre Julliard | 02ed4c2 | 1996-03-02 19:34:10 +0000 | [diff] [blame] | 1371 | } |
| 1372 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1373 | |
Alexandre Julliard | 02ed4c2 | 1996-03-02 19:34:10 +0000 | [diff] [blame] | 1374 | /********************************************************************* |
Alexandre Julliard | 02ed4c2 | 1996-03-02 19:34:10 +0000 | [diff] [blame] | 1375 | * |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1376 | * EDIT_CharFromPos |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1377 | * |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1378 | * Beware: This is not the function called on EM_CHARFROMPOS |
| 1379 | * The position _can_ be outside the formatting / client |
| 1380 | * rectangle |
| 1381 | * The return value is only the character index |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1382 | * |
Alexandre Julliard | 02ed4c2 | 1996-03-02 19:34:10 +0000 | [diff] [blame] | 1383 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1384 | static INT EDIT_CharFromPos(EDITSTATE *es, INT x, INT y, LPBOOL after_wrap) |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 1385 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1386 | INT index; |
| 1387 | HDC dc; |
| 1388 | HFONT old_font = 0; |
Alexandre Julliard | 02ed4c2 | 1996-03-02 19:34:10 +0000 | [diff] [blame] | 1389 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1390 | if (es->style & ES_MULTILINE) { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1391 | INT line = (y - es->format_rect.top) / es->line_height + es->y_offset; |
| 1392 | INT line_index = 0; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1393 | LINEDEF *line_def = es->first_line_def; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1394 | INT low, high; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1395 | while ((line > 0) && line_def->next) { |
| 1396 | line_index += line_def->length; |
| 1397 | line_def = line_def->next; |
| 1398 | line--; |
| 1399 | } |
| 1400 | x += es->x_offset - es->format_rect.left; |
| 1401 | if (x >= line_def->width) { |
| 1402 | if (after_wrap) |
| 1403 | *after_wrap = (line_def->ending == END_WRAP); |
| 1404 | return line_index + line_def->net_length; |
| 1405 | } |
| 1406 | if (x <= 0) { |
| 1407 | if (after_wrap) |
| 1408 | *after_wrap = FALSE; |
| 1409 | return line_index; |
| 1410 | } |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1411 | dc = GetDC(es->hwndSelf); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1412 | if (es->font) |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1413 | old_font = SelectObject(dc, es->font); |
Alexandre Julliard | e658d82 | 1997-11-30 17:45:40 +0000 | [diff] [blame] | 1414 | low = line_index + 1; |
| 1415 | high = line_index + line_def->net_length + 1; |
| 1416 | while (low < high - 1) |
| 1417 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1418 | INT mid = (low + high) / 2; |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1419 | if (LOWORD(GetTabbedTextExtentW(dc, es->text + line_index,mid - line_index, es->tabs_count, es->tabs)) > x) high = mid; |
Alexandre Julliard | e658d82 | 1997-11-30 17:45:40 +0000 | [diff] [blame] | 1420 | else low = mid; |
| 1421 | } |
| 1422 | index = low; |
| 1423 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1424 | if (after_wrap) |
| 1425 | *after_wrap = ((index == line_index + line_def->net_length) && |
| 1426 | (line_def->ending == END_WRAP)); |
| 1427 | } else { |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1428 | LPWSTR text; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1429 | SIZE size; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1430 | if (after_wrap) |
| 1431 | *after_wrap = FALSE; |
| 1432 | x -= es->format_rect.left; |
| 1433 | if (!x) |
| 1434 | return es->x_offset; |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 1435 | text = EDIT_GetPasswordPointer_SL(es); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1436 | dc = GetDC(es->hwndSelf); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1437 | if (es->font) |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1438 | old_font = SelectObject(dc, es->font); |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 1439 | if (x < 0) |
| 1440 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1441 | INT low = 0; |
| 1442 | INT high = es->x_offset; |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 1443 | while (low < high - 1) |
| 1444 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1445 | INT mid = (low + high) / 2; |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1446 | GetTextExtentPoint32W( dc, text + mid, |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 1447 | es->x_offset - mid, &size ); |
| 1448 | if (size.cx > -x) low = mid; |
| 1449 | else high = mid; |
| 1450 | } |
| 1451 | index = low; |
| 1452 | } |
| 1453 | else |
| 1454 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1455 | INT low = es->x_offset; |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1456 | INT high = strlenW(es->text) + 1; |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 1457 | while (low < high - 1) |
| 1458 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1459 | INT mid = (low + high) / 2; |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1460 | GetTextExtentPoint32W( dc, text + es->x_offset, |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 1461 | mid - es->x_offset, &size ); |
| 1462 | if (size.cx > x) high = mid; |
| 1463 | else low = mid; |
| 1464 | } |
| 1465 | index = low; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1466 | } |
| 1467 | if (es->style & ES_PASSWORD) |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1468 | HeapFree(GetProcessHeap(), 0, text); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1469 | } |
| 1470 | if (es->font) |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1471 | SelectObject(dc, old_font); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1472 | ReleaseDC(es->hwndSelf, dc); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1473 | return index; |
Alexandre Julliard | 02ed4c2 | 1996-03-02 19:34:10 +0000 | [diff] [blame] | 1474 | } |
| 1475 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1476 | |
Alexandre Julliard | 02ed4c2 | 1996-03-02 19:34:10 +0000 | [diff] [blame] | 1477 | /********************************************************************* |
Alexandre Julliard | 02ed4c2 | 1996-03-02 19:34:10 +0000 | [diff] [blame] | 1478 | * |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1479 | * EDIT_ConfinePoint |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1480 | * |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1481 | * adjusts the point to be within the formatting rectangle |
| 1482 | * (so CharFromPos returns the nearest _visible_ character) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1483 | * |
| 1484 | */ |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 1485 | static void EDIT_ConfinePoint(EDITSTATE *es, LPINT x, LPINT y) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1486 | { |
Francois Gouget | 6d77d3a | 2000-03-25 21:44:35 +0000 | [diff] [blame] | 1487 | *x = min(max(*x, es->format_rect.left), es->format_rect.right - 1); |
| 1488 | *y = min(max(*y, es->format_rect.top), es->format_rect.bottom - 1); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1489 | } |
| 1490 | |
| 1491 | |
| 1492 | /********************************************************************* |
| 1493 | * |
| 1494 | * EDIT_GetLineRect |
| 1495 | * |
| 1496 | * Calculates the bounding rectangle for a line from a starting |
| 1497 | * column to an ending column. |
| 1498 | * |
| 1499 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1500 | static void EDIT_GetLineRect(EDITSTATE *es, INT line, INT scol, INT ecol, LPRECT rc) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1501 | { |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 1502 | INT line_index = EDIT_EM_LineIndex(es, line); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1503 | |
| 1504 | if (es->style & ES_MULTILINE) |
| 1505 | rc->top = es->format_rect.top + (line - es->y_offset) * es->line_height; |
| 1506 | else |
| 1507 | rc->top = es->format_rect.top; |
| 1508 | rc->bottom = rc->top + es->line_height; |
Alexandre Julliard | 9d61596 | 2003-09-17 04:28:28 +0000 | [diff] [blame] | 1509 | rc->left = (scol == 0) ? es->format_rect.left : (short)LOWORD(EDIT_EM_PosFromChar(es, line_index + scol, TRUE)); |
| 1510 | rc->right = (ecol == -1) ? es->format_rect.right : (short)LOWORD(EDIT_EM_PosFromChar(es, line_index + ecol, TRUE)); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1511 | } |
| 1512 | |
| 1513 | |
| 1514 | /********************************************************************* |
| 1515 | * |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1516 | * EDIT_GetPasswordPointer_SL |
| 1517 | * |
| 1518 | * note: caller should free the (optionally) allocated buffer |
| 1519 | * |
| 1520 | */ |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1521 | static LPWSTR EDIT_GetPasswordPointer_SL(EDITSTATE *es) |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1522 | { |
| 1523 | if (es->style & ES_PASSWORD) { |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1524 | INT len = strlenW(es->text); |
| 1525 | LPWSTR text = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR)); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1526 | text[len] = '\0'; |
Dmitry Timoshkov | 8058ead | 2000-12-21 20:19:21 +0000 | [diff] [blame] | 1527 | while(len) text[--len] = es->password_char; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1528 | return text; |
| 1529 | } else |
| 1530 | return es->text; |
| 1531 | } |
| 1532 | |
| 1533 | |
| 1534 | /********************************************************************* |
| 1535 | * |
| 1536 | * EDIT_LockBuffer |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1537 | * |
| 1538 | * This acts as a LOCAL_Lock(), but it locks only once. This way |
| 1539 | * you can call it whenever you like, without unlocking. |
| 1540 | * |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1541 | * Initially the edit control allocates a HLOCAL32 buffer |
| 1542 | * (32 bit linear memory handler). However, 16 bit application |
| 1543 | * might send a EM_GETHANDLE message and expect a HLOCAL16 (16 bit SEG:OFF |
| 1544 | * handler). From that moment on we have to keep using this 16 bit memory |
| 1545 | * handler, because it is supposed to be valid at all times after EM_GETHANDLE. |
| 1546 | * What we do is create a HLOCAL16 buffer, copy the text, and do pointer |
| 1547 | * conversion. |
| 1548 | * |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1549 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1550 | static void EDIT_LockBuffer(EDITSTATE *es) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1551 | { |
Robert Shearman | 2e9436c | 2004-08-17 22:29:29 +0000 | [diff] [blame] | 1552 | HINSTANCE16 hInstance = GetWindowLongPtrW( es->hwndSelf, GWLP_HINSTANCE ); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1553 | if (!es->text) { |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1554 | CHAR *textA = NULL; |
Dmitry Timoshkov | f77709e | 2001-01-10 23:55:02 +0000 | [diff] [blame] | 1555 | UINT countA = 0; |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1556 | BOOL _16bit = FALSE; |
| 1557 | |
| 1558 | if(es->hloc32W) |
| 1559 | { |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1560 | if(es->hloc32A) |
| 1561 | { |
| 1562 | TRACE("Synchronizing with 32-bit ANSI buffer\n"); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1563 | textA = LocalLock(es->hloc32A); |
Dmitry Timoshkov | f77709e | 2001-01-10 23:55:02 +0000 | [diff] [blame] | 1564 | countA = strlen(textA) + 1; |
Alexandre Julliard | 3051b64 | 1996-07-05 17:14:13 +0000 | [diff] [blame] | 1565 | } |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1566 | else if(es->hloc16) |
| 1567 | { |
| 1568 | TRACE("Synchronizing with 16-bit ANSI buffer\n"); |
Alexandre Julliard | de42428 | 2001-08-10 22:51:42 +0000 | [diff] [blame] | 1569 | textA = LOCAL_Lock(hInstance, es->hloc16); |
Dmitry Timoshkov | f77709e | 2001-01-10 23:55:02 +0000 | [diff] [blame] | 1570 | countA = strlen(textA) + 1; |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1571 | _16bit = TRUE; |
| 1572 | } |
| 1573 | } |
| 1574 | else { |
| 1575 | ERR("no buffer ... please report\n"); |
| 1576 | return; |
| 1577 | } |
| 1578 | |
| 1579 | if(textA) |
| 1580 | { |
Dmitry Timoshkov | f77709e | 2001-01-10 23:55:02 +0000 | [diff] [blame] | 1581 | HLOCAL hloc32W_new; |
| 1582 | UINT countW_new = MultiByteToWideChar(CP_ACP, 0, textA, countA, NULL, 0); |
| 1583 | TRACE("%d bytes translated to %d WCHARs\n", countA, countW_new); |
| 1584 | if(countW_new > es->buffer_size + 1) |
| 1585 | { |
Dmitry Timoshkov | df793bc | 2001-01-15 20:20:31 +0000 | [diff] [blame] | 1586 | UINT alloc_size = ROUND_TO_GROW(countW_new * sizeof(WCHAR)); |
Dmitry Timoshkov | f77709e | 2001-01-10 23:55:02 +0000 | [diff] [blame] | 1587 | TRACE("Resizing 32-bit UNICODE buffer from %d+1 to %d WCHARs\n", es->buffer_size, countW_new); |
| 1588 | hloc32W_new = LocalReAlloc(es->hloc32W, alloc_size, LMEM_MOVEABLE | LMEM_ZEROINIT); |
| 1589 | if(hloc32W_new) |
| 1590 | { |
| 1591 | es->hloc32W = hloc32W_new; |
| 1592 | es->buffer_size = LocalSize(hloc32W_new)/sizeof(WCHAR) - 1; |
| 1593 | TRACE("Real new size %d+1 WCHARs\n", es->buffer_size); |
| 1594 | } |
| 1595 | else |
| 1596 | WARN("FAILED! Will synchronize partially\n"); |
| 1597 | } |
| 1598 | } |
| 1599 | |
| 1600 | /*TRACE("Locking 32-bit UNICODE buffer\n");*/ |
| 1601 | es->text = LocalLock(es->hloc32W); |
| 1602 | |
| 1603 | if(textA) |
| 1604 | { |
| 1605 | MultiByteToWideChar(CP_ACP, 0, textA, countA, es->text, es->buffer_size + 1); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1606 | if(_16bit) |
Alexandre Julliard | de42428 | 2001-08-10 22:51:42 +0000 | [diff] [blame] | 1607 | LOCAL_Unlock(hInstance, es->hloc16); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1608 | else |
| 1609 | LocalUnlock(es->hloc32A); |
| 1610 | } |
Alexandre Julliard | 3051b64 | 1996-07-05 17:14:13 +0000 | [diff] [blame] | 1611 | } |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1612 | es->lock_count++; |
Alexandre Julliard | 3051b64 | 1996-07-05 17:14:13 +0000 | [diff] [blame] | 1613 | } |
| 1614 | |
| 1615 | |
| 1616 | /********************************************************************* |
| 1617 | * |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1618 | * EDIT_SL_InvalidateText |
Alexandre Julliard | 139a4b1 | 1996-11-02 14:24:07 +0000 | [diff] [blame] | 1619 | * |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1620 | * Called from EDIT_InvalidateText(). |
| 1621 | * Does the job for single-line controls only. |
Alexandre Julliard | 139a4b1 | 1996-11-02 14:24:07 +0000 | [diff] [blame] | 1622 | * |
| 1623 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1624 | static void EDIT_SL_InvalidateText(EDITSTATE *es, INT start, INT end) |
Alexandre Julliard | 139a4b1 | 1996-11-02 14:24:07 +0000 | [diff] [blame] | 1625 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1626 | RECT line_rect; |
| 1627 | RECT rc; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 1628 | |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1629 | EDIT_GetLineRect(es, 0, start, end, &line_rect); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1630 | if (IntersectRect(&rc, &line_rect, &es->format_rect)) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1631 | EDIT_UpdateText(es, &rc, TRUE); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1632 | } |
| 1633 | |
| 1634 | |
| 1635 | /********************************************************************* |
| 1636 | * |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1637 | * EDIT_ML_InvalidateText |
| 1638 | * |
| 1639 | * Called from EDIT_InvalidateText(). |
| 1640 | * Does the job for multi-line controls only. |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1641 | * |
| 1642 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1643 | static void EDIT_ML_InvalidateText(EDITSTATE *es, INT start, INT end) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1644 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1645 | INT vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height; |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 1646 | INT sl = EDIT_EM_LineFromChar(es, start); |
| 1647 | INT el = EDIT_EM_LineFromChar(es, end); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1648 | INT sc; |
| 1649 | INT ec; |
| 1650 | RECT rc1; |
| 1651 | RECT rcWnd; |
| 1652 | RECT rcLine; |
| 1653 | RECT rcUpdate; |
| 1654 | INT l; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 1655 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1656 | if ((el < es->y_offset) || (sl > es->y_offset + vlc)) |
| 1657 | return; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1658 | |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 1659 | sc = start - EDIT_EM_LineIndex(es, sl); |
| 1660 | ec = end - EDIT_EM_LineIndex(es, el); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1661 | if (sl < es->y_offset) { |
| 1662 | sl = es->y_offset; |
| 1663 | sc = 0; |
| 1664 | } |
| 1665 | if (el > es->y_offset + vlc) { |
| 1666 | el = es->y_offset + vlc; |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 1667 | ec = EDIT_EM_LineLength(es, EDIT_EM_LineIndex(es, el)); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1668 | } |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1669 | GetClientRect(es->hwndSelf, &rc1); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1670 | IntersectRect(&rcWnd, &rc1, &es->format_rect); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1671 | if (sl == el) { |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1672 | EDIT_GetLineRect(es, sl, sc, ec, &rcLine); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1673 | if (IntersectRect(&rcUpdate, &rcWnd, &rcLine)) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1674 | EDIT_UpdateText(es, &rcUpdate, TRUE); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1675 | } else { |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1676 | EDIT_GetLineRect(es, sl, sc, |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 1677 | EDIT_EM_LineLength(es, |
| 1678 | EDIT_EM_LineIndex(es, sl)), |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1679 | &rcLine); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1680 | if (IntersectRect(&rcUpdate, &rcWnd, &rcLine)) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1681 | EDIT_UpdateText(es, &rcUpdate, TRUE); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1682 | for (l = sl + 1 ; l < el ; l++) { |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1683 | EDIT_GetLineRect(es, l, 0, |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 1684 | EDIT_EM_LineLength(es, |
| 1685 | EDIT_EM_LineIndex(es, l)), |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1686 | &rcLine); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1687 | if (IntersectRect(&rcUpdate, &rcWnd, &rcLine)) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1688 | EDIT_UpdateText(es, &rcUpdate, TRUE); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1689 | } |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1690 | EDIT_GetLineRect(es, el, 0, ec, &rcLine); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1691 | if (IntersectRect(&rcUpdate, &rcWnd, &rcLine)) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1692 | EDIT_UpdateText(es, &rcUpdate, TRUE); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1693 | } |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1694 | } |
| 1695 | |
| 1696 | |
| 1697 | /********************************************************************* |
| 1698 | * |
Alexandre Julliard | cdcdede | 1996-04-21 14:57:41 +0000 | [diff] [blame] | 1699 | * EDIT_InvalidateText |
| 1700 | * |
| 1701 | * Invalidate the text from offset start upto, but not including, |
| 1702 | * offset end. Useful for (re)painting the selection. |
| 1703 | * Regions outside the linewidth are not invalidated. |
| 1704 | * end == -1 means end == TextLength. |
| 1705 | * start and end need not be ordered. |
| 1706 | * |
| 1707 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1708 | static void EDIT_InvalidateText(EDITSTATE *es, INT start, INT end) |
Alexandre Julliard | cdcdede | 1996-04-21 14:57:41 +0000 | [diff] [blame] | 1709 | { |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 1710 | if (end == start) |
Alexandre Julliard | cdcdede | 1996-04-21 14:57:41 +0000 | [diff] [blame] | 1711 | return; |
| 1712 | |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 1713 | if (end == -1) |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1714 | end = strlenW(es->text); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1715 | |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1716 | if (end < start) { |
| 1717 | INT tmp = start; |
| 1718 | start = end; |
| 1719 | end = tmp; |
| 1720 | } |
Alexandre Julliard | cdcdede | 1996-04-21 14:57:41 +0000 | [diff] [blame] | 1721 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1722 | if (es->style & ES_MULTILINE) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1723 | EDIT_ML_InvalidateText(es, start, end); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1724 | else |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1725 | EDIT_SL_InvalidateText(es, start, end); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1726 | } |
| 1727 | |
| 1728 | |
| 1729 | /********************************************************************* |
| 1730 | * |
| 1731 | * EDIT_MakeFit |
| 1732 | * |
Carl Sopchak | 23b88ef | 2002-11-21 03:57:05 +0000 | [diff] [blame] | 1733 | * Try to fit size + 1 characters in the buffer. |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1734 | */ |
Krishna Murthy | 4af4ba4 | 2004-05-29 00:21:51 +0000 | [diff] [blame] | 1735 | static BOOL EDIT_MakeFit(EDITSTATE *es, UINT size) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1736 | { |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1737 | HLOCAL hNew32W; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1738 | |
Brad Campbell | 4ba690e | 2003-04-27 00:32:22 +0000 | [diff] [blame] | 1739 | if (size <= es->buffer_size) |
| 1740 | return TRUE; |
| 1741 | |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1742 | TRACE("trying to ReAlloc to %d+1 characters\n", size); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1743 | |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1744 | /* Force edit to unlock it's buffer. es->text now NULL */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1745 | EDIT_UnlockBuffer(es, TRUE); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1746 | |
| 1747 | if (es->hloc32W) { |
Dmitry Timoshkov | df793bc | 2001-01-15 20:20:31 +0000 | [diff] [blame] | 1748 | UINT alloc_size = ROUND_TO_GROW((size + 1) * sizeof(WCHAR)); |
Dmitry Timoshkov | f8b96e2 | 2000-12-20 18:39:14 +0000 | [diff] [blame] | 1749 | if ((hNew32W = LocalReAlloc(es->hloc32W, alloc_size, LMEM_MOVEABLE | LMEM_ZEROINIT))) { |
Alexandre Julliard | aff7dda | 2002-11-22 21:22:14 +0000 | [diff] [blame] | 1750 | TRACE("Old 32 bit handle %p, new handle %p\n", es->hloc32W, hNew32W); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1751 | es->hloc32W = hNew32W; |
| 1752 | es->buffer_size = LocalSize(hNew32W)/sizeof(WCHAR) - 1; |
| 1753 | } |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 1754 | } |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1755 | |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1756 | EDIT_LockBuffer(es); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1757 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1758 | if (es->buffer_size < size) { |
Dimitrie O. Paun | dd03cc1 | 1999-12-08 03:56:23 +0000 | [diff] [blame] | 1759 | WARN("FAILED ! We now have %d+1\n", es->buffer_size); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1760 | EDIT_NOTIFY_PARENT(es, EN_ERRSPACE, "EN_ERRSPACE"); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1761 | return FALSE; |
| 1762 | } else { |
Dimitrie O. Paun | dd03cc1 | 1999-12-08 03:56:23 +0000 | [diff] [blame] | 1763 | TRACE("We now have %d+1\n", es->buffer_size); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1764 | return TRUE; |
| 1765 | } |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 1766 | } |
| 1767 | |
| 1768 | |
| 1769 | /********************************************************************* |
| 1770 | * |
| 1771 | * EDIT_MakeUndoFit |
| 1772 | * |
| 1773 | * Try to fit size + 1 bytes in the undo buffer. |
| 1774 | * |
| 1775 | */ |
Dmitry Timoshkov | 366c0a1 | 2000-12-22 20:28:05 +0000 | [diff] [blame] | 1776 | static BOOL EDIT_MakeUndoFit(EDITSTATE *es, UINT size) |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 1777 | { |
Dmitry Timoshkov | f8b96e2 | 2000-12-20 18:39:14 +0000 | [diff] [blame] | 1778 | UINT alloc_size; |
| 1779 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1780 | if (size <= es->undo_buffer_size) |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 1781 | return TRUE; |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 1782 | |
Dimitrie O. Paun | dd03cc1 | 1999-12-08 03:56:23 +0000 | [diff] [blame] | 1783 | TRACE("trying to ReAlloc to %d+1\n", size); |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 1784 | |
Dmitry Timoshkov | df793bc | 2001-01-15 20:20:31 +0000 | [diff] [blame] | 1785 | alloc_size = ROUND_TO_GROW((size + 1) * sizeof(WCHAR)); |
Dmitry Timoshkov | f8b96e2 | 2000-12-20 18:39:14 +0000 | [diff] [blame] | 1786 | if ((es->undo_text = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, es->undo_text, alloc_size))) { |
Alexandre Julliard | 6356a44 | 2003-02-19 22:04:03 +0000 | [diff] [blame] | 1787 | es->undo_buffer_size = alloc_size/sizeof(WCHAR) - 1; |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 1788 | return TRUE; |
| 1789 | } |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1790 | else |
| 1791 | { |
| 1792 | WARN("FAILED ! We now have %d+1\n", es->undo_buffer_size); |
| 1793 | return FALSE; |
| 1794 | } |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1795 | } |
| 1796 | |
| 1797 | |
| 1798 | /********************************************************************* |
| 1799 | * |
| 1800 | * EDIT_MoveBackward |
| 1801 | * |
| 1802 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1803 | static void EDIT_MoveBackward(EDITSTATE *es, BOOL extend) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1804 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1805 | INT e = es->selection_end; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1806 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1807 | if (e) { |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1808 | e--; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1809 | if ((es->style & ES_MULTILINE) && e && |
| 1810 | (es->text[e - 1] == '\r') && (es->text[e] == '\n')) { |
| 1811 | e--; |
| 1812 | if (e && (es->text[e - 1] == '\r')) |
| 1813 | e--; |
| 1814 | } |
| 1815 | } |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1816 | EDIT_EM_SetSel(es, extend ? es->selection_start : e, e, FALSE); |
| 1817 | EDIT_EM_ScrollCaret(es); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1818 | } |
| 1819 | |
| 1820 | |
| 1821 | /********************************************************************* |
| 1822 | * |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1823 | * EDIT_MoveDown_ML |
| 1824 | * |
| 1825 | * Only for multi line controls |
| 1826 | * Move the caret one line down, on a column with the nearest |
| 1827 | * x coordinate on the screen (might be a different column). |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1828 | * |
| 1829 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1830 | static void EDIT_MoveDown_ML(EDITSTATE *es, BOOL extend) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1831 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1832 | INT s = es->selection_start; |
| 1833 | INT e = es->selection_end; |
| 1834 | BOOL after_wrap = (es->flags & EF_AFTER_WRAP); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1835 | LRESULT pos = EDIT_EM_PosFromChar(es, e, after_wrap); |
Alexandre Julliard | 9d61596 | 2003-09-17 04:28:28 +0000 | [diff] [blame] | 1836 | INT x = (short)LOWORD(pos); |
| 1837 | INT y = (short)HIWORD(pos); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1838 | |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1839 | e = EDIT_CharFromPos(es, x, y + es->line_height, &after_wrap); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1840 | if (!extend) |
| 1841 | s = e; |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1842 | EDIT_EM_SetSel(es, s, e, after_wrap); |
| 1843 | EDIT_EM_ScrollCaret(es); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1844 | } |
| 1845 | |
| 1846 | |
| 1847 | /********************************************************************* |
| 1848 | * |
| 1849 | * EDIT_MoveEnd |
| 1850 | * |
| 1851 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1852 | static void EDIT_MoveEnd(EDITSTATE *es, BOOL extend) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1853 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1854 | BOOL after_wrap = FALSE; |
| 1855 | INT e; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1856 | |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1857 | /* Pass a high value in x to make sure of receiving the end of the line */ |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1858 | if (es->style & ES_MULTILINE) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1859 | e = EDIT_CharFromPos(es, 0x3fffffff, |
| 1860 | HIWORD(EDIT_EM_PosFromChar(es, es->selection_end, es->flags & EF_AFTER_WRAP)), &after_wrap); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1861 | else |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 1862 | e = strlenW(es->text); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1863 | EDIT_EM_SetSel(es, extend ? es->selection_start : e, e, after_wrap); |
| 1864 | EDIT_EM_ScrollCaret(es); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1865 | } |
| 1866 | |
| 1867 | |
| 1868 | /********************************************************************* |
| 1869 | * |
| 1870 | * EDIT_MoveForward |
| 1871 | * |
| 1872 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1873 | static void EDIT_MoveForward(EDITSTATE *es, BOOL extend) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1874 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1875 | INT e = es->selection_end; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1876 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1877 | if (es->text[e]) { |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1878 | e++; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1879 | if ((es->style & ES_MULTILINE) && (es->text[e - 1] == '\r')) { |
| 1880 | if (es->text[e] == '\n') |
| 1881 | e++; |
| 1882 | else if ((es->text[e] == '\r') && (es->text[e + 1] == '\n')) |
| 1883 | e += 2; |
| 1884 | } |
| 1885 | } |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1886 | EDIT_EM_SetSel(es, extend ? es->selection_start : e, e, FALSE); |
| 1887 | EDIT_EM_ScrollCaret(es); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1888 | } |
| 1889 | |
| 1890 | |
| 1891 | /********************************************************************* |
| 1892 | * |
| 1893 | * EDIT_MoveHome |
| 1894 | * |
| 1895 | * Home key: move to beginning of line. |
| 1896 | * |
| 1897 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1898 | static void EDIT_MoveHome(EDITSTATE *es, BOOL extend) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1899 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1900 | INT e; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1901 | |
Pascal Lessard | 3405f5c | 1999-09-04 10:59:07 +0000 | [diff] [blame] | 1902 | /* Pass the x_offset in x to make sure of receiving the first position of the line */ |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1903 | if (es->style & ES_MULTILINE) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1904 | e = EDIT_CharFromPos(es, -es->x_offset, |
| 1905 | HIWORD(EDIT_EM_PosFromChar(es, es->selection_end, es->flags & EF_AFTER_WRAP)), NULL); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1906 | else |
Alexandre Julliard | d37eb36 | 1997-07-20 16:23:21 +0000 | [diff] [blame] | 1907 | e = 0; |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1908 | EDIT_EM_SetSel(es, extend ? es->selection_start : e, e, FALSE); |
| 1909 | EDIT_EM_ScrollCaret(es); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1910 | } |
| 1911 | |
| 1912 | |
| 1913 | /********************************************************************* |
| 1914 | * |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1915 | * EDIT_MovePageDown_ML |
| 1916 | * |
| 1917 | * Only for multi line controls |
| 1918 | * Move the caret one page down, on a column with the nearest |
| 1919 | * x coordinate on the screen (might be a different column). |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1920 | * |
| 1921 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1922 | static void EDIT_MovePageDown_ML(EDITSTATE *es, BOOL extend) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1923 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1924 | INT s = es->selection_start; |
| 1925 | INT e = es->selection_end; |
| 1926 | BOOL after_wrap = (es->flags & EF_AFTER_WRAP); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1927 | LRESULT pos = EDIT_EM_PosFromChar(es, e, after_wrap); |
Alexandre Julliard | 9d61596 | 2003-09-17 04:28:28 +0000 | [diff] [blame] | 1928 | INT x = (short)LOWORD(pos); |
| 1929 | INT y = (short)HIWORD(pos); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1930 | |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1931 | e = EDIT_CharFromPos(es, x, |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1932 | y + (es->format_rect.bottom - es->format_rect.top), |
| 1933 | &after_wrap); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1934 | if (!extend) |
| 1935 | s = e; |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1936 | EDIT_EM_SetSel(es, s, e, after_wrap); |
| 1937 | EDIT_EM_ScrollCaret(es); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1938 | } |
| 1939 | |
| 1940 | |
| 1941 | /********************************************************************* |
| 1942 | * |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1943 | * EDIT_MovePageUp_ML |
| 1944 | * |
| 1945 | * Only for multi line controls |
| 1946 | * Move the caret one page up, on a column with the nearest |
| 1947 | * x coordinate on the screen (might be a different column). |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1948 | * |
| 1949 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1950 | static void EDIT_MovePageUp_ML(EDITSTATE *es, BOOL extend) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1951 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1952 | INT s = es->selection_start; |
| 1953 | INT e = es->selection_end; |
| 1954 | BOOL after_wrap = (es->flags & EF_AFTER_WRAP); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1955 | LRESULT pos = EDIT_EM_PosFromChar(es, e, after_wrap); |
Alexandre Julliard | 9d61596 | 2003-09-17 04:28:28 +0000 | [diff] [blame] | 1956 | INT x = (short)LOWORD(pos); |
| 1957 | INT y = (short)HIWORD(pos); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1958 | |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1959 | e = EDIT_CharFromPos(es, x, |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1960 | y - (es->format_rect.bottom - es->format_rect.top), |
| 1961 | &after_wrap); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1962 | if (!extend) |
| 1963 | s = e; |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1964 | EDIT_EM_SetSel(es, s, e, after_wrap); |
| 1965 | EDIT_EM_ScrollCaret(es); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1966 | } |
| 1967 | |
| 1968 | |
| 1969 | /********************************************************************* |
| 1970 | * |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1971 | * EDIT_MoveUp_ML |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1972 | * |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 1973 | * Only for multi line controls |
| 1974 | * Move the caret one line up, on a column with the nearest |
| 1975 | * x coordinate on the screen (might be a different column). |
| 1976 | * |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1977 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1978 | static void EDIT_MoveUp_ML(EDITSTATE *es, BOOL extend) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1979 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1980 | INT s = es->selection_start; |
| 1981 | INT e = es->selection_end; |
| 1982 | BOOL after_wrap = (es->flags & EF_AFTER_WRAP); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1983 | LRESULT pos = EDIT_EM_PosFromChar(es, e, after_wrap); |
Alexandre Julliard | 9d61596 | 2003-09-17 04:28:28 +0000 | [diff] [blame] | 1984 | INT x = (short)LOWORD(pos); |
| 1985 | INT y = (short)HIWORD(pos); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1986 | |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1987 | e = EDIT_CharFromPos(es, x, y - es->line_height, &after_wrap); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1988 | if (!extend) |
| 1989 | s = e; |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 1990 | EDIT_EM_SetSel(es, s, e, after_wrap); |
| 1991 | EDIT_EM_ScrollCaret(es); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 1992 | } |
| 1993 | |
| 1994 | |
| 1995 | /********************************************************************* |
| 1996 | * |
| 1997 | * EDIT_MoveWordBackward |
| 1998 | * |
| 1999 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2000 | static void EDIT_MoveWordBackward(EDITSTATE *es, BOOL extend) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2001 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2002 | INT s = es->selection_start; |
| 2003 | INT e = es->selection_end; |
| 2004 | INT l; |
| 2005 | INT ll; |
| 2006 | INT li; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2007 | |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 2008 | l = EDIT_EM_LineFromChar(es, e); |
| 2009 | ll = EDIT_EM_LineLength(es, e); |
| 2010 | li = EDIT_EM_LineIndex(es, l); |
Alexandre Julliard | cdcdede | 1996-04-21 14:57:41 +0000 | [diff] [blame] | 2011 | if (e - li == 0) { |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2012 | if (l) { |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 2013 | li = EDIT_EM_LineIndex(es, l - 1); |
| 2014 | e = li + EDIT_EM_LineLength(es, li); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2015 | } |
| 2016 | } else { |
Dmitry Timoshkov | 8058ead | 2000-12-21 20:19:21 +0000 | [diff] [blame] | 2017 | e = li + (INT)EDIT_CallWordBreakProc(es, |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2018 | li, e - li, ll, WB_LEFT); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2019 | } |
| 2020 | if (!extend) |
| 2021 | s = e; |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2022 | EDIT_EM_SetSel(es, s, e, FALSE); |
| 2023 | EDIT_EM_ScrollCaret(es); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2024 | } |
| 2025 | |
| 2026 | |
| 2027 | /********************************************************************* |
| 2028 | * |
| 2029 | * EDIT_MoveWordForward |
| 2030 | * |
| 2031 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2032 | static void EDIT_MoveWordForward(EDITSTATE *es, BOOL extend) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2033 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2034 | INT s = es->selection_start; |
| 2035 | INT e = es->selection_end; |
| 2036 | INT l; |
| 2037 | INT ll; |
| 2038 | INT li; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2039 | |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 2040 | l = EDIT_EM_LineFromChar(es, e); |
| 2041 | ll = EDIT_EM_LineLength(es, e); |
| 2042 | li = EDIT_EM_LineIndex(es, l); |
Alexandre Julliard | cdcdede | 1996-04-21 14:57:41 +0000 | [diff] [blame] | 2043 | if (e - li == ll) { |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2044 | if ((es->style & ES_MULTILINE) && (l != es->line_count - 1)) |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 2045 | e = EDIT_EM_LineIndex(es, l + 1); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2046 | } else { |
Dmitry Timoshkov | 8058ead | 2000-12-21 20:19:21 +0000 | [diff] [blame] | 2047 | e = li + EDIT_CallWordBreakProc(es, |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2048 | li, e - li + 1, ll, WB_RIGHT); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2049 | } |
| 2050 | if (!extend) |
| 2051 | s = e; |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2052 | EDIT_EM_SetSel(es, s, e, FALSE); |
| 2053 | EDIT_EM_ScrollCaret(es); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2054 | } |
| 2055 | |
| 2056 | |
| 2057 | /********************************************************************* |
| 2058 | * |
| 2059 | * EDIT_PaintLine |
| 2060 | * |
| 2061 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2062 | static void EDIT_PaintLine(EDITSTATE *es, HDC dc, INT line, BOOL rev) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2063 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2064 | INT s = es->selection_start; |
| 2065 | INT e = es->selection_end; |
| 2066 | INT li; |
| 2067 | INT ll; |
| 2068 | INT x; |
| 2069 | INT y; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2070 | LRESULT pos; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2071 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2072 | if (es->style & ES_MULTILINE) { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2073 | INT vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2074 | if ((line < es->y_offset) || (line > es->y_offset + vlc) || (line >= es->line_count)) |
| 2075 | return; |
| 2076 | } else if (line) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2077 | return; |
| 2078 | |
Dimitrie O. Paun | dd03cc1 | 1999-12-08 03:56:23 +0000 | [diff] [blame] | 2079 | TRACE("line=%d\n", line); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2080 | |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2081 | pos = EDIT_EM_PosFromChar(es, EDIT_EM_LineIndex(es, line), FALSE); |
Alexandre Julliard | 9d61596 | 2003-09-17 04:28:28 +0000 | [diff] [blame] | 2082 | x = (short)LOWORD(pos); |
| 2083 | y = (short)HIWORD(pos); |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 2084 | li = EDIT_EM_LineIndex(es, line); |
| 2085 | ll = EDIT_EM_LineLength(es, li); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2086 | s = min(es->selection_start, es->selection_end); |
| 2087 | e = max(es->selection_start, es->selection_end); |
Francois Gouget | 6d77d3a | 2000-03-25 21:44:35 +0000 | [diff] [blame] | 2088 | s = min(li + ll, max(li, s)); |
| 2089 | e = min(li + ll, max(li, e)); |
Alexandre Julliard | cdcdede | 1996-04-21 14:57:41 +0000 | [diff] [blame] | 2090 | if (rev && (s != e) && |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2091 | ((es->flags & EF_FOCUSED) || (es->style & ES_NOHIDESEL))) { |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 2092 | x += EDIT_PaintText(es, dc, x, y, line, 0, s - li, FALSE); |
| 2093 | x += EDIT_PaintText(es, dc, x, y, line, s - li, e - s, TRUE); |
| 2094 | x += EDIT_PaintText(es, dc, x, y, line, e - li, li + ll - e, FALSE); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2095 | } else |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 2096 | x += EDIT_PaintText(es, dc, x, y, line, 0, ll, FALSE); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2097 | } |
| 2098 | |
| 2099 | |
| 2100 | /********************************************************************* |
| 2101 | * |
| 2102 | * EDIT_PaintText |
| 2103 | * |
| 2104 | */ |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 2105 | static INT EDIT_PaintText(EDITSTATE *es, HDC dc, INT x, INT y, INT line, INT col, INT count, BOOL rev) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2106 | { |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2107 | COLORREF BkColor; |
| 2108 | COLORREF TextColor; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2109 | INT ret; |
| 2110 | INT li; |
Dan Engel | 7c7a357 | 2001-04-16 19:32:05 +0000 | [diff] [blame] | 2111 | INT BkMode; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2112 | SIZE size; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2113 | |
Alexandre Julliard | cdcdede | 1996-04-21 14:57:41 +0000 | [diff] [blame] | 2114 | if (!count) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2115 | return 0; |
Dan Engel | 7c7a357 | 2001-04-16 19:32:05 +0000 | [diff] [blame] | 2116 | BkMode = GetBkMode(dc); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2117 | BkColor = GetBkColor(dc); |
| 2118 | TextColor = GetTextColor(dc); |
Alexandre Julliard | df2673b | 1997-03-29 17:20:20 +0000 | [diff] [blame] | 2119 | if (rev) { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2120 | SetBkColor(dc, GetSysColor(COLOR_HIGHLIGHT)); |
| 2121 | SetTextColor(dc, GetSysColor(COLOR_HIGHLIGHTTEXT)); |
Dan Engel | 7c7a357 | 2001-04-16 19:32:05 +0000 | [diff] [blame] | 2122 | SetBkMode( dc, OPAQUE); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2123 | } |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 2124 | li = EDIT_EM_LineIndex(es, line); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2125 | if (es->style & ES_MULTILINE) { |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2126 | ret = (INT)LOWORD(TabbedTextOutW(dc, x, y, es->text + li + col, count, |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2127 | es->tabs_count, es->tabs, es->format_rect.left - es->x_offset)); |
| 2128 | } else { |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2129 | LPWSTR text = EDIT_GetPasswordPointer_SL(es); |
| 2130 | TextOutW(dc, x, y, text + li + col, count); |
| 2131 | GetTextExtentPoint32W(dc, text + li + col, count, &size); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2132 | ret = size.cx; |
| 2133 | if (es->style & ES_PASSWORD) |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2134 | HeapFree(GetProcessHeap(), 0, text); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2135 | } |
Alexandre Julliard | df2673b | 1997-03-29 17:20:20 +0000 | [diff] [blame] | 2136 | if (rev) { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2137 | SetBkColor(dc, BkColor); |
| 2138 | SetTextColor(dc, TextColor); |
Dan Engel | 7c7a357 | 2001-04-16 19:32:05 +0000 | [diff] [blame] | 2139 | SetBkMode( dc, BkMode); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2140 | } |
| 2141 | return ret; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 2142 | } |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2143 | |
| 2144 | |
| 2145 | /********************************************************************* |
| 2146 | * |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 2147 | * EDIT_SetCaretPos |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 2148 | * |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2149 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2150 | static void EDIT_SetCaretPos(EDITSTATE *es, INT pos, |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2151 | BOOL after_wrap) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2152 | { |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2153 | LRESULT res = EDIT_EM_PosFromChar(es, pos, after_wrap); |
Lionel Ulmer | 28d9aaf | 2004-03-29 22:54:05 +0000 | [diff] [blame] | 2154 | TRACE("%d - %dx%d\n", pos, (short)LOWORD(res), (short)HIWORD(res)); |
Alexandre Julliard | 9d61596 | 2003-09-17 04:28:28 +0000 | [diff] [blame] | 2155 | SetCaretPos((short)LOWORD(res), (short)HIWORD(res)); |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 2156 | } |
| 2157 | |
| 2158 | |
| 2159 | /********************************************************************* |
| 2160 | * |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2161 | * EDIT_SetRectNP |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2162 | * |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2163 | * note: this is not (exactly) the handler called on EM_SETRECTNP |
| 2164 | * it is also used to set the rect of a single line control |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2165 | * |
| 2166 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2167 | static void EDIT_SetRectNP(EDITSTATE *es, LPRECT rc) |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 2168 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2169 | CopyRect(&es->format_rect, rc); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2170 | if (es->style & WS_BORDER) { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2171 | INT bw = GetSystemMetrics(SM_CXBORDER) + 1; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2172 | es->format_rect.left += bw; |
| 2173 | es->format_rect.top += bw; |
| 2174 | es->format_rect.right -= bw; |
| 2175 | es->format_rect.bottom -= bw; |
| 2176 | } |
| 2177 | es->format_rect.left += es->left_margin; |
| 2178 | es->format_rect.right -= es->right_margin; |
Francois Gouget | 6d77d3a | 2000-03-25 21:44:35 +0000 | [diff] [blame] | 2179 | es->format_rect.right = max(es->format_rect.right, es->format_rect.left + es->char_width); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2180 | if (es->style & ES_MULTILINE) |
Dmitry Timoshkov | 11dbda6 | 2001-01-05 03:40:35 +0000 | [diff] [blame] | 2181 | { |
| 2182 | INT fw, vlc, max_x_offset, max_y_offset; |
| 2183 | |
| 2184 | vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height; |
| 2185 | es->format_rect.bottom = es->format_rect.top + max(1, vlc) * es->line_height; |
| 2186 | |
| 2187 | /* correct es->x_offset */ |
| 2188 | fw = es->format_rect.right - es->format_rect.left; |
| 2189 | max_x_offset = es->text_width - fw; |
| 2190 | if(max_x_offset < 0) max_x_offset = 0; |
| 2191 | if(es->x_offset > max_x_offset) |
| 2192 | es->x_offset = max_x_offset; |
| 2193 | |
| 2194 | /* correct es->y_offset */ |
| 2195 | max_y_offset = es->line_count - vlc; |
| 2196 | if(max_y_offset < 0) max_y_offset = 0; |
| 2197 | if(es->y_offset > max_y_offset) |
| 2198 | es->y_offset = max_y_offset; |
Dmitry Timoshkov | a234db8 | 2001-01-19 20:49:54 +0000 | [diff] [blame] | 2199 | |
| 2200 | /* force scroll info update */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2201 | EDIT_UpdateScrollInfo(es); |
Dmitry Timoshkov | 11dbda6 | 2001-01-05 03:40:35 +0000 | [diff] [blame] | 2202 | } |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2203 | else |
Dmitry Timoshkov | 11dbda6 | 2001-01-05 03:40:35 +0000 | [diff] [blame] | 2204 | /* Windows doesn't care to fix text placement for SL controls */ |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2205 | es->format_rect.bottom = es->format_rect.top + es->line_height; |
Dmitry Timoshkov | 11dbda6 | 2001-01-05 03:40:35 +0000 | [diff] [blame] | 2206 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2207 | if ((es->style & ES_MULTILINE) && !(es->style & ES_AUTOHSCROLL)) |
Francois Gouget | d2667a4 | 2002-12-02 18:10:57 +0000 | [diff] [blame] | 2208 | EDIT_BuildLineDefs_ML(es, 0, strlenW(es->text), 0, NULL); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2209 | } |
| 2210 | |
| 2211 | |
| 2212 | /********************************************************************* |
| 2213 | * |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2214 | * EDIT_UnlockBuffer |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2215 | * |
| 2216 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2217 | static void EDIT_UnlockBuffer(EDITSTATE *es, BOOL force) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2218 | { |
Robert Shearman | 2e9436c | 2004-08-17 22:29:29 +0000 | [diff] [blame] | 2219 | HINSTANCE16 hInstance = GetWindowLongPtrW( es->hwndSelf, GWLP_HINSTANCE ); |
Alexandre Julliard | de42428 | 2001-08-10 22:51:42 +0000 | [diff] [blame] | 2220 | |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2221 | /* Edit window might be already destroyed */ |
| 2222 | if(!IsWindow(es->hwndSelf)) |
| 2223 | { |
Alexandre Julliard | aff7dda | 2002-11-22 21:22:14 +0000 | [diff] [blame] | 2224 | WARN("edit hwnd %p already destroyed\n", es->hwndSelf); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2225 | return; |
| 2226 | } |
Dmitry Timoshkov | fbc3619 | 2001-03-05 19:29:47 +0000 | [diff] [blame] | 2227 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2228 | if (!es->lock_count) { |
Dimitrie O. Paun | dd03cc1 | 1999-12-08 03:56:23 +0000 | [diff] [blame] | 2229 | ERR("lock_count == 0 ... please report\n"); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2230 | return; |
| 2231 | } |
| 2232 | if (!es->text) { |
Dimitrie O. Paun | dd03cc1 | 1999-12-08 03:56:23 +0000 | [diff] [blame] | 2233 | ERR("es->text == 0 ... please report\n"); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2234 | return; |
| 2235 | } |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2236 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2237 | if (force || (es->lock_count == 1)) { |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2238 | if (es->hloc32W) { |
| 2239 | CHAR *textA = NULL; |
| 2240 | BOOL _16bit = FALSE; |
Dmitry Timoshkov | f77709e | 2001-01-10 23:55:02 +0000 | [diff] [blame] | 2241 | UINT countA = 0; |
| 2242 | UINT countW = strlenW(es->text) + 1; |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2243 | |
| 2244 | if(es->hloc32A) |
| 2245 | { |
Dmitry Timoshkov | f77709e | 2001-01-10 23:55:02 +0000 | [diff] [blame] | 2246 | UINT countA_new = WideCharToMultiByte(CP_ACP, 0, es->text, countW, NULL, 0, NULL, NULL); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2247 | TRACE("Synchronizing with 32-bit ANSI buffer\n"); |
Dmitry Timoshkov | f77709e | 2001-01-10 23:55:02 +0000 | [diff] [blame] | 2248 | TRACE("%d WCHARs translated to %d bytes\n", countW, countA_new); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2249 | countA = LocalSize(es->hloc32A); |
Dmitry Timoshkov | f77709e | 2001-01-10 23:55:02 +0000 | [diff] [blame] | 2250 | if(countA_new > countA) |
| 2251 | { |
| 2252 | HLOCAL hloc32A_new; |
Dmitry Timoshkov | df793bc | 2001-01-15 20:20:31 +0000 | [diff] [blame] | 2253 | UINT alloc_size = ROUND_TO_GROW(countA_new); |
Dmitry Timoshkov | f77709e | 2001-01-10 23:55:02 +0000 | [diff] [blame] | 2254 | TRACE("Resizing 32-bit ANSI buffer from %d to %d bytes\n", countA, alloc_size); |
| 2255 | hloc32A_new = LocalReAlloc(es->hloc32A, alloc_size, LMEM_MOVEABLE | LMEM_ZEROINIT); |
| 2256 | if(hloc32A_new) |
| 2257 | { |
| 2258 | es->hloc32A = hloc32A_new; |
| 2259 | countA = LocalSize(hloc32A_new); |
| 2260 | TRACE("Real new size %d bytes\n", countA); |
| 2261 | } |
| 2262 | else |
| 2263 | WARN("FAILED! Will synchronize partially\n"); |
| 2264 | } |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2265 | textA = LocalLock(es->hloc32A); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2266 | } |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2267 | else if(es->hloc16) |
| 2268 | { |
Dmitry Timoshkov | f77709e | 2001-01-10 23:55:02 +0000 | [diff] [blame] | 2269 | UINT countA_new = WideCharToMultiByte(CP_ACP, 0, es->text, countW, NULL, 0, NULL, NULL); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2270 | TRACE("Synchronizing with 16-bit ANSI buffer\n"); |
Dmitry Timoshkov | f77709e | 2001-01-10 23:55:02 +0000 | [diff] [blame] | 2271 | TRACE("%d WCHARs translated to %d bytes\n", countW, countA_new); |
Alexandre Julliard | de42428 | 2001-08-10 22:51:42 +0000 | [diff] [blame] | 2272 | countA = LOCAL_Size(hInstance, es->hloc16); |
Dmitry Timoshkov | f77709e | 2001-01-10 23:55:02 +0000 | [diff] [blame] | 2273 | if(countA_new > countA) |
| 2274 | { |
| 2275 | HLOCAL16 hloc16_new; |
Dmitry Timoshkov | df793bc | 2001-01-15 20:20:31 +0000 | [diff] [blame] | 2276 | UINT alloc_size = ROUND_TO_GROW(countA_new); |
Dmitry Timoshkov | f77709e | 2001-01-10 23:55:02 +0000 | [diff] [blame] | 2277 | TRACE("Resizing 16-bit ANSI buffer from %d to %d bytes\n", countA, alloc_size); |
Alexandre Julliard | de42428 | 2001-08-10 22:51:42 +0000 | [diff] [blame] | 2278 | hloc16_new = LOCAL_ReAlloc(hInstance, es->hloc16, alloc_size, LMEM_MOVEABLE | LMEM_ZEROINIT); |
Dmitry Timoshkov | f77709e | 2001-01-10 23:55:02 +0000 | [diff] [blame] | 2279 | if(hloc16_new) |
| 2280 | { |
| 2281 | es->hloc16 = hloc16_new; |
Alexandre Julliard | de42428 | 2001-08-10 22:51:42 +0000 | [diff] [blame] | 2282 | countA = LOCAL_Size(hInstance, hloc16_new); |
Dmitry Timoshkov | f77709e | 2001-01-10 23:55:02 +0000 | [diff] [blame] | 2283 | TRACE("Real new size %d bytes\n", countA); |
| 2284 | } |
| 2285 | else |
| 2286 | WARN("FAILED! Will synchronize partially\n"); |
| 2287 | } |
Alexandre Julliard | de42428 | 2001-08-10 22:51:42 +0000 | [diff] [blame] | 2288 | textA = LOCAL_Lock(hInstance, es->hloc16); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2289 | _16bit = TRUE; |
| 2290 | } |
| 2291 | |
| 2292 | if(textA) |
| 2293 | { |
Dmitry Timoshkov | f77709e | 2001-01-10 23:55:02 +0000 | [diff] [blame] | 2294 | WideCharToMultiByte(CP_ACP, 0, es->text, countW, textA, countA, NULL, NULL); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2295 | if(_16bit) |
Alexandre Julliard | de42428 | 2001-08-10 22:51:42 +0000 | [diff] [blame] | 2296 | LOCAL_Unlock(hInstance, es->hloc16); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2297 | else |
| 2298 | LocalUnlock(es->hloc32A); |
| 2299 | } |
| 2300 | |
| 2301 | LocalUnlock(es->hloc32W); |
| 2302 | es->text = NULL; |
| 2303 | } |
| 2304 | else { |
| 2305 | ERR("no buffer ... please report\n"); |
| 2306 | return; |
| 2307 | } |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2308 | } |
| 2309 | es->lock_count--; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2310 | } |
| 2311 | |
| 2312 | |
| 2313 | /********************************************************************* |
| 2314 | * |
Dmitry Timoshkov | 11dbda6 | 2001-01-05 03:40:35 +0000 | [diff] [blame] | 2315 | * EDIT_UpdateScrollInfo |
| 2316 | * |
| 2317 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2318 | static void EDIT_UpdateScrollInfo(EDITSTATE *es) |
Dmitry Timoshkov | 11dbda6 | 2001-01-05 03:40:35 +0000 | [diff] [blame] | 2319 | { |
| 2320 | if ((es->style & WS_VSCROLL) && !(es->flags & EF_VSCROLL_TRACK)) |
| 2321 | { |
| 2322 | SCROLLINFO si; |
| 2323 | si.cbSize = sizeof(SCROLLINFO); |
| 2324 | si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE | SIF_DISABLENOSCROLL; |
| 2325 | si.nMin = 0; |
| 2326 | si.nMax = es->line_count - 1; |
| 2327 | si.nPage = (es->format_rect.bottom - es->format_rect.top) / es->line_height; |
| 2328 | si.nPos = es->y_offset; |
| 2329 | TRACE("SB_VERT, nMin=%d, nMax=%d, nPage=%d, nPos=%d\n", |
| 2330 | si.nMin, si.nMax, si.nPage, si.nPos); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2331 | SetScrollInfo(es->hwndSelf, SB_VERT, &si, TRUE); |
Dmitry Timoshkov | 11dbda6 | 2001-01-05 03:40:35 +0000 | [diff] [blame] | 2332 | } |
| 2333 | |
| 2334 | if ((es->style & WS_HSCROLL) && !(es->flags & EF_HSCROLL_TRACK)) |
| 2335 | { |
| 2336 | SCROLLINFO si; |
| 2337 | si.cbSize = sizeof(SCROLLINFO); |
| 2338 | si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE | SIF_DISABLENOSCROLL; |
| 2339 | si.nMin = 0; |
| 2340 | si.nMax = es->text_width - 1; |
| 2341 | si.nPage = es->format_rect.right - es->format_rect.left; |
| 2342 | si.nPos = es->x_offset; |
| 2343 | TRACE("SB_HORZ, nMin=%d, nMax=%d, nPage=%d, nPos=%d\n", |
| 2344 | si.nMin, si.nMax, si.nPage, si.nPos); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2345 | SetScrollInfo(es->hwndSelf, SB_HORZ, &si, TRUE); |
Dmitry Timoshkov | 11dbda6 | 2001-01-05 03:40:35 +0000 | [diff] [blame] | 2346 | } |
| 2347 | } |
| 2348 | |
| 2349 | /********************************************************************* |
| 2350 | * |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2351 | * EDIT_WordBreakProc |
| 2352 | * |
| 2353 | * Find the beginning of words. |
| 2354 | * Note: unlike the specs for a WordBreakProc, this function only |
| 2355 | * allows to be called without linebreaks between s[0] upto |
| 2356 | * s[count - 1]. Remember it is only called |
| 2357 | * internally, so we can decide this for ourselves. |
| 2358 | * |
Alexandre Julliard | 02ed4c2 | 1996-03-02 19:34:10 +0000 | [diff] [blame] | 2359 | */ |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2360 | static INT CALLBACK EDIT_WordBreakProc(LPWSTR s, INT index, INT count, INT action) |
Alexandre Julliard | 02ed4c2 | 1996-03-02 19:34:10 +0000 | [diff] [blame] | 2361 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2362 | INT ret = 0; |
Alexandre Julliard | 02ed4c2 | 1996-03-02 19:34:10 +0000 | [diff] [blame] | 2363 | |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2364 | TRACE("s=%p, index=%d, count=%d, action=%d\n", s, index, count, action); |
| 2365 | |
| 2366 | if(!s) return 0; |
Alexandre Julliard | d2e1c1a | 1996-03-09 16:12:43 +0000 | [diff] [blame] | 2367 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2368 | switch (action) { |
| 2369 | case WB_LEFT: |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 2370 | if (!count) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2371 | break; |
| 2372 | if (index) |
| 2373 | index--; |
| 2374 | if (s[index] == ' ') { |
| 2375 | while (index && (s[index] == ' ')) |
| 2376 | index--; |
| 2377 | if (index) { |
| 2378 | while (index && (s[index] != ' ')) |
| 2379 | index--; |
| 2380 | if (s[index] == ' ') |
| 2381 | index++; |
| 2382 | } |
| 2383 | } else { |
| 2384 | while (index && (s[index] != ' ')) |
| 2385 | index--; |
| 2386 | if (s[index] == ' ') |
| 2387 | index++; |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 2388 | } |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2389 | ret = index; |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 2390 | break; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2391 | case WB_RIGHT: |
| 2392 | if (!count) |
| 2393 | break; |
| 2394 | if (index) |
| 2395 | index--; |
| 2396 | if (s[index] == ' ') |
| 2397 | while ((index < count) && (s[index] == ' ')) index++; |
| 2398 | else { |
| 2399 | while (s[index] && (s[index] != ' ') && (index < count)) |
| 2400 | index++; |
| 2401 | while ((s[index] == ' ') && (index < count)) index++; |
| 2402 | } |
| 2403 | ret = index; |
| 2404 | break; |
| 2405 | case WB_ISDELIMITER: |
| 2406 | ret = (s[index] == ' '); |
| 2407 | break; |
| 2408 | default: |
Dimitrie O. Paun | dd03cc1 | 1999-12-08 03:56:23 +0000 | [diff] [blame] | 2409 | ERR("unknown action code, please report !\n"); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2410 | break; |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 2411 | } |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2412 | return ret; |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 2413 | } |
| 2414 | |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 2415 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2416 | /********************************************************************* |
| 2417 | * |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 2418 | * EM_CHARFROMPOS |
| 2419 | * |
Gerard Patel | c9b6534 | 1999-01-24 18:57:23 +0000 | [diff] [blame] | 2420 | * returns line number (not index) in high-order word of result. |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 2421 | * NB : Q137805 is unclear about this. POINT * pointer in lParam apply |
Gerard Patel | c9b6534 | 1999-01-24 18:57:23 +0000 | [diff] [blame] | 2422 | * to Richedit, not to the edit control. Original documentation is valid. |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2423 | * FIXME: do the specs mean to return -1 if outside client area or |
| 2424 | * if outside formatting rectangle ??? |
| 2425 | * |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 2426 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2427 | static LRESULT EDIT_EM_CharFromPos(EDITSTATE *es, INT x, INT y) |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 2428 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2429 | POINT pt; |
| 2430 | RECT rc; |
| 2431 | INT index; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 2432 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2433 | pt.x = x; |
| 2434 | pt.y = y; |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2435 | GetClientRect(es->hwndSelf, &rc); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2436 | if (!PtInRect(&rc, pt)) |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 2437 | return -1; |
| 2438 | |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2439 | index = EDIT_CharFromPos(es, x, y, NULL); |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 2440 | return MAKELONG(index, EDIT_EM_LineFromChar(es, index)); |
Alexandre Julliard | d2e1c1a | 1996-03-09 16:12:43 +0000 | [diff] [blame] | 2441 | } |
| 2442 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2443 | |
Alexandre Julliard | d2e1c1a | 1996-03-09 16:12:43 +0000 | [diff] [blame] | 2444 | /********************************************************************* |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2445 | * |
| 2446 | * EM_FMTLINES |
| 2447 | * |
Alexandre Julliard | a845b88 | 1998-06-01 10:44:35 +0000 | [diff] [blame] | 2448 | * Enable or disable soft breaks. |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2449 | * |
| 2450 | * This means: insert or remove the soft linebreak character (\r\r\n). |
| 2451 | * Take care to check if the text still fits the buffer after insertion. |
| 2452 | * If not, notify with EN_ERRSPACE. |
| 2453 | * |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 2454 | */ |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 2455 | static BOOL EDIT_EM_FmtLines(EDITSTATE *es, BOOL add_eol) |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 2456 | { |
Alexandre Julliard | a845b88 | 1998-06-01 10:44:35 +0000 | [diff] [blame] | 2457 | es->flags &= ~EF_USE_SOFTBRK; |
| 2458 | if (add_eol) { |
| 2459 | es->flags |= EF_USE_SOFTBRK; |
Dimitrie O. Paun | dd03cc1 | 1999-12-08 03:56:23 +0000 | [diff] [blame] | 2460 | FIXME("soft break enabled, not implemented\n"); |
Alexandre Julliard | a845b88 | 1998-06-01 10:44:35 +0000 | [diff] [blame] | 2461 | } |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2462 | return add_eol; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2463 | } |
Alexandre Julliard | 988ca97 | 1994-06-21 16:15:21 +0000 | [diff] [blame] | 2464 | |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 2465 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2466 | /********************************************************************* |
| 2467 | * |
| 2468 | * EM_GETHANDLE |
| 2469 | * |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2470 | * Hopefully this won't fire back at us. |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2471 | * We always start with a fixed buffer in the local heap. |
Dmitry Timoshkov | 11dbda6 | 2001-01-05 03:40:35 +0000 | [diff] [blame] | 2472 | * Despite of the documentation says that the local heap is used |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2473 | * only if DS_LOCALEDIT flag is set, NT and 2000 always allocate |
| 2474 | * buffer on the local heap. |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2475 | * |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2476 | */ |
Dmitry Timoshkov | 8058ead | 2000-12-21 20:19:21 +0000 | [diff] [blame] | 2477 | static HLOCAL EDIT_EM_GetHandle(EDITSTATE *es) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2478 | { |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2479 | HLOCAL hLocal; |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 2480 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2481 | if (!(es->style & ES_MULTILINE)) |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 2482 | return 0; |
| 2483 | |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2484 | if(es->is_unicode) |
| 2485 | hLocal = es->hloc32W; |
| 2486 | else |
| 2487 | { |
| 2488 | if(!es->hloc32A) |
| 2489 | { |
| 2490 | CHAR *textA; |
Dmitry Timoshkov | df793bc | 2001-01-15 20:20:31 +0000 | [diff] [blame] | 2491 | UINT countA, alloc_size; |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2492 | TRACE("Allocating 32-bit ANSI alias buffer\n"); |
James Hatheway | ba9b964 | 2001-01-10 22:54:33 +0000 | [diff] [blame] | 2493 | countA = WideCharToMultiByte(CP_ACP, 0, es->text, -1, NULL, 0, NULL, NULL); |
Dmitry Timoshkov | df793bc | 2001-01-15 20:20:31 +0000 | [diff] [blame] | 2494 | alloc_size = ROUND_TO_GROW(countA); |
| 2495 | if(!(es->hloc32A = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT, alloc_size))) |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2496 | { |
Dmitry Timoshkov | df793bc | 2001-01-15 20:20:31 +0000 | [diff] [blame] | 2497 | ERR("Could not allocate %d bytes for 32-bit ANSI alias buffer\n", alloc_size); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2498 | return 0; |
| 2499 | } |
| 2500 | textA = LocalLock(es->hloc32A); |
James Hatheway | ba9b964 | 2001-01-10 22:54:33 +0000 | [diff] [blame] | 2501 | WideCharToMultiByte(CP_ACP, 0, es->text, -1, textA, countA, NULL, NULL); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2502 | LocalUnlock(es->hloc32A); |
| 2503 | } |
| 2504 | hLocal = es->hloc32A; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2505 | } |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2506 | |
Alexandre Julliard | aff7dda | 2002-11-22 21:22:14 +0000 | [diff] [blame] | 2507 | TRACE("Returning %p, LocalSize() = %ld\n", hLocal, LocalSize(hLocal)); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2508 | return hLocal; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2509 | } |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 2510 | |
| 2511 | |
| 2512 | /********************************************************************* |
| 2513 | * |
| 2514 | * EM_GETHANDLE16 |
| 2515 | * |
| 2516 | * Hopefully this won't fire back at us. |
| 2517 | * We always start with a buffer in 32 bit linear memory. |
| 2518 | * However, with this message a 16 bit application requests |
| 2519 | * a handle of 16 bit local heap memory, where it expects to find |
| 2520 | * the text. |
| 2521 | * It's a pitty that from this moment on we have to use this |
| 2522 | * local heap, because applications may rely on the handle |
| 2523 | * in the future. |
| 2524 | * |
| 2525 | * In this function we'll try to switch to local heap. |
| 2526 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2527 | static HLOCAL16 EDIT_EM_GetHandle16(EDITSTATE *es) |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 2528 | { |
Robert Shearman | 2e9436c | 2004-08-17 22:29:29 +0000 | [diff] [blame] | 2529 | HINSTANCE16 hInstance = GetWindowLongPtrW( es->hwndSelf, GWLP_HINSTANCE ); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2530 | CHAR *textA; |
Dmitry Timoshkov | df793bc | 2001-01-15 20:20:31 +0000 | [diff] [blame] | 2531 | UINT countA, alloc_size; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 2532 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2533 | if (!(es->style & ES_MULTILINE)) |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 2534 | return 0; |
| 2535 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2536 | if (es->hloc16) |
| 2537 | return es->hloc16; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 2538 | |
Alexandre Julliard | de42428 | 2001-08-10 22:51:42 +0000 | [diff] [blame] | 2539 | if (!LOCAL_HeapSize(hInstance)) { |
| 2540 | if (!LocalInit16(hInstance, 0, |
| 2541 | GlobalSize16(hInstance))) { |
Dimitrie O. Paun | dd03cc1 | 1999-12-08 03:56:23 +0000 | [diff] [blame] | 2542 | ERR("could not initialize local heap\n"); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 2543 | return 0; |
| 2544 | } |
Dimitrie O. Paun | dd03cc1 | 1999-12-08 03:56:23 +0000 | [diff] [blame] | 2545 | TRACE("local heap initialized\n"); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 2546 | } |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2547 | |
James Hatheway | ba9b964 | 2001-01-10 22:54:33 +0000 | [diff] [blame] | 2548 | countA = WideCharToMultiByte(CP_ACP, 0, es->text, -1, NULL, 0, NULL, NULL); |
Dmitry Timoshkov | df793bc | 2001-01-15 20:20:31 +0000 | [diff] [blame] | 2549 | alloc_size = ROUND_TO_GROW(countA); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2550 | |
| 2551 | TRACE("Allocating 16-bit ANSI alias buffer\n"); |
Alexandre Julliard | de42428 | 2001-08-10 22:51:42 +0000 | [diff] [blame] | 2552 | if (!(es->hloc16 = LOCAL_Alloc(hInstance, LMEM_MOVEABLE | LMEM_ZEROINIT, alloc_size))) { |
Dimitrie O. Paun | dd03cc1 | 1999-12-08 03:56:23 +0000 | [diff] [blame] | 2553 | ERR("could not allocate new 16 bit buffer\n"); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 2554 | return 0; |
| 2555 | } |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2556 | |
Alexandre Julliard | de42428 | 2001-08-10 22:51:42 +0000 | [diff] [blame] | 2557 | if (!(textA = (LPSTR)LOCAL_Lock(hInstance, es->hloc16))) { |
Dimitrie O. Paun | dd03cc1 | 1999-12-08 03:56:23 +0000 | [diff] [blame] | 2558 | ERR("could not lock new 16 bit buffer\n"); |
Alexandre Julliard | de42428 | 2001-08-10 22:51:42 +0000 | [diff] [blame] | 2559 | LOCAL_Free(hInstance, es->hloc16); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2560 | es->hloc16 = 0; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 2561 | return 0; |
| 2562 | } |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 2563 | |
James Hatheway | ba9b964 | 2001-01-10 22:54:33 +0000 | [diff] [blame] | 2564 | WideCharToMultiByte(CP_ACP, 0, es->text, -1, textA, countA, NULL, NULL); |
Alexandre Julliard | de42428 | 2001-08-10 22:51:42 +0000 | [diff] [blame] | 2565 | LOCAL_Unlock(hInstance, es->hloc16); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2566 | |
Alexandre Julliard | de42428 | 2001-08-10 22:51:42 +0000 | [diff] [blame] | 2567 | TRACE("Returning %04X, LocalSize() = %d\n", es->hloc16, LOCAL_Size(hInstance, es->hloc16)); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2568 | return es->hloc16; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 2569 | } |
| 2570 | |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 2571 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2572 | /********************************************************************* |
| 2573 | * |
| 2574 | * EM_GETLINE |
| 2575 | * |
| 2576 | */ |
Dmitry Timoshkov | bf60453 | 2001-02-12 19:15:33 +0000 | [diff] [blame] | 2577 | static INT EDIT_EM_GetLine(EDITSTATE *es, INT line, LPARAM lParam, BOOL unicode) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2578 | { |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2579 | LPWSTR src; |
Dmitry Timoshkov | bf60453 | 2001-02-12 19:15:33 +0000 | [diff] [blame] | 2580 | INT line_len, dst_len; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2581 | INT i; |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 2582 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2583 | if (es->style & ES_MULTILINE) { |
| 2584 | if (line >= es->line_count) |
| 2585 | return 0; |
| 2586 | } else |
| 2587 | line = 0; |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 2588 | i = EDIT_EM_LineIndex(es, line); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 2589 | src = es->text + i; |
Dmitry Timoshkov | bf60453 | 2001-02-12 19:15:33 +0000 | [diff] [blame] | 2590 | line_len = EDIT_EM_LineLength(es, i); |
| 2591 | dst_len = *(WORD *)lParam; |
| 2592 | if(unicode) |
| 2593 | { |
| 2594 | LPWSTR dst = (LPWSTR)lParam; |
| 2595 | if(dst_len <= line_len) |
| 2596 | { |
| 2597 | memcpy(dst, src, dst_len * sizeof(WCHAR)); |
| 2598 | return dst_len; |
| 2599 | } |
| 2600 | else /* Append 0 if enough space */ |
| 2601 | { |
| 2602 | memcpy(dst, src, line_len * sizeof(WCHAR)); |
| 2603 | dst[line_len] = 0; |
| 2604 | return line_len; |
| 2605 | } |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2606 | } |
Dmitry Timoshkov | bf60453 | 2001-02-12 19:15:33 +0000 | [diff] [blame] | 2607 | else |
| 2608 | { |
| 2609 | LPSTR dst = (LPSTR)lParam; |
| 2610 | INT ret; |
| 2611 | ret = WideCharToMultiByte(CP_ACP, 0, src, line_len, dst, dst_len, NULL, NULL); |
| 2612 | if(!ret) /* Insufficient buffer size */ |
| 2613 | return dst_len; |
| 2614 | if(ret < dst_len) /* Append 0 if enough space */ |
| 2615 | dst[ret] = 0; |
| 2616 | return ret; |
| 2617 | } |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2618 | } |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 2619 | |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 2620 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2621 | /********************************************************************* |
| 2622 | * |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2623 | * EM_GETSEL |
| 2624 | * |
| 2625 | */ |
Francois Gouget | bba4bb1 | 2002-09-17 01:35:09 +0000 | [diff] [blame] | 2626 | static LRESULT EDIT_EM_GetSel(EDITSTATE *es, PUINT start, PUINT end) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2627 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2628 | UINT s = es->selection_start; |
| 2629 | UINT e = es->selection_end; |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 2630 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2631 | ORDER_UINT(s, e); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2632 | if (start) |
| 2633 | *start = s; |
| 2634 | if (end) |
| 2635 | *end = e; |
| 2636 | return MAKELONG(s, e); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2637 | } |
| 2638 | |
| 2639 | |
| 2640 | /********************************************************************* |
| 2641 | * |
| 2642 | * EM_GETTHUMB |
| 2643 | * |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2644 | * FIXME: is this right ? (or should it be only VSCROLL) |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 2645 | * (and maybe only for edit controls that really have their |
| 2646 | * own scrollbars) (and maybe only for multiline controls ?) |
| 2647 | * All in all: very poorly documented |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2648 | * |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2649 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2650 | static LRESULT EDIT_EM_GetThumb(EDITSTATE *es) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2651 | { |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2652 | return MAKELONG(EDIT_WM_VScroll(es, EM_GETTHUMB16, 0), |
| 2653 | EDIT_WM_HScroll(es, EM_GETTHUMB16, 0)); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2654 | } |
| 2655 | |
| 2656 | |
| 2657 | /********************************************************************* |
| 2658 | * |
| 2659 | * EM_LINEFROMCHAR |
| 2660 | * |
| 2661 | */ |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 2662 | static INT EDIT_EM_LineFromChar(EDITSTATE *es, INT index) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2663 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2664 | INT line; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2665 | LINEDEF *line_def; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2666 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2667 | if (!(es->style & ES_MULTILINE)) |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 2668 | return 0; |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2669 | if (index > (INT)strlenW(es->text)) |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2670 | return es->line_count - 1; |
| 2671 | if (index == -1) |
Francois Gouget | 6d77d3a | 2000-03-25 21:44:35 +0000 | [diff] [blame] | 2672 | index = min(es->selection_start, es->selection_end); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2673 | |
| 2674 | line = 0; |
| 2675 | line_def = es->first_line_def; |
| 2676 | index -= line_def->length; |
| 2677 | while ((index >= 0) && line_def->next) { |
| 2678 | line++; |
| 2679 | line_def = line_def->next; |
| 2680 | index -= line_def->length; |
| 2681 | } |
| 2682 | return line; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2683 | } |
| 2684 | |
| 2685 | |
| 2686 | /********************************************************************* |
| 2687 | * |
| 2688 | * EM_LINEINDEX |
| 2689 | * |
| 2690 | */ |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 2691 | static INT EDIT_EM_LineIndex(EDITSTATE *es, INT line) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2692 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2693 | INT line_index; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2694 | LINEDEF *line_def; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2695 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2696 | if (!(es->style & ES_MULTILINE)) |
| 2697 | return 0; |
| 2698 | if (line >= es->line_count) |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 2699 | return -1; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2700 | |
| 2701 | line_index = 0; |
| 2702 | line_def = es->first_line_def; |
| 2703 | if (line == -1) { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2704 | INT index = es->selection_end - line_def->length; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2705 | while ((index >= 0) && line_def->next) { |
| 2706 | line_index += line_def->length; |
| 2707 | line_def = line_def->next; |
| 2708 | index -= line_def->length; |
| 2709 | } |
| 2710 | } else { |
| 2711 | while (line > 0) { |
| 2712 | line_index += line_def->length; |
| 2713 | line_def = line_def->next; |
| 2714 | line--; |
| 2715 | } |
| 2716 | } |
| 2717 | return line_index; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2718 | } |
| 2719 | |
| 2720 | |
| 2721 | /********************************************************************* |
| 2722 | * |
| 2723 | * EM_LINELENGTH |
| 2724 | * |
| 2725 | */ |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 2726 | static INT EDIT_EM_LineLength(EDITSTATE *es, INT index) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2727 | { |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2728 | LINEDEF *line_def; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2729 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2730 | if (!(es->style & ES_MULTILINE)) |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2731 | return strlenW(es->text); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2732 | |
| 2733 | if (index == -1) { |
Andreas Mohr | a8edb3e | 2000-05-23 04:05:05 +0000 | [diff] [blame] | 2734 | /* get the number of remaining non-selected chars of selected lines */ |
Andreas Mohr | 07216db | 2001-11-13 21:29:38 +0000 | [diff] [blame] | 2735 | INT32 l; /* line number */ |
| 2736 | INT32 li; /* index of first char in line */ |
Andreas Mohr | a8edb3e | 2000-05-23 04:05:05 +0000 | [diff] [blame] | 2737 | INT32 count; |
Andreas Mohr | 07216db | 2001-11-13 21:29:38 +0000 | [diff] [blame] | 2738 | l = EDIT_EM_LineFromChar(es, es->selection_start); |
Andreas Mohr | a8edb3e | 2000-05-23 04:05:05 +0000 | [diff] [blame] | 2739 | /* # chars before start of selection area */ |
Andreas Mohr | 07216db | 2001-11-13 21:29:38 +0000 | [diff] [blame] | 2740 | count = es->selection_start - EDIT_EM_LineIndex(es, l); |
| 2741 | l = EDIT_EM_LineFromChar(es, es->selection_end); |
Andreas Mohr | a8edb3e | 2000-05-23 04:05:05 +0000 | [diff] [blame] | 2742 | /* # chars after end of selection */ |
Andreas Mohr | 07216db | 2001-11-13 21:29:38 +0000 | [diff] [blame] | 2743 | li = EDIT_EM_LineIndex(es, l); |
| 2744 | count += li + EDIT_EM_LineLength(es, li) - es->selection_end; |
Andreas Mohr | a8edb3e | 2000-05-23 04:05:05 +0000 | [diff] [blame] | 2745 | return count; |
Alexandre Julliard | cdcdede | 1996-04-21 14:57:41 +0000 | [diff] [blame] | 2746 | } |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2747 | line_def = es->first_line_def; |
| 2748 | index -= line_def->length; |
| 2749 | while ((index >= 0) && line_def->next) { |
| 2750 | line_def = line_def->next; |
| 2751 | index -= line_def->length; |
| 2752 | } |
| 2753 | return line_def->net_length; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2754 | } |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 2755 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2756 | |
| 2757 | /********************************************************************* |
| 2758 | * |
| 2759 | * EM_LINESCROLL |
| 2760 | * |
Dmitry Timoshkov | 11dbda6 | 2001-01-05 03:40:35 +0000 | [diff] [blame] | 2761 | * NOTE: dx is in average character widths, dy - in lines; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 2762 | * |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2763 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2764 | static BOOL EDIT_EM_LineScroll(EDITSTATE *es, INT dx, INT dy) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2765 | { |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2766 | if (!(es->style & ES_MULTILINE)) |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 2767 | return FALSE; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2768 | |
Dmitry Timoshkov | 11dbda6 | 2001-01-05 03:40:35 +0000 | [diff] [blame] | 2769 | dx *= es->char_width; |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2770 | return EDIT_EM_LineScroll_internal(es, dx, dy); |
Dmitry Timoshkov | 11dbda6 | 2001-01-05 03:40:35 +0000 | [diff] [blame] | 2771 | } |
| 2772 | |
| 2773 | /********************************************************************* |
| 2774 | * |
| 2775 | * EDIT_EM_LineScroll_internal |
| 2776 | * |
| 2777 | * Version of EDIT_EM_LineScroll for internal use. |
| 2778 | * It doesn't refuse if ES_MULTILINE is set and assumes that |
| 2779 | * dx is in pixels, dy - in lines. |
| 2780 | * |
| 2781 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2782 | static BOOL EDIT_EM_LineScroll_internal(EDITSTATE *es, INT dx, INT dy) |
Dmitry Timoshkov | 11dbda6 | 2001-01-05 03:40:35 +0000 | [diff] [blame] | 2783 | { |
| 2784 | INT nyoff; |
| 2785 | INT x_offset_in_pixels; |
| 2786 | |
| 2787 | if (es->style & ES_MULTILINE) |
| 2788 | { |
| 2789 | x_offset_in_pixels = es->x_offset; |
| 2790 | } |
| 2791 | else |
| 2792 | { |
| 2793 | dy = 0; |
Alexandre Julliard | 9d61596 | 2003-09-17 04:28:28 +0000 | [diff] [blame] | 2794 | x_offset_in_pixels = (short)LOWORD(EDIT_EM_PosFromChar(es, es->x_offset, FALSE)); |
Dmitry Timoshkov | 11dbda6 | 2001-01-05 03:40:35 +0000 | [diff] [blame] | 2795 | } |
| 2796 | |
| 2797 | if (-dx > x_offset_in_pixels) |
| 2798 | dx = -x_offset_in_pixels; |
| 2799 | if (dx > es->text_width - x_offset_in_pixels) |
| 2800 | dx = es->text_width - x_offset_in_pixels; |
Francois Gouget | 6d77d3a | 2000-03-25 21:44:35 +0000 | [diff] [blame] | 2801 | nyoff = max(0, es->y_offset + dy); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2802 | if (nyoff >= es->line_count) |
| 2803 | nyoff = es->line_count - 1; |
| 2804 | dy = (es->y_offset - nyoff) * es->line_height; |
| 2805 | if (dx || dy) { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2806 | RECT rc1; |
| 2807 | RECT rc; |
Dmitry Timoshkov | 11dbda6 | 2001-01-05 03:40:35 +0000 | [diff] [blame] | 2808 | |
| 2809 | es->y_offset = nyoff; |
| 2810 | if(es->style & ES_MULTILINE) |
| 2811 | es->x_offset += dx; |
| 2812 | else |
| 2813 | es->x_offset += dx / es->char_width; |
| 2814 | |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2815 | GetClientRect(es->hwndSelf, &rc1); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2816 | IntersectRect(&rc, &rc1, &es->format_rect); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2817 | ScrollWindowEx(es->hwndSelf, -dx, dy, |
Francois Gouget | d2667a4 | 2002-12-02 18:10:57 +0000 | [diff] [blame] | 2818 | NULL, &rc, NULL, NULL, SW_INVALIDATE); |
Dmitry Timoshkov | a234db8 | 2001-01-19 20:49:54 +0000 | [diff] [blame] | 2819 | /* force scroll info update */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2820 | EDIT_UpdateScrollInfo(es); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2821 | } |
| 2822 | if (dx && !(es->flags & EF_HSCROLL_TRACK)) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2823 | EDIT_NOTIFY_PARENT(es, EN_HSCROLL, "EN_HSCROLL"); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2824 | if (dy && !(es->flags & EF_VSCROLL_TRACK)) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2825 | EDIT_NOTIFY_PARENT(es, EN_VSCROLL, "EN_VSCROLL"); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2826 | return TRUE; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 2827 | } |
| 2828 | |
| 2829 | |
| 2830 | /********************************************************************* |
| 2831 | * |
| 2832 | * EM_POSFROMCHAR |
| 2833 | * |
| 2834 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2835 | static LRESULT EDIT_EM_PosFromChar(EDITSTATE *es, INT index, BOOL after_wrap) |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 2836 | { |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2837 | INT len = strlenW(es->text); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2838 | INT l; |
| 2839 | INT li; |
| 2840 | INT x; |
| 2841 | INT y = 0; |
| 2842 | HDC dc; |
| 2843 | HFONT old_font = 0; |
| 2844 | SIZE size; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 2845 | |
Francois Gouget | 6d77d3a | 2000-03-25 21:44:35 +0000 | [diff] [blame] | 2846 | index = min(index, len); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2847 | dc = GetDC(es->hwndSelf); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2848 | if (es->font) |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2849 | old_font = SelectObject(dc, es->font); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2850 | if (es->style & ES_MULTILINE) { |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 2851 | l = EDIT_EM_LineFromChar(es, index); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2852 | y = (l - es->y_offset) * es->line_height; |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 2853 | li = EDIT_EM_LineIndex(es, l); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2854 | if (after_wrap && (li == index) && l) { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2855 | INT l2 = l - 1; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2856 | LINEDEF *line_def = es->first_line_def; |
| 2857 | while (l2) { |
| 2858 | line_def = line_def->next; |
| 2859 | l2--; |
| 2860 | } |
| 2861 | if (line_def->ending == END_WRAP) { |
| 2862 | l--; |
| 2863 | y -= es->line_height; |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 2864 | li = EDIT_EM_LineIndex(es, l); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2865 | } |
| 2866 | } |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2867 | x = LOWORD(GetTabbedTextExtentW(dc, es->text + li, index - li, |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2868 | es->tabs_count, es->tabs)) - es->x_offset; |
| 2869 | } else { |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2870 | LPWSTR text = EDIT_GetPasswordPointer_SL(es); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2871 | if (index < es->x_offset) { |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2872 | GetTextExtentPoint32W(dc, text + index, |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2873 | es->x_offset - index, &size); |
| 2874 | x = -size.cx; |
| 2875 | } else { |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2876 | GetTextExtentPoint32W(dc, text + es->x_offset, |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2877 | index - es->x_offset, &size); |
| 2878 | x = size.cx; |
| 2879 | } |
| 2880 | y = 0; |
| 2881 | if (es->style & ES_PASSWORD) |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2882 | HeapFree(GetProcessHeap(), 0, text); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2883 | } |
| 2884 | x += es->format_rect.left; |
| 2885 | y += es->format_rect.top; |
| 2886 | if (es->font) |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2887 | SelectObject(dc, old_font); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 2888 | ReleaseDC(es->hwndSelf, dc); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2889 | return MAKELONG((INT16)x, (INT16)y); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2890 | } |
| 2891 | |
| 2892 | |
| 2893 | /********************************************************************* |
| 2894 | * |
| 2895 | * EM_REPLACESEL |
| 2896 | * |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2897 | * FIXME: handle ES_NUMBER and ES_OEMCONVERT here |
| 2898 | * |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2899 | */ |
Carl Sopchak | 23b88ef | 2002-11-21 03:57:05 +0000 | [diff] [blame] | 2900 | static void EDIT_EM_ReplaceSel(EDITSTATE *es, BOOL can_undo, LPCWSTR lpsz_replace, BOOL send_update, BOOL honor_limit) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 2901 | { |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2902 | UINT strl = strlenW(lpsz_replace); |
| 2903 | UINT tl = strlenW(es->text); |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 2904 | UINT utl; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2905 | UINT s; |
| 2906 | UINT e; |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 2907 | UINT i; |
Krishna Murthy | 4af4ba4 | 2004-05-29 00:21:51 +0000 | [diff] [blame] | 2908 | UINT size; |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2909 | LPWSTR p; |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 2910 | HRGN hrgn = 0; |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2911 | |
| 2912 | TRACE("%s, can_undo %d, send_update %d\n", |
| 2913 | debugstr_w(lpsz_replace), can_undo, send_update); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 2914 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2915 | s = es->selection_start; |
| 2916 | e = es->selection_end; |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 2917 | |
| 2918 | if ((s == e) && !strl) |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2919 | return; |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 2920 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2921 | ORDER_UINT(s, e); |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 2922 | |
Krishna Murthy | 4af4ba4 | 2004-05-29 00:21:51 +0000 | [diff] [blame] | 2923 | /* Issue the EN_MAXTEXT notification and continue with replacing text |
| 2924 | * such that buffer limit is honored. */ |
| 2925 | size = tl - (e - s) + strl; |
| 2926 | if ((honor_limit) && (es->buffer_limit > 0) && (size > es->buffer_limit)) { |
| 2927 | EDIT_NOTIFY_PARENT(es, EN_MAXTEXT, "EN_MAXTEXT"); |
| 2928 | strl = es->buffer_limit - (tl - (e-s)); |
| 2929 | } |
| 2930 | |
| 2931 | if (!EDIT_MakeFit(es, tl - (e - s) + strl)) |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2932 | return; |
| 2933 | |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 2934 | if (e != s) { |
| 2935 | /* there is something to be deleted */ |
Andreas Mohr | 07216db | 2001-11-13 21:29:38 +0000 | [diff] [blame] | 2936 | TRACE("deleting stuff.\n"); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2937 | if (can_undo) { |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2938 | utl = strlenW(es->undo_text); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2939 | if (!es->undo_insert_count && (*es->undo_text && (s == es->undo_position))) { |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 2940 | /* undo-buffer is extended to the right */ |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 2941 | EDIT_MakeUndoFit(es, utl + e - s); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2942 | strncpyW(es->undo_text + utl, es->text + s, e - s + 1); |
Dmitry Timoshkov | f8b96e2 | 2000-12-20 18:39:14 +0000 | [diff] [blame] | 2943 | (es->undo_text + utl)[e - s] = 0; /* ensure 0 termination */ |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2944 | } else if (!es->undo_insert_count && (*es->undo_text && (e == es->undo_position))) { |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 2945 | /* undo-buffer is extended to the left */ |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 2946 | EDIT_MakeUndoFit(es, utl + e - s); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2947 | for (p = es->undo_text + utl ; p >= es->undo_text ; p--) |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 2948 | p[e - s] = p[0]; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2949 | for (i = 0 , p = es->undo_text ; i < e - s ; i++) |
| 2950 | p[i] = (es->text + s)[i]; |
| 2951 | es->undo_position = s; |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 2952 | } else { |
| 2953 | /* new undo-buffer */ |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 2954 | EDIT_MakeUndoFit(es, e - s); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2955 | strncpyW(es->undo_text, es->text + s, e - s + 1); |
Dmitry Timoshkov | f8b96e2 | 2000-12-20 18:39:14 +0000 | [diff] [blame] | 2956 | es->undo_text[e - s] = 0; /* ensure 0 termination */ |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2957 | es->undo_position = s; |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 2958 | } |
| 2959 | /* any deletion makes the old insertion-undo invalid */ |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2960 | es->undo_insert_count = 0; |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 2961 | } else |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 2962 | EDIT_EM_EmptyUndoBuffer(es); |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 2963 | |
| 2964 | /* now delete */ |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2965 | strcpyW(es->text + s, es->text + e); |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 2966 | } |
| 2967 | if (strl) { |
| 2968 | /* there is an insertion */ |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2969 | if (can_undo) { |
| 2970 | if ((s == es->undo_position) || |
| 2971 | ((es->undo_insert_count) && |
| 2972 | (s == es->undo_position + es->undo_insert_count))) |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 2973 | /* |
| 2974 | * insertion is new and at delete position or |
| 2975 | * an extension to either left or right |
| 2976 | */ |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2977 | es->undo_insert_count += strl; |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 2978 | else { |
| 2979 | /* new insertion undo */ |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2980 | es->undo_position = s; |
| 2981 | es->undo_insert_count = strl; |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 2982 | /* new insertion makes old delete-buffer invalid */ |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2983 | *es->undo_text = '\0'; |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 2984 | } |
| 2985 | } else |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 2986 | EDIT_EM_EmptyUndoBuffer(es); |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 2987 | |
| 2988 | /* now insert */ |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2989 | tl = strlenW(es->text); |
Andreas Mohr | 07216db | 2001-11-13 21:29:38 +0000 | [diff] [blame] | 2990 | TRACE("inserting stuff (tl %d, strl %d, selstart %d ('%s'), text '%s')\n", tl, strl, s, debugstr_w(es->text + s), debugstr_w(es->text)); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2991 | for (p = es->text + tl ; p >= es->text + s ; p--) |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 2992 | p[strl] = p[0]; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2993 | for (i = 0 , p = es->text + s ; i < strl ; i++) |
| 2994 | p[i] = lpsz_replace[i]; |
| 2995 | if(es->style & ES_UPPERCASE) |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2996 | CharUpperBuffW(p, strl); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 2997 | else if(es->style & ES_LOWERCASE) |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 2998 | CharLowerBuffW(p, strl); |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 2999 | s += strl; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 3000 | } |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3001 | if (es->style & ES_MULTILINE) |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 3002 | { |
| 3003 | INT s = min(es->selection_start, es->selection_end); |
| 3004 | |
| 3005 | hrgn = CreateRectRgn(0, 0, 0, 0); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3006 | EDIT_BuildLineDefs_ML(es, s, s + strl, |
Ulrich Czekalla | 2d382c6 | 2001-05-09 17:12:30 +0000 | [diff] [blame] | 3007 | strl - abs(es->selection_end - es->selection_start), hrgn); |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 3008 | } |
Dmitry Timoshkov | 11dbda6 | 2001-01-05 03:40:35 +0000 | [diff] [blame] | 3009 | else |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3010 | EDIT_CalcLineWidth_SL(es); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3011 | |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3012 | EDIT_EM_SetSel(es, s, s, FALSE); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3013 | es->flags |= EF_MODIFIED; |
Ulrich Weigand | 6bfbc3d | 2000-10-23 00:38:10 +0000 | [diff] [blame] | 3014 | if (send_update) es->flags |= EF_UPDATE; |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 3015 | if (hrgn) |
| 3016 | { |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3017 | EDIT_UpdateTextRegion(es, hrgn, TRUE); |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 3018 | DeleteObject(hrgn); |
| 3019 | } |
| 3020 | else |
Huw Davies | 4c7b65d | 2003-11-11 00:26:53 +0000 | [diff] [blame] | 3021 | EDIT_UpdateText(es, NULL, TRUE); |
| 3022 | |
| 3023 | EDIT_EM_ScrollCaret(es); |
| 3024 | |
| 3025 | /* force scroll info update */ |
| 3026 | EDIT_UpdateScrollInfo(es); |
| 3027 | |
Dmitry Timoshkov | a62f06d | 2001-03-13 23:31:08 +0000 | [diff] [blame] | 3028 | |
| 3029 | if(es->flags & EF_UPDATE) |
| 3030 | { |
| 3031 | es->flags &= ~EF_UPDATE; |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3032 | EDIT_NOTIFY_PARENT(es, EN_CHANGE, "EN_CHANGE"); |
Dmitry Timoshkov | a62f06d | 2001-03-13 23:31:08 +0000 | [diff] [blame] | 3033 | } |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3034 | } |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 3035 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3036 | |
| 3037 | /********************************************************************* |
| 3038 | * |
| 3039 | * EM_SCROLL |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3040 | * |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3041 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3042 | static LRESULT EDIT_EM_Scroll(EDITSTATE *es, INT action) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3043 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 3044 | INT dy; |
Alexandre Julliard | df2673b | 1997-03-29 17:20:20 +0000 | [diff] [blame] | 3045 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3046 | if (!(es->style & ES_MULTILINE)) |
| 3047 | return (LRESULT)FALSE; |
| 3048 | |
| 3049 | dy = 0; |
| 3050 | |
| 3051 | switch (action) { |
| 3052 | case SB_LINEUP: |
| 3053 | if (es->y_offset) |
| 3054 | dy = -1; |
| 3055 | break; |
| 3056 | case SB_LINEDOWN: |
| 3057 | if (es->y_offset < es->line_count - 1) |
| 3058 | dy = 1; |
| 3059 | break; |
| 3060 | case SB_PAGEUP: |
| 3061 | if (es->y_offset) |
| 3062 | dy = -(es->format_rect.bottom - es->format_rect.top) / es->line_height; |
| 3063 | break; |
Alexandre Julliard | df2673b | 1997-03-29 17:20:20 +0000 | [diff] [blame] | 3064 | case SB_PAGEDOWN: |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3065 | if (es->y_offset < es->line_count - 1) |
| 3066 | dy = (es->format_rect.bottom - es->format_rect.top) / es->line_height; |
| 3067 | break; |
Alexandre Julliard | df2673b | 1997-03-29 17:20:20 +0000 | [diff] [blame] | 3068 | default: |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3069 | return (LRESULT)FALSE; |
Alexandre Julliard | df2673b | 1997-03-29 17:20:20 +0000 | [diff] [blame] | 3070 | } |
| 3071 | if (dy) { |
Dmitry Timoshkov | 11dbda6 | 2001-01-05 03:40:35 +0000 | [diff] [blame] | 3072 | INT vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height; |
| 3073 | /* check if we are going to move too far */ |
| 3074 | if(es->y_offset + dy > es->line_count - vlc) |
| 3075 | dy = es->line_count - vlc - es->y_offset; |
| 3076 | |
| 3077 | /* Notification is done in EDIT_EM_LineScroll */ |
| 3078 | if(dy) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3079 | EDIT_EM_LineScroll(es, 0, dy); |
Alexandre Julliard | df2673b | 1997-03-29 17:20:20 +0000 | [diff] [blame] | 3080 | } |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3081 | return MAKELONG((INT16)dy, (BOOL16)TRUE); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3082 | } |
| 3083 | |
| 3084 | |
| 3085 | /********************************************************************* |
| 3086 | * |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 3087 | * EM_SCROLLCARET |
| 3088 | * |
| 3089 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3090 | static void EDIT_EM_ScrollCaret(EDITSTATE *es) |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 3091 | { |
| 3092 | if (es->style & ES_MULTILINE) { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 3093 | INT l; |
| 3094 | INT li; |
| 3095 | INT vlc; |
| 3096 | INT ww; |
| 3097 | INT cw = es->char_width; |
| 3098 | INT x; |
| 3099 | INT dy = 0; |
| 3100 | INT dx = 0; |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 3101 | |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 3102 | l = EDIT_EM_LineFromChar(es, es->selection_end); |
| 3103 | li = EDIT_EM_LineIndex(es, l); |
Alexandre Julliard | 9d61596 | 2003-09-17 04:28:28 +0000 | [diff] [blame] | 3104 | x = (short)LOWORD(EDIT_EM_PosFromChar(es, es->selection_end, es->flags & EF_AFTER_WRAP)); |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 3105 | vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height; |
| 3106 | if (l >= es->y_offset + vlc) |
| 3107 | dy = l - vlc + 1 - es->y_offset; |
| 3108 | if (l < es->y_offset) |
| 3109 | dy = l - es->y_offset; |
| 3110 | ww = es->format_rect.right - es->format_rect.left; |
| 3111 | if (x < es->format_rect.left) |
| 3112 | dx = x - es->format_rect.left - ww / HSCROLL_FRACTION / cw * cw; |
| 3113 | if (x > es->format_rect.right) |
| 3114 | dx = x - es->format_rect.left - (HSCROLL_FRACTION - 1) * ww / HSCROLL_FRACTION / cw * cw; |
| 3115 | if (dy || dx) |
Dmitry Timoshkov | 11dbda6 | 2001-01-05 03:40:35 +0000 | [diff] [blame] | 3116 | { |
| 3117 | /* check if we are going to move too far */ |
| 3118 | if(es->x_offset + dx + ww > es->text_width) |
| 3119 | dx = es->text_width - ww - es->x_offset; |
| 3120 | if(dx || dy) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3121 | EDIT_EM_LineScroll_internal(es, dx, dy); |
Dmitry Timoshkov | 11dbda6 | 2001-01-05 03:40:35 +0000 | [diff] [blame] | 3122 | } |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 3123 | } else { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 3124 | INT x; |
| 3125 | INT goal; |
| 3126 | INT format_width; |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 3127 | |
| 3128 | if (!(es->style & ES_AUTOHSCROLL)) |
| 3129 | return; |
| 3130 | |
Alexandre Julliard | 9d61596 | 2003-09-17 04:28:28 +0000 | [diff] [blame] | 3131 | x = (short)LOWORD(EDIT_EM_PosFromChar(es, es->selection_end, FALSE)); |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 3132 | format_width = es->format_rect.right - es->format_rect.left; |
| 3133 | if (x < es->format_rect.left) { |
| 3134 | goal = es->format_rect.left + format_width / HSCROLL_FRACTION; |
| 3135 | do { |
| 3136 | es->x_offset--; |
Alexandre Julliard | 9d61596 | 2003-09-17 04:28:28 +0000 | [diff] [blame] | 3137 | x = (short)LOWORD(EDIT_EM_PosFromChar(es, es->selection_end, FALSE)); |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 3138 | } while ((x < goal) && es->x_offset); |
| 3139 | /* FIXME: use ScrollWindow() somehow to improve performance */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3140 | EDIT_UpdateText(es, NULL, TRUE); |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 3141 | } else if (x > es->format_rect.right) { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 3142 | INT x_last; |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3143 | INT len = strlenW(es->text); |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 3144 | goal = es->format_rect.right - format_width / HSCROLL_FRACTION; |
| 3145 | do { |
| 3146 | es->x_offset++; |
Alexandre Julliard | 9d61596 | 2003-09-17 04:28:28 +0000 | [diff] [blame] | 3147 | x = (short)LOWORD(EDIT_EM_PosFromChar(es, es->selection_end, FALSE)); |
| 3148 | x_last = (short)LOWORD(EDIT_EM_PosFromChar(es, len, FALSE)); |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 3149 | } while ((x > goal) && (x_last > es->format_rect.right)); |
| 3150 | /* FIXME: use ScrollWindow() somehow to improve performance */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3151 | EDIT_UpdateText(es, NULL, TRUE); |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 3152 | } |
| 3153 | } |
Dmitry Timoshkov | 11dbda6 | 2001-01-05 03:40:35 +0000 | [diff] [blame] | 3154 | |
| 3155 | if(es->flags & EF_FOCUSED) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3156 | EDIT_SetCaretPos(es, es->selection_end, es->flags & EF_AFTER_WRAP); |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 3157 | } |
| 3158 | |
| 3159 | |
| 3160 | /********************************************************************* |
| 3161 | * |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3162 | * EM_SETHANDLE |
| 3163 | * |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3164 | * FIXME: ES_LOWERCASE, ES_UPPERCASE, ES_OEMCONVERT, ES_NUMBER ??? |
| 3165 | * |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3166 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3167 | static void EDIT_EM_SetHandle(EDITSTATE *es, HLOCAL hloc) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3168 | { |
Robert Shearman | 2e9436c | 2004-08-17 22:29:29 +0000 | [diff] [blame] | 3169 | HINSTANCE16 hInstance = GetWindowLongPtrW( es->hwndSelf, GWLP_HINSTANCE ); |
Alexandre Julliard | de42428 | 2001-08-10 22:51:42 +0000 | [diff] [blame] | 3170 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3171 | if (!(es->style & ES_MULTILINE)) |
| 3172 | return; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3173 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3174 | if (!hloc) { |
Dimitrie O. Paun | dd03cc1 | 1999-12-08 03:56:23 +0000 | [diff] [blame] | 3175 | WARN("called with NULL handle\n"); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3176 | return; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3177 | } |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3178 | |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3179 | EDIT_UnlockBuffer(es, TRUE); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3180 | |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3181 | if(es->hloc16) |
| 3182 | { |
Alexandre Julliard | de42428 | 2001-08-10 22:51:42 +0000 | [diff] [blame] | 3183 | LOCAL_Free(hInstance, es->hloc16); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3184 | es->hloc16 = (HLOCAL16)NULL; |
| 3185 | } |
| 3186 | |
| 3187 | if(es->is_unicode) |
| 3188 | { |
| 3189 | if(es->hloc32A) |
| 3190 | { |
| 3191 | LocalFree(es->hloc32A); |
Francois Gouget | d2667a4 | 2002-12-02 18:10:57 +0000 | [diff] [blame] | 3192 | es->hloc32A = NULL; |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3193 | } |
| 3194 | es->hloc32W = hloc; |
| 3195 | } |
| 3196 | else |
| 3197 | { |
| 3198 | INT countW, countA; |
| 3199 | HLOCAL hloc32W_new; |
| 3200 | WCHAR *textW; |
| 3201 | CHAR *textA; |
| 3202 | |
| 3203 | countA = LocalSize(hloc); |
| 3204 | textA = LocalLock(hloc); |
| 3205 | countW = MultiByteToWideChar(CP_ACP, 0, textA, countA, NULL, 0); |
| 3206 | if(!(hloc32W_new = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT, countW * sizeof(WCHAR)))) |
| 3207 | { |
| 3208 | ERR("Could not allocate new unicode buffer\n"); |
| 3209 | return; |
| 3210 | } |
| 3211 | textW = LocalLock(hloc32W_new); |
| 3212 | MultiByteToWideChar(CP_ACP, 0, textA, countA, textW, countW); |
| 3213 | LocalUnlock(hloc32W_new); |
| 3214 | LocalUnlock(hloc); |
| 3215 | |
| 3216 | if(es->hloc32W) |
| 3217 | LocalFree(es->hloc32W); |
| 3218 | |
| 3219 | es->hloc32W = hloc32W_new; |
| 3220 | es->hloc32A = hloc; |
| 3221 | } |
| 3222 | |
| 3223 | es->buffer_size = LocalSize(es->hloc32W)/sizeof(WCHAR) - 1; |
| 3224 | |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3225 | EDIT_LockBuffer(es); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3226 | |
| 3227 | es->x_offset = es->y_offset = 0; |
| 3228 | es->selection_start = es->selection_end = 0; |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 3229 | EDIT_EM_EmptyUndoBuffer(es); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3230 | es->flags &= ~EF_MODIFIED; |
| 3231 | es->flags &= ~EF_UPDATE; |
Francois Gouget | d2667a4 | 2002-12-02 18:10:57 +0000 | [diff] [blame] | 3232 | EDIT_BuildLineDefs_ML(es, 0, strlenW(es->text), 0, NULL); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3233 | EDIT_UpdateText(es, NULL, TRUE); |
| 3234 | EDIT_EM_ScrollCaret(es); |
Dmitry Timoshkov | a234db8 | 2001-01-19 20:49:54 +0000 | [diff] [blame] | 3235 | /* force scroll info update */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3236 | EDIT_UpdateScrollInfo(es); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 3237 | } |
| 3238 | |
| 3239 | |
| 3240 | /********************************************************************* |
| 3241 | * |
| 3242 | * EM_SETHANDLE16 |
| 3243 | * |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3244 | * FIXME: ES_LOWERCASE, ES_UPPERCASE, ES_OEMCONVERT, ES_NUMBER ??? |
| 3245 | * |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 3246 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3247 | static void EDIT_EM_SetHandle16(EDITSTATE *es, HLOCAL16 hloc) |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 3248 | { |
Robert Shearman | 2e9436c | 2004-08-17 22:29:29 +0000 | [diff] [blame] | 3249 | HINSTANCE16 hInstance = GetWindowLongPtrW( es->hwndSelf, GWLP_HINSTANCE ); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3250 | INT countW, countA; |
| 3251 | HLOCAL hloc32W_new; |
| 3252 | WCHAR *textW; |
| 3253 | CHAR *textA; |
| 3254 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3255 | if (!(es->style & ES_MULTILINE)) |
| 3256 | return; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 3257 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3258 | if (!hloc) { |
Dimitrie O. Paun | dd03cc1 | 1999-12-08 03:56:23 +0000 | [diff] [blame] | 3259 | WARN("called with NULL handle\n"); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3260 | return; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 3261 | } |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3262 | |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3263 | EDIT_UnlockBuffer(es, TRUE); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3264 | |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3265 | if(es->hloc32A) |
| 3266 | { |
| 3267 | LocalFree(es->hloc32A); |
Francois Gouget | d2667a4 | 2002-12-02 18:10:57 +0000 | [diff] [blame] | 3268 | es->hloc32A = NULL; |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3269 | } |
| 3270 | |
Alexandre Julliard | de42428 | 2001-08-10 22:51:42 +0000 | [diff] [blame] | 3271 | countA = LOCAL_Size(hInstance, hloc); |
| 3272 | textA = LOCAL_Lock(hInstance, hloc); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3273 | countW = MultiByteToWideChar(CP_ACP, 0, textA, countA, NULL, 0); |
| 3274 | if(!(hloc32W_new = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT, countW * sizeof(WCHAR)))) |
| 3275 | { |
| 3276 | ERR("Could not allocate new unicode buffer\n"); |
| 3277 | return; |
| 3278 | } |
| 3279 | textW = LocalLock(hloc32W_new); |
| 3280 | MultiByteToWideChar(CP_ACP, 0, textA, countA, textW, countW); |
| 3281 | LocalUnlock(hloc32W_new); |
Alexandre Julliard | de42428 | 2001-08-10 22:51:42 +0000 | [diff] [blame] | 3282 | LOCAL_Unlock(hInstance, hloc); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3283 | |
| 3284 | if(es->hloc32W) |
| 3285 | LocalFree(es->hloc32W); |
| 3286 | |
| 3287 | es->hloc32W = hloc32W_new; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3288 | es->hloc16 = hloc; |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3289 | |
| 3290 | es->buffer_size = LocalSize(es->hloc32W)/sizeof(WCHAR) - 1; |
| 3291 | |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3292 | EDIT_LockBuffer(es); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3293 | |
| 3294 | es->x_offset = es->y_offset = 0; |
| 3295 | es->selection_start = es->selection_end = 0; |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 3296 | EDIT_EM_EmptyUndoBuffer(es); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3297 | es->flags &= ~EF_MODIFIED; |
| 3298 | es->flags &= ~EF_UPDATE; |
Francois Gouget | d2667a4 | 2002-12-02 18:10:57 +0000 | [diff] [blame] | 3299 | EDIT_BuildLineDefs_ML(es, 0, strlenW(es->text), 0, NULL); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3300 | EDIT_UpdateText(es, NULL, TRUE); |
| 3301 | EDIT_EM_ScrollCaret(es); |
Dmitry Timoshkov | a234db8 | 2001-01-19 20:49:54 +0000 | [diff] [blame] | 3302 | /* force scroll info update */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3303 | EDIT_UpdateScrollInfo(es); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 3304 | } |
| 3305 | |
| 3306 | |
| 3307 | /********************************************************************* |
| 3308 | * |
| 3309 | * EM_SETLIMITTEXT |
| 3310 | * |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 3311 | * FIXME: in WinNT maxsize is 0x7FFFFFFF / 0xFFFFFFFF |
| 3312 | * However, the windows version is not complied to yet in all of edit.c |
| 3313 | * |
Aric Stewart | 08e6939 | 2002-08-16 01:41:32 +0000 | [diff] [blame] | 3314 | * Additionally as the wrapper for RichEdit controls we need larger buffers |
| 3315 | * at present -1 will represent nolimit |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 3316 | */ |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 3317 | static void EDIT_EM_SetLimitText(EDITSTATE *es, INT limit) |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 3318 | { |
Aric Stewart | 08e6939 | 2002-08-16 01:41:32 +0000 | [diff] [blame] | 3319 | if (limit == 0xFFFFFFFF) |
| 3320 | es->buffer_limit = -1; |
| 3321 | else if (es->style & ES_MULTILINE) { |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3322 | if (limit) |
Francois Gouget | 6d77d3a | 2000-03-25 21:44:35 +0000 | [diff] [blame] | 3323 | es->buffer_limit = min(limit, BUFLIMIT_MULTI); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 3324 | else |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3325 | es->buffer_limit = BUFLIMIT_MULTI; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 3326 | } else { |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3327 | if (limit) |
Francois Gouget | 6d77d3a | 2000-03-25 21:44:35 +0000 | [diff] [blame] | 3328 | es->buffer_limit = min(limit, BUFLIMIT_SINGLE); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 3329 | else |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3330 | es->buffer_limit = BUFLIMIT_SINGLE; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 3331 | } |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 3332 | } |
| 3333 | |
| 3334 | |
| 3335 | /********************************************************************* |
| 3336 | * |
| 3337 | * EM_SETMARGINS |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 3338 | * |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 3339 | * EC_USEFONTINFO is used as a left or right value i.e. lParam and not as an |
Achim Kaiser | 6d3ce41 | 2003-05-06 18:23:17 +0000 | [diff] [blame] | 3340 | * action wParam despite what the docs say. EC_USEFONTINFO calculates the |
| 3341 | * margin according to the textmetrics of the current font. |
| 3342 | * |
| 3343 | * FIXME - With TrueType or vector fonts EC_USEFONTINFO currently sets one third |
| 3344 | * of the char's width as the margin, but this is not how Windows handles this. |
| 3345 | * For all other fonts Windows sets the margins to zero. |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 3346 | * |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 3347 | */ |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 3348 | static void EDIT_EM_SetMargins(EDITSTATE *es, INT action, |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 3349 | INT left, INT right) |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 3350 | { |
Achim Kaiser | 6d3ce41 | 2003-05-06 18:23:17 +0000 | [diff] [blame] | 3351 | TEXTMETRICW tm; |
| 3352 | INT default_left_margin = 0; /* in pixels */ |
| 3353 | INT default_right_margin = 0; /* in pixels */ |
| 3354 | |
| 3355 | /* Set the default margins depending on the font */ |
| 3356 | if (es->font && (left == EC_USEFONTINFO || right == EC_USEFONTINFO)) { |
| 3357 | HDC dc = GetDC(es->hwndSelf); |
| 3358 | HFONT old_font = SelectObject(dc, es->font); |
| 3359 | GetTextMetricsW(dc, &tm); |
| 3360 | /* The default margins are only non zero for TrueType or Vector fonts */ |
| 3361 | if (tm.tmPitchAndFamily & ( TMPF_VECTOR | TMPF_TRUETYPE )) { |
| 3362 | /* This must be calculated more exactly! But how? */ |
| 3363 | default_left_margin = tm.tmAveCharWidth / 3; |
| 3364 | default_right_margin = tm.tmAveCharWidth / 3; |
| 3365 | } |
| 3366 | SelectObject(dc, old_font); |
| 3367 | ReleaseDC(es->hwndSelf, dc); |
| 3368 | } |
| 3369 | |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 3370 | if (action & EC_LEFTMARGIN) { |
| 3371 | if (left != EC_USEFONTINFO) |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3372 | es->left_margin = left; |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 3373 | else |
Achim Kaiser | 6d3ce41 | 2003-05-06 18:23:17 +0000 | [diff] [blame] | 3374 | es->left_margin = default_left_margin; |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 3375 | } |
| 3376 | |
| 3377 | if (action & EC_RIGHTMARGIN) { |
| 3378 | if (right != EC_USEFONTINFO) |
| 3379 | es->right_margin = right; |
| 3380 | else |
Achim Kaiser | 6d3ce41 | 2003-05-06 18:23:17 +0000 | [diff] [blame] | 3381 | es->right_margin = default_right_margin; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 3382 | } |
Dimitrie O. Paun | dd03cc1 | 1999-12-08 03:56:23 +0000 | [diff] [blame] | 3383 | TRACE("left=%d, right=%d\n", es->left_margin, es->right_margin); |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 3384 | } |
| 3385 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3386 | |
| 3387 | /********************************************************************* |
| 3388 | * |
| 3389 | * EM_SETPASSWORDCHAR |
| 3390 | * |
| 3391 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3392 | static void EDIT_EM_SetPasswordChar(EDITSTATE *es, WCHAR c) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3393 | { |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3394 | LONG style; |
Alexandre Julliard | de42428 | 2001-08-10 22:51:42 +0000 | [diff] [blame] | 3395 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3396 | if (es->style & ES_MULTILINE) |
| 3397 | return; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3398 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3399 | if (es->password_char == c) |
| 3400 | return; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3401 | |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3402 | style = GetWindowLongW( es->hwndSelf, GWL_STYLE ); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3403 | es->password_char = c; |
| 3404 | if (c) { |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3405 | SetWindowLongW( es->hwndSelf, GWL_STYLE, style | ES_PASSWORD ); |
Alexandre Julliard | de42428 | 2001-08-10 22:51:42 +0000 | [diff] [blame] | 3406 | es->style |= ES_PASSWORD; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3407 | } else { |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3408 | SetWindowLongW( es->hwndSelf, GWL_STYLE, style & ~ES_PASSWORD ); |
Alexandre Julliard | de42428 | 2001-08-10 22:51:42 +0000 | [diff] [blame] | 3409 | es->style &= ~ES_PASSWORD; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3410 | } |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3411 | EDIT_UpdateText(es, NULL, TRUE); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 3412 | } |
| 3413 | |
| 3414 | |
| 3415 | /********************************************************************* |
| 3416 | * |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3417 | * EDIT_EM_SetSel |
| 3418 | * |
| 3419 | * note: unlike the specs say: the order of start and end |
| 3420 | * _is_ preserved in Windows. (i.e. start can be > end) |
| 3421 | * In other words: this handler is OK |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 3422 | * |
| 3423 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3424 | static void EDIT_EM_SetSel(EDITSTATE *es, UINT start, UINT end, BOOL after_wrap) |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 3425 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 3426 | UINT old_start = es->selection_start; |
| 3427 | UINT old_end = es->selection_end; |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3428 | UINT len = strlenW(es->text); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 3429 | |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 3430 | if (start == (UINT)-1) { |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3431 | start = es->selection_end; |
| 3432 | end = es->selection_end; |
| 3433 | } else { |
Francois Gouget | 6d77d3a | 2000-03-25 21:44:35 +0000 | [diff] [blame] | 3434 | start = min(start, len); |
| 3435 | end = min(end, len); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3436 | } |
| 3437 | es->selection_start = start; |
| 3438 | es->selection_end = end; |
| 3439 | if (after_wrap) |
| 3440 | es->flags |= EF_AFTER_WRAP; |
| 3441 | else |
| 3442 | es->flags &= ~EF_AFTER_WRAP; |
Andreas Mohr | a8edb3e | 2000-05-23 04:05:05 +0000 | [diff] [blame] | 3443 | /* This is a little bit more efficient than before, not sure if it can be improved. FIXME? */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 3444 | ORDER_UINT(start, end); |
| 3445 | ORDER_UINT(end, old_end); |
| 3446 | ORDER_UINT(start, old_start); |
| 3447 | ORDER_UINT(old_start, old_end); |
Alexandre Julliard | e658d82 | 1997-11-30 17:45:40 +0000 | [diff] [blame] | 3448 | if (end != old_start) |
| 3449 | { |
| 3450 | /* |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 3451 | * One can also do |
Alexandre Julliard | e658d82 | 1997-11-30 17:45:40 +0000 | [diff] [blame] | 3452 | * ORDER_UINT32(end, old_start); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3453 | * EDIT_InvalidateText(es, start, end); |
| 3454 | * EDIT_InvalidateText(es, old_start, old_end); |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 3455 | * in place of the following if statement. |
Alexandre Julliard | e658d82 | 1997-11-30 17:45:40 +0000 | [diff] [blame] | 3456 | */ |
| 3457 | if (old_start > end ) |
| 3458 | { |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3459 | EDIT_InvalidateText(es, start, end); |
| 3460 | EDIT_InvalidateText(es, old_start, old_end); |
Alexandre Julliard | e658d82 | 1997-11-30 17:45:40 +0000 | [diff] [blame] | 3461 | } |
| 3462 | else |
| 3463 | { |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3464 | EDIT_InvalidateText(es, start, old_start); |
| 3465 | EDIT_InvalidateText(es, end, old_end); |
Alexandre Julliard | e658d82 | 1997-11-30 17:45:40 +0000 | [diff] [blame] | 3466 | } |
| 3467 | } |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3468 | else EDIT_InvalidateText(es, start, old_end); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3469 | } |
| 3470 | |
| 3471 | |
| 3472 | /********************************************************************* |
| 3473 | * |
| 3474 | * EM_SETTABSTOPS |
| 3475 | * |
| 3476 | */ |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 3477 | static BOOL EDIT_EM_SetTabStops(EDITSTATE *es, INT count, LPINT tabs) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3478 | { |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3479 | if (!(es->style & ES_MULTILINE)) |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 3480 | return FALSE; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3481 | if (es->tabs) |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3482 | HeapFree(GetProcessHeap(), 0, es->tabs); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3483 | es->tabs_count = count; |
| 3484 | if (!count) |
| 3485 | es->tabs = NULL; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 3486 | else { |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3487 | es->tabs = HeapAlloc(GetProcessHeap(), 0, count * sizeof(INT)); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 3488 | memcpy(es->tabs, tabs, count * sizeof(INT)); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 3489 | } |
| 3490 | return TRUE; |
| 3491 | } |
| 3492 | |
| 3493 | |
| 3494 | /********************************************************************* |
| 3495 | * |
| 3496 | * EM_SETTABSTOPS16 |
| 3497 | * |
| 3498 | */ |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 3499 | static BOOL EDIT_EM_SetTabStops16(EDITSTATE *es, INT count, LPINT16 tabs) |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 3500 | { |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3501 | if (!(es->style & ES_MULTILINE)) |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 3502 | return FALSE; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3503 | if (es->tabs) |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3504 | HeapFree(GetProcessHeap(), 0, es->tabs); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3505 | es->tabs_count = count; |
| 3506 | if (!count) |
| 3507 | es->tabs = NULL; |
| 3508 | else { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 3509 | INT i; |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3510 | es->tabs = HeapAlloc(GetProcessHeap(), 0, count * sizeof(INT)); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3511 | for (i = 0 ; i < count ; i++) |
| 3512 | es->tabs[i] = *tabs++; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3513 | } |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 3514 | return TRUE; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3515 | } |
| 3516 | |
| 3517 | |
| 3518 | /********************************************************************* |
| 3519 | * |
| 3520 | * EM_SETWORDBREAKPROC |
| 3521 | * |
| 3522 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3523 | static void EDIT_EM_SetWordBreakProc(EDITSTATE *es, LPARAM lParam) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3524 | { |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3525 | if (es->word_break_proc == (void *)lParam) |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3526 | return; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3527 | |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3528 | es->word_break_proc = (void *)lParam; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3529 | es->word_break_proc16 = NULL; |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3530 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3531 | if ((es->style & ES_MULTILINE) && !(es->style & ES_AUTOHSCROLL)) { |
Francois Gouget | d2667a4 | 2002-12-02 18:10:57 +0000 | [diff] [blame] | 3532 | EDIT_BuildLineDefs_ML(es, 0, strlenW(es->text), 0, NULL); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3533 | EDIT_UpdateText(es, NULL, TRUE); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3534 | } |
| 3535 | } |
| 3536 | |
| 3537 | |
| 3538 | /********************************************************************* |
| 3539 | * |
| 3540 | * EM_SETWORDBREAKPROC16 |
| 3541 | * |
| 3542 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3543 | static void EDIT_EM_SetWordBreakProc16(EDITSTATE *es, EDITWORDBREAKPROC16 wbp) |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3544 | { |
| 3545 | if (es->word_break_proc16 == wbp) |
| 3546 | return; |
| 3547 | |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3548 | es->word_break_proc = NULL; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3549 | es->word_break_proc16 = wbp; |
| 3550 | if ((es->style & ES_MULTILINE) && !(es->style & ES_AUTOHSCROLL)) { |
Francois Gouget | d2667a4 | 2002-12-02 18:10:57 +0000 | [diff] [blame] | 3551 | EDIT_BuildLineDefs_ML(es, 0, strlenW(es->text), 0, NULL); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3552 | EDIT_UpdateText(es, NULL, TRUE); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3553 | } |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3554 | } |
| 3555 | |
| 3556 | |
| 3557 | /********************************************************************* |
| 3558 | * |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 3559 | * EM_UNDO / WM_UNDO |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3560 | * |
| 3561 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3562 | static BOOL EDIT_EM_Undo(EDITSTATE *es) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3563 | { |
Dmitry Timoshkov | 9c446a1 | 2001-01-22 19:28:27 +0000 | [diff] [blame] | 3564 | INT ulength; |
| 3565 | LPWSTR utext; |
| 3566 | |
Krishna Murthy | a7c3107 | 2004-05-07 00:40:18 +0000 | [diff] [blame] | 3567 | /* As per MSDN spec, for a single-line edit control, |
| 3568 | the return value is always TRUE */ |
| 3569 | if( es->style & ES_READONLY ) |
| 3570 | return !(es->style & ES_MULTILINE); |
Dmitry Timoshkov | 9c446a1 | 2001-01-22 19:28:27 +0000 | [diff] [blame] | 3571 | |
| 3572 | ulength = strlenW(es->undo_text); |
Krishna Murthy | a7c3107 | 2004-05-07 00:40:18 +0000 | [diff] [blame] | 3573 | |
Dmitry Timoshkov | 9c446a1 | 2001-01-22 19:28:27 +0000 | [diff] [blame] | 3574 | utext = HeapAlloc(GetProcessHeap(), 0, (ulength + 1) * sizeof(WCHAR)); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3575 | |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3576 | strcpyW(utext, es->undo_text); |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 3577 | |
Dimitrie O. Paun | dd03cc1 | 1999-12-08 03:56:23 +0000 | [diff] [blame] | 3578 | TRACE("before UNDO:insertion length = %d, deletion buffer = %s\n", |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3579 | es->undo_insert_count, debugstr_w(utext)); |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 3580 | |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3581 | EDIT_EM_SetSel(es, es->undo_position, es->undo_position + es->undo_insert_count, FALSE); |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 3582 | EDIT_EM_EmptyUndoBuffer(es); |
Krishna Murthy | ca8e313 | 2004-06-18 22:29:05 +0000 | [diff] [blame] | 3583 | EDIT_EM_ReplaceSel(es, TRUE, utext, TRUE, TRUE); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3584 | EDIT_EM_SetSel(es, es->undo_position, es->undo_position + es->undo_insert_count, FALSE); |
Rein Klazes | 9d4ae0e | 2001-04-02 19:13:24 +0000 | [diff] [blame] | 3585 | /* send the notification after the selection start and end are set */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3586 | EDIT_NOTIFY_PARENT(es, EN_CHANGE, "EN_CHANGE"); |
| 3587 | EDIT_EM_ScrollCaret(es); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3588 | HeapFree(GetProcessHeap(), 0, utext); |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 3589 | |
Dimitrie O. Paun | dd03cc1 | 1999-12-08 03:56:23 +0000 | [diff] [blame] | 3590 | TRACE("after UNDO:insertion length = %d, deletion buffer = %s\n", |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3591 | es->undo_insert_count, debugstr_w(es->undo_text)); |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 3592 | return TRUE; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3593 | } |
| 3594 | |
| 3595 | |
| 3596 | /********************************************************************* |
| 3597 | * |
| 3598 | * WM_CHAR |
| 3599 | * |
| 3600 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3601 | static void EDIT_WM_Char(EDITSTATE *es, WCHAR c) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3602 | { |
Dmitry Timoshkov | 9c446a1 | 2001-01-22 19:28:27 +0000 | [diff] [blame] | 3603 | BOOL control; |
| 3604 | |
| 3605 | /* Protect read-only edit control from modification */ |
| 3606 | if(es->style & ES_READONLY) |
| 3607 | return; |
| 3608 | |
| 3609 | control = GetKeyState(VK_CONTROL) & 0x8000; |
| 3610 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3611 | switch (c) { |
| 3612 | case '\r': |
Stephane Lussier | 5ca2ec4 | 1999-09-27 11:45:07 +0000 | [diff] [blame] | 3613 | /* If the edit doesn't want the return and it's not a multiline edit, do nothing */ |
| 3614 | if(!(es->style & ES_MULTILINE) && !(es->style & ES_WANTRETURN)) |
Pascal Lessard | aed79e5 | 1999-09-10 13:58:34 +0000 | [diff] [blame] | 3615 | break; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3616 | case '\n': |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3617 | if (es->style & ES_MULTILINE) { |
| 3618 | if (es->style & ES_READONLY) { |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3619 | EDIT_MoveHome(es, FALSE); |
| 3620 | EDIT_MoveDown_ML(es, FALSE); |
Alexandre Julliard | fa2c793 | 2000-05-26 01:24:56 +0000 | [diff] [blame] | 3621 | } else { |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3622 | static const WCHAR cr_lfW[] = {'\r','\n',0}; |
Carl Sopchak | 23b88ef | 2002-11-21 03:57:05 +0000 | [diff] [blame] | 3623 | EDIT_EM_ReplaceSel(es, TRUE, cr_lfW, TRUE, TRUE); |
Alexandre Julliard | fa2c793 | 2000-05-26 01:24:56 +0000 | [diff] [blame] | 3624 | } |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3625 | } |
| 3626 | break; |
| 3627 | case '\t': |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3628 | if ((es->style & ES_MULTILINE) && !(es->style & ES_READONLY)) |
Alexandre Julliard | fa2c793 | 2000-05-26 01:24:56 +0000 | [diff] [blame] | 3629 | { |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3630 | static const WCHAR tabW[] = {'\t',0}; |
Carl Sopchak | 23b88ef | 2002-11-21 03:57:05 +0000 | [diff] [blame] | 3631 | EDIT_EM_ReplaceSel(es, TRUE, tabW, TRUE, TRUE); |
Alexandre Julliard | fa2c793 | 2000-05-26 01:24:56 +0000 | [diff] [blame] | 3632 | } |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3633 | break; |
Pascal Lessard | 6fe38e5 | 1999-09-03 15:02:48 +0000 | [diff] [blame] | 3634 | case VK_BACK: |
| 3635 | if (!(es->style & ES_READONLY) && !control) { |
| 3636 | if (es->selection_start != es->selection_end) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3637 | EDIT_WM_Clear(es); |
Pascal Lessard | 6fe38e5 | 1999-09-03 15:02:48 +0000 | [diff] [blame] | 3638 | else { |
| 3639 | /* delete character left of caret */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3640 | EDIT_EM_SetSel(es, (UINT)-1, 0, FALSE); |
| 3641 | EDIT_MoveBackward(es, TRUE); |
| 3642 | EDIT_WM_Clear(es); |
Pascal Lessard | 6fe38e5 | 1999-09-03 15:02:48 +0000 | [diff] [blame] | 3643 | } |
| 3644 | } |
| 3645 | break; |
Ulrich Czekalla | c804e3e | 2000-05-23 21:16:07 +0000 | [diff] [blame] | 3646 | case 0x03: /* ^C */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3647 | SendMessageW(es->hwndSelf, WM_COPY, 0, 0); |
Susan Farley | 86d0b03 | 2000-05-05 18:21:02 +0000 | [diff] [blame] | 3648 | break; |
Ulrich Czekalla | c804e3e | 2000-05-23 21:16:07 +0000 | [diff] [blame] | 3649 | case 0x16: /* ^V */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3650 | SendMessageW(es->hwndSelf, WM_PASTE, 0, 0); |
Susan Farley | 86d0b03 | 2000-05-05 18:21:02 +0000 | [diff] [blame] | 3651 | break; |
Ulrich Czekalla | c804e3e | 2000-05-23 21:16:07 +0000 | [diff] [blame] | 3652 | case 0x18: /* ^X */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3653 | SendMessageW(es->hwndSelf, WM_CUT, 0, 0); |
Susan Farley | 86d0b03 | 2000-05-05 18:21:02 +0000 | [diff] [blame] | 3654 | break; |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 3655 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3656 | default: |
Krishna Murthy | fd43a46 | 2004-07-24 02:26:24 +0000 | [diff] [blame] | 3657 | /*If Edit control style is ES_NUMBER allow users to key in only numeric values*/ |
| 3658 | if( (es->style & ES_NUMBER) && !( c >= '0' && c <= '9') ) |
| 3659 | break; |
| 3660 | |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3661 | if (!(es->style & ES_READONLY) && (c >= ' ') && (c != 127)) { |
| 3662 | WCHAR str[2]; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3663 | str[0] = c; |
| 3664 | str[1] = '\0'; |
Carl Sopchak | 23b88ef | 2002-11-21 03:57:05 +0000 | [diff] [blame] | 3665 | EDIT_EM_ReplaceSel(es, TRUE, str, TRUE, TRUE); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3666 | } |
| 3667 | break; |
| 3668 | } |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 3669 | } |
| 3670 | |
| 3671 | |
| 3672 | /********************************************************************* |
| 3673 | * |
| 3674 | * WM_COMMAND |
| 3675 | * |
| 3676 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3677 | static void EDIT_WM_Command(EDITSTATE *es, INT code, INT id, HWND control) |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 3678 | { |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3679 | if (code || control) |
| 3680 | return; |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 3681 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3682 | switch (id) { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 3683 | case EM_UNDO: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3684 | EDIT_EM_Undo(es); |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 3685 | break; |
| 3686 | case WM_CUT: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3687 | EDIT_WM_Cut(es); |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 3688 | break; |
| 3689 | case WM_COPY: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3690 | EDIT_WM_Copy(es); |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 3691 | break; |
| 3692 | case WM_PASTE: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3693 | EDIT_WM_Paste(es); |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 3694 | break; |
| 3695 | case WM_CLEAR: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3696 | EDIT_WM_Clear(es); |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 3697 | break; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 3698 | case EM_SETSEL: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3699 | EDIT_EM_SetSel(es, 0, (UINT)-1, FALSE); |
| 3700 | EDIT_EM_ScrollCaret(es); |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 3701 | break; |
| 3702 | default: |
Dimitrie O. Paun | dd03cc1 | 1999-12-08 03:56:23 +0000 | [diff] [blame] | 3703 | ERR("unknown menu item, please report\n"); |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 3704 | break; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3705 | } |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 3706 | } |
| 3707 | |
| 3708 | |
| 3709 | /********************************************************************* |
| 3710 | * |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 3711 | * WM_CONTEXTMENU |
| 3712 | * |
| 3713 | * Note: the resource files resource/sysres_??.rc cannot define a |
| 3714 | * single popup menu. Hence we use a (dummy) menubar |
| 3715 | * containing the single popup menu as its first item. |
| 3716 | * |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 3717 | * FIXME: the message identifiers have been chosen arbitrarily, |
| 3718 | * hence we use MF_BYPOSITION. |
| 3719 | * We might as well use the "real" values (anybody knows ?) |
| 3720 | * The menu definition is in resources/sysres_??.rc. |
| 3721 | * Once these are OK, we better use MF_BYCOMMAND here |
| 3722 | * (as we do in EDIT_WM_Command()). |
| 3723 | * |
| 3724 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3725 | static void EDIT_WM_ContextMenu(EDITSTATE *es, INT x, INT y) |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 3726 | { |
Alexandre Julliard | a2e2e18 | 2004-02-12 00:35:01 +0000 | [diff] [blame] | 3727 | HMENU menu = LoadMenuA(user32_module, "EDITMENU"); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 3728 | HMENU popup = GetSubMenu(menu, 0); |
| 3729 | UINT start = es->selection_start; |
| 3730 | UINT end = es->selection_end; |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 3731 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 3732 | ORDER_UINT(start, end); |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 3733 | |
| 3734 | /* undo */ |
Dmitry Timoshkov | 9c446a1 | 2001-01-22 19:28:27 +0000 | [diff] [blame] | 3735 | EnableMenuItem(popup, 0, MF_BYPOSITION | (EDIT_EM_CanUndo(es) && !(es->style & ES_READONLY) ? MF_ENABLED : MF_GRAYED)); |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 3736 | /* cut */ |
Dmitry Timoshkov | 9c446a1 | 2001-01-22 19:28:27 +0000 | [diff] [blame] | 3737 | EnableMenuItem(popup, 2, MF_BYPOSITION | ((end - start) && !(es->style & ES_PASSWORD) && !(es->style & ES_READONLY) ? MF_ENABLED : MF_GRAYED)); |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 3738 | /* copy */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 3739 | EnableMenuItem(popup, 3, MF_BYPOSITION | ((end - start) && !(es->style & ES_PASSWORD) ? MF_ENABLED : MF_GRAYED)); |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 3740 | /* paste */ |
Dmitry Timoshkov | 9c446a1 | 2001-01-22 19:28:27 +0000 | [diff] [blame] | 3741 | EnableMenuItem(popup, 4, MF_BYPOSITION | (IsClipboardFormatAvailable(CF_UNICODETEXT) && !(es->style & ES_READONLY) ? MF_ENABLED : MF_GRAYED)); |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 3742 | /* delete */ |
Dmitry Timoshkov | 9c446a1 | 2001-01-22 19:28:27 +0000 | [diff] [blame] | 3743 | EnableMenuItem(popup, 5, MF_BYPOSITION | ((end - start) && !(es->style & ES_READONLY) ? MF_ENABLED : MF_GRAYED)); |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 3744 | /* select all */ |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3745 | EnableMenuItem(popup, 7, MF_BYPOSITION | (start || (end != strlenW(es->text)) ? MF_ENABLED : MF_GRAYED)); |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 3746 | |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3747 | TrackPopupMenu(popup, TPM_LEFTALIGN | TPM_RIGHTBUTTON, x, y, 0, es->hwndSelf, NULL); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 3748 | DestroyMenu(menu); |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 3749 | } |
| 3750 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3751 | |
Alexandre Julliard | df2673b | 1997-03-29 17:20:20 +0000 | [diff] [blame] | 3752 | /********************************************************************* |
| 3753 | * |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3754 | * WM_COPY |
| 3755 | * |
Alexandre Julliard | df2673b | 1997-03-29 17:20:20 +0000 | [diff] [blame] | 3756 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3757 | static void EDIT_WM_Copy(EDITSTATE *es) |
Alexandre Julliard | df2673b | 1997-03-29 17:20:20 +0000 | [diff] [blame] | 3758 | { |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3759 | INT s = min(es->selection_start, es->selection_end); |
| 3760 | INT e = max(es->selection_start, es->selection_end); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 3761 | HGLOBAL hdst; |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3762 | LPWSTR dst; |
Alexandre Julliard | df2673b | 1997-03-29 17:20:20 +0000 | [diff] [blame] | 3763 | |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3764 | if (e == s) return; |
| 3765 | |
Dmitry Timoshkov | f8b96e2 | 2000-12-20 18:39:14 +0000 | [diff] [blame] | 3766 | hdst = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, (DWORD)(e - s + 1) * sizeof(WCHAR)); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 3767 | dst = GlobalLock(hdst); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3768 | strncpyW(dst, es->text + s, e - s); |
Dmitry Timoshkov | f8b96e2 | 2000-12-20 18:39:14 +0000 | [diff] [blame] | 3769 | dst[e - s] = 0; /* ensure 0 termination */ |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3770 | TRACE("%s\n", debugstr_w(dst)); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 3771 | GlobalUnlock(hdst); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3772 | OpenClipboard(es->hwndSelf); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 3773 | EmptyClipboard(); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3774 | SetClipboardData(CF_UNICODETEXT, hdst); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 3775 | CloseClipboard(); |
Alexandre Julliard | df2673b | 1997-03-29 17:20:20 +0000 | [diff] [blame] | 3776 | } |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 3777 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3778 | |
| 3779 | /********************************************************************* |
| 3780 | * |
| 3781 | * WM_CREATE |
| 3782 | * |
| 3783 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3784 | static LRESULT EDIT_WM_Create(EDITSTATE *es, LPCWSTR name) |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3785 | { |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3786 | TRACE("%s\n", debugstr_w(name)); |
Pascal Lessard | dde4d61 | 1999-08-15 16:30:11 +0000 | [diff] [blame] | 3787 | /* |
| 3788 | * To initialize some final structure members, we call some helper |
| 3789 | * functions. However, since the EDITSTATE is not consistent (i.e. |
| 3790 | * not fully initialized), we should be very careful which |
| 3791 | * functions can be called, and in what order. |
| 3792 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3793 | EDIT_WM_SetFont(es, 0, FALSE); |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 3794 | EDIT_EM_EmptyUndoBuffer(es); |
Andreas Mohr | 5f5213a | 1999-02-13 09:04:22 +0000 | [diff] [blame] | 3795 | |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3796 | if (name && *name) { |
Carl Sopchak | 23b88ef | 2002-11-21 03:57:05 +0000 | [diff] [blame] | 3797 | EDIT_EM_ReplaceSel(es, FALSE, name, FALSE, TRUE); |
Pascal Lessard | dde4d61 | 1999-08-15 16:30:11 +0000 | [diff] [blame] | 3798 | /* if we insert text to the editline, the text scrolls out |
| 3799 | * of the window, as the caret is placed after the insert |
| 3800 | * pos normally; thus we reset es->selection... to 0 and |
| 3801 | * update caret |
| 3802 | */ |
| 3803 | es->selection_start = es->selection_end = 0; |
Aric Stewart | 2e0d8cf | 2002-08-20 00:24:17 +0000 | [diff] [blame] | 3804 | /* Adobe Photoshop does NOT like this. and MSDN says that EN_CHANGE |
| 3805 | * Messages are only to be sent when the USER does something to |
| 3806 | * change the contents. So I am removing this EN_CHANGE |
| 3807 | * |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3808 | * EDIT_NOTIFY_PARENT(es, EN_CHANGE, "EN_CHANGE"); |
Aric Stewart | 2e0d8cf | 2002-08-20 00:24:17 +0000 | [diff] [blame] | 3809 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3810 | EDIT_EM_ScrollCaret(es); |
Pascal Lessard | dde4d61 | 1999-08-15 16:30:11 +0000 | [diff] [blame] | 3811 | } |
Dmitry Timoshkov | a234db8 | 2001-01-19 20:49:54 +0000 | [diff] [blame] | 3812 | /* force scroll info update */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3813 | EDIT_UpdateScrollInfo(es); |
Rein Klazes | 0de8b21 | 2003-10-21 23:49:03 +0000 | [diff] [blame] | 3814 | /* The rule seems to return 1 here for success */ |
| 3815 | /* Power Builder masked edit controls will crash */ |
| 3816 | /* if not. */ |
| 3817 | /* FIXME: is that in all cases so ? */ |
| 3818 | return 1; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3819 | } |
| 3820 | |
| 3821 | |
| 3822 | /********************************************************************* |
| 3823 | * |
| 3824 | * WM_DESTROY |
| 3825 | * |
| 3826 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3827 | static LRESULT EDIT_WM_Destroy(EDITSTATE *es) |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3828 | { |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 3829 | LINEDEF *pc, *pp; |
| 3830 | |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3831 | if (es->hloc32W) { |
| 3832 | while (LocalUnlock(es->hloc32W)) ; |
| 3833 | LocalFree(es->hloc32W); |
| 3834 | } |
| 3835 | if (es->hloc32A) { |
| 3836 | while (LocalUnlock(es->hloc32A)) ; |
| 3837 | LocalFree(es->hloc32A); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3838 | } |
| 3839 | if (es->hloc16) { |
Robert Shearman | 2e9436c | 2004-08-17 22:29:29 +0000 | [diff] [blame] | 3840 | HINSTANCE16 hInstance = GetWindowLongPtrW( es->hwndSelf, GWLP_HINSTANCE ); |
Alexandre Julliard | de42428 | 2001-08-10 22:51:42 +0000 | [diff] [blame] | 3841 | while (LOCAL_Unlock(hInstance, es->hloc16)) ; |
| 3842 | LOCAL_Free(hInstance, es->hloc16); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3843 | } |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 3844 | |
| 3845 | pc = es->first_line_def; |
| 3846 | while (pc) |
| 3847 | { |
| 3848 | pp = pc->next; |
| 3849 | HeapFree(GetProcessHeap(), 0, pc); |
| 3850 | pc = pp; |
| 3851 | } |
| 3852 | |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3853 | SetWindowLongW( es->hwndSelf, 0, 0 ); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3854 | HeapFree(GetProcessHeap(), 0, es); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3855 | |
| 3856 | return 0; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3857 | } |
| 3858 | |
| 3859 | |
| 3860 | /********************************************************************* |
| 3861 | * |
| 3862 | * WM_ERASEBKGND |
| 3863 | * |
| 3864 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3865 | static LRESULT EDIT_WM_EraseBkGnd(EDITSTATE *es, HDC dc) |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3866 | { |
Robert Shearman | 8570328 | 2004-08-17 22:09:16 +0000 | [diff] [blame] | 3867 | /* we do the proper erase in EDIT_WM_Paint */ |
| 3868 | return -1; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3869 | } |
| 3870 | |
| 3871 | |
| 3872 | /********************************************************************* |
| 3873 | * |
| 3874 | * WM_GETTEXT |
| 3875 | * |
| 3876 | */ |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3877 | static INT EDIT_WM_GetText(EDITSTATE *es, INT count, LPARAM lParam, BOOL unicode) |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3878 | { |
Dmitry Timoshkov | f8b96e2 | 2000-12-20 18:39:14 +0000 | [diff] [blame] | 3879 | if(!count) return 0; |
| 3880 | |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3881 | if(unicode) |
| 3882 | { |
| 3883 | LPWSTR textW = (LPWSTR)lParam; |
Alexandre Julliard | 331bf3d | 2002-08-15 23:28:45 +0000 | [diff] [blame] | 3884 | lstrcpynW(textW, es->text, count); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3885 | return strlenW(textW); |
| 3886 | } |
| 3887 | else |
| 3888 | { |
| 3889 | LPSTR textA = (LPSTR)lParam; |
Alexandre Julliard | 331bf3d | 2002-08-15 23:28:45 +0000 | [diff] [blame] | 3890 | if (!WideCharToMultiByte(CP_ACP, 0, es->text, -1, textA, count, NULL, NULL)) |
| 3891 | textA[count - 1] = 0; /* ensure 0 termination */ |
Dmitry Timoshkov | 785203c | 2001-01-11 20:17:21 +0000 | [diff] [blame] | 3892 | return strlen(textA); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 3893 | } |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3894 | } |
| 3895 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3896 | /********************************************************************* |
| 3897 | * |
| 3898 | * WM_HSCROLL |
| 3899 | * |
| 3900 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3901 | static LRESULT EDIT_WM_HScroll(EDITSTATE *es, INT action, INT pos) |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3902 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 3903 | INT dx; |
| 3904 | INT fw; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3905 | |
| 3906 | if (!(es->style & ES_MULTILINE)) |
| 3907 | return 0; |
| 3908 | |
| 3909 | if (!(es->style & ES_AUTOHSCROLL)) |
| 3910 | return 0; |
| 3911 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3912 | dx = 0; |
| 3913 | fw = es->format_rect.right - es->format_rect.left; |
| 3914 | switch (action) { |
| 3915 | case SB_LINELEFT: |
Dmitry Timoshkov | a234db8 | 2001-01-19 20:49:54 +0000 | [diff] [blame] | 3916 | TRACE("SB_LINELEFT\n"); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3917 | if (es->x_offset) |
| 3918 | dx = -es->char_width; |
| 3919 | break; |
| 3920 | case SB_LINERIGHT: |
Dmitry Timoshkov | a234db8 | 2001-01-19 20:49:54 +0000 | [diff] [blame] | 3921 | TRACE("SB_LINERIGHT\n"); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3922 | if (es->x_offset < es->text_width) |
| 3923 | dx = es->char_width; |
| 3924 | break; |
| 3925 | case SB_PAGELEFT: |
Dmitry Timoshkov | a234db8 | 2001-01-19 20:49:54 +0000 | [diff] [blame] | 3926 | TRACE("SB_PAGELEFT\n"); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3927 | if (es->x_offset) |
| 3928 | dx = -fw / HSCROLL_FRACTION / es->char_width * es->char_width; |
| 3929 | break; |
| 3930 | case SB_PAGERIGHT: |
Dmitry Timoshkov | a234db8 | 2001-01-19 20:49:54 +0000 | [diff] [blame] | 3931 | TRACE("SB_PAGERIGHT\n"); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3932 | if (es->x_offset < es->text_width) |
| 3933 | dx = fw / HSCROLL_FRACTION / es->char_width * es->char_width; |
| 3934 | break; |
| 3935 | case SB_LEFT: |
Dmitry Timoshkov | a234db8 | 2001-01-19 20:49:54 +0000 | [diff] [blame] | 3936 | TRACE("SB_LEFT\n"); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3937 | if (es->x_offset) |
| 3938 | dx = -es->x_offset; |
| 3939 | break; |
| 3940 | case SB_RIGHT: |
Dmitry Timoshkov | a234db8 | 2001-01-19 20:49:54 +0000 | [diff] [blame] | 3941 | TRACE("SB_RIGHT\n"); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3942 | if (es->x_offset < es->text_width) |
| 3943 | dx = es->text_width - es->x_offset; |
| 3944 | break; |
| 3945 | case SB_THUMBTRACK: |
Dmitry Timoshkov | a234db8 | 2001-01-19 20:49:54 +0000 | [diff] [blame] | 3946 | TRACE("SB_THUMBTRACK %d\n", pos); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3947 | es->flags |= EF_HSCROLL_TRACK; |
Dmitry Timoshkov | a234db8 | 2001-01-19 20:49:54 +0000 | [diff] [blame] | 3948 | if(es->style & WS_HSCROLL) |
| 3949 | dx = pos - es->x_offset; |
| 3950 | else |
| 3951 | { |
| 3952 | INT fw, new_x; |
| 3953 | /* Sanity check */ |
| 3954 | if(pos < 0 || pos > 100) return 0; |
| 3955 | /* Assume default scroll range 0-100 */ |
| 3956 | fw = es->format_rect.right - es->format_rect.left; |
| 3957 | new_x = pos * (es->text_width - fw) / 100; |
| 3958 | dx = es->text_width ? (new_x - es->x_offset) : 0; |
| 3959 | } |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3960 | break; |
| 3961 | case SB_THUMBPOSITION: |
Dmitry Timoshkov | a234db8 | 2001-01-19 20:49:54 +0000 | [diff] [blame] | 3962 | TRACE("SB_THUMBPOSITION %d\n", pos); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3963 | es->flags &= ~EF_HSCROLL_TRACK; |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3964 | if(GetWindowLongW( es->hwndSelf, GWL_STYLE ) & WS_HSCROLL) |
Dmitry Timoshkov | a234db8 | 2001-01-19 20:49:54 +0000 | [diff] [blame] | 3965 | dx = pos - es->x_offset; |
| 3966 | else |
| 3967 | { |
| 3968 | INT fw, new_x; |
| 3969 | /* Sanity check */ |
| 3970 | if(pos < 0 || pos > 100) return 0; |
| 3971 | /* Assume default scroll range 0-100 */ |
| 3972 | fw = es->format_rect.right - es->format_rect.left; |
| 3973 | new_x = pos * (es->text_width - fw) / 100; |
| 3974 | dx = es->text_width ? (new_x - es->x_offset) : 0; |
| 3975 | } |
| 3976 | if (!dx) { |
| 3977 | /* force scroll info update */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3978 | EDIT_UpdateScrollInfo(es); |
| 3979 | EDIT_NOTIFY_PARENT(es, EN_HSCROLL, "EN_HSCROLL"); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 3980 | } |
| 3981 | break; |
| 3982 | case SB_ENDSCROLL: |
Dmitry Timoshkov | a234db8 | 2001-01-19 20:49:54 +0000 | [diff] [blame] | 3983 | TRACE("SB_ENDSCROLL\n"); |
| 3984 | break; |
| 3985 | /* |
| 3986 | * FIXME : the next two are undocumented ! |
| 3987 | * Are we doing the right thing ? |
| 3988 | * At least Win 3.1 Notepad makes use of EM_GETTHUMB this way, |
| 3989 | * although it's also a regular control message. |
| 3990 | */ |
| 3991 | case EM_GETTHUMB: /* this one is used by NT notepad */ |
| 3992 | case EM_GETTHUMB16: |
| 3993 | { |
| 3994 | LRESULT ret; |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 3995 | if(GetWindowLongW( es->hwndSelf, GWL_STYLE ) & WS_HSCROLL) |
| 3996 | ret = GetScrollPos(es->hwndSelf, SB_HORZ); |
Dmitry Timoshkov | a234db8 | 2001-01-19 20:49:54 +0000 | [diff] [blame] | 3997 | else |
| 3998 | { |
| 3999 | /* Assume default scroll range 0-100 */ |
| 4000 | INT fw = es->format_rect.right - es->format_rect.left; |
| 4001 | ret = es->text_width ? es->x_offset * 100 / (es->text_width - fw) : 0; |
| 4002 | } |
| 4003 | TRACE("EM_GETTHUMB: returning %ld\n", ret); |
| 4004 | return ret; |
| 4005 | } |
| 4006 | case EM_LINESCROLL16: |
| 4007 | TRACE("EM_LINESCROLL16\n"); |
| 4008 | dx = pos; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4009 | break; |
| 4010 | |
| 4011 | default: |
Dmitry Timoshkov | a234db8 | 2001-01-19 20:49:54 +0000 | [diff] [blame] | 4012 | ERR("undocumented WM_HSCROLL action %d (0x%04x), please report\n", |
| 4013 | action, action); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4014 | return 0; |
| 4015 | } |
| 4016 | if (dx) |
Dmitry Timoshkov | 11dbda6 | 2001-01-05 03:40:35 +0000 | [diff] [blame] | 4017 | { |
| 4018 | INT fw = es->format_rect.right - es->format_rect.left; |
| 4019 | /* check if we are going to move too far */ |
| 4020 | if(es->x_offset + dx + fw > es->text_width) |
| 4021 | dx = es->text_width - fw - es->x_offset; |
| 4022 | if(dx) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4023 | EDIT_EM_LineScroll_internal(es, dx, 0); |
Dmitry Timoshkov | 11dbda6 | 2001-01-05 03:40:35 +0000 | [diff] [blame] | 4024 | } |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4025 | return 0; |
| 4026 | } |
| 4027 | |
| 4028 | |
| 4029 | /********************************************************************* |
| 4030 | * |
| 4031 | * EDIT_CheckCombo |
| 4032 | * |
| 4033 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4034 | static BOOL EDIT_CheckCombo(EDITSTATE *es, UINT msg, INT key) |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4035 | { |
Serge Ivanov | 9eedcf5 | 2000-06-07 03:47:34 +0000 | [diff] [blame] | 4036 | HWND hLBox = es->hwndListBox; |
| 4037 | HWND hCombo; |
| 4038 | BOOL bDropped; |
| 4039 | int nEUI; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4040 | |
Serge Ivanov | 9eedcf5 | 2000-06-07 03:47:34 +0000 | [diff] [blame] | 4041 | if (!hLBox) |
| 4042 | return FALSE; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4043 | |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4044 | hCombo = GetParent(es->hwndSelf); |
Serge Ivanov | 9eedcf5 | 2000-06-07 03:47:34 +0000 | [diff] [blame] | 4045 | bDropped = TRUE; |
| 4046 | nEUI = 0; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4047 | |
Alexandre Julliard | aff7dda | 2002-11-22 21:22:14 +0000 | [diff] [blame] | 4048 | TRACE_(combo)("[%p]: handling msg %x (%x)\n", es->hwndSelf, msg, key); |
Serge Ivanov | 9eedcf5 | 2000-06-07 03:47:34 +0000 | [diff] [blame] | 4049 | |
| 4050 | if (key == VK_UP || key == VK_DOWN) |
| 4051 | { |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 4052 | if (SendMessageW(hCombo, CB_GETEXTENDEDUI, 0, 0)) |
Serge Ivanov | 9eedcf5 | 2000-06-07 03:47:34 +0000 | [diff] [blame] | 4053 | nEUI = 1; |
| 4054 | |
| 4055 | if (msg == WM_KEYDOWN || nEUI) |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 4056 | bDropped = (BOOL)SendMessageW(hCombo, CB_GETDROPPEDSTATE, 0, 0); |
Serge Ivanov | 9eedcf5 | 2000-06-07 03:47:34 +0000 | [diff] [blame] | 4057 | } |
| 4058 | |
| 4059 | switch (msg) |
| 4060 | { |
| 4061 | case WM_KEYDOWN: |
| 4062 | if (!bDropped && nEUI && (key == VK_UP || key == VK_DOWN)) |
| 4063 | { |
| 4064 | /* make sure ComboLBox pops up */ |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 4065 | SendMessageW(hCombo, CB_SETEXTENDEDUI, FALSE, 0); |
Serge Ivanov | 9eedcf5 | 2000-06-07 03:47:34 +0000 | [diff] [blame] | 4066 | key = VK_F4; |
| 4067 | nEUI = 2; |
| 4068 | } |
| 4069 | |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 4070 | SendMessageW(hLBox, WM_KEYDOWN, (WPARAM)key, 0); |
Serge Ivanov | 9eedcf5 | 2000-06-07 03:47:34 +0000 | [diff] [blame] | 4071 | break; |
| 4072 | |
| 4073 | case WM_SYSKEYDOWN: /* Handle Alt+up/down arrows */ |
| 4074 | if (nEUI) |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 4075 | SendMessageW(hCombo, CB_SHOWDROPDOWN, bDropped ? FALSE : TRUE, 0); |
Serge Ivanov | 9eedcf5 | 2000-06-07 03:47:34 +0000 | [diff] [blame] | 4076 | else |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 4077 | SendMessageW(hLBox, WM_KEYDOWN, (WPARAM)VK_F4, 0); |
Serge Ivanov | 9eedcf5 | 2000-06-07 03:47:34 +0000 | [diff] [blame] | 4078 | break; |
| 4079 | } |
| 4080 | |
| 4081 | if(nEUI == 2) |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 4082 | SendMessageW(hCombo, CB_SETEXTENDEDUI, TRUE, 0); |
Serge Ivanov | 9eedcf5 | 2000-06-07 03:47:34 +0000 | [diff] [blame] | 4083 | |
| 4084 | return TRUE; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4085 | } |
| 4086 | |
| 4087 | |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 4088 | /********************************************************************* |
| 4089 | * |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4090 | * WM_KEYDOWN |
| 4091 | * |
| 4092 | * Handling of special keys that don't produce a WM_CHAR |
| 4093 | * (i.e. non-printable keys) & Backspace & Delete |
| 4094 | * |
| 4095 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4096 | static LRESULT EDIT_WM_KeyDown(EDITSTATE *es, INT key) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4097 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 4098 | BOOL shift; |
| 4099 | BOOL control; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4100 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 4101 | if (GetKeyState(VK_MENU) & 0x8000) |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 4102 | return 0; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4103 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 4104 | shift = GetKeyState(VK_SHIFT) & 0x8000; |
| 4105 | control = GetKeyState(VK_CONTROL) & 0x8000; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4106 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4107 | switch (key) { |
Alexandre Julliard | df2673b | 1997-03-29 17:20:20 +0000 | [diff] [blame] | 4108 | case VK_F4: |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4109 | case VK_UP: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4110 | if (EDIT_CheckCombo(es, WM_KEYDOWN, key) || key == VK_F4) |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4111 | break; |
Serge Ivanov | 9eedcf5 | 2000-06-07 03:47:34 +0000 | [diff] [blame] | 4112 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4113 | /* fall through */ |
Alexandre Julliard | df2673b | 1997-03-29 17:20:20 +0000 | [diff] [blame] | 4114 | case VK_LEFT: |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4115 | if ((es->style & ES_MULTILINE) && (key == VK_UP)) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4116 | EDIT_MoveUp_ML(es, shift); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4117 | else |
| 4118 | if (control) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4119 | EDIT_MoveWordBackward(es, shift); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4120 | else |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4121 | EDIT_MoveBackward(es, shift); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4122 | break; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4123 | case VK_DOWN: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4124 | if (EDIT_CheckCombo(es, WM_KEYDOWN, key)) |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4125 | break; |
Alexandre Julliard | df2673b | 1997-03-29 17:20:20 +0000 | [diff] [blame] | 4126 | /* fall through */ |
| 4127 | case VK_RIGHT: |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4128 | if ((es->style & ES_MULTILINE) && (key == VK_DOWN)) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4129 | EDIT_MoveDown_ML(es, shift); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4130 | else if (control) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4131 | EDIT_MoveWordForward(es, shift); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4132 | else |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4133 | EDIT_MoveForward(es, shift); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4134 | break; |
| 4135 | case VK_HOME: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4136 | EDIT_MoveHome(es, shift); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4137 | break; |
| 4138 | case VK_END: |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4139 | EDIT_MoveEnd(es, shift); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4140 | break; |
| 4141 | case VK_PRIOR: |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4142 | if (es->style & ES_MULTILINE) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4143 | EDIT_MovePageUp_ML(es, shift); |
Serge Ivanov | 9eedcf5 | 2000-06-07 03:47:34 +0000 | [diff] [blame] | 4144 | else |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4145 | EDIT_CheckCombo(es, WM_KEYDOWN, key); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4146 | break; |
| 4147 | case VK_NEXT: |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4148 | if (es->style & ES_MULTILINE) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4149 | EDIT_MovePageDown_ML(es, shift); |
Serge Ivanov | 9eedcf5 | 2000-06-07 03:47:34 +0000 | [diff] [blame] | 4150 | else |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4151 | EDIT_CheckCombo(es, WM_KEYDOWN, key); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4152 | break; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4153 | case VK_DELETE: |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 4154 | if (!(es->style & ES_READONLY) && !(shift && control)) { |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4155 | if (es->selection_start != es->selection_end) { |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4156 | if (shift) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4157 | EDIT_WM_Cut(es); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4158 | else |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4159 | EDIT_WM_Clear(es); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4160 | } else { |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4161 | if (shift) { |
| 4162 | /* delete character left of caret */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4163 | EDIT_EM_SetSel(es, (UINT)-1, 0, FALSE); |
| 4164 | EDIT_MoveBackward(es, TRUE); |
| 4165 | EDIT_WM_Clear(es); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4166 | } else if (control) { |
| 4167 | /* delete to end of line */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4168 | EDIT_EM_SetSel(es, (UINT)-1, 0, FALSE); |
| 4169 | EDIT_MoveEnd(es, TRUE); |
| 4170 | EDIT_WM_Clear(es); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4171 | } else { |
| 4172 | /* delete character right of caret */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4173 | EDIT_EM_SetSel(es, (UINT)-1, 0, FALSE); |
| 4174 | EDIT_MoveForward(es, TRUE); |
| 4175 | EDIT_WM_Clear(es); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4176 | } |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4177 | } |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 4178 | } |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4179 | break; |
| 4180 | case VK_INSERT: |
| 4181 | if (shift) { |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4182 | if (!(es->style & ES_READONLY)) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4183 | EDIT_WM_Paste(es); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4184 | } else if (control) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4185 | EDIT_WM_Copy(es); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4186 | break; |
Pascal Lessard | aed79e5 | 1999-09-10 13:58:34 +0000 | [diff] [blame] | 4187 | case VK_RETURN: |
| 4188 | /* If the edit doesn't want the return send a message to the default object */ |
| 4189 | if(!(es->style & ES_WANTRETURN)) |
| 4190 | { |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4191 | HWND hwndParent = GetParent(es->hwndSelf); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 4192 | DWORD dw = SendMessageW( hwndParent, DM_GETDEFID, 0, 0 ); |
Pascal Lessard | aed79e5 | 1999-09-10 13:58:34 +0000 | [diff] [blame] | 4193 | if (HIWORD(dw) == DC_HASDEFID) |
| 4194 | { |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 4195 | SendMessageW( hwndParent, WM_COMMAND, |
Pascal Lessard | aed79e5 | 1999-09-10 13:58:34 +0000 | [diff] [blame] | 4196 | MAKEWPARAM( LOWORD(dw), BN_CLICKED ), |
| 4197 | (LPARAM)GetDlgItem( hwndParent, LOWORD(dw) ) ); |
| 4198 | } |
| 4199 | } |
| 4200 | break; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4201 | } |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 4202 | return 0; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4203 | } |
| 4204 | |
| 4205 | |
| 4206 | /********************************************************************* |
| 4207 | * |
| 4208 | * WM_KILLFOCUS |
| 4209 | * |
| 4210 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4211 | static LRESULT EDIT_WM_KillFocus(EDITSTATE *es) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4212 | { |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4213 | es->flags &= ~EF_FOCUSED; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 4214 | DestroyCaret(); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4215 | if(!(es->style & ES_NOHIDESEL)) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4216 | EDIT_InvalidateText(es, es->selection_start, es->selection_end); |
| 4217 | EDIT_NOTIFY_PARENT(es, EN_KILLFOCUS, "EN_KILLFOCUS"); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 4218 | return 0; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4219 | } |
| 4220 | |
| 4221 | |
| 4222 | /********************************************************************* |
| 4223 | * |
| 4224 | * WM_LBUTTONDBLCLK |
| 4225 | * |
Alexandre Julliard | cdcdede | 1996-04-21 14:57:41 +0000 | [diff] [blame] | 4226 | * The caret position has been set on the WM_LBUTTONDOWN message |
| 4227 | * |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4228 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4229 | static LRESULT EDIT_WM_LButtonDblClk(EDITSTATE *es) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4230 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 4231 | INT s; |
| 4232 | INT e = es->selection_end; |
| 4233 | INT l; |
| 4234 | INT li; |
| 4235 | INT ll; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4236 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4237 | if (!(es->flags & EF_FOCUSED)) |
| 4238 | return 0; |
| 4239 | |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 4240 | l = EDIT_EM_LineFromChar(es, e); |
| 4241 | li = EDIT_EM_LineIndex(es, l); |
| 4242 | ll = EDIT_EM_LineLength(es, e); |
Dmitry Timoshkov | 8058ead | 2000-12-21 20:19:21 +0000 | [diff] [blame] | 4243 | s = li + EDIT_CallWordBreakProc(es, li, e - li, ll, WB_LEFT); |
| 4244 | e = li + EDIT_CallWordBreakProc(es, li, e - li, ll, WB_RIGHT); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4245 | EDIT_EM_SetSel(es, s, e, FALSE); |
| 4246 | EDIT_EM_ScrollCaret(es); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 4247 | return 0; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4248 | } |
| 4249 | |
| 4250 | |
| 4251 | /********************************************************************* |
| 4252 | * |
| 4253 | * WM_LBUTTONDOWN |
| 4254 | * |
| 4255 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4256 | static LRESULT EDIT_WM_LButtonDown(EDITSTATE *es, DWORD keys, INT x, INT y) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4257 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 4258 | INT e; |
| 4259 | BOOL after_wrap; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4260 | |
Huw Davies | 137f41d | 2003-11-03 22:15:59 +0000 | [diff] [blame] | 4261 | SetFocus(es->hwndSelf); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4262 | if (!(es->flags & EF_FOCUSED)) |
| 4263 | return 0; |
| 4264 | |
Abey George | 6e013e5 | 1999-07-27 17:08:26 +0000 | [diff] [blame] | 4265 | es->bCaptureState = TRUE; |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4266 | SetCapture(es->hwndSelf); |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 4267 | EDIT_ConfinePoint(es, &x, &y); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4268 | e = EDIT_CharFromPos(es, x, y, &after_wrap); |
| 4269 | EDIT_EM_SetSel(es, (keys & MK_SHIFT) ? es->selection_start : e, e, after_wrap); |
| 4270 | EDIT_EM_ScrollCaret(es); |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 4271 | es->region_posx = es->region_posy = 0; |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4272 | SetTimer(es->hwndSelf, 0, 100, NULL); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 4273 | return 0; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4274 | } |
| 4275 | |
| 4276 | |
| 4277 | /********************************************************************* |
| 4278 | * |
| 4279 | * WM_LBUTTONUP |
| 4280 | * |
| 4281 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4282 | static LRESULT EDIT_WM_LButtonUp(EDITSTATE *es) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4283 | { |
Alexandre Julliard | 6356a44 | 2003-02-19 22:04:03 +0000 | [diff] [blame] | 4284 | if (es->bCaptureState) { |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4285 | KillTimer(es->hwndSelf, 0); |
Alexandre Julliard | 6356a44 | 2003-02-19 22:04:03 +0000 | [diff] [blame] | 4286 | if (GetCapture() == es->hwndSelf) ReleaseCapture(); |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 4287 | } |
Abey George | 6e013e5 | 1999-07-27 17:08:26 +0000 | [diff] [blame] | 4288 | es->bCaptureState = FALSE; |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 4289 | return 0; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4290 | } |
| 4291 | |
| 4292 | |
| 4293 | /********************************************************************* |
| 4294 | * |
Alexandre Julliard | c616625 | 2000-05-25 23:01:39 +0000 | [diff] [blame] | 4295 | * WM_MBUTTONDOWN |
| 4296 | * |
| 4297 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4298 | static LRESULT EDIT_WM_MButtonDown(EDITSTATE *es) |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 4299 | { |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4300 | SendMessageW(es->hwndSelf, WM_PASTE, 0, 0); |
Alexandre Julliard | c616625 | 2000-05-25 23:01:39 +0000 | [diff] [blame] | 4301 | return 0; |
| 4302 | } |
| 4303 | |
| 4304 | |
| 4305 | /********************************************************************* |
| 4306 | * |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4307 | * WM_MOUSEMOVE |
| 4308 | * |
| 4309 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4310 | static LRESULT EDIT_WM_MouseMove(EDITSTATE *es, INT x, INT y) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4311 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 4312 | INT e; |
| 4313 | BOOL after_wrap; |
| 4314 | INT prex, prey; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4315 | |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4316 | if (GetCapture() != es->hwndSelf) |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4317 | return 0; |
| 4318 | |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 4319 | /* |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4320 | * FIXME: gotta do some scrolling if outside client |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 4321 | * area. Maybe reset the timer ? |
| 4322 | */ |
Alexandre Julliard | e658d82 | 1997-11-30 17:45:40 +0000 | [diff] [blame] | 4323 | prex = x; prey = y; |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 4324 | EDIT_ConfinePoint(es, &x, &y); |
Alexandre Julliard | e658d82 | 1997-11-30 17:45:40 +0000 | [diff] [blame] | 4325 | es->region_posx = (prex < x) ? -1 : ((prex > x) ? 1 : 0); |
| 4326 | es->region_posy = (prey < y) ? -1 : ((prey > y) ? 1 : 0); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4327 | e = EDIT_CharFromPos(es, x, y, &after_wrap); |
| 4328 | EDIT_EM_SetSel(es, es->selection_start, e, after_wrap); |
| 4329 | EDIT_SetCaretPos(es,es->selection_end,es->flags & EF_AFTER_WRAP); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 4330 | return 0; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4331 | } |
| 4332 | |
| 4333 | |
| 4334 | /********************************************************************* |
| 4335 | * |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 4336 | * WM_NCCREATE |
| 4337 | * |
Bill Medland | 86bfa4c | 2001-06-28 18:01:00 +0000 | [diff] [blame] | 4338 | * See also EDIT_WM_StyleChanged |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 4339 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4340 | static LRESULT EDIT_WM_NCCreate(HWND hwnd, LPCREATESTRUCTW lpcs, BOOL unicode) |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 4341 | { |
| 4342 | EDITSTATE *es; |
Dmitry Timoshkov | f8b96e2 | 2000-12-20 18:39:14 +0000 | [diff] [blame] | 4343 | UINT alloc_size; |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 4344 | |
Alexandre Julliard | de42428 | 2001-08-10 22:51:42 +0000 | [diff] [blame] | 4345 | TRACE("Creating %s edit control, style = %08lx\n", |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4346 | unicode ? "Unicode" : "ANSI", lpcs->style); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 4347 | |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 4348 | if (!(es = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*es)))) |
| 4349 | return FALSE; |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4350 | SetWindowLongW( hwnd, 0, (LONG)es ); |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 4351 | |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 4352 | /* |
| 4353 | * Note: since the EDITSTATE has not been fully initialized yet, |
| 4354 | * we can't use any API calls that may send |
| 4355 | * WM_XXX messages before WM_NCCREATE is completed. |
| 4356 | */ |
| 4357 | |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 4358 | es->is_unicode = unicode; |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4359 | es->style = lpcs->style; |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 4360 | |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4361 | es->bEnableState = !(es->style & WS_DISABLED); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 4362 | |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4363 | es->hwndSelf = hwnd; |
Dmitry Timoshkov | a62f06d | 2001-03-13 23:31:08 +0000 | [diff] [blame] | 4364 | /* Save parent, which will be notified by EN_* messages */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4365 | es->hwndParent = lpcs->hwndParent; |
Dmitry Timoshkov | a62f06d | 2001-03-13 23:31:08 +0000 | [diff] [blame] | 4366 | |
Serge Ivanov | 9eedcf5 | 2000-06-07 03:47:34 +0000 | [diff] [blame] | 4367 | if (es->style & ES_COMBO) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4368 | es->hwndListBox = GetDlgItem(es->hwndParent, ID_CB_LISTBOX); |
Serge Ivanov | 9eedcf5 | 2000-06-07 03:47:34 +0000 | [diff] [blame] | 4369 | |
Bill Medland | 86bfa4c | 2001-06-28 18:01:00 +0000 | [diff] [blame] | 4370 | /* Number overrides lowercase overrides uppercase (at least it |
| 4371 | * does in Win95). However I'll bet that ES_NUMBER would be |
| 4372 | * invalid under Win 3.1. |
| 4373 | */ |
| 4374 | if (es->style & ES_NUMBER) { |
| 4375 | ; /* do not override the ES_NUMBER */ |
| 4376 | } else if (es->style & ES_LOWERCASE) { |
| 4377 | es->style &= ~ES_UPPERCASE; |
| 4378 | } |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 4379 | if (es->style & ES_MULTILINE) { |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 4380 | es->buffer_limit = BUFLIMIT_MULTI; |
| 4381 | if (es->style & WS_VSCROLL) |
| 4382 | es->style |= ES_AUTOVSCROLL; |
| 4383 | if (es->style & WS_HSCROLL) |
| 4384 | es->style |= ES_AUTOHSCROLL; |
| 4385 | es->style &= ~ES_PASSWORD; |
| 4386 | if ((es->style & ES_CENTER) || (es->style & ES_RIGHT)) { |
Bill Medland | 86bfa4c | 2001-06-28 18:01:00 +0000 | [diff] [blame] | 4387 | /* Confirmed - RIGHT overrides CENTER */ |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 4388 | if (es->style & ES_RIGHT) |
| 4389 | es->style &= ~ES_CENTER; |
| 4390 | es->style &= ~WS_HSCROLL; |
| 4391 | es->style &= ~ES_AUTOHSCROLL; |
| 4392 | } |
| 4393 | |
| 4394 | /* FIXME: for now, all multi line controls are AUTOVSCROLL */ |
| 4395 | es->style |= ES_AUTOVSCROLL; |
| 4396 | } else { |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 4397 | es->buffer_limit = BUFLIMIT_SINGLE; |
Dimitrie O. Paun | abe9c97 | 2004-04-01 21:06:14 +0000 | [diff] [blame] | 4398 | es->style &= ~ES_CENTER; |
| 4399 | es->style &= ~ES_RIGHT; |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 4400 | es->style &= ~WS_HSCROLL; |
| 4401 | es->style &= ~WS_VSCROLL; |
| 4402 | es->style &= ~ES_AUTOVSCROLL; |
| 4403 | es->style &= ~ES_WANTRETURN; |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 4404 | if (es->style & ES_PASSWORD) |
| 4405 | es->password_char = '*'; |
| 4406 | |
| 4407 | /* FIXME: for now, all single line controls are AUTOHSCROLL */ |
| 4408 | es->style |= ES_AUTOHSCROLL; |
| 4409 | } |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 4410 | |
Dmitry Timoshkov | df793bc | 2001-01-15 20:20:31 +0000 | [diff] [blame] | 4411 | alloc_size = ROUND_TO_GROW((es->buffer_size + 1) * sizeof(WCHAR)); |
Dmitry Timoshkov | f8b96e2 | 2000-12-20 18:39:14 +0000 | [diff] [blame] | 4412 | if(!(es->hloc32W = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT, alloc_size))) |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 4413 | return FALSE; |
| 4414 | es->buffer_size = LocalSize(es->hloc32W)/sizeof(WCHAR) - 1; |
| 4415 | |
| 4416 | if (!(es->undo_text = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (es->buffer_size + 1) * sizeof(WCHAR)))) |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 4417 | return FALSE; |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 4418 | es->undo_buffer_size = es->buffer_size; |
| 4419 | |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 4420 | if (es->style & ES_MULTILINE) |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 4421 | if (!(es->first_line_def = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LINEDEF)))) |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 4422 | return FALSE; |
| 4423 | es->line_count = 1; |
| 4424 | |
Dmitry Timoshkov | b85a6e8 | 2001-10-08 20:33:08 +0000 | [diff] [blame] | 4425 | /* |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 4426 | * In Win95 look and feel, the WS_BORDER style is replaced by the |
| 4427 | * WS_EX_CLIENTEDGE style for the edit control. This gives the edit |
Dmitry Timoshkov | b85a6e8 | 2001-10-08 20:33:08 +0000 | [diff] [blame] | 4428 | * control a non client area. Not always. This coordinates in some |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 4429 | * way with the window creation code in dialog.c When making |
Dmitry Timoshkov | b85a6e8 | 2001-10-08 20:33:08 +0000 | [diff] [blame] | 4430 | * modifications please ensure that the code still works for edit |
| 4431 | * controls created directly with style 0x50800000, exStyle 0 ( |
| 4432 | * which should have a single pixel border) |
| 4433 | */ |
Dimitrie O. Paun | 126227a | 2004-04-01 04:57:12 +0000 | [diff] [blame] | 4434 | es->style &= ~WS_BORDER; |
Dmitry Timoshkov | b85a6e8 | 2001-10-08 20:33:08 +0000 | [diff] [blame] | 4435 | |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 4436 | return TRUE; |
| 4437 | } |
| 4438 | |
| 4439 | /********************************************************************* |
| 4440 | * |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4441 | * WM_PAINT |
| 4442 | * |
| 4443 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4444 | static void EDIT_WM_Paint(EDITSTATE *es, WPARAM wParam) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4445 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 4446 | PAINTSTRUCT ps; |
| 4447 | INT i; |
| 4448 | HDC dc; |
| 4449 | HFONT old_font = 0; |
| 4450 | RECT rc; |
Robert Shearman | 8570328 | 2004-08-17 22:09:16 +0000 | [diff] [blame] | 4451 | RECT rcClient; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 4452 | RECT rcLine; |
| 4453 | RECT rcRgn; |
Robert Shearman | 8570328 | 2004-08-17 22:09:16 +0000 | [diff] [blame] | 4454 | HBRUSH brush; |
Stephane Lussier | 9380534 | 1999-09-03 16:37:00 +0000 | [diff] [blame] | 4455 | BOOL rev = es->bEnableState && |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4456 | ((es->flags & EF_FOCUSED) || |
| 4457 | (es->style & ES_NOHIDESEL)); |
Gerard Patel | 8e5c72e | 1999-09-03 12:23:52 +0000 | [diff] [blame] | 4458 | if (!wParam) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4459 | dc = BeginPaint(es->hwndSelf, &ps); |
Gerard Patel | 8e5c72e | 1999-09-03 12:23:52 +0000 | [diff] [blame] | 4460 | else |
| 4461 | dc = (HDC) wParam; |
Robert Shearman | 8570328 | 2004-08-17 22:09:16 +0000 | [diff] [blame] | 4462 | |
| 4463 | GetClientRect(es->hwndSelf, &rcClient); |
| 4464 | |
| 4465 | /* paint the background */ |
| 4466 | if (!(brush = EDIT_NotifyCtlColor(es, dc))) |
| 4467 | brush = (HBRUSH)GetStockObject(WHITE_BRUSH); |
| 4468 | IntersectClipRect(dc, rcClient.left, rcClient.top, rcClient.right, rcClient.bottom); |
| 4469 | GetClipBox(dc, &rc); |
| 4470 | FillRect(dc, &rc, brush); |
| 4471 | |
| 4472 | /* draw the border */ |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 4473 | if(es->style & WS_BORDER) { |
Robert Shearman | 8570328 | 2004-08-17 22:09:16 +0000 | [diff] [blame] | 4474 | rc = rcClient; |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 4475 | if(es->style & ES_MULTILINE) { |
| 4476 | if(es->style & WS_HSCROLL) rc.bottom++; |
| 4477 | if(es->style & WS_VSCROLL) rc.right++; |
| 4478 | } |
Francis Beaudet | 06e8886 | 1999-07-30 17:59:35 +0000 | [diff] [blame] | 4479 | Rectangle(dc, rc.left, rc.top, rc.right, rc.bottom); |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 4480 | } |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 4481 | IntersectClipRect(dc, es->format_rect.left, |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4482 | es->format_rect.top, |
| 4483 | es->format_rect.right, |
| 4484 | es->format_rect.bottom); |
| 4485 | if (es->style & ES_MULTILINE) { |
Robert Shearman | 8570328 | 2004-08-17 22:09:16 +0000 | [diff] [blame] | 4486 | rc = rcClient; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 4487 | IntersectClipRect(dc, rc.left, rc.top, rc.right, rc.bottom); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4488 | } |
| 4489 | if (es->font) |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 4490 | old_font = SelectObject(dc, es->font); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4491 | EDIT_NotifyCtlColor(es, dc); |
Stephane Lussier | 9380534 | 1999-09-03 16:37:00 +0000 | [diff] [blame] | 4492 | |
| 4493 | if (!es->bEnableState) |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 4494 | SetTextColor(dc, GetSysColor(COLOR_GRAYTEXT)); |
| 4495 | GetClipBox(dc, &rcRgn); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4496 | if (es->style & ES_MULTILINE) { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 4497 | INT vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height; |
Francois Gouget | 6d77d3a | 2000-03-25 21:44:35 +0000 | [diff] [blame] | 4498 | for (i = es->y_offset ; i <= min(es->y_offset + vlc, es->y_offset + es->line_count - 1) ; i++) { |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4499 | EDIT_GetLineRect(es, i, 0, -1, &rcLine); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 4500 | if (IntersectRect(&rc, &rcRgn, &rcLine)) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4501 | EDIT_PaintLine(es, dc, i, rev); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4502 | } |
| 4503 | } else { |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4504 | EDIT_GetLineRect(es, 0, 0, -1, &rcLine); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 4505 | if (IntersectRect(&rc, &rcRgn, &rcLine)) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4506 | EDIT_PaintLine(es, dc, 0, rev); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4507 | } |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4508 | if (es->font) |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 4509 | SelectObject(dc, old_font); |
Dmitry Timoshkov | 11dbda6 | 2001-01-05 03:40:35 +0000 | [diff] [blame] | 4510 | |
Gerard Patel | 8e5c72e | 1999-09-03 12:23:52 +0000 | [diff] [blame] | 4511 | if (!wParam) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4512 | EndPaint(es->hwndSelf, &ps); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4513 | } |
| 4514 | |
| 4515 | |
| 4516 | /********************************************************************* |
| 4517 | * |
| 4518 | * WM_PASTE |
| 4519 | * |
| 4520 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4521 | static void EDIT_WM_Paste(EDITSTATE *es) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4522 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 4523 | HGLOBAL hsrc; |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 4524 | LPWSTR src; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4525 | |
Dmitry Timoshkov | 9c446a1 | 2001-01-22 19:28:27 +0000 | [diff] [blame] | 4526 | /* Protect read-only edit control from modification */ |
| 4527 | if(es->style & ES_READONLY) |
| 4528 | return; |
| 4529 | |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4530 | OpenClipboard(es->hwndSelf); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 4531 | if ((hsrc = GetClipboardData(CF_UNICODETEXT))) { |
| 4532 | src = (LPWSTR)GlobalLock(hsrc); |
Carl Sopchak | 23b88ef | 2002-11-21 03:57:05 +0000 | [diff] [blame] | 4533 | EDIT_EM_ReplaceSel(es, TRUE, src, TRUE, TRUE); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 4534 | GlobalUnlock(hsrc); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4535 | } |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 4536 | CloseClipboard(); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4537 | } |
| 4538 | |
| 4539 | |
| 4540 | /********************************************************************* |
| 4541 | * |
| 4542 | * WM_SETFOCUS |
| 4543 | * |
| 4544 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4545 | static void EDIT_WM_SetFocus(EDITSTATE *es) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4546 | { |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4547 | es->flags |= EF_FOCUSED; |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4548 | CreateCaret(es->hwndSelf, 0, 2, es->line_height); |
| 4549 | EDIT_SetCaretPos(es, es->selection_end, |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 4550 | es->flags & EF_AFTER_WRAP); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4551 | if(!(es->style & ES_NOHIDESEL)) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4552 | EDIT_InvalidateText(es, es->selection_start, es->selection_end); |
| 4553 | ShowCaret(es->hwndSelf); |
| 4554 | EDIT_NOTIFY_PARENT(es, EN_SETFOCUS, "EN_SETFOCUS"); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4555 | } |
| 4556 | |
| 4557 | |
| 4558 | /********************************************************************* |
| 4559 | * |
| 4560 | * WM_SETFONT |
| 4561 | * |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 4562 | * With Win95 look the margins are set to default font value unless |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 4563 | * the system font (font == 0) is being set, in which case they are left |
| 4564 | * unchanged. |
| 4565 | * |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4566 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4567 | static void EDIT_WM_SetFont(EDITSTATE *es, HFONT font, BOOL redraw) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4568 | { |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 4569 | TEXTMETRICW tm; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 4570 | HDC dc; |
| 4571 | HFONT old_font = 0; |
Pascal Lessard | 3405f5c | 1999-09-04 10:59:07 +0000 | [diff] [blame] | 4572 | RECT r; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4573 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4574 | es->font = font; |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4575 | dc = GetDC(es->hwndSelf); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4576 | if (font) |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 4577 | old_font = SelectObject(dc, font); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 4578 | GetTextMetricsW(dc, &tm); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4579 | es->line_height = tm.tmHeight; |
| 4580 | es->char_width = tm.tmAveCharWidth; |
| 4581 | if (font) |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 4582 | SelectObject(dc, old_font); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4583 | ReleaseDC(es->hwndSelf, dc); |
Dimitrie O. Paun | 126227a | 2004-04-01 04:57:12 +0000 | [diff] [blame] | 4584 | EDIT_EM_SetMargins(es, EC_LEFTMARGIN | EC_RIGHTMARGIN, |
| 4585 | EC_USEFONTINFO, EC_USEFONTINFO); |
Pascal Lessard | 3405f5c | 1999-09-04 10:59:07 +0000 | [diff] [blame] | 4586 | |
| 4587 | /* Force the recalculation of the format rect for each font change */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4588 | GetClientRect(es->hwndSelf, &r); |
| 4589 | EDIT_SetRectNP(es, &r); |
Pascal Lessard | 3405f5c | 1999-09-04 10:59:07 +0000 | [diff] [blame] | 4590 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4591 | if (es->style & ES_MULTILINE) |
Francois Gouget | d2667a4 | 2002-12-02 18:10:57 +0000 | [diff] [blame] | 4592 | EDIT_BuildLineDefs_ML(es, 0, strlenW(es->text), 0, NULL); |
Dmitry Timoshkov | 11dbda6 | 2001-01-05 03:40:35 +0000 | [diff] [blame] | 4593 | else |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4594 | EDIT_CalcLineWidth_SL(es); |
Pascal Lessard | 3405f5c | 1999-09-04 10:59:07 +0000 | [diff] [blame] | 4595 | |
Alexandre Julliard | e658d82 | 1997-11-30 17:45:40 +0000 | [diff] [blame] | 4596 | if (redraw) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4597 | EDIT_UpdateText(es, NULL, TRUE); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4598 | if (es->flags & EF_FOCUSED) { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 4599 | DestroyCaret(); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4600 | CreateCaret(es->hwndSelf, 0, 2, es->line_height); |
| 4601 | EDIT_SetCaretPos(es, es->selection_end, |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 4602 | es->flags & EF_AFTER_WRAP); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4603 | ShowCaret(es->hwndSelf); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4604 | } |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4605 | } |
| 4606 | |
| 4607 | |
| 4608 | /********************************************************************* |
| 4609 | * |
| 4610 | * WM_SETTEXT |
| 4611 | * |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 4612 | * NOTES |
| 4613 | * For multiline controls (ES_MULTILINE), reception of WM_SETTEXT triggers: |
| 4614 | * The modified flag is reset. No notifications are sent. |
| 4615 | * |
| 4616 | * For single-line controls, reception of WM_SETTEXT triggers: |
| 4617 | * The modified flag is reset. EN_UPDATE and EN_CHANGE notifications are sent. |
| 4618 | * |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4619 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4620 | static void EDIT_WM_SetText(EDITSTATE *es, LPARAM lParam, BOOL unicode) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4621 | { |
James Hatheway | f3ea345 | 2001-01-12 23:01:41 +0000 | [diff] [blame] | 4622 | LPWSTR text = NULL; |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 4623 | |
| 4624 | if(unicode) |
| 4625 | text = (LPWSTR)lParam; |
James Hatheway | f3ea345 | 2001-01-12 23:01:41 +0000 | [diff] [blame] | 4626 | else if (lParam) |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 4627 | { |
| 4628 | LPCSTR textA = (LPCSTR)lParam; |
| 4629 | INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0); |
| 4630 | if((text = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR)))) |
| 4631 | MultiByteToWideChar(CP_ACP, 0, textA, -1, text, countW); |
| 4632 | } |
| 4633 | |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4634 | EDIT_EM_SetSel(es, 0, (UINT)-1, FALSE); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4635 | if (text) { |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 4636 | TRACE("%s\n", debugstr_w(text)); |
Carl Sopchak | 23b88ef | 2002-11-21 03:57:05 +0000 | [diff] [blame] | 4637 | EDIT_EM_ReplaceSel(es, FALSE, text, FALSE, FALSE); |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 4638 | if(!unicode) |
| 4639 | HeapFree(GetProcessHeap(), 0, text); |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 4640 | } else { |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 4641 | static const WCHAR empty_stringW[] = {0}; |
| 4642 | TRACE("<NULL>\n"); |
Carl Sopchak | 23b88ef | 2002-11-21 03:57:05 +0000 | [diff] [blame] | 4643 | EDIT_EM_ReplaceSel(es, FALSE, empty_stringW, FALSE, FALSE); |
Alexandre Julliard | df2673b | 1997-03-29 17:20:20 +0000 | [diff] [blame] | 4644 | } |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 4645 | es->x_offset = 0; |
Alexandre Julliard | 829fe32 | 1998-07-26 14:27:39 +0000 | [diff] [blame] | 4646 | es->flags &= ~EF_MODIFIED; |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4647 | EDIT_EM_SetSel(es, 0, 0, FALSE); |
Rein Klazes | 9d4ae0e | 2001-04-02 19:13:24 +0000 | [diff] [blame] | 4648 | /* Send the notification after the selection start and end have been set |
| 4649 | * edit control doesn't send notification on WM_SETTEXT |
| 4650 | * if it is multiline, or it is part of combobox |
| 4651 | */ |
| 4652 | if( !((es->style & ES_MULTILINE) || es->hwndListBox)) |
Rizsanyi Zsolt | 83d6efb | 2002-04-11 17:30:22 +0000 | [diff] [blame] | 4653 | { |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4654 | EDIT_NOTIFY_PARENT(es, EN_CHANGE, "EN_CHANGE"); |
| 4655 | EDIT_NOTIFY_PARENT(es, EN_UPDATE, "EN_UPDATE"); |
Rizsanyi Zsolt | 83d6efb | 2002-04-11 17:30:22 +0000 | [diff] [blame] | 4656 | } |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4657 | EDIT_EM_ScrollCaret(es); |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4658 | } |
| 4659 | |
| 4660 | |
| 4661 | /********************************************************************* |
| 4662 | * |
| 4663 | * WM_SIZE |
| 4664 | * |
| 4665 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4666 | static void EDIT_WM_Size(EDITSTATE *es, UINT action, INT width, INT height) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4667 | { |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4668 | if ((action == SIZE_MAXIMIZED) || (action == SIZE_RESTORED)) { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 4669 | RECT rc; |
Dmitry Timoshkov | 4e62b9d | 2000-12-19 19:36:49 +0000 | [diff] [blame] | 4670 | TRACE("width = %d, height = %d\n", width, height); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 4671 | SetRect(&rc, 0, 0, width, height); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4672 | EDIT_SetRectNP(es, &rc); |
| 4673 | EDIT_UpdateText(es, NULL, TRUE); |
Alexandre Julliard | cdcdede | 1996-04-21 14:57:41 +0000 | [diff] [blame] | 4674 | } |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4675 | } |
| 4676 | |
| 4677 | |
| 4678 | /********************************************************************* |
| 4679 | * |
Bill Medland | 86bfa4c | 2001-06-28 18:01:00 +0000 | [diff] [blame] | 4680 | * WM_STYLECHANGED |
| 4681 | * |
| 4682 | * This message is sent by SetWindowLong on having changed either the Style |
| 4683 | * or the extended style. |
| 4684 | * |
| 4685 | * We ensure that the window's version of the styles and the EDITSTATE's agree. |
| 4686 | * |
| 4687 | * See also EDIT_WM_NCCreate |
| 4688 | * |
| 4689 | * It appears that the Windows version of the edit control allows the style |
| 4690 | * (as retrieved by GetWindowLong) to be any value and maintains an internal |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 4691 | * style variable which will generally be different. In this function we |
Bill Medland | 86bfa4c | 2001-06-28 18:01:00 +0000 | [diff] [blame] | 4692 | * update the internal style based on what changed in the externally visible |
| 4693 | * style. |
| 4694 | * |
| 4695 | * Much of this content as based upon the MSDN, especially: |
| 4696 | * Platform SDK Documentation -> User Interface Services -> |
| 4697 | * Windows User Interface -> Edit Controls -> Edit Control Reference -> |
| 4698 | * Edit Control Styles |
| 4699 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4700 | static LRESULT EDIT_WM_StyleChanged ( EDITSTATE *es, WPARAM which, const STYLESTRUCT *style) |
Bill Medland | 86bfa4c | 2001-06-28 18:01:00 +0000 | [diff] [blame] | 4701 | { |
| 4702 | if (GWL_STYLE == which) { |
| 4703 | DWORD style_change_mask; |
| 4704 | DWORD new_style; |
| 4705 | /* Only a subset of changes can be applied after the control |
| 4706 | * has been created. |
| 4707 | */ |
| 4708 | style_change_mask = ES_UPPERCASE | ES_LOWERCASE | |
| 4709 | ES_NUMBER; |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 4710 | if (es->style & ES_MULTILINE) |
Bill Medland | 86bfa4c | 2001-06-28 18:01:00 +0000 | [diff] [blame] | 4711 | style_change_mask |= ES_WANTRETURN; |
| 4712 | |
| 4713 | new_style = style->styleNew & style_change_mask; |
| 4714 | |
| 4715 | /* Number overrides lowercase overrides uppercase (at least it |
| 4716 | * does in Win95). However I'll bet that ES_NUMBER would be |
| 4717 | * invalid under Win 3.1. |
| 4718 | */ |
| 4719 | if (new_style & ES_NUMBER) { |
| 4720 | ; /* do not override the ES_NUMBER */ |
| 4721 | } else if (new_style & ES_LOWERCASE) { |
| 4722 | new_style &= ~ES_UPPERCASE; |
| 4723 | } |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 4724 | |
Bill Medland | 86bfa4c | 2001-06-28 18:01:00 +0000 | [diff] [blame] | 4725 | es->style = (es->style & ~style_change_mask) | new_style; |
| 4726 | } else if (GWL_EXSTYLE == which) { |
| 4727 | ; /* FIXME - what is needed here */ |
| 4728 | } else { |
| 4729 | WARN ("Invalid style change %d\n",which); |
| 4730 | } |
| 4731 | |
| 4732 | return 0; |
| 4733 | } |
| 4734 | |
| 4735 | /********************************************************************* |
| 4736 | * |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 4737 | * WM_SYSKEYDOWN |
| 4738 | * |
| 4739 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4740 | static LRESULT EDIT_WM_SysKeyDown(EDITSTATE *es, INT key, DWORD key_data) |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 4741 | { |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4742 | if ((key == VK_BACK) && (key_data & 0x2000)) { |
Dmitry Timoshkov | 7a947b3 | 2000-11-27 01:34:25 +0000 | [diff] [blame] | 4743 | if (EDIT_EM_CanUndo(es)) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4744 | EDIT_EM_Undo(es); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4745 | return 0; |
Serge Ivanov | 9eedcf5 | 2000-06-07 03:47:34 +0000 | [diff] [blame] | 4746 | } else if (key == VK_UP || key == VK_DOWN) { |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4747 | if (EDIT_CheckCombo(es, WM_SYSKEYDOWN, key)) |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4748 | return 0; |
Serge Ivanov | 9eedcf5 | 2000-06-07 03:47:34 +0000 | [diff] [blame] | 4749 | } |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4750 | return DefWindowProcW(es->hwndSelf, WM_SYSKEYDOWN, (WPARAM)key, (LPARAM)key_data); |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 4751 | } |
| 4752 | |
| 4753 | |
| 4754 | /********************************************************************* |
| 4755 | * |
| 4756 | * WM_TIMER |
| 4757 | * |
| 4758 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4759 | static void EDIT_WM_Timer(EDITSTATE *es) |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 4760 | { |
Alexandre Julliard | e658d82 | 1997-11-30 17:45:40 +0000 | [diff] [blame] | 4761 | if (es->region_posx < 0) { |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4762 | EDIT_MoveBackward(es, TRUE); |
Alexandre Julliard | e658d82 | 1997-11-30 17:45:40 +0000 | [diff] [blame] | 4763 | } else if (es->region_posx > 0) { |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4764 | EDIT_MoveForward(es, TRUE); |
Alexandre Julliard | e658d82 | 1997-11-30 17:45:40 +0000 | [diff] [blame] | 4765 | } |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 4766 | /* |
Alexandre Julliard | e658d82 | 1997-11-30 17:45:40 +0000 | [diff] [blame] | 4767 | * FIXME: gotta do some vertical scrolling here, like |
Alexandre Julliard | de42428 | 2001-08-10 22:51:42 +0000 | [diff] [blame] | 4768 | * EDIT_EM_LineScroll(hwnd, 0, 1); |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 4769 | */ |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4770 | } |
| 4771 | |
Alexandre Julliard | 01d6346 | 1997-01-20 19:43:45 +0000 | [diff] [blame] | 4772 | /********************************************************************* |
| 4773 | * |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4774 | * WM_VSCROLL |
| 4775 | * |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4776 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4777 | static LRESULT EDIT_WM_VScroll(EDITSTATE *es, INT action, INT pos) |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4778 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 4779 | INT dy; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4780 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4781 | if (!(es->style & ES_MULTILINE)) |
| 4782 | return 0; |
| 4783 | |
| 4784 | if (!(es->style & ES_AUTOVSCROLL)) |
| 4785 | return 0; |
| 4786 | |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4787 | dy = 0; |
| 4788 | switch (action) { |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4789 | case SB_LINEUP: |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4790 | case SB_LINEDOWN: |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4791 | case SB_PAGEUP: |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4792 | case SB_PAGEDOWN: |
Lionel Ulmer | 28d9aaf | 2004-03-29 22:54:05 +0000 | [diff] [blame] | 4793 | TRACE("action %d (%s)\n", action, (action == SB_LINEUP ? "SB_LINEUP" : |
| 4794 | (action == SB_LINEDOWN ? "SB_LINEDOWN" : |
| 4795 | (action == SB_PAGEUP ? "SB_PAGEUP" : |
| 4796 | "SB_PAGEDOWN")))); |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4797 | EDIT_EM_Scroll(es, action); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4798 | return 0; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4799 | case SB_TOP: |
Dmitry Timoshkov | a234db8 | 2001-01-19 20:49:54 +0000 | [diff] [blame] | 4800 | TRACE("SB_TOP\n"); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4801 | dy = -es->y_offset; |
| 4802 | break; |
| 4803 | case SB_BOTTOM: |
Dmitry Timoshkov | a234db8 | 2001-01-19 20:49:54 +0000 | [diff] [blame] | 4804 | TRACE("SB_BOTTOM\n"); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4805 | dy = es->line_count - 1 - es->y_offset; |
| 4806 | break; |
| 4807 | case SB_THUMBTRACK: |
Dmitry Timoshkov | a234db8 | 2001-01-19 20:49:54 +0000 | [diff] [blame] | 4808 | TRACE("SB_THUMBTRACK %d\n", pos); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4809 | es->flags |= EF_VSCROLL_TRACK; |
Dmitry Timoshkov | a234db8 | 2001-01-19 20:49:54 +0000 | [diff] [blame] | 4810 | if(es->style & WS_VSCROLL) |
| 4811 | dy = pos - es->y_offset; |
| 4812 | else |
| 4813 | { |
| 4814 | /* Assume default scroll range 0-100 */ |
| 4815 | INT vlc, new_y; |
| 4816 | /* Sanity check */ |
| 4817 | if(pos < 0 || pos > 100) return 0; |
| 4818 | vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height; |
| 4819 | new_y = pos * (es->line_count - vlc) / 100; |
| 4820 | dy = es->line_count ? (new_y - es->y_offset) : 0; |
| 4821 | TRACE("line_count=%d, y_offset=%d, pos=%d, dy = %d\n", |
| 4822 | es->line_count, es->y_offset, pos, dy); |
| 4823 | } |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4824 | break; |
| 4825 | case SB_THUMBPOSITION: |
Dmitry Timoshkov | a234db8 | 2001-01-19 20:49:54 +0000 | [diff] [blame] | 4826 | TRACE("SB_THUMBPOSITION %d\n", pos); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4827 | es->flags &= ~EF_VSCROLL_TRACK; |
Dmitry Timoshkov | a234db8 | 2001-01-19 20:49:54 +0000 | [diff] [blame] | 4828 | if(es->style & WS_VSCROLL) |
| 4829 | dy = pos - es->y_offset; |
| 4830 | else |
| 4831 | { |
| 4832 | /* Assume default scroll range 0-100 */ |
| 4833 | INT vlc, new_y; |
| 4834 | /* Sanity check */ |
| 4835 | if(pos < 0 || pos > 100) return 0; |
| 4836 | vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height; |
| 4837 | new_y = pos * (es->line_count - vlc) / 100; |
| 4838 | dy = es->line_count ? (new_y - es->y_offset) : 0; |
| 4839 | TRACE("line_count=%d, y_offset=%d, pos=%d, dy = %d\n", |
| 4840 | es->line_count, es->y_offset, pos, dy); |
| 4841 | } |
| 4842 | if (!dy) |
| 4843 | { |
| 4844 | /* force scroll info update */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4845 | EDIT_UpdateScrollInfo(es); |
| 4846 | EDIT_NOTIFY_PARENT(es, EN_VSCROLL, "EN_VSCROLL"); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4847 | } |
| 4848 | break; |
| 4849 | case SB_ENDSCROLL: |
Dmitry Timoshkov | a234db8 | 2001-01-19 20:49:54 +0000 | [diff] [blame] | 4850 | TRACE("SB_ENDSCROLL\n"); |
| 4851 | break; |
| 4852 | /* |
| 4853 | * FIXME : the next two are undocumented ! |
| 4854 | * Are we doing the right thing ? |
| 4855 | * At least Win 3.1 Notepad makes use of EM_GETTHUMB this way, |
| 4856 | * although it's also a regular control message. |
| 4857 | */ |
| 4858 | case EM_GETTHUMB: /* this one is used by NT notepad */ |
| 4859 | case EM_GETTHUMB16: |
| 4860 | { |
| 4861 | LRESULT ret; |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4862 | if(GetWindowLongW( es->hwndSelf, GWL_STYLE ) & WS_VSCROLL) |
| 4863 | ret = GetScrollPos(es->hwndSelf, SB_VERT); |
Dmitry Timoshkov | a234db8 | 2001-01-19 20:49:54 +0000 | [diff] [blame] | 4864 | else |
| 4865 | { |
| 4866 | /* Assume default scroll range 0-100 */ |
| 4867 | INT vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height; |
| 4868 | ret = es->line_count ? es->y_offset * 100 / (es->line_count - vlc) : 0; |
| 4869 | } |
| 4870 | TRACE("EM_GETTHUMB: returning %ld\n", ret); |
| 4871 | return ret; |
| 4872 | } |
| 4873 | case EM_LINESCROLL16: |
| 4874 | TRACE("EM_LINESCROLL16 %d\n", pos); |
| 4875 | dy = pos; |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4876 | break; |
| 4877 | |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4878 | default: |
Dmitry Timoshkov | a234db8 | 2001-01-19 20:49:54 +0000 | [diff] [blame] | 4879 | ERR("undocumented WM_VSCROLL action %d (0x%04x), please report\n", |
| 4880 | action, action); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4881 | return 0; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4882 | } |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4883 | if (dy) |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4884 | EDIT_EM_LineScroll(es, 0, dy); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 4885 | return 0; |
Alexandre Julliard | 329f068 | 1996-04-14 13:21:20 +0000 | [diff] [blame] | 4886 | } |
Ulrich Czekalla | 70d5a95 | 2000-05-26 01:17:34 +0000 | [diff] [blame] | 4887 | |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 4888 | /********************************************************************* |
| 4889 | * |
| 4890 | * EDIT_UpdateText |
| 4891 | * |
| 4892 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4893 | static void EDIT_UpdateTextRegion(EDITSTATE *es, HRGN hrgn, BOOL bErase) |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 4894 | { |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4895 | if (es->flags & EF_UPDATE) EDIT_NOTIFY_PARENT(es, EN_UPDATE, "EN_UPDATE"); |
| 4896 | InvalidateRgn(es->hwndSelf, hrgn, bErase); |
Ulrich Czekalla | f11ff2a | 2001-03-31 00:51:10 +0000 | [diff] [blame] | 4897 | } |
| 4898 | |
Ulrich Czekalla | 70d5a95 | 2000-05-26 01:17:34 +0000 | [diff] [blame] | 4899 | |
| 4900 | /********************************************************************* |
| 4901 | * |
| 4902 | * EDIT_UpdateText |
| 4903 | * |
| 4904 | */ |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4905 | static void EDIT_UpdateText(EDITSTATE *es, LPRECT rc, BOOL bErase) |
Ulrich Czekalla | 70d5a95 | 2000-05-26 01:17:34 +0000 | [diff] [blame] | 4906 | { |
Dimitrie O. Paun | a4273ca | 2002-09-25 03:24:53 +0000 | [diff] [blame] | 4907 | if (es->flags & EF_UPDATE) EDIT_NOTIFY_PARENT(es, EN_UPDATE, "EN_UPDATE"); |
| 4908 | InvalidateRect(es->hwndSelf, rc, bErase); |
Ulrich Czekalla | 70d5a95 | 2000-05-26 01:17:34 +0000 | [diff] [blame] | 4909 | } |