Changeset 10195 for trunk/src


Ignore:
Timestamp:
Jul 31, 2003, 6:07:57 PM (22 years ago)
Author:
sandervl
Message:

KOMH: DBCS updates/fixes

Location:
trunk/src/user32
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/user32/clipboard.cpp

    r9423 r10195  
    1 /* $Id: clipboard.cpp,v 1.16 2002-11-25 09:48:13 sandervl Exp $ */
     1/* $Id: clipboard.cpp,v 1.17 2003-07-31 16:07:56 sandervl Exp $ */
    22
    33/*
     
    5757int WIN32API CountClipboardFormats(void)
    5858{
    59     dprintf(("USER32: CountClipboardFormats"));
    6059    return O32_CountClipboardFormats();
    6160}
     
    6463BOOL WIN32API EmptyClipboard(void)
    6564{
    66     dprintf(("USER32: EmptyClipboard"));
    6765    return O32_EmptyClipboard();
    6866}
    6967//******************************************************************************
    7068//******************************************************************************
    71 UINT WIN32API EnumClipboardFormats(UINT arg1)
    72 {
    73     dprintf(("USER32: EnumClipboardFormats %d", arg1));
    74     return O32_EnumClipboardFormats(arg1);
     69UINT WIN32API EnumClipboardFormats(UINT uFormat)
     70{
     71    return O32_EnumClipboardFormats(uFormat);
    7572}
    7673//******************************************************************************
     
    167164    HWND hwnd;
    168165
    169     dprintf(("USER32: GetOpenClipboardWindow"));
    170166    hwnd = O32_GetOpenClipboardWindow();
    171167
     
    216212BOOL WIN32API CloseClipboard(void)
    217213{
    218     dprintf(("USER32: CloseClipboard"));
    219214    return O32_CloseClipboard();
    220215}
  • trunk/src/user32/edit.c

    r9760 r10195  
    11/*
    2  *      Edit control
    3  *
    4  *      Copyright  David W. Metcalfe, 1994
    5  *      Copyright  William Magro, 1995, 1996
    6  *      Copyright  Frans van Dorsselaer, 1996, 1997
     2 *  Edit control
     3 *
     4 *  Copyright  David W. Metcalfe, 1994
     5 *  Copyright  William Magro, 1995, 1996
     6 *  Copyright  Frans van Dorsselaer, 1996, 1997
    77 *
    88 */
    99
    1010/*
    11  *      please read EDIT.TODO (and update it when you change things)
     11 *  please read EDIT.TODO (and update it when you change things)
    1212 */
    1313
     
    3030#ifdef __WIN32OS2__
    3131#include "ctrlconf.h"
     32#include <heapstring.h>
    3233#endif
    3334
     
    3738DECLARE_DEBUG_CHANNEL(relay);
    3839
    39 #define BUFLIMIT_MULTI          0x7FFFFFF       /* maximum buffer size (not including '\0')
    40 #define BUFLIMIT_SINGLE         0x7FFFFFF       /* maximum buffer size (not including '\0') */
     40#define BUFLIMIT_MULTI      0x7FFFFFF   /* maximum buffer size (not including '\0')
     41#define BUFLIMIT_SINGLE     0x7FFFFFF   /* maximum buffer size (not including '\0') */
    4142#else
    42 #define BUFLIMIT_MULTI          65534   /* maximum buffer size (not including '\0')
    43                                            FIXME: BTW, new specs say 65535 (do you dare ???) */
    44 #define BUFLIMIT_SINGLE         32766   /* maximum buffer size (not including '\0') */
     43#define BUFLIMIT_MULTI      65534   /* maximum buffer size (not including '\0')
     44                       FIXME: BTW, new specs say 65535 (do you dare ???) */
     45#define BUFLIMIT_SINGLE     32766   /* maximum buffer size (not including '\0') */
    4546#endif
    4647
    47 #define GROWLENGTH              32      /* buffers granularity in bytes: must be power of 2 */
    48 #define ROUND_TO_GROW(size)     (((size) + (GROWLENGTH - 1)) & ~(GROWLENGTH - 1))
    49 #define HSCROLL_FRACTION        3       /* scroll window by 1/3 width */
     48#define GROWLENGTH      32  /* buffers granularity in bytes: must be power of 2 */
     49#define ROUND_TO_GROW(size) (((size) + (GROWLENGTH - 1)) & ~(GROWLENGTH - 1))
     50#define HSCROLL_FRACTION    3   /* scroll window by 1/3 width */
    5051
    5152/*
    52  *      extra flags for EDITSTATE.flags field
    53  */
    54 #define EF_MODIFIED             0x0001  /* text has been modified */
    55 #define EF_FOCUSED              0x0002  /* we have input focus */
    56 #define EF_UPDATE               0x0004  /* notify parent of changed state */
    57 #define EF_VSCROLL_TRACK        0x0008  /* don't SetScrollPos() since we are tracking the thumb */
    58 #define EF_HSCROLL_TRACK        0x0010  /* don't SetScrollPos() since we are tracking the thumb */
    59 #define EF_AFTER_WRAP           0x0080  /* the caret is displayed after the last character of a
    60                                            wrapped line, instead of in front of the next character */
    61 #define EF_USE_SOFTBRK          0x0100  /* Enable soft breaks in text. */
     53 *  extra flags for EDITSTATE.flags field
     54 */
     55#define EF_MODIFIED     0x0001  /* text has been modified */
     56#define EF_FOCUSED      0x0002  /* we have input focus */
     57#define EF_UPDATE       0x0004  /* notify parent of changed state */
     58#define EF_VSCROLL_TRACK    0x0008  /* don't SetScrollPos() since we are tracking the thumb */
     59#define EF_HSCROLL_TRACK    0x0010  /* don't SetScrollPos() since we are tracking the thumb */
     60#define EF_AFTER_WRAP       0x0080  /* the caret is displayed after the last character of a
     61                       wrapped line, instead of in front of the next character */
     62#define EF_USE_SOFTBRK      0x0100  /* Enable soft breaks in text. */
    6263
    6364typedef enum
    6465{
    65         END_0 = 0,      /* line ends with terminating '\0' character */
    66         END_WRAP,       /* line is wrapped */
    67         END_HARD,       /* line ends with a hard return '\r\n' */
    68         END_SOFT        /* line ends with a soft return '\r\r\n' */
     66    END_0 = 0,  /* line ends with terminating '\0' character */
     67    END_WRAP,   /* line is wrapped */
     68    END_HARD,   /* line ends with a hard return '\r\n' */
     69    END_SOFT    /* line ends with a soft return '\r\r\n' */
    6970} LINE_END;
    7071
    7172typedef struct tagLINEDEF {
    72         INT length;             /* bruto length of a line in bytes */
    73         INT net_length; /* netto length of a line in visible characters */
    74         LINE_END ending;
    75         INT width;              /* width of the line in pixels */
    76         INT index; /* line index into the buffer */
    77         struct tagLINEDEF *next;
     73    INT length;     /* bruto length of a line in bytes */
     74    INT net_length; /* netto length of a line in visible characters */
     75    LINE_END ending;
     76    INT width;      /* width of the line in pixels */
     77    INT index; /* line index into the buffer */
     78    struct tagLINEDEF *next;
    7879} LINEDEF;
    7980
    8081typedef struct
    8182{
    82         BOOL is_unicode;                /* how the control was created */
    83         LPWSTR text;                    /* the actual contents of the control */
    84         UINT buffer_size;               /* the size of the buffer in characters */
    85         UINT buffer_limit;              /* the maximum size to which the buffer may grow in characters */
    86         HFONT font;                     /* NULL means standard system font */
    87         INT x_offset;                   /* scroll offset        for multi lines this is in pixels
    88                                                                 for single lines it's in characters */
    89         INT line_height;                /* height of a screen line in pixels */
    90         INT char_width;         /* average character width in pixels */
    91         DWORD style;                    /* sane version of wnd->dwStyle */
    92         WORD flags;                     /* flags that are not in es->style or wnd->flags (EF_XXX) */
    93         INT undo_insert_count;  /* number of characters inserted in sequence */
    94         UINT undo_position;             /* character index of the insertion and deletion */
    95         LPWSTR undo_text;               /* deleted text */
    96         UINT undo_buffer_size;          /* size of the deleted text buffer */
    97         INT selection_start;            /* == selection_end if no selection */
    98         INT selection_end;              /* == current caret position */
    99         WCHAR password_char;            /* == 0 if no password char, and for multi line controls */
    100         INT left_margin;                /* in pixels */
    101         INT right_margin;               /* in pixels */
    102         RECT format_rect;
    103         INT text_width;                 /* width of the widest line in pixels for multi line controls
    104                                            and just line width for single line controls */
    105         INT region_posx;                /* Position of cursor relative to region: */
    106         INT region_posy;                /* -1: to left, 0: within, 1: to right */
    107         EDITWORDBREAKPROC16 word_break_proc16;
    108         void *word_break_proc;          /* 32-bit word break proc: ANSI or Unicode */
    109         INT line_count;         /* number of lines */
    110         INT y_offset;                   /* scroll offset in number of lines */
    111         BOOL bCaptureState; /* flag indicating whether mouse was captured */
    112         BOOL bEnableState;             /* flag keeping the enable state */
    113         HWND hwndParent;               /* Handle of parent for sending EN_* messages.
    114                                           Even if parent will change, EN_* messages
    115                                           should be sent to the first parent. */
    116         HWND hwndListBox;              /* handle of ComboBox's listbox or NULL */
    117         /*
    118          *      only for multi line controls
    119         */
    120         INT lock_count;         /* amount of re-entries in the EditWndProc */
    121         INT tabs_count;
    122         LPINT tabs;
    123         LINEDEF *first_line_def;        /* linked list of (soft) linebreaks */
    124         HLOCAL hloc32W;         /* our unicode local memory block */
    125         HLOCAL16 hloc16;        /* alias for 16-bit control receiving EM_GETHANDLE16
    126                                    or EM_SETHANDLE16 */
    127         HLOCAL hloc32A;         /* alias for ANSI control receiving EM_GETHANDLE
    128                                    or EM_SETHANDLE */
     83    BOOL is_unicode;        /* how the control was created */
     84    LPWSTR text;            /* the actual contents of the control */
     85    UINT buffer_size;       /* the size of the buffer in characters */
     86    UINT buffer_limit;      /* the maximum size to which the buffer may grow in characters */
     87    HFONT font;         /* NULL means standard system font */
     88    INT x_offset;           /* scroll offset    for multi lines this is in pixels
     89                                for single lines it's in characters */
     90    INT line_height;        /* height of a screen line in pixels */
     91    INT char_width;     /* average character width in pixels */
     92    DWORD style;            /* sane version of wnd->dwStyle */
     93    WORD flags;         /* flags that are not in es->style or wnd->flags (EF_XXX) */
     94    INT undo_insert_count;  /* number of characters inserted in sequence */
     95    UINT undo_position;     /* character index of the insertion and deletion */
     96    LPWSTR undo_text;       /* deleted text */
     97    UINT undo_buffer_size;      /* size of the deleted text buffer */
     98    INT selection_start;        /* == selection_end if no selection */
     99    INT selection_end;      /* == current caret position */
     100    WCHAR password_char;        /* == 0 if no password char, and for multi line controls */
     101    INT left_margin;        /* in pixels */
     102    INT right_margin;       /* in pixels */
     103    RECT format_rect;
     104    INT text_width;         /* width of the widest line in pixels for multi line controls
     105                       and just line width for single line controls */
     106    INT region_posx;        /* Position of cursor relative to region: */
     107    INT region_posy;        /* -1: to left, 0: within, 1: to right */
     108    EDITWORDBREAKPROC16 word_break_proc16;
     109    void *word_break_proc;      /* 32-bit word break proc: ANSI or Unicode */
     110    INT line_count;     /* number of lines */
     111    INT y_offset;           /* scroll offset in number of lines */
     112    BOOL bCaptureState; /* flag indicating whether mouse was captured */
     113    BOOL bEnableState;             /* flag keeping the enable state */
     114    HWND hwndParent;               /* Handle of parent for sending EN_* messages.
     115                          Even if parent will change, EN_* messages
     116                      should be sent to the first parent. */
     117    HWND hwndListBox;              /* handle of ComboBox's listbox or NULL */
     118    /*
     119     *  only for multi line controls
     120    */
     121    INT lock_count;     /* amount of re-entries in the EditWndProc */
     122    INT tabs_count;
     123    LPINT tabs;
     124    LINEDEF *first_line_def;    /* linked list of (soft) linebreaks */
     125    HLOCAL hloc32W;     /* our unicode local memory block */
     126    HLOCAL16 hloc16;    /* alias for 16-bit control receiving EM_GETHANDLE16
     127                   or EM_SETHANDLE16 */
     128    HLOCAL hloc32A;     /* alias for ANSI control receiving EM_GETHANDLE
     129                   or EM_SETHANDLE */
    129130} EDITSTATE;
    130131
     
    137138
    138139#define DPRINTF_EDIT_NOTIFY(hwnd, str) \
    139         do {TRACE("notification " str " sent to hwnd=%08x\n", \
    140                        (UINT)(hwnd));} while(0)
     140    do {TRACE("notification " str " sent to hwnd=%08x\n", \
     141               (UINT)(hwnd));} while(0)
    141142
    142143/* used for disabled or read-only edit control */
    143144#define EDIT_SEND_CTLCOLORSTATIC(hwnd,hdc) \
    144         (SendMessageW(GetParent(hwnd), WM_CTLCOLORSTATIC, \
    145                         (WPARAM)(hdc), (LPARAM)(hwnd)))
     145    (SendMessageW(GetParent(hwnd), WM_CTLCOLORSTATIC, \
     146            (WPARAM)(hdc), (LPARAM)(hwnd)))
    146147#define EDIT_SEND_CTLCOLOR(hwnd,hdc) \
    147         (SendMessageW(GetParent(hwnd), WM_CTLCOLOREDIT, \
    148                         (WPARAM)(hdc), (LPARAM)(hwnd)))
     148    (SendMessageW(GetParent(hwnd), WM_CTLCOLOREDIT, \
     149            (WPARAM)(hdc), (LPARAM)(hwnd)))
    149150#define EDIT_NOTIFY_PARENT(hwnd, es, wNotifyCode, str) \
    150         do \
    151         { /* Notify parent which has created this edit control */ \
    152             DPRINTF_EDIT_NOTIFY((es)->hwndParent, str); \
    153             SendMessageW((es)->hwndParent, WM_COMMAND, \
    154                      MAKEWPARAM(GetWindowLongA((hwnd),GWL_ID), wNotifyCode), \
    155                      (LPARAM)(hwnd)); \
    156         } while(0)
     151    do \
     152    { /* Notify parent which has created this edit control */ \
     153        DPRINTF_EDIT_NOTIFY((es)->hwndParent, str); \
     154        SendMessageW((es)->hwndParent, WM_COMMAND, \
     155             MAKEWPARAM(GetWindowLongA((hwnd),GWL_ID), wNotifyCode), \
     156             (LPARAM)(hwnd)); \
     157    } while(0)
    157158#define DPRINTF_EDIT_MSG16(str) \
    158         TRACE(\
    159                      "16 bit : " str ": hwnd=%08x, wParam=%08x, lParam=%08x\n", \
    160                      hwnd, (UINT)wParam, (UINT)lParam)
     159    TRACE(\
     160             "16 bit : " str ": hwnd=%08x, wParam=%08x, lParam=%08x\n", \
     161             hwnd, (UINT)wParam, (UINT)lParam)
    161162#define DPRINTF_EDIT_MSG32(str) \
    162         TRACE(\
    163                      "32 bit %c : " str ": hwnd=%08x, wParam=%08x, lParam=%08x\n", \
    164                      unicode ? 'W' : 'A', \
    165                      hwnd, (UINT)wParam, (UINT)lParam)
    166 
    167 /*********************************************************************
    168  *
    169  *      Declarations
     163    TRACE(\
     164             "32 bit %c : " str ": hwnd=%08x, wParam=%08x, lParam=%08x\n", \
     165             unicode ? 'W' : 'A', \
     166             hwnd, (UINT)wParam, (UINT)lParam)
     167
     168/*********************************************************************
     169 *
     170 *  Declarations
    170171 *
    171172 */
    172173
    173174/*
    174  *      These functions have trivial implementations
    175  *      We still like to call them internally
    176  *      "static inline" makes them more like macro's
    177  */
    178 static inline BOOL      EDIT_EM_CanUndo(EDITSTATE *es);
    179 static inline void      EDIT_EM_EmptyUndoBuffer(EDITSTATE *es);
    180 static inline void      EDIT_WM_Clear(HWND hwnd, EDITSTATE *es);
    181 static inline void      EDIT_WM_Cut(HWND hwnd, EDITSTATE *es);
     175 *  These functions have trivial implementations
     176 *  We still like to call them internally
     177 *  "static inline" makes them more like macro's
     178 */
     179static inline BOOL  EDIT_EM_CanUndo(EDITSTATE *es);
     180static inline void  EDIT_EM_EmptyUndoBuffer(EDITSTATE *es);
     181static inline void  EDIT_WM_Clear(HWND hwnd, EDITSTATE *es);
     182static inline void  EDIT_WM_Cut(HWND hwnd, EDITSTATE *es);
    182183
    183184/*
    184  *      Helper functions only valid for one type of control
    185  */
    186 static void     EDIT_BuildLineDefs_ML(HWND hwnd, EDITSTATE *es, INT iStart, INT iEnd, INT delta, HRGN hrgn);
    187 static void     EDIT_CalcLineWidth_SL(HWND hwnd, EDITSTATE *es);
    188 static LPWSTR   EDIT_GetPasswordPointer_SL(EDITSTATE *es);
    189 static void     EDIT_MoveDown_ML(HWND hwnd, EDITSTATE *es, BOOL extend);
    190 static void     EDIT_MovePageDown_ML(HWND hwnd, EDITSTATE *es, BOOL extend);
    191 static void     EDIT_MovePageUp_ML(HWND hwnd, EDITSTATE *es, BOOL extend);
    192 static void     EDIT_MoveUp_ML(HWND hwnd, EDITSTATE *es, BOOL extend);
     185 *  Helper functions only valid for one type of control
     186 */
     187static void EDIT_BuildLineDefs_ML(HWND hwnd, EDITSTATE *es, INT iStart, INT iEnd, INT delta, HRGN hrgn);
     188static void EDIT_CalcLineWidth_SL(HWND hwnd, EDITSTATE *es);
     189static LPWSTR   EDIT_GetPasswordPointer_SL(EDITSTATE *es);
     190static void EDIT_MoveDown_ML(HWND hwnd, EDITSTATE *es, BOOL extend);
     191static void EDIT_MovePageDown_ML(HWND hwnd, EDITSTATE *es, BOOL extend);
     192static void EDIT_MovePageUp_ML(HWND hwnd, EDITSTATE *es, BOOL extend);
     193static void EDIT_MoveUp_ML(HWND hwnd, EDITSTATE *es, BOOL extend);
    193194/*
    194  *      Helper functions valid for both single line _and_ multi line controls
    195  */
    196 static INT      EDIT_CallWordBreakProc(EDITSTATE *es, INT start, INT index, INT count, INT action);
    197 static INT      EDIT_CharFromPos(HWND hwnd, EDITSTATE *es, INT x, INT y, LPBOOL after_wrap);
    198 static void     EDIT_ConfinePoint(EDITSTATE *es, LPINT x, LPINT y);
    199 static void     EDIT_GetLineRect(HWND hwnd, EDITSTATE *es, INT line, INT scol, INT ecol, LPRECT rc);
    200 static void     EDIT_InvalidateText(HWND hwnd, EDITSTATE *es, INT start, INT end);
    201 static void     EDIT_LockBuffer(HWND hwnd, EDITSTATE *es);
    202 static BOOL     EDIT_MakeFit(HWND hwnd, EDITSTATE *es, UINT size);
    203 static BOOL     EDIT_MakeUndoFit(EDITSTATE *es, UINT size);
    204 static void     EDIT_MoveBackward(HWND hwnd, EDITSTATE *es, BOOL extend);
    205 static void     EDIT_MoveEnd(HWND hwnd, EDITSTATE *es, BOOL extend);
    206 static void     EDIT_MoveForward(HWND hwnd, EDITSTATE *es, BOOL extend);
    207 static void     EDIT_MoveHome(HWND hwnd, EDITSTATE *es, BOOL extend);
    208 static void     EDIT_MoveWordBackward(HWND hwnd, EDITSTATE *es, BOOL extend);
    209 static void     EDIT_MoveWordForward(HWND hwnd, EDITSTATE *es, BOOL extend);
    210 static void     EDIT_PaintLine(HWND hwnd, EDITSTATE *es, HDC hdc, INT line, BOOL rev);
    211 static INT      EDIT_PaintText(EDITSTATE *es, HDC hdc, INT x, INT y, INT line, INT col, INT count, BOOL rev);
    212 static void     EDIT_SetCaretPos(HWND hwnd, EDITSTATE *es, INT pos, BOOL after_wrap);
    213 static void     EDIT_SetRectNP(HWND hwnd, EDITSTATE *es, LPRECT lprc);
    214 static void     EDIT_UnlockBuffer(HWND hwnd, EDITSTATE *es, BOOL force);
    215 static void     EDIT_UpdateScrollInfo(HWND hwnd, EDITSTATE *es);
     195 *  Helper functions valid for both single line _and_ multi line controls
     196 */
     197static INT  EDIT_CallWordBreakProc(EDITSTATE *es, INT start, INT index, INT count, INT action);
     198static INT  EDIT_CharFromPos(HWND hwnd, EDITSTATE *es, INT x, INT y, LPBOOL after_wrap);
     199static void EDIT_ConfinePoint(EDITSTATE *es, LPINT x, LPINT y);
     200static void EDIT_GetLineRect(HWND hwnd, EDITSTATE *es, INT line, INT scol, INT ecol, LPRECT rc);
     201static void EDIT_InvalidateText(HWND hwnd, EDITSTATE *es, INT start, INT end);
     202static void EDIT_LockBuffer(HWND hwnd, EDITSTATE *es);
     203static BOOL EDIT_MakeFit(HWND hwnd, EDITSTATE *es, UINT size);
     204static BOOL EDIT_MakeUndoFit(EDITSTATE *es, UINT size);
     205static void EDIT_MoveBackward(HWND hwnd, EDITSTATE *es, BOOL extend);
     206static void EDIT_MoveEnd(HWND hwnd, EDITSTATE *es, BOOL extend);
     207static void EDIT_MoveForward(HWND hwnd, EDITSTATE *es, BOOL extend);
     208static void EDIT_MoveHome(HWND hwnd, EDITSTATE *es, BOOL extend);
     209static void EDIT_MoveWordBackward(HWND hwnd, EDITSTATE *es, BOOL extend);
     210static void EDIT_MoveWordForward(HWND hwnd, EDITSTATE *es, BOOL extend);
     211static void EDIT_PaintLine(HWND hwnd, EDITSTATE *es, HDC hdc, INT line, BOOL rev);
     212static INT  EDIT_PaintText(EDITSTATE *es, HDC hdc, INT x, INT y, INT line, INT col, INT count, BOOL rev);
     213static void EDIT_SetCaretPos(HWND hwnd, EDITSTATE *es, INT pos, BOOL after_wrap);
     214static void EDIT_SetRectNP(HWND hwnd, EDITSTATE *es, LPRECT lprc);
     215static void EDIT_UnlockBuffer(HWND hwnd, EDITSTATE *es, BOOL force);
     216static void EDIT_UpdateScrollInfo(HWND hwnd, EDITSTATE *es);
    216217static INT CALLBACK EDIT_WordBreakProc(LPWSTR s, INT index, INT count, INT action);
    217218/*
    218  *      EM_XXX message handlers
    219  */
    220 static LRESULT  EDIT_EM_CharFromPos(HWND hwnd, EDITSTATE *es, INT x, INT y);
    221 static BOOL     EDIT_EM_FmtLines(EDITSTATE *es, BOOL add_eol);
    222 static HLOCAL   EDIT_EM_GetHandle(EDITSTATE *es);
     219 *  EM_XXX message handlers
     220 */
     221static LRESULT  EDIT_EM_CharFromPos(HWND hwnd, EDITSTATE *es, INT x, INT y);
     222static BOOL EDIT_EM_FmtLines(EDITSTATE *es, BOOL add_eol);
     223static HLOCAL   EDIT_EM_GetHandle(EDITSTATE *es);
    223224#ifndef __WIN32OS2__
    224 static HLOCAL16 EDIT_EM_GetHandle16(HWND hwnd, EDITSTATE *es);
     225static HLOCAL16 EDIT_EM_GetHandle16(HWND hwnd, EDITSTATE *es);
    225226#endif
    226 static INT      EDIT_EM_GetLine(EDITSTATE *es, INT line, LPARAM lParam, BOOL unicode);
    227 static LRESULT  EDIT_EM_GetSel(EDITSTATE *es, LPUINT start, LPUINT end);
    228 static LRESULT  EDIT_EM_GetThumb(HWND hwnd, EDITSTATE *es);
    229 static INT      EDIT_EM_LineFromChar(EDITSTATE *es, INT index);
    230 static INT      EDIT_EM_LineIndex(EDITSTATE *es, INT line);
    231 static INT      EDIT_EM_LineLength(EDITSTATE *es, INT index);
    232 static BOOL     EDIT_EM_LineScroll(HWND hwnd, EDITSTATE *es, INT dx, INT dy);
    233 static BOOL     EDIT_EM_LineScroll_internal(HWND hwnd, EDITSTATE *es, INT dx, INT dy);
    234 static LRESULT  EDIT_EM_PosFromChar(HWND hwnd, EDITSTATE *es, INT index, BOOL after_wrap);
    235 static void     EDIT_EM_ReplaceSel(HWND hwnd, EDITSTATE *es, BOOL can_undo, LPCWSTR lpsz_replace, BOOL send_update);
    236 static LRESULT  EDIT_EM_Scroll(HWND hwnd, EDITSTATE *es, INT action);
    237 static void     EDIT_EM_ScrollCaret(HWND hwnd, EDITSTATE *es);
    238 static void     EDIT_EM_SetHandle(HWND hwnd, EDITSTATE *es, HLOCAL hloc);
     227static INT  EDIT_EM_GetLine(EDITSTATE *es, INT line, LPARAM lParam, BOOL unicode);
     228static LRESULT  EDIT_EM_GetSel(EDITSTATE *es, LPUINT start, LPUINT end);
     229static LRESULT  EDIT_EM_GetThumb(HWND hwnd, EDITSTATE *es);
     230static INT  EDIT_EM_LineFromChar(EDITSTATE *es, INT index);
     231static INT  EDIT_EM_LineIndex(EDITSTATE *es, INT line);
     232static INT  EDIT_EM_LineLength(EDITSTATE *es, INT index);
     233static BOOL EDIT_EM_LineScroll(HWND hwnd, EDITSTATE *es, INT dx, INT dy);
     234static BOOL EDIT_EM_LineScroll_internal(HWND hwnd, EDITSTATE *es, INT dx, INT dy);
     235static LRESULT  EDIT_EM_PosFromChar(HWND hwnd, EDITSTATE *es, INT index, BOOL after_wrap);
     236static void EDIT_EM_ReplaceSel(HWND hwnd, EDITSTATE *es, BOOL can_undo, LPCWSTR lpsz_replace, BOOL send_update);
     237static LRESULT  EDIT_EM_Scroll(HWND hwnd, EDITSTATE *es, INT action);
     238static void EDIT_EM_ScrollCaret(HWND hwnd, EDITSTATE *es);
     239static void EDIT_EM_SetHandle(HWND hwnd, EDITSTATE *es, HLOCAL hloc);
    239240#ifndef __WIN32OS2__
    240 static void     EDIT_EM_SetHandle16(HWND hwnd, EDITSTATE *es, HLOCAL16 hloc);
     241static void EDIT_EM_SetHandle16(HWND hwnd, EDITSTATE *es, HLOCAL16 hloc);
    241242#endif
    242 static void     EDIT_EM_SetLimitText(EDITSTATE *es, INT limit);
    243 static void     EDIT_EM_SetMargins(EDITSTATE *es, INT action, INT left, INT right);
    244 static void     EDIT_EM_SetPasswordChar(HWND hwnd, EDITSTATE *es, WCHAR c);
    245 static void     EDIT_EM_SetSel(HWND hwnd, EDITSTATE *es, UINT start, UINT end, BOOL after_wrap);
    246 static BOOL     EDIT_EM_SetTabStops(EDITSTATE *es, INT count, LPINT tabs);
    247 static BOOL     EDIT_EM_SetTabStops16(EDITSTATE *es, INT count, LPINT16 tabs);
    248 static void     EDIT_EM_SetWordBreakProc(HWND hwnd, EDITSTATE *es, LPARAM lParam);
     243static void EDIT_EM_SetLimitText(EDITSTATE *es, INT limit);
     244static void EDIT_EM_SetMargins(EDITSTATE *es, INT action, INT left, INT right);
     245static void EDIT_EM_SetPasswordChar(HWND hwnd, EDITSTATE *es, WCHAR c);
     246static void EDIT_EM_SetSel(HWND hwnd, EDITSTATE *es, UINT start, UINT end, BOOL after_wrap);
     247static BOOL EDIT_EM_SetTabStops(EDITSTATE *es, INT count, LPINT tabs);
     248static BOOL EDIT_EM_SetTabStops16(EDITSTATE *es, INT count, LPINT16 tabs);
     249static void EDIT_EM_SetWordBreakProc(HWND hwnd, EDITSTATE *es, LPARAM lParam);
    249250#ifndef __WIN32OS2__
    250 static void     EDIT_EM_SetWordBreakProc16(HWND hwnd, EDITSTATE *es, EDITWORDBREAKPROC16 wbp);
     251static void EDIT_EM_SetWordBreakProc16(HWND hwnd, EDITSTATE *es, EDITWORDBREAKPROC16 wbp);
    251252#endif
    252 static BOOL     EDIT_EM_Undo(HWND hwnd, EDITSTATE *es);
     253static BOOL EDIT_EM_Undo(HWND hwnd, EDITSTATE *es);
    253254/*
    254  *      WM_XXX message handlers
    255  */
    256 static void     EDIT_WM_Char(HWND hwnd, EDITSTATE *es, WCHAR c);
    257 static void     EDIT_WM_Command(HWND hwnd, EDITSTATE *es, INT code, INT id, HWND conrtol);
    258 static void     EDIT_WM_ContextMenu(HWND hwnd, EDITSTATE *es, INT x, INT y);
    259 static void     EDIT_WM_Copy(HWND hwnd, EDITSTATE *es);
    260 static LRESULT  EDIT_WM_Create(HWND hwnd, EDITSTATE *es, LPCWSTR name);
    261 static void     EDIT_WM_Destroy(HWND hwnd, EDITSTATE *es);
    262 static LRESULT  EDIT_WM_EraseBkGnd(HWND hwnd, EDITSTATE *es, HDC dc);
    263 static INT      EDIT_WM_GetText(EDITSTATE *es, INT count, LPARAM lParam, BOOL unicode);
    264 static LRESULT  EDIT_WM_HScroll(HWND hwnd, EDITSTATE *es, INT action, INT pos);
    265 static LRESULT  EDIT_WM_KeyDown(HWND hwnd, EDITSTATE *es, INT key);
    266 static LRESULT  EDIT_WM_KillFocus(HWND hwnd, EDITSTATE *es);
    267 static LRESULT  EDIT_WM_LButtonDblClk(HWND hwnd, EDITSTATE *es);
    268 static LRESULT  EDIT_WM_LButtonDown(HWND hwnd, EDITSTATE *es, DWORD keys, INT x, INT y);
    269 static LRESULT  EDIT_WM_LButtonUp(HWND hwndSelf, EDITSTATE *es);
    270 static LRESULT  EDIT_WM_MButtonDown(HWND hwnd);
    271 static LRESULT  EDIT_WM_MouseMove(HWND hwnd, EDITSTATE *es, INT x, INT y);
    272 static LRESULT  EDIT_WM_NCCreate(HWND hwnd, DWORD style, HWND hwndParent, BOOL unicode);
    273 static void     EDIT_WM_Paint(HWND hwnd, EDITSTATE *es, WPARAM wParam);
    274 static void     EDIT_WM_Paste(HWND hwnd, EDITSTATE *es);
    275 static void     EDIT_WM_SetFocus(HWND hwnd, EDITSTATE *es);
    276 static void     EDIT_WM_SetFont(HWND hwnd, EDITSTATE *es, HFONT font, BOOL redraw);
    277 static void     EDIT_WM_SetText(HWND hwnd, EDITSTATE *es, LPARAM lParam, BOOL unicode);
    278 static void     EDIT_WM_Size(HWND hwnd, EDITSTATE *es, UINT action, INT width, INT height);
     255 *  WM_XXX message handlers
     256 */
     257static void EDIT_WM_Char(HWND hwnd, EDITSTATE *es, WCHAR c);
     258static void EDIT_WM_Command(HWND hwnd, EDITSTATE *es, INT code, INT id, HWND conrtol);
     259static void EDIT_WM_ContextMenu(HWND hwnd, EDITSTATE *es, INT x, INT y);
     260static void EDIT_WM_Copy(HWND hwnd, EDITSTATE *es);
     261static LRESULT  EDIT_WM_Create(HWND hwnd, EDITSTATE *es, LPCWSTR name);
     262static void EDIT_WM_Destroy(HWND hwnd, EDITSTATE *es);
     263static LRESULT  EDIT_WM_EraseBkGnd(HWND hwnd, EDITSTATE *es, HDC dc);
     264static INT  EDIT_WM_GetText(EDITSTATE *es, INT count, LPARAM lParam, BOOL unicode);
     265static LRESULT  EDIT_WM_HScroll(HWND hwnd, EDITSTATE *es, INT action, INT pos);
     266static LRESULT  EDIT_WM_KeyDown(HWND hwnd, EDITSTATE *es, INT key);
     267static LRESULT  EDIT_WM_KillFocus(HWND hwnd, EDITSTATE *es);
     268static LRESULT  EDIT_WM_LButtonDblClk(HWND hwnd, EDITSTATE *es);
     269static LRESULT  EDIT_WM_LButtonDown(HWND hwnd, EDITSTATE *es, DWORD keys, INT x, INT y);
     270static LRESULT  EDIT_WM_LButtonUp(HWND hwndSelf, EDITSTATE *es);
     271static LRESULT  EDIT_WM_MButtonDown(HWND hwnd);
     272static LRESULT  EDIT_WM_MouseMove(HWND hwnd, EDITSTATE *es, INT x, INT y);
     273static LRESULT  EDIT_WM_NCCreate(HWND hwnd, DWORD style, HWND hwndParent, BOOL unicode);
     274static void EDIT_WM_Paint(HWND hwnd, EDITSTATE *es, WPARAM wParam);
     275static void EDIT_WM_Paste(HWND hwnd, EDITSTATE *es);
     276static void EDIT_WM_SetFocus(HWND hwnd, EDITSTATE *es);
     277static void EDIT_WM_SetFont(HWND hwnd, EDITSTATE *es, HFONT font, BOOL redraw);
     278static void EDIT_WM_SetText(HWND hwnd, EDITSTATE *es, LPARAM lParam, BOOL unicode);
     279static void EDIT_WM_Size(HWND hwnd, EDITSTATE *es, UINT action, INT width, INT height);
    279280static LRESULT  EDIT_WM_StyleChanged (HWND hwnd, EDITSTATE *es, WPARAM which, const STYLESTRUCT *style);
    280 static LRESULT  EDIT_WM_SysKeyDown(HWND hwnd, EDITSTATE *es, INT key, DWORD key_data);
    281 static void     EDIT_WM_Timer(HWND hwnd, EDITSTATE *es);
    282 static LRESULT  EDIT_WM_VScroll(HWND hwnd, EDITSTATE *es, INT action, INT pos);
     281static LRESULT  EDIT_WM_SysKeyDown(HWND hwnd, EDITSTATE *es, INT key, DWORD key_data);
     282static void EDIT_WM_Timer(HWND hwnd, EDITSTATE *es);
     283static LRESULT  EDIT_WM_VScroll(HWND hwnd, EDITSTATE *es, INT action, INT pos);
    283284static void EDIT_UpdateText(HWND hwnd, EDITSTATE *es, LPRECT rc, BOOL bErase);
    284285static void EDIT_UpdateTextRegion(HWND hwnd, EDITSTATE *es, HRGN hrgn, BOOL bErase);
     
    304305/*********************************************************************
    305306 *
    306  *      EM_CANUNDO
     307 *  EM_CANUNDO
    307308 *
    308309 */
    309310static inline BOOL EDIT_EM_CanUndo(EDITSTATE *es)
    310311{
    311         return (es->undo_insert_count || strlenW(es->undo_text));
    312 }
    313 
    314 
    315 /*********************************************************************
    316  *
    317  *      EM_EMPTYUNDOBUFFER
     312    return (es->undo_insert_count || strlenW(es->undo_text));
     313}
     314
     315
     316/*********************************************************************
     317 *
     318 *  EM_EMPTYUNDOBUFFER
    318319 *
    319320 */
    320321static inline void EDIT_EM_EmptyUndoBuffer(EDITSTATE *es)
    321322{
    322         es->undo_insert_count = 0;
    323         *es->undo_text = '\0';
    324 }
    325 
    326 
    327 /*********************************************************************
    328  *
    329  *      WM_CLEAR
     323    es->undo_insert_count = 0;
     324    *es->undo_text = '\0';
     325}
     326
     327
     328/*********************************************************************
     329 *
     330 *  WM_CLEAR
    330331 *
    331332 */
    332333static inline void EDIT_WM_Clear(HWND hwnd, EDITSTATE *es)
    333334{
    334         static const WCHAR empty_stringW[] = {0};
    335 
    336         /* Protect read-only edit control from modification */
    337         if(es->style & ES_READONLY)
    338             return;
    339 
    340         EDIT_EM_ReplaceSel(hwnd, es, TRUE, empty_stringW, TRUE);
    341 }
    342 
    343 
    344 /*********************************************************************
    345  *
    346  *      WM_CUT
     335    static const WCHAR empty_stringW[] = {0};
     336
     337    /* Protect read-only edit control from modification */
     338    if(es->style & ES_READONLY)
     339        return;
     340
     341    EDIT_EM_ReplaceSel(hwnd, es, TRUE, empty_stringW, TRUE);
     342}
     343
     344
     345/*********************************************************************
     346 *
     347 *  WM_CUT
    347348 *
    348349 */
    349350static inline void EDIT_WM_Cut(HWND hwnd, EDITSTATE *es)
    350351{
    351         EDIT_WM_Copy(hwnd, es);
    352         EDIT_WM_Clear(hwnd, es);
     352    EDIT_WM_Copy(hwnd, es);
     353    EDIT_WM_Clear(hwnd, es);
    353354}
    354355
     
    379380        DWORD dwProcVersion = GetProcessVersion(0);
    380381
    381         info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
     382    info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
    382383        GetVersionExW( &info );
    383384        dwEmulatedVersion = MAKELONG( info.dwMinorVersion, info.dwMajorVersion );
     
    392393/*********************************************************************
    393394 *
    394  *      EditWndProc_common
    395  *
    396  *      The messages are in the order of the actual integer values
    397  *      (which can be found in include/windows.h)
    398  *      Wherever possible the 16 bit versions are converted to
    399  *      the 32 bit ones, so that we can 'fall through' to the
    400  *      helper functions.  These are mostly 32 bit (with a few
    401  *      exceptions, clearly indicated by a '16' extension to their
    402  *      names).
     395 *  EditWndProc_common
     396 *
     397 *  The messages are in the order of the actual integer values
     398 *  (which can be found in include/windows.h)
     399 *  Wherever possible the 16 bit versions are converted to
     400 *  the 32 bit ones, so that we can 'fall through' to the
     401 *  helper functions.  These are mostly 32 bit (with a few
     402 *  exceptions, clearly indicated by a '16' extension to their
     403 *  names).
    403404 *
    404405 */
     
    406407                                          WPARAM wParam, LPARAM lParam, BOOL unicode )
    407408{
    408         EDITSTATE *es = (EDITSTATE *)GetWindowLongA( hwnd, 0 );
    409         LRESULT result = 0;
    410 
    411         switch (msg) {
    412         case WM_DESTROY:
    413                 DPRINTF_EDIT_MSG32("WM_DESTROY");
    414                 if (es) EDIT_WM_Destroy(hwnd, es);
     409    EDITSTATE *es = (EDITSTATE *)GetWindowLongA( hwnd, 0 );
     410    LRESULT result = 0;
     411
     412    switch (msg) {
     413    case WM_DESTROY:
     414        DPRINTF_EDIT_MSG32("WM_DESTROY");
     415        if (es) EDIT_WM_Destroy(hwnd, es);
    415416                result = 0;
    416417                goto END;
    417418
    418         case WM_NCCREATE:
    419                 DPRINTF_EDIT_MSG32("WM_NCCREATE");
    420                 if(unicode)
    421                 {
    422                     LPCREATESTRUCTW cs = (LPCREATESTRUCTW)lParam;
    423                     result = EDIT_WM_NCCreate(hwnd, cs->style, cs->hwndParent, TRUE);
    424                 }
    425                 else
    426                 {
    427                     LPCREATESTRUCTA cs = (LPCREATESTRUCTA)lParam;
    428                     result = EDIT_WM_NCCreate(hwnd, cs->style, cs->hwndParent, FALSE);
    429                 }
     419    case WM_NCCREATE:
     420        DPRINTF_EDIT_MSG32("WM_NCCREATE");
     421        if(unicode)
     422        {
     423            LPCREATESTRUCTW cs = (LPCREATESTRUCTW)lParam;
     424            result = EDIT_WM_NCCreate(hwnd, cs->style, cs->hwndParent, TRUE);
     425        }
     426        else
     427        {
     428            LPCREATESTRUCTA cs = (LPCREATESTRUCTA)lParam;
     429            result = EDIT_WM_NCCreate(hwnd, cs->style, cs->hwndParent, FALSE);
     430        }
    430431                goto END;
    431         }
    432 
    433         if (!es)
     432    }
     433
     434    if (!es)
    434435        {
    435             if(unicode)
    436                 result = DefWindowProcW(hwnd, msg, wParam, lParam);
    437             else
    438                 result = DefWindowProcA(hwnd, msg, wParam, lParam);
     436        if(unicode)
     437        result = DefWindowProcW(hwnd, msg, wParam, lParam);
     438        else
     439        result = DefWindowProcA(hwnd, msg, wParam, lParam);
    439440            goto END;
    440441        }
    441442
    442443
    443         EDIT_LockBuffer(hwnd, es);
    444         switch (msg) {
    445         case EM_GETSEL16:
    446                 DPRINTF_EDIT_MSG16("EM_GETSEL");
    447                 wParam = 0;
    448                 lParam = 0;
    449                 /* fall through */
    450         case EM_GETSEL:
    451                 DPRINTF_EDIT_MSG32("EM_GETSEL");
    452                 result = EDIT_EM_GetSel(es, (LPUINT)wParam, (LPUINT)lParam);
    453                 break;
    454 
    455         case EM_SETSEL16:
    456                 DPRINTF_EDIT_MSG16("EM_SETSEL");
    457                 if (SLOWORD(lParam) == -1)
    458                         EDIT_EM_SetSel(hwnd, es, (UINT)-1, 0, FALSE);
    459                 else
    460                         EDIT_EM_SetSel(hwnd, es, LOWORD(lParam), HIWORD(lParam), FALSE);
    461                 if (!wParam)
    462                         EDIT_EM_ScrollCaret(hwnd, es);
    463                 result = 1;
    464                 break;
    465         case EM_SETSEL:
    466                 DPRINTF_EDIT_MSG32("EM_SETSEL");
    467                 EDIT_EM_SetSel(hwnd, es, wParam, lParam, FALSE);
    468                 EDIT_EM_ScrollCaret(hwnd, es);
    469                 result = 1;
    470                 break;
    471 
    472         case EM_GETRECT16:
    473                 DPRINTF_EDIT_MSG16("EM_GETRECT");
    474                 if (lParam)
    475                         CONV_RECT32TO16(&es->format_rect, MapSL(lParam));
    476                 break;
    477         case EM_GETRECT:
    478                 DPRINTF_EDIT_MSG32("EM_GETRECT");
    479                 if (lParam)
    480                         CopyRect((LPRECT)lParam, &es->format_rect);
    481                 break;
    482 
    483         case EM_SETRECT16:
    484                 DPRINTF_EDIT_MSG16("EM_SETRECT");
    485                 if ((es->style & ES_MULTILINE) && lParam) {
    486                         RECT rc;
    487                         CONV_RECT16TO32(MapSL(lParam), &rc);
    488                         EDIT_SetRectNP(hwnd, es, &rc);
    489                         EDIT_UpdateText(hwnd, es, NULL, TRUE);
    490                 }
    491                 break;
    492         case EM_SETRECT:
    493                 DPRINTF_EDIT_MSG32("EM_SETRECT");
    494                 if ((es->style & ES_MULTILINE) && lParam) {
    495                         EDIT_SetRectNP(hwnd, es, (LPRECT)lParam);
    496                         EDIT_UpdateText(hwnd, es, NULL, TRUE);
    497                 }
    498                 break;
    499 
    500         case EM_SETRECTNP16:
    501                 DPRINTF_EDIT_MSG16("EM_SETRECTNP");
    502                 if ((es->style & ES_MULTILINE) && lParam) {
    503                         RECT rc;
    504                         CONV_RECT16TO32(MapSL(lParam), &rc);
    505                         EDIT_SetRectNP(hwnd, es, &rc);
    506                 }
    507                 break;
    508         case EM_SETRECTNP:
    509                 DPRINTF_EDIT_MSG32("EM_SETRECTNP");
    510                 if ((es->style & ES_MULTILINE) && lParam)
    511                         EDIT_SetRectNP(hwnd, es, (LPRECT)lParam);
    512                 break;
    513 
    514         case EM_SCROLL16:
    515                 DPRINTF_EDIT_MSG16("EM_SCROLL");
    516                 /* fall through */
    517         case EM_SCROLL:
    518                 DPRINTF_EDIT_MSG32("EM_SCROLL");
    519                 result = EDIT_EM_Scroll(hwnd, es, (INT)wParam);
    520                 break;
    521 
    522         case EM_LINESCROLL16:
    523                 DPRINTF_EDIT_MSG16("EM_LINESCROLL");
    524                 wParam = (WPARAM)(INT)SHIWORD(lParam);
    525                 lParam = (LPARAM)(INT)SLOWORD(lParam);
    526                 /* fall through */
    527         case EM_LINESCROLL:
    528                 DPRINTF_EDIT_MSG32("EM_LINESCROLL");
    529                 result = (LRESULT)EDIT_EM_LineScroll(hwnd, es, (INT)wParam, (INT)lParam);
    530                 break;
    531 
    532         case EM_SCROLLCARET16:
    533                 DPRINTF_EDIT_MSG16("EM_SCROLLCARET");
    534                 /* fall through */
    535         case EM_SCROLLCARET:
    536                 DPRINTF_EDIT_MSG32("EM_SCROLLCARET");
    537                 EDIT_EM_ScrollCaret(hwnd, es);
    538                 result = 1;
    539                 break;
    540 
    541         case EM_GETMODIFY16:
    542                 DPRINTF_EDIT_MSG16("EM_GETMODIFY");
    543                 /* fall through */
    544         case EM_GETMODIFY:
    545                 DPRINTF_EDIT_MSG32("EM_GETMODIFY");
    546                 result = ((es->flags & EF_MODIFIED) != 0);
    547                 break;
    548 
    549         case EM_SETMODIFY16:
    550                 DPRINTF_EDIT_MSG16("EM_SETMODIFY");
    551                 /* fall through */
    552         case EM_SETMODIFY:
    553                 DPRINTF_EDIT_MSG32("EM_SETMODIFY");
    554                 if (wParam)
    555                         es->flags |= EF_MODIFIED;
    556                 else
     444    EDIT_LockBuffer(hwnd, es);
     445    switch (msg) {
     446    case EM_GETSEL16:
     447        DPRINTF_EDIT_MSG16("EM_GETSEL");
     448        wParam = 0;
     449        lParam = 0;
     450        /* fall through */
     451    case EM_GETSEL:
     452        DPRINTF_EDIT_MSG32("EM_GETSEL");
     453        result = EDIT_EM_GetSel(es, (LPUINT)wParam, (LPUINT)lParam);
     454        break;
     455
     456    case EM_SETSEL16:
     457        DPRINTF_EDIT_MSG16("EM_SETSEL");
     458        if (SLOWORD(lParam) == -1)
     459            EDIT_EM_SetSel(hwnd, es, (UINT)-1, 0, FALSE);
     460        else
     461            EDIT_EM_SetSel(hwnd, es, LOWORD(lParam), HIWORD(lParam), FALSE);
     462        if (!wParam)
     463            EDIT_EM_ScrollCaret(hwnd, es);
     464        result = 1;
     465        break;
     466    case EM_SETSEL:
     467        DPRINTF_EDIT_MSG32("EM_SETSEL");
     468        EDIT_EM_SetSel(hwnd, es, wParam, lParam, FALSE);
     469        EDIT_EM_ScrollCaret(hwnd, es);
     470        result = 1;
     471        break;
     472
     473    case EM_GETRECT16:
     474        DPRINTF_EDIT_MSG16("EM_GETRECT");
     475        if (lParam)
     476            CONV_RECT32TO16(&es->format_rect, MapSL(lParam));
     477        break;
     478    case EM_GETRECT:
     479        DPRINTF_EDIT_MSG32("EM_GETRECT");
     480        if (lParam)
     481            CopyRect((LPRECT)lParam, &es->format_rect);
     482        break;
     483
     484    case EM_SETRECT16:
     485        DPRINTF_EDIT_MSG16("EM_SETRECT");
     486        if ((es->style & ES_MULTILINE) && lParam) {
     487            RECT rc;
     488            CONV_RECT16TO32(MapSL(lParam), &rc);
     489            EDIT_SetRectNP(hwnd, es, &rc);
     490            EDIT_UpdateText(hwnd, es, NULL, TRUE);
     491        }
     492        break;
     493    case EM_SETRECT:
     494        DPRINTF_EDIT_MSG32("EM_SETRECT");
     495        if ((es->style & ES_MULTILINE) && lParam) {
     496            EDIT_SetRectNP(hwnd, es, (LPRECT)lParam);
     497            EDIT_UpdateText(hwnd, es, NULL, TRUE);
     498        }
     499        break;
     500
     501    case EM_SETRECTNP16:
     502        DPRINTF_EDIT_MSG16("EM_SETRECTNP");
     503        if ((es->style & ES_MULTILINE) && lParam) {
     504            RECT rc;
     505            CONV_RECT16TO32(MapSL(lParam), &rc);
     506            EDIT_SetRectNP(hwnd, es, &rc);
     507        }
     508        break;
     509    case EM_SETRECTNP:
     510        DPRINTF_EDIT_MSG32("EM_SETRECTNP");
     511        if ((es->style & ES_MULTILINE) && lParam)
     512            EDIT_SetRectNP(hwnd, es, (LPRECT)lParam);
     513        break;
     514
     515    case EM_SCROLL16:
     516        DPRINTF_EDIT_MSG16("EM_SCROLL");
     517        /* fall through */
     518    case EM_SCROLL:
     519        DPRINTF_EDIT_MSG32("EM_SCROLL");
     520        result = EDIT_EM_Scroll(hwnd, es, (INT)wParam);
     521        break;
     522
     523    case EM_LINESCROLL16:
     524        DPRINTF_EDIT_MSG16("EM_LINESCROLL");
     525        wParam = (WPARAM)(INT)SHIWORD(lParam);
     526        lParam = (LPARAM)(INT)SLOWORD(lParam);
     527        /* fall through */
     528    case EM_LINESCROLL:
     529        DPRINTF_EDIT_MSG32("EM_LINESCROLL");
     530        result = (LRESULT)EDIT_EM_LineScroll(hwnd, es, (INT)wParam, (INT)lParam);
     531        break;
     532
     533    case EM_SCROLLCARET16:
     534        DPRINTF_EDIT_MSG16("EM_SCROLLCARET");
     535        /* fall through */
     536    case EM_SCROLLCARET:
     537        DPRINTF_EDIT_MSG32("EM_SCROLLCARET");
     538        EDIT_EM_ScrollCaret(hwnd, es);
     539        result = 1;
     540        break;
     541
     542    case EM_GETMODIFY16:
     543        DPRINTF_EDIT_MSG16("EM_GETMODIFY");
     544        /* fall through */
     545    case EM_GETMODIFY:
     546        DPRINTF_EDIT_MSG32("EM_GETMODIFY");
     547        result = ((es->flags & EF_MODIFIED) != 0);
     548        break;
     549
     550    case EM_SETMODIFY16:
     551        DPRINTF_EDIT_MSG16("EM_SETMODIFY");
     552        /* fall through */
     553    case EM_SETMODIFY:
     554        DPRINTF_EDIT_MSG32("EM_SETMODIFY");
     555        if (wParam)
     556            es->flags |= EF_MODIFIED;
     557        else
    557558                        es->flags &= ~(EF_MODIFIED | EF_UPDATE);  /* reset pending updates */
    558                 break;
    559 
    560         case EM_GETLINECOUNT16:
    561                 DPRINTF_EDIT_MSG16("EM_GETLINECOUNT");
    562                 /* fall through */
    563         case EM_GETLINECOUNT:
    564                 DPRINTF_EDIT_MSG32("EM_GETLINECOUNT");
    565                 result = (es->style & ES_MULTILINE) ? es->line_count : 1;
    566                 break;
    567 
    568         case EM_LINEINDEX16:
    569                 DPRINTF_EDIT_MSG16("EM_LINEINDEX");
    570                 if ((INT16)wParam == -1)
    571                         wParam = (WPARAM)-1;
    572                 /* fall through */
    573         case EM_LINEINDEX:
    574                 DPRINTF_EDIT_MSG32("EM_LINEINDEX");
    575                 result = (LRESULT)EDIT_EM_LineIndex(es, (INT)wParam);
    576                 break;
     559        break;
     560
     561    case EM_GETLINECOUNT16:
     562        DPRINTF_EDIT_MSG16("EM_GETLINECOUNT");
     563        /* fall through */
     564    case EM_GETLINECOUNT:
     565        DPRINTF_EDIT_MSG32("EM_GETLINECOUNT");
     566        result = (es->style & ES_MULTILINE) ? es->line_count : 1;
     567        break;
     568
     569    case EM_LINEINDEX16:
     570        DPRINTF_EDIT_MSG16("EM_LINEINDEX");
     571        if ((INT16)wParam == -1)
     572            wParam = (WPARAM)-1;
     573        /* fall through */
     574    case EM_LINEINDEX:
     575        DPRINTF_EDIT_MSG32("EM_LINEINDEX");
     576        result = (LRESULT)EDIT_EM_LineIndex(es, (INT)wParam);
     577        break;
    577578
    578579#ifndef __WIN32OS2__
    579         case EM_SETHANDLE16:
    580                 DPRINTF_EDIT_MSG16("EM_SETHANDLE");
    581                 EDIT_EM_SetHandle16(hwnd, es, (HLOCAL16)wParam);
    582                 break;
     580    case EM_SETHANDLE16:
     581        DPRINTF_EDIT_MSG16("EM_SETHANDLE");
     582        EDIT_EM_SetHandle16(hwnd, es, (HLOCAL16)wParam);
     583        break;
    583584#endif
    584         case EM_SETHANDLE:
    585                 DPRINTF_EDIT_MSG32("EM_SETHANDLE");
    586                 EDIT_EM_SetHandle(hwnd, es, (HLOCAL)wParam);
    587                 break;
     585    case EM_SETHANDLE:
     586        DPRINTF_EDIT_MSG32("EM_SETHANDLE");
     587        EDIT_EM_SetHandle(hwnd, es, (HLOCAL)wParam);
     588        break;
    588589
    589590#ifndef __WIN32OS2__
    590         case EM_GETHANDLE16:
    591                 DPRINTF_EDIT_MSG16("EM_GETHANDLE");
    592                 result = (LRESULT)EDIT_EM_GetHandle16(hwnd, es);
    593                 break;
     591    case EM_GETHANDLE16:
     592        DPRINTF_EDIT_MSG16("EM_GETHANDLE");
     593        result = (LRESULT)EDIT_EM_GetHandle16(hwnd, es);
     594        break;
    594595#endif
    595         case EM_GETHANDLE:
    596                 DPRINTF_EDIT_MSG32("EM_GETHANDLE");
    597                 result = (LRESULT)EDIT_EM_GetHandle(es);
    598                 break;
    599 
    600         case EM_GETTHUMB16:
    601                 DPRINTF_EDIT_MSG16("EM_GETTHUMB");
    602                 /* fall through */
    603         case EM_GETTHUMB:
    604                 DPRINTF_EDIT_MSG32("EM_GETTHUMB");
    605                 result = EDIT_EM_GetThumb(hwnd, es);
    606                 break;
    607 
    608         /* messages 0x00bf and 0x00c0 missing from specs */
    609 
    610         case WM_USER+15:
    611                 DPRINTF_EDIT_MSG16("undocumented WM_USER+15, please report");
    612                 /* fall through */
    613         case 0x00bf:
    614                 DPRINTF_EDIT_MSG32("undocumented 0x00bf, please report");
    615                 result = DefWindowProcW(hwnd, msg, wParam, lParam);
    616                 break;
    617 
    618         case WM_USER+16:
    619                 DPRINTF_EDIT_MSG16("undocumented WM_USER+16, please report");
    620                 /* fall through */
    621         case 0x00c0:
    622                 DPRINTF_EDIT_MSG32("undocumented 0x00c0, please report");
    623                 result = DefWindowProcW(hwnd, msg, wParam, lParam);
    624                 break;
    625 
    626         case EM_LINELENGTH16:
    627                 DPRINTF_EDIT_MSG16("EM_LINELENGTH");
    628                 /* fall through */
    629         case EM_LINELENGTH:
    630                 DPRINTF_EDIT_MSG32("EM_LINELENGTH");
    631                 result = (LRESULT)EDIT_EM_LineLength(es, (INT)wParam);
    632                 break;
    633 
    634         case EM_REPLACESEL16:
    635                 DPRINTF_EDIT_MSG16("EM_REPLACESEL");
    636                 lParam = (LPARAM)MapSL(lParam);
    637                 unicode = FALSE;  /* 16-bit message is always ascii */
    638                 /* fall through */
    639         case EM_REPLACESEL:
    640         {
    641                 LPWSTR textW;
    642                 DPRINTF_EDIT_MSG32("EM_REPLACESEL");
    643 
    644                 if(unicode)
    645                     textW = (LPWSTR)lParam;
    646                 else
    647                 {
    648                     LPSTR textA = (LPSTR)lParam;
    649                     INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0);
    650                     if((textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR))))
    651                         MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW);
    652                 }
    653 
    654                 EDIT_EM_ReplaceSel(hwnd, es, (BOOL)wParam, textW, TRUE);
    655                 result = 1;
    656 
    657                 if(!unicode)
    658                     HeapFree(GetProcessHeap(), 0, textW);
    659                 break;
    660         }
    661         /* message 0x00c3 missing from specs */
    662 
    663         case WM_USER+19:
    664                 DPRINTF_EDIT_MSG16("undocumented WM_USER+19, please report");
    665                 /* fall through */
    666         case 0x00c3:
    667                 DPRINTF_EDIT_MSG32("undocumented 0x00c3, please report");
    668                 result = DefWindowProcW(hwnd, msg, wParam, lParam);
    669                 break;
    670 
    671         case EM_GETLINE16:
    672                 DPRINTF_EDIT_MSG16("EM_GETLINE");
    673                 lParam = (LPARAM)MapSL(lParam);
    674                 unicode = FALSE;  /* 16-bit message is always ascii */
    675                 /* fall through */
    676         case EM_GETLINE:
    677                 DPRINTF_EDIT_MSG32("EM_GETLINE");
    678                 result = (LRESULT)EDIT_EM_GetLine(es, (INT)wParam, lParam, unicode);
    679                 break;
    680 
    681         case EM_LIMITTEXT16:
    682                 DPRINTF_EDIT_MSG16("EM_LIMITTEXT");
    683                 /* fall through */
    684         case EM_SETLIMITTEXT:
    685                 DPRINTF_EDIT_MSG32("EM_SETLIMITTEXT");
    686                 EDIT_EM_SetLimitText(es, (INT)wParam);
    687                 break;
    688 
    689         case EM_CANUNDO16:
    690                 DPRINTF_EDIT_MSG16("EM_CANUNDO");
    691                 /* fall through */
    692         case EM_CANUNDO:
    693                 DPRINTF_EDIT_MSG32("EM_CANUNDO");
    694                 result = (LRESULT)EDIT_EM_CanUndo(es);
    695                 break;
    696 
    697         case EM_UNDO16:
    698                 DPRINTF_EDIT_MSG16("EM_UNDO");
    699                 /* fall through */
    700         case EM_UNDO:
    701                 /* fall through */
    702         case WM_UNDO:
    703                 DPRINTF_EDIT_MSG32("EM_UNDO / WM_UNDO");
    704                 result = (LRESULT)EDIT_EM_Undo(hwnd, es);
    705                 break;
    706 
    707         case EM_FMTLINES16:
    708                 DPRINTF_EDIT_MSG16("EM_FMTLINES");
    709                 /* fall through */
    710         case EM_FMTLINES:
    711                 DPRINTF_EDIT_MSG32("EM_FMTLINES");
    712                 result = (LRESULT)EDIT_EM_FmtLines(es, (BOOL)wParam);
    713                 break;
    714 
    715         case EM_LINEFROMCHAR16:
    716                 DPRINTF_EDIT_MSG16("EM_LINEFROMCHAR");
    717                 /* fall through */
    718         case EM_LINEFROMCHAR:
    719                 DPRINTF_EDIT_MSG32("EM_LINEFROMCHAR");
    720                 result = (LRESULT)EDIT_EM_LineFromChar(es, (INT)wParam);
    721                 break;
    722 
    723         /* message 0x00ca missing from specs */
    724 
    725         case WM_USER+26:
    726                 DPRINTF_EDIT_MSG16("undocumented WM_USER+26, please report");
    727                 /* fall through */
    728         case 0x00ca:
    729                 DPRINTF_EDIT_MSG32("undocumented 0x00ca, please report");
    730                 result = DefWindowProcW(hwnd, msg, wParam, lParam);
    731                 break;
    732 
    733         case EM_SETTABSTOPS16:
    734                 DPRINTF_EDIT_MSG16("EM_SETTABSTOPS");
    735                 result = (LRESULT)EDIT_EM_SetTabStops16(es, (INT)wParam, MapSL(lParam));
    736                 break;
    737         case EM_SETTABSTOPS:
    738                 DPRINTF_EDIT_MSG32("EM_SETTABSTOPS");
    739                 result = (LRESULT)EDIT_EM_SetTabStops(es, (INT)wParam, (LPINT)lParam);
    740                 break;
    741 
    742         case EM_SETPASSWORDCHAR16:
    743                 DPRINTF_EDIT_MSG16("EM_SETPASSWORDCHAR");
    744                 unicode = FALSE;  /* 16-bit message is always ascii */
    745                 /* fall through */
    746         case EM_SETPASSWORDCHAR:
    747         {
    748                 WCHAR charW = 0;
    749                 DPRINTF_EDIT_MSG32("EM_SETPASSWORDCHAR");
    750 
    751                 if(unicode)
    752                     charW = (WCHAR)wParam;
    753                 else
    754                 {
    755                     CHAR charA = wParam;
    756                     MultiByteToWideChar(CP_ACP, 0, &charA, 1, &charW, 1);
    757                 }
    758 
    759                 EDIT_EM_SetPasswordChar(hwnd, es, charW);
    760                 break;
    761         }
    762 
    763         case EM_EMPTYUNDOBUFFER16:
    764                 DPRINTF_EDIT_MSG16("EM_EMPTYUNDOBUFFER");
    765                 /* fall through */
    766         case EM_EMPTYUNDOBUFFER:
    767                 DPRINTF_EDIT_MSG32("EM_EMPTYUNDOBUFFER");
    768                 EDIT_EM_EmptyUndoBuffer(es);
    769                 break;
    770 
    771         case EM_GETFIRSTVISIBLELINE16:
    772                 DPRINTF_EDIT_MSG16("EM_GETFIRSTVISIBLELINE");
    773                 result = es->y_offset;
    774                 break;
    775         case EM_GETFIRSTVISIBLELINE:
    776                 DPRINTF_EDIT_MSG32("EM_GETFIRSTVISIBLELINE");
    777                 result = (es->style & ES_MULTILINE) ? es->y_offset : es->x_offset;
    778                 break;
    779 
    780         case EM_SETREADONLY16:
    781                 DPRINTF_EDIT_MSG16("EM_SETREADONLY");
    782                 /* fall through */
    783         case EM_SETREADONLY:
    784                 DPRINTF_EDIT_MSG32("EM_SETREADONLY");
    785                 if (wParam) {
     596    case EM_GETHANDLE:
     597        DPRINTF_EDIT_MSG32("EM_GETHANDLE");
     598        result = (LRESULT)EDIT_EM_GetHandle(es);
     599        break;
     600
     601    case EM_GETTHUMB16:
     602        DPRINTF_EDIT_MSG16("EM_GETTHUMB");
     603        /* fall through */
     604    case EM_GETTHUMB:
     605        DPRINTF_EDIT_MSG32("EM_GETTHUMB");
     606        result = EDIT_EM_GetThumb(hwnd, es);
     607        break;
     608
     609    /* messages 0x00bf and 0x00c0 missing from specs */
     610
     611    case WM_USER+15:
     612        DPRINTF_EDIT_MSG16("undocumented WM_USER+15, please report");
     613        /* fall through */
     614    case 0x00bf:
     615        DPRINTF_EDIT_MSG32("undocumented 0x00bf, please report");
     616        result = DefWindowProcW(hwnd, msg, wParam, lParam);
     617        break;
     618
     619    case WM_USER+16:
     620        DPRINTF_EDIT_MSG16("undocumented WM_USER+16, please report");
     621        /* fall through */
     622    case 0x00c0:
     623        DPRINTF_EDIT_MSG32("undocumented 0x00c0, please report");
     624        result = DefWindowProcW(hwnd, msg, wParam, lParam);
     625        break;
     626
     627    case EM_LINELENGTH16:
     628        DPRINTF_EDIT_MSG16("EM_LINELENGTH");
     629        /* fall through */
     630    case EM_LINELENGTH:
     631        DPRINTF_EDIT_MSG32("EM_LINELENGTH");
     632        result = (LRESULT)EDIT_EM_LineLength(es, (INT)wParam);
     633        break;
     634
     635    case EM_REPLACESEL16:
     636        DPRINTF_EDIT_MSG16("EM_REPLACESEL");
     637        lParam = (LPARAM)MapSL(lParam);
     638        unicode = FALSE;  /* 16-bit message is always ascii */
     639        /* fall through */
     640    case EM_REPLACESEL:
     641    {
     642        LPWSTR textW;
     643        DPRINTF_EDIT_MSG32("EM_REPLACESEL");
     644
     645        if(unicode)
     646            textW = (LPWSTR)lParam;
     647        else
     648        {
     649            LPSTR textA = (LPSTR)lParam;
     650            INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0);
     651            if((textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR))))
     652            MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW);
     653        }
     654
     655        EDIT_EM_ReplaceSel(hwnd, es, (BOOL)wParam, textW, TRUE);
     656        result = 1;
     657
     658        if(!unicode)
     659            HeapFree(GetProcessHeap(), 0, textW);
     660        break;
     661    }
     662    /* message 0x00c3 missing from specs */
     663
     664    case WM_USER+19:
     665        DPRINTF_EDIT_MSG16("undocumented WM_USER+19, please report");
     666        /* fall through */
     667    case 0x00c3:
     668        DPRINTF_EDIT_MSG32("undocumented 0x00c3, please report");
     669        result = DefWindowProcW(hwnd, msg, wParam, lParam);
     670        break;
     671
     672    case EM_GETLINE16:
     673        DPRINTF_EDIT_MSG16("EM_GETLINE");
     674        lParam = (LPARAM)MapSL(lParam);
     675        unicode = FALSE;  /* 16-bit message is always ascii */
     676        /* fall through */
     677    case EM_GETLINE:
     678        DPRINTF_EDIT_MSG32("EM_GETLINE");
     679        result = (LRESULT)EDIT_EM_GetLine(es, (INT)wParam, lParam, unicode);
     680        break;
     681
     682    case EM_LIMITTEXT16:
     683        DPRINTF_EDIT_MSG16("EM_LIMITTEXT");
     684        /* fall through */
     685    case EM_SETLIMITTEXT:
     686        DPRINTF_EDIT_MSG32("EM_SETLIMITTEXT");
     687        EDIT_EM_SetLimitText(es, (INT)wParam);
     688        break;
     689
     690    case EM_CANUNDO16:
     691        DPRINTF_EDIT_MSG16("EM_CANUNDO");
     692        /* fall through */
     693    case EM_CANUNDO:
     694        DPRINTF_EDIT_MSG32("EM_CANUNDO");
     695        result = (LRESULT)EDIT_EM_CanUndo(es);
     696        break;
     697
     698    case EM_UNDO16:
     699        DPRINTF_EDIT_MSG16("EM_UNDO");
     700        /* fall through */
     701    case EM_UNDO:
     702        /* fall through */
     703    case WM_UNDO:
     704        DPRINTF_EDIT_MSG32("EM_UNDO / WM_UNDO");
     705        result = (LRESULT)EDIT_EM_Undo(hwnd, es);
     706        break;
     707
     708    case EM_FMTLINES16:
     709        DPRINTF_EDIT_MSG16("EM_FMTLINES");
     710        /* fall through */
     711    case EM_FMTLINES:
     712        DPRINTF_EDIT_MSG32("EM_FMTLINES");
     713        result = (LRESULT)EDIT_EM_FmtLines(es, (BOOL)wParam);
     714        break;
     715
     716    case EM_LINEFROMCHAR16:
     717        DPRINTF_EDIT_MSG16("EM_LINEFROMCHAR");
     718        /* fall through */
     719    case EM_LINEFROMCHAR:
     720        DPRINTF_EDIT_MSG32("EM_LINEFROMCHAR");
     721        result = (LRESULT)EDIT_EM_LineFromChar(es, (INT)wParam);
     722        break;
     723
     724    /* message 0x00ca missing from specs */
     725
     726    case WM_USER+26:
     727        DPRINTF_EDIT_MSG16("undocumented WM_USER+26, please report");
     728        /* fall through */
     729    case 0x00ca:
     730        DPRINTF_EDIT_MSG32("undocumented 0x00ca, please report");
     731        result = DefWindowProcW(hwnd, msg, wParam, lParam);
     732        break;
     733
     734    case EM_SETTABSTOPS16:
     735        DPRINTF_EDIT_MSG16("EM_SETTABSTOPS");
     736        result = (LRESULT)EDIT_EM_SetTabStops16(es, (INT)wParam, MapSL(lParam));
     737        break;
     738    case EM_SETTABSTOPS:
     739        DPRINTF_EDIT_MSG32("EM_SETTABSTOPS");
     740        result = (LRESULT)EDIT_EM_SetTabStops(es, (INT)wParam, (LPINT)lParam);
     741        break;
     742
     743    case EM_SETPASSWORDCHAR16:
     744        DPRINTF_EDIT_MSG16("EM_SETPASSWORDCHAR");
     745        unicode = FALSE;  /* 16-bit message is always ascii */
     746        /* fall through */
     747    case EM_SETPASSWORDCHAR:
     748    {
     749        WCHAR charW = 0;
     750        DPRINTF_EDIT_MSG32("EM_SETPASSWORDCHAR");
     751
     752        if(unicode)
     753            charW = (WCHAR)wParam;
     754        else
     755        {
     756            CHAR charA = wParam;
     757            MultiByteToWideChar(CP_ACP, 0, &charA, 1, &charW, 1);
     758        }
     759
     760        EDIT_EM_SetPasswordChar(hwnd, es, charW);
     761        break;
     762    }
     763
     764    case EM_EMPTYUNDOBUFFER16:
     765        DPRINTF_EDIT_MSG16("EM_EMPTYUNDOBUFFER");
     766        /* fall through */
     767    case EM_EMPTYUNDOBUFFER:
     768        DPRINTF_EDIT_MSG32("EM_EMPTYUNDOBUFFER");
     769        EDIT_EM_EmptyUndoBuffer(es);
     770        break;
     771
     772    case EM_GETFIRSTVISIBLELINE16:
     773        DPRINTF_EDIT_MSG16("EM_GETFIRSTVISIBLELINE");
     774        result = es->y_offset;
     775        break;
     776    case EM_GETFIRSTVISIBLELINE:
     777        DPRINTF_EDIT_MSG32("EM_GETFIRSTVISIBLELINE");
     778        result = (es->style & ES_MULTILINE) ? es->y_offset : es->x_offset;
     779        break;
     780
     781    case EM_SETREADONLY16:
     782        DPRINTF_EDIT_MSG16("EM_SETREADONLY");
     783        /* fall through */
     784    case EM_SETREADONLY:
     785        DPRINTF_EDIT_MSG32("EM_SETREADONLY");
     786        if (wParam) {
    786787                    SetWindowLongA( hwnd, GWL_STYLE,
    787788                                    GetWindowLongA( hwnd, GWL_STYLE ) | ES_READONLY );
    788789                    es->style |= ES_READONLY;
    789                 } else {
     790        } else {
    790791                    SetWindowLongA( hwnd, GWL_STYLE,
    791792                                    GetWindowLongA( hwnd, GWL_STYLE ) & ~ES_READONLY );
    792793                    es->style &= ~ES_READONLY;
    793                 }
     794        }
    794795                result = 1;
    795                 break;
     796        break;
    796797#ifndef __WIN32OS2__
    797         case EM_SETWORDBREAKPROC16:
    798                 DPRINTF_EDIT_MSG16("EM_SETWORDBREAKPROC");
    799                 EDIT_EM_SetWordBreakProc16(hwnd, es, (EDITWORDBREAKPROC16)lParam);
    800                 break;
     798    case EM_SETWORDBREAKPROC16:
     799        DPRINTF_EDIT_MSG16("EM_SETWORDBREAKPROC");
     800        EDIT_EM_SetWordBreakProc16(hwnd, es, (EDITWORDBREAKPROC16)lParam);
     801        break;
    801802#endif
    802         case EM_SETWORDBREAKPROC:
    803                 DPRINTF_EDIT_MSG32("EM_SETWORDBREAKPROC");
    804                 EDIT_EM_SetWordBreakProc(hwnd, es, lParam);
    805                 break;
    806 
    807         case EM_GETWORDBREAKPROC16:
    808                 DPRINTF_EDIT_MSG16("EM_GETWORDBREAKPROC");
    809                 result = (LRESULT)es->word_break_proc16;
    810                 break;
    811         case EM_GETWORDBREAKPROC:
    812                 DPRINTF_EDIT_MSG32("EM_GETWORDBREAKPROC");
    813                 result = (LRESULT)es->word_break_proc;
    814                 break;
    815 
    816         case EM_GETPASSWORDCHAR16:
    817                 DPRINTF_EDIT_MSG16("EM_GETPASSWORDCHAR");
    818                 unicode = FALSE;  /* 16-bit message is always ascii */
    819                 /* fall through */
    820         case EM_GETPASSWORDCHAR:
    821         {
    822                 DPRINTF_EDIT_MSG32("EM_GETPASSWORDCHAR");
    823 
    824                 if(unicode)
    825                     result = es->password_char;
    826                 else
    827                 {
    828                     WCHAR charW = es->password_char;
    829                     CHAR charA = 0;
    830                     WideCharToMultiByte(CP_ACP, 0, &charW, 1, &charA, 1, NULL, NULL);
    831                     result = charA;
    832                 }
    833                 break;
    834         }
    835 
    836         /* The following EM_xxx are new to win95 and don't exist for 16 bit */
    837 
    838         case EM_SETMARGINS:
    839                 DPRINTF_EDIT_MSG32("EM_SETMARGINS");
    840                 EDIT_EM_SetMargins(es, (INT)wParam, SLOWORD(lParam), SHIWORD(lParam));
    841                 break;
    842 
    843         case EM_GETMARGINS:
    844                 DPRINTF_EDIT_MSG32("EM_GETMARGINS");
    845                 result = MAKELONG(es->left_margin, es->right_margin);
    846                 break;
    847 
    848         case EM_GETLIMITTEXT:
    849                 DPRINTF_EDIT_MSG32("EM_GETLIMITTEXT");
    850                 result = es->buffer_limit;
    851                 break;
    852 
    853         case EM_POSFROMCHAR:
    854                 DPRINTF_EDIT_MSG32("EM_POSFROMCHAR");
    855                 result = EDIT_EM_PosFromChar(hwnd, es, (INT)wParam, FALSE);
    856                 break;
    857 
    858         case EM_CHARFROMPOS:
    859                 DPRINTF_EDIT_MSG32("EM_CHARFROMPOS");
    860                 result = EDIT_EM_CharFromPos(hwnd, es, SLOWORD(lParam), SHIWORD(lParam));
    861                 break;
     803    case EM_SETWORDBREAKPROC:
     804        DPRINTF_EDIT_MSG32("EM_SETWORDBREAKPROC");
     805        EDIT_EM_SetWordBreakProc(hwnd, es, lParam);
     806        break;
     807
     808    case EM_GETWORDBREAKPROC16:
     809        DPRINTF_EDIT_MSG16("EM_GETWORDBREAKPROC");
     810        result = (LRESULT)es->word_break_proc16;
     811        break;
     812    case EM_GETWORDBREAKPROC:
     813        DPRINTF_EDIT_MSG32("EM_GETWORDBREAKPROC");
     814        result = (LRESULT)es->word_break_proc;
     815        break;
     816
     817    case EM_GETPASSWORDCHAR16:
     818        DPRINTF_EDIT_MSG16("EM_GETPASSWORDCHAR");
     819        unicode = FALSE;  /* 16-bit message is always ascii */
     820        /* fall through */
     821    case EM_GETPASSWORDCHAR:
     822    {
     823        DPRINTF_EDIT_MSG32("EM_GETPASSWORDCHAR");
     824
     825        if(unicode)
     826            result = es->password_char;
     827        else
     828        {
     829            WCHAR charW = es->password_char;
     830            CHAR charA = 0;
     831            WideCharToMultiByte(CP_ACP, 0, &charW, 1, &charA, 1, NULL, NULL);
     832            result = charA;
     833        }
     834        break;
     835    }
     836
     837    /* The following EM_xxx are new to win95 and don't exist for 16 bit */
     838
     839    case EM_SETMARGINS:
     840        DPRINTF_EDIT_MSG32("EM_SETMARGINS");
     841        EDIT_EM_SetMargins(es, (INT)wParam, SLOWORD(lParam), SHIWORD(lParam));
     842        break;
     843
     844    case EM_GETMARGINS:
     845        DPRINTF_EDIT_MSG32("EM_GETMARGINS");
     846        result = MAKELONG(es->left_margin, es->right_margin);
     847        break;
     848
     849    case EM_GETLIMITTEXT:
     850        DPRINTF_EDIT_MSG32("EM_GETLIMITTEXT");
     851        result = es->buffer_limit;
     852        break;
     853
     854    case EM_POSFROMCHAR:
     855        DPRINTF_EDIT_MSG32("EM_POSFROMCHAR");
     856        result = EDIT_EM_PosFromChar(hwnd, es, (INT)wParam, FALSE);
     857        break;
     858
     859    case EM_CHARFROMPOS:
     860        DPRINTF_EDIT_MSG32("EM_CHARFROMPOS");
     861        result = EDIT_EM_CharFromPos(hwnd, es, SLOWORD(lParam), SHIWORD(lParam));
     862        break;
    862863
    863864        /* End of the EM_ messages which were in numerical order; what order
     
    865866         */
    866867
    867         case WM_GETDLGCODE:
    868                 DPRINTF_EDIT_MSG32("WM_GETDLGCODE");
    869                 result = DLGC_HASSETSEL | DLGC_WANTCHARS | DLGC_WANTARROWS;
    870 
    871                 if (lParam && (((LPMSG)lParam)->message == WM_KEYDOWN))
    872                 {
    873                    int vk = (int)((LPMSG)lParam)->wParam;
    874 
    875                    if (vk == VK_RETURN && (GetWindowLongA( hwnd, GWL_STYLE ) & ES_WANTRETURN))
    876                    {
    877                       result |= DLGC_WANTMESSAGE;
    878                    }
    879                    else if (es->hwndListBox && (vk == VK_RETURN || vk == VK_ESCAPE))
    880                    {
    881                       if (SendMessageW(GetParent(hwnd), CB_GETDROPPEDSTATE, 0, 0))
    882                          result |= DLGC_WANTMESSAGE;
    883                    }
    884                 }
    885                 break;
    886 
    887         case WM_CHAR:
    888         {
     868    case WM_GETDLGCODE:
     869        DPRINTF_EDIT_MSG32("WM_GETDLGCODE");
     870        result = DLGC_HASSETSEL | DLGC_WANTCHARS | DLGC_WANTARROWS;
     871
     872        if (lParam && (((LPMSG)lParam)->message == WM_KEYDOWN))
     873        {
     874           int vk = (int)((LPMSG)lParam)->wParam;
     875
     876           if (vk == VK_RETURN && (GetWindowLongA( hwnd, GWL_STYLE ) & ES_WANTRETURN))
     877           {
     878              result |= DLGC_WANTMESSAGE;
     879           }
     880           else if (es->hwndListBox && (vk == VK_RETURN || vk == VK_ESCAPE))
     881           {
     882              if (SendMessageW(GetParent(hwnd), CB_GETDROPPEDSTATE, 0, 0))
     883                 result |= DLGC_WANTMESSAGE;
     884           }
     885        }
     886        break;
     887
     888    case WM_CHAR:
     889    {
     890#ifdef __WIN32OS2__
     891        static BOOL bDbcsLead = FALSE;
     892        static CHAR cDbcsLead = 0;
     893
     894        WCHAR charW;
     895        DPRINTF_EDIT_MSG32("WM_CHAR");
     896
     897        if(unicode)
     898            charW = wParam;
     899        else
     900        {
     901            WCHAR charA = bDbcsLead ? (( wParam << 8 ) | cDbcsLead ) : wParam;
     902            int   size = bDbcsLead ? 2 : 1;
     903
     904            bDbcsLead = !bDbcsLead && IsDBCSLeadByte( wParam );
     905
     906            if( bDbcsLead )
     907                cDbcsLead = wParam;
     908            else
     909                MultiByteToWideChar(CP_ACP, 0, (LPSTR)&charA, size, &charW, 1);
     910        }
     911
     912        if ((charW == VK_RETURN || charW == VK_ESCAPE) && es->hwndListBox)
     913        {
     914           if (SendMessageW(GetParent(hwnd), CB_GETDROPPEDSTATE, 0, 0))
     915              SendMessageW(GetParent(hwnd), WM_KEYDOWN, charW, 0);
     916           break;
     917        }
     918        if( !bDbcsLead )
     919            EDIT_WM_Char(hwnd, es, charW);
     920#else
    889921                WCHAR charW;
    890922                DPRINTF_EDIT_MSG32("WM_CHAR");
     
    905937                }
    906938                EDIT_WM_Char(hwnd, es, charW);
    907                 break;
    908         }
    909 
    910         case WM_CLEAR:
    911                 DPRINTF_EDIT_MSG32("WM_CLEAR");
    912                 EDIT_WM_Clear(hwnd, es);
    913                 break;
    914 
    915         case WM_COMMAND:
    916                 DPRINTF_EDIT_MSG32("WM_COMMAND");
    917                 EDIT_WM_Command(hwnd, es, HIWORD(wParam), LOWORD(wParam), (HWND)lParam);
    918                 break;
    919 
    920         case WM_CONTEXTMENU:
    921                 DPRINTF_EDIT_MSG32("WM_CONTEXTMENU");
    922                 EDIT_WM_ContextMenu(hwnd, es, SLOWORD(lParam), SHIWORD(lParam));
    923                 break;
    924 
    925         case WM_COPY:
    926                 DPRINTF_EDIT_MSG32("WM_COPY");
    927                 EDIT_WM_Copy(hwnd, es);
    928                 break;
    929 
    930         case WM_CREATE:
    931                 DPRINTF_EDIT_MSG32("WM_CREATE");
    932                 if(unicode)
    933                     result = EDIT_WM_Create(hwnd, es, ((LPCREATESTRUCTW)lParam)->lpszName);
    934                 else
    935                 {
    936                     LPCSTR nameA = ((LPCREATESTRUCTA)lParam)->lpszName;
    937                     LPWSTR nameW = NULL;
    938                     if(nameA)
    939                     {
    940                         INT countW = MultiByteToWideChar(CP_ACP, 0, nameA, -1, NULL, 0);
    941                         if((nameW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR))))
    942                             MultiByteToWideChar(CP_ACP, 0, nameA, -1, nameW, countW);
    943                     }
    944                     result = EDIT_WM_Create(hwnd, es, nameW);
    945                     if(nameW)
    946                         HeapFree(GetProcessHeap(), 0, nameW);
    947                 }
    948                 break;
    949 
    950         case WM_CUT:
    951                 DPRINTF_EDIT_MSG32("WM_CUT");
    952                 EDIT_WM_Cut(hwnd, es);
    953                 break;
    954 
    955         case WM_ENABLE:
    956                 DPRINTF_EDIT_MSG32("WM_ENABLE");
     939#endif
     940        break;
     941    }
     942
     943    case WM_CLEAR:
     944        DPRINTF_EDIT_MSG32("WM_CLEAR");
     945        EDIT_WM_Clear(hwnd, es);
     946        break;
     947
     948    case WM_COMMAND:
     949        DPRINTF_EDIT_MSG32("WM_COMMAND");
     950        EDIT_WM_Command(hwnd, es, HIWORD(wParam), LOWORD(wParam), (HWND)lParam);
     951        break;
     952
     953    case WM_CONTEXTMENU:
     954        DPRINTF_EDIT_MSG32("WM_CONTEXTMENU");
     955        EDIT_WM_ContextMenu(hwnd, es, SLOWORD(lParam), SHIWORD(lParam));
     956        break;
     957
     958    case WM_COPY:
     959        DPRINTF_EDIT_MSG32("WM_COPY");
     960        EDIT_WM_Copy(hwnd, es);
     961        break;
     962
     963    case WM_CREATE:
     964        DPRINTF_EDIT_MSG32("WM_CREATE");
     965        if(unicode)
     966            result = EDIT_WM_Create(hwnd, es, ((LPCREATESTRUCTW)lParam)->lpszName);
     967        else
     968        {
     969            LPCSTR nameA = ((LPCREATESTRUCTA)lParam)->lpszName;
     970            LPWSTR nameW = NULL;
     971            if(nameA)
     972            {
     973            INT countW = MultiByteToWideChar(CP_ACP, 0, nameA, -1, NULL, 0);
     974            if((nameW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR))))
     975                MultiByteToWideChar(CP_ACP, 0, nameA, -1, nameW, countW);
     976            }
     977            result = EDIT_WM_Create(hwnd, es, nameW);
     978            if(nameW)
     979            HeapFree(GetProcessHeap(), 0, nameW);
     980        }
     981        break;
     982
     983    case WM_CUT:
     984        DPRINTF_EDIT_MSG32("WM_CUT");
     985        EDIT_WM_Cut(hwnd, es);
     986        break;
     987
     988    case WM_ENABLE:
     989        DPRINTF_EDIT_MSG32("WM_ENABLE");
    957990                es->bEnableState = (BOOL) wParam;
    958                 EDIT_UpdateText(hwnd, es, NULL, TRUE);
    959                 break;
    960 
    961         case WM_ERASEBKGND:
    962                 DPRINTF_EDIT_MSG32("WM_ERASEBKGND");
    963                 result = EDIT_WM_EraseBkGnd(hwnd, es, (HDC)wParam);
    964                 break;
    965 
    966         case WM_GETFONT:
    967                 DPRINTF_EDIT_MSG32("WM_GETFONT");
    968                 result = (LRESULT)es->font;
    969                 break;
    970 
    971         case WM_GETTEXT:
    972                 DPRINTF_EDIT_MSG32("WM_GETTEXT");
    973                 result = (LRESULT)EDIT_WM_GetText(es, (INT)wParam, lParam, unicode);
    974                 break;
    975 
    976         case WM_GETTEXTLENGTH:
    977                 DPRINTF_EDIT_MSG32("WM_GETTEXTLENGTH");
    978                 result = strlenW(es->text);
    979                 break;
    980 
    981         case WM_HSCROLL:
    982                 DPRINTF_EDIT_MSG32("WM_HSCROLL");
    983                 result = EDIT_WM_HScroll(hwnd, es, LOWORD(wParam), SHIWORD(wParam));
    984                 break;
    985 
    986         case WM_KEYDOWN:
    987                 DPRINTF_EDIT_MSG32("WM_KEYDOWN");
    988                 result = EDIT_WM_KeyDown(hwnd, es, (INT)wParam);
    989                 break;
    990 
    991         case WM_KILLFOCUS:
    992                 DPRINTF_EDIT_MSG32("WM_KILLFOCUS");
    993                 result = EDIT_WM_KillFocus(hwnd, es);
    994                 break;
    995 
    996         case WM_LBUTTONDBLCLK:
    997                 DPRINTF_EDIT_MSG32("WM_LBUTTONDBLCLK");
    998                 result = EDIT_WM_LButtonDblClk(hwnd, es);
    999                 break;
    1000 
    1001         case WM_LBUTTONDOWN:
    1002                 DPRINTF_EDIT_MSG32("WM_LBUTTONDOWN");
    1003                 result = EDIT_WM_LButtonDown(hwnd, es, (DWORD)wParam, SLOWORD(lParam), SHIWORD(lParam));
    1004                 break;
    1005 
    1006         case WM_LBUTTONUP:
    1007                 DPRINTF_EDIT_MSG32("WM_LBUTTONUP");
    1008                 result = EDIT_WM_LButtonUp(hwnd, es);
    1009                 break;
    1010 
    1011         case WM_MBUTTONDOWN:
    1012                 DPRINTF_EDIT_MSG32("WM_MBUTTONDOWN");
    1013                 result = EDIT_WM_MButtonDown(hwnd);
    1014                 break;
    1015 
    1016         case WM_MOUSEACTIVATE:
    1017                 /*
    1018                  *      FIXME: maybe DefWindowProc() screws up, but it seems that
    1019                  *              modeless dialog boxes need this.  If we don't do this, the focus
    1020                  *              will _not_ be set by DefWindowProc() for edit controls in a
    1021                  *              modeless dialog box ???
    1022                 */
    1023                 DPRINTF_EDIT_MSG32("WM_MOUSEACTIVATE");
    1024                 SetFocus(hwnd);
    1025                 result = MA_ACTIVATE;
    1026                 break;
    1027 
    1028         case WM_MOUSEMOVE:
    1029                 /*
    1030                  *      DPRINTF_EDIT_MSG32("WM_MOUSEMOVE");
    1031                 */
    1032                 result = EDIT_WM_MouseMove(hwnd, es, SLOWORD(lParam), SHIWORD(lParam));
    1033                 break;
    1034 
    1035         case WM_PAINT:
    1036                 DPRINTF_EDIT_MSG32("WM_PAINT");
    1037                 EDIT_WM_Paint(hwnd, es, wParam);
    1038                 break;
    1039 
    1040         case WM_PASTE:
    1041                 DPRINTF_EDIT_MSG32("WM_PASTE");
    1042                 EDIT_WM_Paste(hwnd, es);
    1043                 break;
    1044 
    1045         case WM_SETFOCUS:
    1046                 DPRINTF_EDIT_MSG32("WM_SETFOCUS");
    1047                 EDIT_WM_SetFocus(hwnd, es);
    1048                 break;
    1049 
    1050         case WM_SETFONT:
    1051                 DPRINTF_EDIT_MSG32("WM_SETFONT");
    1052                 EDIT_WM_SetFont(hwnd, es, (HFONT)wParam, LOWORD(lParam) != 0);
    1053                 break;
    1054 
    1055         case WM_SETREDRAW:
    1056                 /* FIXME: actually set an internal flag and behave accordingly */
    1057                 break;
    1058 
    1059         case WM_SETTEXT:
    1060                 DPRINTF_EDIT_MSG32("WM_SETTEXT");
    1061                 EDIT_WM_SetText(hwnd, es, lParam, unicode);
    1062                 result = TRUE;
    1063                 break;
    1064 
    1065         case WM_SIZE:
    1066                 DPRINTF_EDIT_MSG32("WM_SIZE");
    1067                 EDIT_WM_Size(hwnd, es, (UINT)wParam, LOWORD(lParam), HIWORD(lParam));
    1068                 break;
     991        EDIT_UpdateText(hwnd, es, NULL, TRUE);
     992        break;
     993
     994    case WM_ERASEBKGND:
     995        DPRINTF_EDIT_MSG32("WM_ERASEBKGND");
     996        result = EDIT_WM_EraseBkGnd(hwnd, es, (HDC)wParam);
     997        break;
     998
     999    case WM_GETFONT:
     1000        DPRINTF_EDIT_MSG32("WM_GETFONT");
     1001        result = (LRESULT)es->font;
     1002        break;
     1003
     1004    case WM_GETTEXT:
     1005        DPRINTF_EDIT_MSG32("WM_GETTEXT");
     1006        result = (LRESULT)EDIT_WM_GetText(es, (INT)wParam, lParam, unicode);
     1007        break;
     1008
     1009    case WM_GETTEXTLENGTH:
     1010        DPRINTF_EDIT_MSG32("WM_GETTEXTLENGTH");
     1011        result = strlenW(es->text);
     1012        break;
     1013
     1014    case WM_HSCROLL:
     1015        DPRINTF_EDIT_MSG32("WM_HSCROLL");
     1016        result = EDIT_WM_HScroll(hwnd, es, LOWORD(wParam), SHIWORD(wParam));
     1017        break;
     1018
     1019    case WM_KEYDOWN:
     1020        DPRINTF_EDIT_MSG32("WM_KEYDOWN");
     1021        result = EDIT_WM_KeyDown(hwnd, es, (INT)wParam);
     1022        break;
     1023
     1024    case WM_KILLFOCUS:
     1025        DPRINTF_EDIT_MSG32("WM_KILLFOCUS");
     1026        result = EDIT_WM_KillFocus(hwnd, es);
     1027        break;
     1028
     1029    case WM_LBUTTONDBLCLK:
     1030        DPRINTF_EDIT_MSG32("WM_LBUTTONDBLCLK");
     1031        result = EDIT_WM_LButtonDblClk(hwnd, es);
     1032        break;
     1033
     1034    case WM_LBUTTONDOWN:
     1035        DPRINTF_EDIT_MSG32("WM_LBUTTONDOWN");
     1036        result = EDIT_WM_LButtonDown(hwnd, es, (DWORD)wParam, SLOWORD(lParam), SHIWORD(lParam));
     1037        break;
     1038
     1039    case WM_LBUTTONUP:
     1040        DPRINTF_EDIT_MSG32("WM_LBUTTONUP");
     1041        result = EDIT_WM_LButtonUp(hwnd, es);
     1042        break;
     1043
     1044    case WM_MBUTTONDOWN:
     1045        DPRINTF_EDIT_MSG32("WM_MBUTTONDOWN");
     1046        result = EDIT_WM_MButtonDown(hwnd);
     1047        break;
     1048
     1049    case WM_MOUSEACTIVATE:
     1050        /*
     1051         *  FIXME: maybe DefWindowProc() screws up, but it seems that
     1052         *      modeless dialog boxes need this.  If we don't do this, the focus
     1053         *      will _not_ be set by DefWindowProc() for edit controls in a
     1054         *      modeless dialog box ???
     1055        */
     1056        DPRINTF_EDIT_MSG32("WM_MOUSEACTIVATE");
     1057        SetFocus(hwnd);
     1058        result = MA_ACTIVATE;
     1059        break;
     1060
     1061    case WM_MOUSEMOVE:
     1062        /*
     1063         *  DPRINTF_EDIT_MSG32("WM_MOUSEMOVE");
     1064        */
     1065        result = EDIT_WM_MouseMove(hwnd, es, SLOWORD(lParam), SHIWORD(lParam));
     1066        break;
     1067
     1068    case WM_PAINT:
     1069        DPRINTF_EDIT_MSG32("WM_PAINT");
     1070            EDIT_WM_Paint(hwnd, es, wParam);
     1071        break;
     1072
     1073    case WM_PASTE:
     1074        DPRINTF_EDIT_MSG32("WM_PASTE");
     1075        EDIT_WM_Paste(hwnd, es);
     1076        break;
     1077
     1078    case WM_SETFOCUS:
     1079        DPRINTF_EDIT_MSG32("WM_SETFOCUS");
     1080        EDIT_WM_SetFocus(hwnd, es);
     1081        break;
     1082
     1083    case WM_SETFONT:
     1084        DPRINTF_EDIT_MSG32("WM_SETFONT");
     1085        EDIT_WM_SetFont(hwnd, es, (HFONT)wParam, LOWORD(lParam) != 0);
     1086        break;
     1087
     1088    case WM_SETREDRAW:
     1089        /* FIXME: actually set an internal flag and behave accordingly */
     1090        break;
     1091
     1092    case WM_SETTEXT:
     1093        DPRINTF_EDIT_MSG32("WM_SETTEXT");
     1094        EDIT_WM_SetText(hwnd, es, lParam, unicode);
     1095        result = TRUE;
     1096        break;
     1097
     1098    case WM_SIZE:
     1099        DPRINTF_EDIT_MSG32("WM_SIZE");
     1100        EDIT_WM_Size(hwnd, es, (UINT)wParam, LOWORD(lParam), HIWORD(lParam));
     1101        break;
    10691102
    10701103        case WM_STYLECHANGED:
    1071                 DPRINTF_EDIT_MSG32("WM_STYLECHANGED");
     1104        DPRINTF_EDIT_MSG32("WM_STYLECHANGED");
    10721105                result = EDIT_WM_StyleChanged (hwnd, es, wParam, (const STYLESTRUCT *)lParam);
    10731106                break;
    10741107
    10751108        case WM_STYLECHANGING:
    1076                 DPRINTF_EDIT_MSG32("WM_STYLECHANGING");
     1109        DPRINTF_EDIT_MSG32("WM_STYLECHANGING");
    10771110                result = 0; /* See EDIT_WM_StyleChanged */
    10781111                break;
    10791112
    1080         case WM_SYSKEYDOWN:
    1081                 DPRINTF_EDIT_MSG32("WM_SYSKEYDOWN");
    1082                 result = EDIT_WM_SysKeyDown(hwnd, es, (INT)wParam, (DWORD)lParam);
    1083                 break;
    1084 
    1085         case WM_TIMER:
    1086                 DPRINTF_EDIT_MSG32("WM_TIMER");
    1087                 EDIT_WM_Timer(hwnd, es);
    1088                 break;
    1089 
    1090         case WM_VSCROLL:
    1091                 DPRINTF_EDIT_MSG32("WM_VSCROLL");
    1092                 result = EDIT_WM_VScroll(hwnd, es, LOWORD(wParam), SHIWORD(wParam));
    1093                 break;
     1113    case WM_SYSKEYDOWN:
     1114        DPRINTF_EDIT_MSG32("WM_SYSKEYDOWN");
     1115        result = EDIT_WM_SysKeyDown(hwnd, es, (INT)wParam, (DWORD)lParam);
     1116        break;
     1117
     1118    case WM_TIMER:
     1119        DPRINTF_EDIT_MSG32("WM_TIMER");
     1120        EDIT_WM_Timer(hwnd, es);
     1121        break;
     1122
     1123    case WM_VSCROLL:
     1124        DPRINTF_EDIT_MSG32("WM_VSCROLL");
     1125        result = EDIT_WM_VScroll(hwnd, es, LOWORD(wParam), SHIWORD(wParam));
     1126        break;
    10941127
    10951128        case WM_MOUSEWHEEL:
     
    11081141                        int cLineScroll= (int) min((UINT) es->line_count, pulScrollLines);
    11091142                        cLineScroll *= (gcWheelDelta / WHEEL_DELTA);
    1110                         result = EDIT_EM_LineScroll(hwnd, es, 0, cLineScroll);
     1143            result = EDIT_EM_LineScroll(hwnd, es, 0, cLineScroll);
    11111144                    }
    11121145                }
    11131146                break;
    1114         default:
    1115                 if(unicode)
    1116                     result = DefWindowProcW(hwnd, msg, wParam, lParam);
    1117                 else
    1118                     result = DefWindowProcA(hwnd, msg, wParam, lParam);
    1119                 break;
    1120         }
    1121         EDIT_UnlockBuffer(hwnd, es, FALSE);
     1147    default:
     1148        if(unicode)
     1149            result = DefWindowProcW(hwnd, msg, wParam, lParam);
     1150        else
     1151            result = DefWindowProcA(hwnd, msg, wParam, lParam);
     1152        break;
     1153    }
     1154    EDIT_UnlockBuffer(hwnd, es, FALSE);
    11221155    END:
    1123         return result;
    1124 }
    1125 
    1126 /*********************************************************************
    1127  *
    1128  *      EditWndProcW   (USER32.@)
     1156    return result;
     1157}
     1158
     1159/*********************************************************************
     1160 *
     1161 *  EditWndProcW   (USER32.@)
    11291162 */
    11301163LRESULT WINAPI EditWndProcW(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
     
    11361169/*********************************************************************
    11371170 *
    1138  *      EditWndProc   (USER32.@)
     1171 *  EditWndProc   (USER32.@)
    11391172 */
    11401173LRESULT WINAPI EditWndProcA(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
     
    11461179/*********************************************************************
    11471180 *
    1148  *      EDIT_BuildLineDefs_ML
    1149  *
    1150  *      Build linked list of text lines.
    1151  *      Lines can end with '\0' (last line), a character (if it is wrapped),
    1152  *      a soft return '\r\r\n' or a hard return '\r\n'
     1181 *  EDIT_BuildLineDefs_ML
     1182 *
     1183 *  Build linked list of text lines.
     1184 *  Lines can end with '\0' (last line), a character (if it is wrapped),
     1185 *  a soft return '\r\r\n' or a hard return '\r\n'
    11531186 *
    11541187 */
    11551188static void EDIT_BuildLineDefs_ML(HWND hwnd, EDITSTATE *es, INT istart, INT iend, INT delta, HRGN hrgn)
    11561189{
    1157         HDC dc;
    1158         HFONT old_font = 0;
    1159         LPWSTR current_position, cp;
    1160         INT fw;
    1161         LINEDEF *current_line;
    1162         LINEDEF *previous_line;
    1163         LINEDEF *start_line;
    1164         INT line_index = 0, nstart_line = 0, nstart_index = 0;
    1165         INT line_count = es->line_count;
    1166         INT orig_net_length;
    1167         RECT rc;
    1168 
    1169         if (istart == iend && delta == 0)
    1170                 return;
    1171 
    1172         dc = GetDC(hwnd);
    1173         if (es->font)
    1174                 old_font = SelectObject(dc, es->font);
    1175 
    1176         previous_line = NULL;
    1177         current_line = es->first_line_def;
    1178 
    1179         /* Find starting line. istart must lie inside an existing line or
    1180         * at the end of buffer */
    1181         do {
    1182                 if (istart < current_line->index + current_line->length ||
    1183                                 current_line->ending == END_0)
    1184                         break;
    1185 
    1186                 previous_line = current_line;
    1187                 current_line = current_line->next;
    1188                 line_index++;
    1189         } while (current_line);
    1190 
    1191         if (!current_line) /* Error occurred start is not inside previous buffer */
    1192         {
    1193                 FIXME(" modification occurred outside buffer\n");
    1194                 return;
    1195         }
    1196 
    1197         /* Remember start of modifications in order to calculate update region */
    1198         nstart_line = line_index;
    1199         nstart_index = current_line->index;
    1200 
    1201         /* We must start to reformat from the previous line since the modifications
    1202         * may have caused the line to wrap upwards. */
    1203         if (!(es->style & ES_AUTOHSCROLL) && line_index > 0)
    1204         {
    1205                 line_index--;
    1206                 current_line = previous_line;
    1207         }
    1208         start_line = current_line;
    1209 
    1210         fw = es->format_rect.right - es->format_rect.left;
    1211         current_position = es->text + current_line->index;
    1212         do {
    1213                 if (current_line != start_line)
    1214                 {
    1215                         if (!current_line || current_line->index + delta > current_position - es->text)
    1216                         {
    1217                                 /* The buffer has been expanded, create a new line and
    1218                                    insert it into the link list */
    1219                                 LINEDEF *new_line = HeapAlloc(GetProcessHeap(), 0, sizeof(LINEDEF));
    1220                                 new_line->next = previous_line->next;
    1221                                 previous_line->next = new_line;
    1222                                 current_line = new_line;
    1223                                 es->line_count++;
    1224                         }
    1225                         else if (current_line->index + delta < current_position - es->text)
    1226                         {
    1227                                 /* The previous line merged with this line so we delete this extra entry */
    1228                                 previous_line->next = current_line->next;
    1229                                 HeapFree(GetProcessHeap(), 0, current_line);
    1230                                 current_line = previous_line->next;
    1231                                 es->line_count--;
    1232                                 continue;
    1233                         }
    1234                         else /* current_line->index + delta == current_position */
    1235                         {
    1236                                 if (current_position - es->text > iend)
    1237                                         break; /* We reached end of line modifications */
    1238                                 /* else recalulate this line */
    1239                         }
    1240                 }
    1241 
    1242                 current_line->index = current_position - es->text;
    1243                 orig_net_length = current_line->net_length;
    1244 
    1245                 /* Find end of line */
    1246                 cp = current_position;
    1247                 while (*cp) {
    1248                         if ((*cp == '\r') && (*(cp + 1) == '\n'))
    1249                                 break;
    1250                         cp++;
    1251                 }
    1252 
    1253                 /* Mark type of line termination */
    1254                 if (!(*cp)) {
    1255                         current_line->ending = END_0;
    1256                         current_line->net_length = strlenW(current_position);
    1257                 } else if ((cp > current_position) && (*(cp - 1) == '\r')) {
    1258                         current_line->ending = END_SOFT;
    1259                         current_line->net_length = cp - current_position - 1;
    1260                 } else {
    1261                         current_line->ending = END_HARD;
    1262                         current_line->net_length = cp - current_position;
    1263                 }
    1264 
    1265                 /* Calculate line width */
    1266                 current_line->width = (INT)LOWORD(GetTabbedTextExtentW(dc,
    1267                                         current_position, current_line->net_length,
    1268                                         es->tabs_count, es->tabs));
    1269 
    1270                 /* FIXME: check here for lines that are too wide even in AUTOHSCROLL (> 32767 ???) */
    1271                 if ((!(es->style & ES_AUTOHSCROLL)) && (current_line->width > fw)) {
    1272                         INT next = 0;
    1273                         INT prev;
    1274                         do {
    1275                                 prev = next;
    1276                                 next = EDIT_CallWordBreakProc(es, current_position - es->text,
    1277                                                 prev + 1, current_line->net_length, WB_RIGHT);
    1278                                 current_line->width = (INT)LOWORD(GetTabbedTextExtentW(dc,
    1279                                                         current_position, next, es->tabs_count, es->tabs));
    1280                         } while (current_line->width <= fw);
    1281                         if (!prev) { /* Didn't find a line break so force a break */
    1282                                 next = 0;
    1283                                 do {
    1284                                         prev = next;
    1285                                         next++;
    1286                                         current_line->width = (INT)LOWORD(GetTabbedTextExtentW(dc,
    1287                                                                 current_position, next, es->tabs_count, es->tabs));
    1288                                 } while (current_line->width <= fw);
    1289                                 if (!prev)
    1290                                         prev = 1;
    1291                         }
    1292 
    1293                         /* If the first line we are calculating, wrapped before istart, we must
    1294                         * adjust istart in order for this to be reflected in the update region. */
    1295                         if (current_line->index == nstart_index && istart > current_line->index + prev)
    1296                                 istart = current_line->index + prev;
    1297                         /* else if we are updating the previous line before the first line we
    1298                         * are re-calculating and it expanded */
    1299                         else if (current_line == start_line &&
    1300                                         current_line->index != nstart_index && orig_net_length < prev)
    1301                         {
    1302                           /* Line expanded due to an upwards line wrap so we must partially include
    1303                            * previous line in update region */
    1304                                 nstart_line = line_index;
    1305                                 nstart_index = current_line->index;
    1306                                 istart = current_line->index + orig_net_length;
    1307                         }
    1308 
    1309                         current_line->net_length = prev;
    1310                         current_line->ending = END_WRAP;
    1311                         current_line->width = (INT)LOWORD(GetTabbedTextExtentW(dc, current_position,
    1312                                         current_line->net_length, es->tabs_count, es->tabs));
    1313                 }
    1314 
    1315 
    1316                 /* Adjust length to include line termination */
    1317                 switch (current_line->ending) {
    1318                 case END_SOFT:
    1319                         current_line->length = current_line->net_length + 3;
    1320                         break;
    1321                 case END_HARD:
    1322                         current_line->length = current_line->net_length + 2;
    1323                         break;
    1324                 case END_WRAP:
    1325                 case END_0:
    1326                         current_line->length = current_line->net_length;
    1327                         break;
    1328                 }
    1329                 es->text_width = max(es->text_width, current_line->width);
    1330                 current_position += current_line->length;
    1331                 previous_line = current_line;
    1332                 current_line = current_line->next;
    1333                 line_index++;
    1334         } while (previous_line->ending != END_0);
    1335 
    1336         /* Finish adjusting line indexes by delta or remove hanging lines */
    1337         if (previous_line->ending == END_0)
    1338         {
    1339                 LINEDEF *pnext = NULL;
    1340 
    1341                 previous_line->next = NULL;
    1342                 while (current_line)
    1343                 {
    1344                         pnext = current_line->next;
    1345                         HeapFree(GetProcessHeap(), 0, current_line);
    1346                         current_line = pnext;
    1347                         es->line_count--;
    1348                 }
    1349         }
    1350         else
    1351         {
    1352                 while (current_line)
    1353                 {
    1354                         current_line->index += delta;
    1355                         current_line = current_line->next;
    1356                 }
    1357         }
    1358 
    1359         /* Calculate rest of modification rectangle */
    1360         if (hrgn)
    1361         {
    1362                 HRGN tmphrgn;
    1363            /*
    1364                 * We calculate two rectangles. One for the first line which may have
    1365                 * an indent with respect to the format rect. The other is a format-width
    1366                 * rectangle that spans the rest of the lines that changed or moved.
    1367                 */
    1368                 rc.top = es->format_rect.top + nstart_line * es->line_height -
    1369                         (es->y_offset * es->line_height); /* Adjust for vertical scrollbar */
    1370                 rc.bottom = rc.top + es->line_height;
    1371                 rc.left = es->format_rect.left + (INT)LOWORD(GetTabbedTextExtentW(dc,
    1372                                         es->text + nstart_index, istart - nstart_index,
    1373                                         es->tabs_count, es->tabs)) - es->x_offset; /* Adjust for horz scroll */
    1374                 rc.right = es->format_rect.right;
    1375                 SetRectRgn(hrgn, rc.left, rc.top, rc.right, rc.bottom);
    1376 
    1377                 rc.top = rc.bottom;
    1378                 rc.left = es->format_rect.left;
    1379                 rc.right = es->format_rect.right;
    1380            /*
    1381                 * If lines were added or removed we must re-paint the remainder of the
    1382             * lines since the remaining lines were either shifted up or down.
    1383                 */
    1384                 if (line_count < es->line_count) /* We added lines */
    1385                         rc.bottom = es->line_count * es->line_height;
    1386                 else if (line_count > es->line_count) /* We removed lines */
    1387                         rc.bottom = line_count * es->line_height;
    1388                 else
    1389                         rc.bottom = line_index * es->line_height;
    1390                 rc.bottom -= (es->y_offset * es->line_height); /* Adjust for vertical scrollbar */
    1391                 tmphrgn = CreateRectRgn(rc.left, rc.top, rc.right, rc.bottom);
    1392                 CombineRgn(hrgn, hrgn, tmphrgn, RGN_OR);
    1393                 DeleteObject(tmphrgn);
    1394         }
    1395 
    1396         if (es->font)
    1397                 SelectObject(dc, old_font);
    1398 
    1399         ReleaseDC(hwnd, dc);
    1400 }
    1401 
    1402 /*********************************************************************
    1403  *
    1404  *      EDIT_CalcLineWidth_SL
     1190    HDC dc;
     1191    HFONT old_font = 0;
     1192    LPWSTR current_position, cp;
     1193    INT fw;
     1194    LINEDEF *current_line;
     1195    LINEDEF *previous_line;
     1196    LINEDEF *start_line;
     1197    INT line_index = 0, nstart_line = 0, nstart_index = 0;
     1198    INT line_count = es->line_count;
     1199    INT orig_net_length;
     1200    RECT rc;
     1201
     1202    if (istart == iend && delta == 0)
     1203        return;
     1204
     1205    dc = GetDC(hwnd);
     1206    if (es->font)
     1207        old_font = SelectObject(dc, es->font);
     1208
     1209    previous_line = NULL;
     1210    current_line = es->first_line_def;
     1211
     1212    /* Find starting line. istart must lie inside an existing line or
     1213    * at the end of buffer */
     1214    do {
     1215        if (istart < current_line->index + current_line->length ||
     1216                current_line->ending == END_0)
     1217            break;
     1218
     1219        previous_line = current_line;
     1220        current_line = current_line->next;
     1221        line_index++;
     1222    } while (current_line);
     1223
     1224    if (!current_line) /* Error occurred start is not inside previous buffer */
     1225    {
     1226        FIXME(" modification occurred outside buffer\n");
     1227        return;
     1228    }
     1229
     1230    /* Remember start of modifications in order to calculate update region */
     1231    nstart_line = line_index;
     1232    nstart_index = current_line->index;
     1233
     1234    /* We must start to reformat from the previous line since the modifications
     1235    * may have caused the line to wrap upwards. */
     1236    if (!(es->style & ES_AUTOHSCROLL) && line_index > 0)
     1237    {
     1238        line_index--;
     1239        current_line = previous_line;
     1240    }
     1241    start_line = current_line;
     1242
     1243    fw = es->format_rect.right - es->format_rect.left;
     1244    current_position = es->text + current_line->index;
     1245    do {
     1246        if (current_line != start_line)
     1247        {
     1248            if (!current_line || current_line->index + delta > current_position - es->text)
     1249            {
     1250                /* The buffer has been expanded, create a new line and
     1251                   insert it into the link list */
     1252                LINEDEF *new_line = HeapAlloc(GetProcessHeap(), 0, sizeof(LINEDEF));
     1253                new_line->next = previous_line->next;
     1254                previous_line->next = new_line;
     1255                current_line = new_line;
     1256                es->line_count++;
     1257            }
     1258            else if (current_line->index + delta < current_position - es->text)
     1259            {
     1260                /* The previous line merged with this line so we delete this extra entry */
     1261                previous_line->next = current_line->next;
     1262                HeapFree(GetProcessHeap(), 0, current_line);
     1263                current_line = previous_line->next;
     1264                es->line_count--;
     1265                continue;
     1266            }
     1267            else /* current_line->index + delta == current_position */
     1268            {
     1269                if (current_position - es->text > iend)
     1270                    break; /* We reached end of line modifications */
     1271                /* else recalulate this line */
     1272            }
     1273        }
     1274
     1275        current_line->index = current_position - es->text;
     1276        orig_net_length = current_line->net_length;
     1277
     1278        /* Find end of line */
     1279        cp = current_position;
     1280        while (*cp) {
     1281            if ((*cp == '\r') && (*(cp + 1) == '\n'))
     1282                break;
     1283            cp++;
     1284        }
     1285
     1286        /* Mark type of line termination */
     1287        if (!(*cp)) {
     1288            current_line->ending = END_0;
     1289            current_line->net_length = strlenW(current_position);
     1290        } else if ((cp > current_position) && (*(cp - 1) == '\r')) {
     1291            current_line->ending = END_SOFT;
     1292            current_line->net_length = cp - current_position - 1;
     1293        } else {
     1294            current_line->ending = END_HARD;
     1295            current_line->net_length = cp - current_position;
     1296        }
     1297
     1298        /* Calculate line width */
     1299        current_line->width = (INT)LOWORD(GetTabbedTextExtentW(dc,
     1300                    current_position, current_line->net_length,
     1301                    es->tabs_count, es->tabs));
     1302
     1303        /* FIXME: check here for lines that are too wide even in AUTOHSCROLL (> 32767 ???) */
     1304        if ((!(es->style & ES_AUTOHSCROLL)) && (current_line->width > fw)) {
     1305            INT next = 0;
     1306            INT prev;
     1307            do {
     1308                prev = next;
     1309                next = EDIT_CallWordBreakProc(es, current_position - es->text,
     1310                        prev + 1, current_line->net_length, WB_RIGHT);
     1311                current_line->width = (INT)LOWORD(GetTabbedTextExtentW(dc,
     1312                            current_position, next, es->tabs_count, es->tabs));
     1313            } while (current_line->width <= fw);
     1314            if (!prev) { /* Didn't find a line break so force a break */
     1315                next = 0;
     1316                do {
     1317                    prev = next;
     1318                    next++;
     1319                    current_line->width = (INT)LOWORD(GetTabbedTextExtentW(dc,
     1320                                current_position, next, es->tabs_count, es->tabs));
     1321                } while (current_line->width <= fw);
     1322                if (!prev)
     1323                    prev = 1;
     1324            }
     1325
     1326            /* If the first line we are calculating, wrapped before istart, we must
     1327            * adjust istart in order for this to be reflected in the update region. */
     1328            if (current_line->index == nstart_index && istart > current_line->index + prev)
     1329                istart = current_line->index + prev;
     1330            /* else if we are updating the previous line before the first line we
     1331            * are re-calculating and it expanded */
     1332            else if (current_line == start_line &&
     1333                    current_line->index != nstart_index && orig_net_length < prev)
     1334            {
     1335              /* Line expanded due to an upwards line wrap so we must partially include
     1336               * previous line in update region */
     1337                nstart_line = line_index;
     1338                nstart_index = current_line->index;
     1339                istart = current_line->index + orig_net_length;
     1340            }
     1341
     1342            current_line->net_length = prev;
     1343            current_line->ending = END_WRAP;
     1344            current_line->width = (INT)LOWORD(GetTabbedTextExtentW(dc, current_position,
     1345                    current_line->net_length, es->tabs_count, es->tabs));
     1346        }
     1347
     1348
     1349        /* Adjust length to include line termination */
     1350        switch (current_line->ending) {
     1351        case END_SOFT:
     1352            current_line->length = current_line->net_length + 3;
     1353            break;
     1354        case END_HARD:
     1355            current_line->length = current_line->net_length + 2;
     1356            break;
     1357        case END_WRAP:
     1358        case END_0:
     1359            current_line->length = current_line->net_length;
     1360            break;
     1361        }
     1362        es->text_width = max(es->text_width, current_line->width);
     1363        current_position += current_line->length;
     1364        previous_line = current_line;
     1365        current_line = current_line->next;
     1366        line_index++;
     1367    } while (previous_line->ending != END_0);
     1368
     1369    /* Finish adjusting line indexes by delta or remove hanging lines */
     1370    if (previous_line->ending == END_0)
     1371    {
     1372        LINEDEF *pnext = NULL;
     1373
     1374        previous_line->next = NULL;
     1375        while (current_line)
     1376        {
     1377            pnext = current_line->next;
     1378            HeapFree(GetProcessHeap(), 0, current_line);
     1379            current_line = pnext;
     1380            es->line_count--;
     1381        }
     1382    }
     1383    else
     1384    {
     1385        while (current_line)
     1386        {
     1387            current_line->index += delta;
     1388            current_line = current_line->next;
     1389        }
     1390    }
     1391
     1392    /* Calculate rest of modification rectangle */
     1393    if (hrgn)
     1394    {
     1395        HRGN tmphrgn;
     1396       /*
     1397        * We calculate two rectangles. One for the first line which may have
     1398        * an indent with respect to the format rect. The other is a format-width
     1399        * rectangle that spans the rest of the lines that changed or moved.
     1400        */
     1401        rc.top = es->format_rect.top + nstart_line * es->line_height -
     1402            (es->y_offset * es->line_height); /* Adjust for vertical scrollbar */
     1403        rc.bottom = rc.top + es->line_height;
     1404        rc.left = es->format_rect.left + (INT)LOWORD(GetTabbedTextExtentW(dc,
     1405                    es->text + nstart_index, istart - nstart_index,
     1406                    es->tabs_count, es->tabs)) - es->x_offset; /* Adjust for horz scroll */
     1407        rc.right = es->format_rect.right;
     1408        SetRectRgn(hrgn, rc.left, rc.top, rc.right, rc.bottom);
     1409
     1410        rc.top = rc.bottom;
     1411        rc.left = es->format_rect.left;
     1412        rc.right = es->format_rect.right;
     1413       /*
     1414        * If lines were added or removed we must re-paint the remainder of the
     1415        * lines since the remaining lines were either shifted up or down.
     1416        */
     1417        if (line_count < es->line_count) /* We added lines */
     1418            rc.bottom = es->line_count * es->line_height;
     1419        else if (line_count > es->line_count) /* We removed lines */
     1420            rc.bottom = line_count * es->line_height;
     1421        else
     1422            rc.bottom = line_index * es->line_height;
     1423        rc.bottom -= (es->y_offset * es->line_height); /* Adjust for vertical scrollbar */
     1424        tmphrgn = CreateRectRgn(rc.left, rc.top, rc.right, rc.bottom);
     1425        CombineRgn(hrgn, hrgn, tmphrgn, RGN_OR);
     1426        DeleteObject(tmphrgn);
     1427    }
     1428
     1429    if (es->font)
     1430        SelectObject(dc, old_font);
     1431
     1432    ReleaseDC(hwnd, dc);
     1433}
     1434
     1435/*********************************************************************
     1436 *
     1437 *  EDIT_CalcLineWidth_SL
    14051438 *
    14061439 */
     
    14121445/*********************************************************************
    14131446 *
    1414  *      EDIT_CallWordBreakProc
    1415  *
    1416  *      Call appropriate WordBreakProc (internal or external).
    1417  *
    1418  *      Note: The "start" argument should always be an index referring
    1419  *              to es->text.  The actual wordbreak proc might be
    1420  *              16 bit, so we can't always pass any 32 bit LPSTR.
    1421  *              Hence we assume that es->text is the buffer that holds
    1422  *              the string under examination (we can decide this for ourselves).
     1447 *  EDIT_CallWordBreakProc
     1448 *
     1449 *  Call appropriate WordBreakProc (internal or external).
     1450 *
     1451 *  Note: The "start" argument should always be an index referring
     1452 *      to es->text.  The actual wordbreak proc might be
     1453 *      16 bit, so we can't always pass any 32 bit LPSTR.
     1454 *      Hence we assume that es->text is the buffer that holds
     1455 *      the string under examination (we can decide this for ourselves).
    14231456 *
    14241457 */
     
    14351468
    14361469#ifndef __WIN32OS2__
    1437         if (es->word_break_proc16) {
    1438             HGLOBAL16 hglob16;
    1439             SEGPTR segptr;
    1440             INT countA;
    1441 
    1442             countA = WideCharToMultiByte(CP_ACP, 0, es->text + start, count, NULL, 0, NULL, NULL);
    1443             hglob16 = GlobalAlloc16(GMEM_MOVEABLE | GMEM_ZEROINIT, countA);
    1444             segptr = K32WOWGlobalLock16(hglob16);
    1445             WideCharToMultiByte(CP_ACP, 0, es->text + start, count, MapSL(segptr), countA, NULL, NULL);
    1446             ret = (INT)EDIT_CallTo16_word_lwww(es->word_break_proc16,
    1447                                                 segptr, index, countA, action);
    1448             GlobalUnlock16(hglob16);
    1449             GlobalFree16(hglob16);
    1450         }
    1451         else
     1470    if (es->word_break_proc16) {
     1471        HGLOBAL16 hglob16;
     1472        SEGPTR segptr;
     1473        INT countA;
     1474
     1475        countA = WideCharToMultiByte(CP_ACP, 0, es->text + start, count, NULL, 0, NULL, NULL);
     1476        hglob16 = GlobalAlloc16(GMEM_MOVEABLE | GMEM_ZEROINIT, countA);
     1477        segptr = K32WOWGlobalLock16(hglob16);
     1478        WideCharToMultiByte(CP_ACP, 0, es->text + start, count, MapSL(segptr), countA, NULL, NULL);
     1479        ret = (INT)EDIT_CallTo16_word_lwww(es->word_break_proc16,
     1480                        segptr, index, countA, action);
     1481        GlobalUnlock16(hglob16);
     1482        GlobalFree16(hglob16);
     1483    }
     1484    else
    14521485#endif
    14531486        if (es->word_break_proc)
    14541487        {
    1455             if(es->is_unicode)
    1456             {
    1457                 EDITWORDBREAKPROCW wbpW = (EDITWORDBREAKPROCW)es->word_break_proc;
    1458 
    1459                 TRACE_(relay)("(UNICODE wordbrk=%p,str=%s,idx=%d,cnt=%d,act=%d)\n",
    1460                         es->word_break_proc, debugstr_wn(es->text + start, count), index, count, action);
    1461                 ret = wbpW(es->text + start, index, count, action);
    1462             }
    1463             else
    1464             {
    1465                 EDITWORDBREAKPROCA wbpA = (EDITWORDBREAKPROCA)es->word_break_proc;
    1466                 INT countA;
    1467                 CHAR *textA;
    1468 
    1469                 countA = WideCharToMultiByte(CP_ACP, 0, es->text + start, count, NULL, 0, NULL, NULL);
    1470                 textA = HeapAlloc(GetProcessHeap(), 0, countA);
    1471                 WideCharToMultiByte(CP_ACP, 0, es->text + start, count, textA, countA, NULL, NULL);
    1472                 TRACE_(relay)("(ANSI wordbrk=%p,str=%s,idx=%d,cnt=%d,act=%d)\n",
    1473                         es->word_break_proc, debugstr_an(textA, countA), index, countA, action);
    1474                 ret = wbpA(textA, index, countA, action);
    1475                 HeapFree(GetProcessHeap(), 0, textA);
    1476             }
    1477         }
    1478         else
     1488        if(es->is_unicode)
     1489        {
     1490        EDITWORDBREAKPROCW wbpW = (EDITWORDBREAKPROCW)es->word_break_proc;
     1491
     1492        TRACE_(relay)("(UNICODE wordbrk=%p,str=%s,idx=%d,cnt=%d,act=%d)\n",
     1493            es->word_break_proc, debugstr_wn(es->text + start, count), index, count, action);
     1494        ret = wbpW(es->text + start, index, count, action);
     1495        }
     1496        else
     1497        {
     1498        EDITWORDBREAKPROCA wbpA = (EDITWORDBREAKPROCA)es->word_break_proc;
     1499        INT countA;
     1500        CHAR *textA;
     1501
     1502        countA = WideCharToMultiByte(CP_ACP, 0, es->text + start, count, NULL, 0, NULL, NULL);
     1503        textA = HeapAlloc(GetProcessHeap(), 0, countA);
     1504        WideCharToMultiByte(CP_ACP, 0, es->text + start, count, textA, countA, NULL, NULL);
     1505        TRACE_(relay)("(ANSI wordbrk=%p,str=%s,idx=%d,cnt=%d,act=%d)\n",
     1506            es->word_break_proc, debugstr_an(textA, countA), index, countA, action);
     1507        ret = wbpA(textA, index, countA, action);
     1508        HeapFree(GetProcessHeap(), 0, textA);
     1509        }
     1510        }
     1511    else
    14791512            ret = EDIT_WordBreakProc(es->text + start, index, count, action);
    14801513
     
    14861519/*********************************************************************
    14871520 *
    1488  *      EDIT_CharFromPos
    1489  *
    1490  *      Beware: This is not the function called on EM_CHARFROMPOS
    1491  *              The position _can_ be outside the formatting / client
    1492  *              rectangle
    1493  *              The return value is only the character index
     1521 *  EDIT_CharFromPos
     1522 *
     1523 *  Beware: This is not the function called on EM_CHARFROMPOS
     1524 *      The position _can_ be outside the formatting / client
     1525 *      rectangle
     1526 *      The return value is only the character index
    14941527 *
    14951528 */
    14961529static INT EDIT_CharFromPos(HWND hwnd, EDITSTATE *es, INT x, INT y, LPBOOL after_wrap)
    14971530{
    1498         INT index;
    1499         HDC dc;
    1500         HFONT old_font = 0;
    1501 
    1502         if (es->style & ES_MULTILINE) {
    1503                 INT line = (y - es->format_rect.top) / es->line_height + es->y_offset;
    1504                 INT line_index = 0;
    1505                 LINEDEF *line_def = es->first_line_def;
    1506                 INT low, high;
    1507                 while ((line > 0) && line_def->next) {
    1508                         line_index += line_def->length;
    1509                         line_def = line_def->next;
    1510                         line--;
    1511                 }
    1512                 x += es->x_offset - es->format_rect.left;
    1513                 if (x >= line_def->width) {
    1514                         if (after_wrap)
    1515                                 *after_wrap = (line_def->ending == END_WRAP);
    1516                         return line_index + line_def->net_length;
    1517                 }
    1518                 if (x <= 0) {
    1519                         if (after_wrap)
    1520                                 *after_wrap = FALSE;
    1521                         return line_index;
    1522                 }
    1523                 dc = GetDC(hwnd);
    1524                 if (es->font)
    1525                         old_font = SelectObject(dc, es->font);
     1531    INT index;
     1532    HDC dc;
     1533    HFONT old_font = 0;
     1534
     1535    if (es->style & ES_MULTILINE) {
     1536        INT line = (y - es->format_rect.top) / es->line_height + es->y_offset;
     1537        INT line_index = 0;
     1538        LINEDEF *line_def = es->first_line_def;
     1539        INT low, high;
     1540        while ((line > 0) && line_def->next) {
     1541            line_index += line_def->length;
     1542            line_def = line_def->next;
     1543            line--;
     1544        }
     1545        x += es->x_offset - es->format_rect.left;
     1546        if (x >= line_def->width) {
     1547            if (after_wrap)
     1548                *after_wrap = (line_def->ending == END_WRAP);
     1549            return line_index + line_def->net_length;
     1550        }
     1551        if (x <= 0) {
     1552            if (after_wrap)
     1553                *after_wrap = FALSE;
     1554            return line_index;
     1555        }
     1556        dc = GetDC(hwnd);
     1557        if (es->font)
     1558            old_font = SelectObject(dc, es->font);
    15261559                    low = line_index + 1;
    15271560                    high = line_index + line_def->net_length + 1;
     
    15291562                    {
    15301563                        INT mid = (low + high) / 2;
    1531                         if (LOWORD(GetTabbedTextExtentW(dc, es->text + line_index,mid - line_index, es->tabs_count, es->tabs)) > x) high = mid;
     1564            if (LOWORD(GetTabbedTextExtentW(dc, es->text + line_index,mid - line_index, es->tabs_count, es->tabs)) > x) high = mid;
    15321565                        else low = mid;
    15331566                    }
    15341567                    index = low;
    15351568
    1536                 if (after_wrap)
    1537                         *after_wrap = ((index == line_index + line_def->net_length) &&
    1538                                                         (line_def->ending == END_WRAP));
    1539         } else {
    1540                 LPWSTR text;
    1541                 SIZE size;
    1542                 if (after_wrap)
    1543                         *after_wrap = FALSE;
    1544                 x -= es->format_rect.left;
    1545                 if (!x)
    1546                         return es->x_offset;
    1547                 text = EDIT_GetPasswordPointer_SL(es);
    1548                 dc = GetDC(hwnd);
    1549                 if (es->font)
    1550                         old_font = SelectObject(dc, es->font);
    1551                 if (x < 0)
     1569        if (after_wrap)
     1570            *after_wrap = ((index == line_index + line_def->net_length) &&
     1571                            (line_def->ending == END_WRAP));
     1572    } else {
     1573        LPWSTR text;
     1574        SIZE size;
     1575        if (after_wrap)
     1576            *after_wrap = FALSE;
     1577        x -= es->format_rect.left;
     1578        if (!x)
     1579            return es->x_offset;
     1580        text = EDIT_GetPasswordPointer_SL(es);
     1581        dc = GetDC(hwnd);
     1582        if (es->font)
     1583            old_font = SelectObject(dc, es->font);
     1584        if (x < 0)
    15521585                {
    15531586                    INT low = 0;
     
    15621595                    }
    15631596                    index = low;
    1564                 }
     1597        }
    15651598                else
    15661599                {
     
    15761609                    }
    15771610                    index = low;
    1578                 }
    1579                 if (es->style & ES_PASSWORD)
    1580                         HeapFree(GetProcessHeap(), 0, text);
    1581         }
    1582         if (es->font)
    1583                 SelectObject(dc, old_font);
    1584         ReleaseDC(hwnd, dc);
    1585         return index;
    1586 }
    1587 
    1588 
    1589 /*********************************************************************
    1590  *
    1591  *      EDIT_ConfinePoint
    1592  *
    1593  *      adjusts the point to be within the formatting rectangle
    1594  *      (so CharFromPos returns the nearest _visible_ character)
     1611        }
     1612        if (es->style & ES_PASSWORD)
     1613            HeapFree(GetProcessHeap(), 0, text);
     1614    }
     1615    if (es->font)
     1616        SelectObject(dc, old_font);
     1617    ReleaseDC(hwnd, dc);
     1618    return index;
     1619}
     1620
     1621
     1622/*********************************************************************
     1623 *
     1624 *  EDIT_ConfinePoint
     1625 *
     1626 *  adjusts the point to be within the formatting rectangle
     1627 *  (so CharFromPos returns the nearest _visible_ character)
    15951628 *
    15961629 */
    15971630static void EDIT_ConfinePoint(EDITSTATE *es, LPINT x, LPINT y)
    15981631{
    1599         *x = min(max(*x, es->format_rect.left), es->format_rect.right - 1);
    1600         *y = min(max(*y, es->format_rect.top), es->format_rect.bottom - 1);
    1601 }
    1602 
    1603 
    1604 /*********************************************************************
    1605  *
    1606  *      EDIT_GetLineRect
    1607  *
    1608  *      Calculates the bounding rectangle for a line from a starting
    1609  *      column to an ending column.
     1632    *x = min(max(*x, es->format_rect.left), es->format_rect.right - 1);
     1633    *y = min(max(*y, es->format_rect.top), es->format_rect.bottom - 1);
     1634}
     1635
     1636
     1637/*********************************************************************
     1638 *
     1639 *  EDIT_GetLineRect
     1640 *
     1641 *  Calculates the bounding rectangle for a line from a starting
     1642 *  column to an ending column.
    16101643 *
    16111644 */
    16121645static void EDIT_GetLineRect(HWND hwnd, EDITSTATE *es, INT line, INT scol, INT ecol, LPRECT rc)
    16131646{
    1614         INT line_index =  EDIT_EM_LineIndex(es, line);
    1615 
    1616         if (es->style & ES_MULTILINE)
    1617                 rc->top = es->format_rect.top + (line - es->y_offset) * es->line_height;
    1618         else
    1619                 rc->top = es->format_rect.top;
    1620         rc->bottom = rc->top + es->line_height;
    1621         rc->left = (scol == 0) ? es->format_rect.left : SLOWORD(EDIT_EM_PosFromChar(hwnd, es, line_index + scol, TRUE));
    1622         rc->right = (ecol == -1) ? es->format_rect.right : SLOWORD(EDIT_EM_PosFromChar(hwnd, es, line_index + ecol, TRUE));
    1623 }
    1624 
    1625 
    1626 /*********************************************************************
    1627  *
    1628  *      EDIT_GetPasswordPointer_SL
    1629  *
    1630  *      note: caller should free the (optionally) allocated buffer
     1647    INT line_index =  EDIT_EM_LineIndex(es, line);
     1648
     1649    if (es->style & ES_MULTILINE)
     1650        rc->top = es->format_rect.top + (line - es->y_offset) * es->line_height;
     1651    else
     1652        rc->top = es->format_rect.top;
     1653    rc->bottom = rc->top + es->line_height;
     1654    rc->left = (scol == 0) ? es->format_rect.left : SLOWORD(EDIT_EM_PosFromChar(hwnd, es, line_index + scol, TRUE));
     1655    rc->right = (ecol == -1) ? es->format_rect.right : SLOWORD(EDIT_EM_PosFromChar(hwnd, es, line_index + ecol, TRUE));
     1656}
     1657
     1658
     1659/*********************************************************************
     1660 *
     1661 *  EDIT_GetPasswordPointer_SL
     1662 *
     1663 *  note: caller should free the (optionally) allocated buffer
    16311664 *
    16321665 */
    16331666static LPWSTR EDIT_GetPasswordPointer_SL(EDITSTATE *es)
    16341667{
    1635         if (es->style & ES_PASSWORD) {
    1636                 INT len = strlenW(es->text);
    1637                 LPWSTR text = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
    1638                 text[len] = '\0';
    1639                 while(len) text[--len] = es->password_char;
    1640                 return text;
    1641         } else
    1642                 return es->text;
    1643 }
    1644 
    1645 
    1646 /*********************************************************************
    1647  *
    1648  *      EDIT_LockBuffer
    1649  *
    1650  *      This acts as a LOCAL_Lock(), but it locks only once.  This way
    1651  *      you can call it whenever you like, without unlocking.
     1668    if (es->style & ES_PASSWORD) {
     1669        INT len = strlenW(es->text);
     1670        LPWSTR text = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
     1671        text[len] = '\0';
     1672        while(len) text[--len] = es->password_char;
     1673        return text;
     1674    } else
     1675        return es->text;
     1676}
     1677
     1678
     1679/*********************************************************************
     1680 *
     1681 *  EDIT_LockBuffer
     1682 *
     1683 *  This acts as a LOCAL_Lock(), but it locks only once.  This way
     1684 *  you can call it whenever you like, without unlocking.
    16521685 *
    16531686 */
     
    16551688{
    16561689    HINSTANCE hInstance = GetWindowLongA( hwnd, GWL_HINSTANCE );
    1657         if (!es) {
    1658                 ERR("no EDITSTATE ... please report\n");
    1659                 return;
    1660         }
    1661         if (!es->text) {
    1662             CHAR *textA = NULL;
    1663             UINT countA = 0;
    1664             BOOL _16bit = FALSE;
    1665 
    1666             if(es->hloc32W)
    1667             {
    1668                 if(es->hloc32A)
    1669                 {
    1670                     TRACE("Synchronizing with 32-bit ANSI buffer\n");
    1671                     textA = LocalLock(es->hloc32A);
    1672                     countA = strlen(textA) + 1;
    1673                 }
    1674                 else if(es->hloc16)
    1675                 {
    1676                     TRACE("Synchronizing with 16-bit ANSI buffer\n");
    1677                     textA = LOCAL_Lock(hInstance, es->hloc16);
    1678                     countA = strlen(textA) + 1;
    1679                     _16bit = TRUE;
    1680                 }
    1681             }
    1682             else {
    1683                 ERR("no buffer ... please report\n");
    1684                 return;
    1685             }
    1686 
    1687             if(textA)
    1688             {
    1689                 HLOCAL hloc32W_new;
    1690                 UINT countW_new = MultiByteToWideChar(CP_ACP, 0, textA, countA, NULL, 0);
    1691                 TRACE("%d bytes translated to %d WCHARs\n", countA, countW_new);
    1692                 if(countW_new > es->buffer_size + 1)
    1693                 {
    1694                     UINT alloc_size = ROUND_TO_GROW(countW_new * sizeof(WCHAR));
    1695                     TRACE("Resizing 32-bit UNICODE buffer from %d+1 to %d WCHARs\n", es->buffer_size, countW_new);
    1696                     hloc32W_new = LocalReAlloc(es->hloc32W, alloc_size, LMEM_MOVEABLE | LMEM_ZEROINIT);
    1697                     if(hloc32W_new)
    1698                     {
    1699                         es->hloc32W = hloc32W_new;
    1700                         es->buffer_size = LocalSize(hloc32W_new)/sizeof(WCHAR) - 1;
    1701                         TRACE("Real new size %d+1 WCHARs\n", es->buffer_size);
    1702                     }
    1703                     else
    1704                         WARN("FAILED! Will synchronize partially\n");
    1705                 }
    1706             }
    1707 
    1708             /*TRACE("Locking 32-bit UNICODE buffer\n");*/
    1709             es->text = LocalLock(es->hloc32W);
    1710 
    1711             if(textA)
    1712             {
    1713                 MultiByteToWideChar(CP_ACP, 0, textA, countA, es->text, es->buffer_size + 1);
    1714                 if(_16bit)
    1715                     LOCAL_Unlock(hInstance, es->hloc16);
    1716                 else
    1717                     LocalUnlock(es->hloc32A);
    1718             }
    1719         }
    1720         es->lock_count++;
    1721 }
    1722 
    1723 
    1724 /*********************************************************************
    1725  *
    1726  *      EDIT_SL_InvalidateText
    1727  *
    1728  *      Called from EDIT_InvalidateText().
    1729  *      Does the job for single-line controls only.
     1690    if (!es) {
     1691        ERR("no EDITSTATE ... please report\n");
     1692        return;
     1693    }
     1694    if (!es->text) {
     1695        CHAR *textA = NULL;
     1696        UINT countA = 0;
     1697        BOOL _16bit = FALSE;
     1698
     1699        if(es->hloc32W)
     1700        {
     1701        if(es->hloc32A)
     1702        {
     1703            TRACE("Synchronizing with 32-bit ANSI buffer\n");
     1704            textA = LocalLock(es->hloc32A);
     1705            countA = strlen(textA) + 1;
     1706        }
     1707        else if(es->hloc16)
     1708        {
     1709            TRACE("Synchronizing with 16-bit ANSI buffer\n");
     1710            textA = LOCAL_Lock(hInstance, es->hloc16);
     1711            countA = strlen(textA) + 1;
     1712            _16bit = TRUE;
     1713        }
     1714        }
     1715        else {
     1716        ERR("no buffer ... please report\n");
     1717        return;
     1718        }
     1719
     1720        if(textA)
     1721        {
     1722        HLOCAL hloc32W_new;
     1723        UINT countW_new = MultiByteToWideChar(CP_ACP, 0, textA, countA, NULL, 0);
     1724        TRACE("%d bytes translated to %d WCHARs\n", countA, countW_new);
     1725        if(countW_new > es->buffer_size + 1)
     1726        {
     1727            UINT alloc_size = ROUND_TO_GROW(countW_new * sizeof(WCHAR));
     1728            TRACE("Resizing 32-bit UNICODE buffer from %d+1 to %d WCHARs\n", es->buffer_size, countW_new);
     1729            hloc32W_new = LocalReAlloc(es->hloc32W, alloc_size, LMEM_MOVEABLE | LMEM_ZEROINIT);
     1730            if(hloc32W_new)
     1731            {
     1732            es->hloc32W = hloc32W_new;
     1733            es->buffer_size = LocalSize(hloc32W_new)/sizeof(WCHAR) - 1;
     1734            TRACE("Real new size %d+1 WCHARs\n", es->buffer_size);
     1735            }
     1736            else
     1737            WARN("FAILED! Will synchronize partially\n");
     1738        }
     1739        }
     1740
     1741        /*TRACE("Locking 32-bit UNICODE buffer\n");*/
     1742        es->text = LocalLock(es->hloc32W);
     1743
     1744        if(textA)
     1745        {
     1746        MultiByteToWideChar(CP_ACP, 0, textA, countA, es->text, es->buffer_size + 1);
     1747        if(_16bit)
     1748            LOCAL_Unlock(hInstance, es->hloc16);
     1749        else
     1750            LocalUnlock(es->hloc32A);
     1751        }
     1752    }
     1753    es->lock_count++;
     1754}
     1755
     1756
     1757/*********************************************************************
     1758 *
     1759 *  EDIT_SL_InvalidateText
     1760 *
     1761 *  Called from EDIT_InvalidateText().
     1762 *  Does the job for single-line controls only.
    17301763 *
    17311764 */
    17321765static void EDIT_SL_InvalidateText(HWND hwnd, EDITSTATE *es, INT start, INT end)
    17331766{
    1734         RECT line_rect;
    1735         RECT rc;
    1736 
    1737         EDIT_GetLineRect(hwnd, es, 0, start, end, &line_rect);
    1738         if (IntersectRect(&rc, &line_rect, &es->format_rect))
    1739                 EDIT_UpdateText(hwnd, es, &rc, FALSE);
    1740 }
    1741 
    1742 
    1743 /*********************************************************************
    1744  *
    1745  *      EDIT_ML_InvalidateText
    1746  *
    1747  *      Called from EDIT_InvalidateText().
    1748  *      Does the job for multi-line controls only.
     1767    RECT line_rect;
     1768    RECT rc;
     1769
     1770    EDIT_GetLineRect(hwnd, es, 0, start, end, &line_rect);
     1771    if (IntersectRect(&rc, &line_rect, &es->format_rect))
     1772        EDIT_UpdateText(hwnd, es, &rc, FALSE);
     1773}
     1774
     1775
     1776/*********************************************************************
     1777 *
     1778 *  EDIT_ML_InvalidateText
     1779 *
     1780 *  Called from EDIT_InvalidateText().
     1781 *  Does the job for multi-line controls only.
    17491782 *
    17501783 */
    17511784static void EDIT_ML_InvalidateText(HWND hwnd, EDITSTATE *es, INT start, INT end)
    17521785{
    1753         INT vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
    1754         INT sl = EDIT_EM_LineFromChar(es, start);
    1755         INT el = EDIT_EM_LineFromChar(es, end);
    1756         INT sc;
    1757         INT ec;
    1758         RECT rc1;
    1759         RECT rcWnd;
    1760         RECT rcLine;
    1761         RECT rcUpdate;
    1762         INT l;
    1763 
    1764         if ((el < es->y_offset) || (sl > es->y_offset + vlc))
    1765                 return;
    1766 
    1767         sc = start - EDIT_EM_LineIndex(es, sl);
    1768         ec = end - EDIT_EM_LineIndex(es, el);
    1769         if (sl < es->y_offset) {
    1770                 sl = es->y_offset;
    1771                 sc = 0;
    1772         }
    1773         if (el > es->y_offset + vlc) {
    1774                 el = es->y_offset + vlc;
    1775                 ec = EDIT_EM_LineLength(es, EDIT_EM_LineIndex(es, el));
    1776         }
    1777         GetClientRect(hwnd, &rc1);
    1778         IntersectRect(&rcWnd, &rc1, &es->format_rect);
    1779         if (sl == el) {
    1780                 EDIT_GetLineRect(hwnd, es, sl, sc, ec, &rcLine);
    1781                 if (IntersectRect(&rcUpdate, &rcWnd, &rcLine))
    1782                         EDIT_UpdateText(hwnd, es, &rcUpdate, FALSE);
    1783         } else {
    1784                 EDIT_GetLineRect(hwnd, es, sl, sc,
    1785                                 EDIT_EM_LineLength(es,
    1786                                         EDIT_EM_LineIndex(es, sl)),
    1787                                 &rcLine);
    1788                 if (IntersectRect(&rcUpdate, &rcWnd, &rcLine))
    1789                         EDIT_UpdateText(hwnd, es, &rcUpdate, FALSE);
    1790                 for (l = sl + 1 ; l < el ; l++) {
    1791                         EDIT_GetLineRect(hwnd, es, l, 0,
    1792                                 EDIT_EM_LineLength(es,
    1793                                         EDIT_EM_LineIndex(es, l)),
    1794                                 &rcLine);
    1795                         if (IntersectRect(&rcUpdate, &rcWnd, &rcLine))
    1796                                 EDIT_UpdateText(hwnd, es, &rcUpdate, FALSE);
    1797                 }
    1798                 EDIT_GetLineRect(hwnd, es, el, 0, ec, &rcLine);
    1799                 if (IntersectRect(&rcUpdate, &rcWnd, &rcLine))
    1800                         EDIT_UpdateText(hwnd, es, &rcUpdate, FALSE);
    1801         }
    1802 }
    1803 
    1804 
    1805 /*********************************************************************
    1806  *
    1807  *      EDIT_InvalidateText
    1808  *
    1809  *      Invalidate the text from offset start upto, but not including,
    1810  *      offset end.  Useful for (re)painting the selection.
    1811  *      Regions outside the linewidth are not invalidated.
    1812  *      end == -1 means end == TextLength.
    1813  *      start and end need not be ordered.
     1786    INT vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
     1787    INT sl = EDIT_EM_LineFromChar(es, start);
     1788    INT el = EDIT_EM_LineFromChar(es, end);
     1789    INT sc;
     1790    INT ec;
     1791    RECT rc1;
     1792    RECT rcWnd;
     1793    RECT rcLine;
     1794    RECT rcUpdate;
     1795    INT l;
     1796
     1797    if ((el < es->y_offset) || (sl > es->y_offset + vlc))
     1798        return;
     1799
     1800    sc = start - EDIT_EM_LineIndex(es, sl);
     1801    ec = end - EDIT_EM_LineIndex(es, el);
     1802    if (sl < es->y_offset) {
     1803        sl = es->y_offset;
     1804        sc = 0;
     1805    }
     1806    if (el > es->y_offset + vlc) {
     1807        el = es->y_offset + vlc;
     1808        ec = EDIT_EM_LineLength(es, EDIT_EM_LineIndex(es, el));
     1809    }
     1810    GetClientRect(hwnd, &rc1);
     1811    IntersectRect(&rcWnd, &rc1, &es->format_rect);
     1812    if (sl == el) {
     1813        EDIT_GetLineRect(hwnd, es, sl, sc, ec, &rcLine);
     1814        if (IntersectRect(&rcUpdate, &rcWnd, &rcLine))
     1815            EDIT_UpdateText(hwnd, es, &rcUpdate, FALSE);
     1816    } else {
     1817        EDIT_GetLineRect(hwnd, es, sl, sc,
     1818                EDIT_EM_LineLength(es,
     1819                    EDIT_EM_LineIndex(es, sl)),
     1820                &rcLine);
     1821        if (IntersectRect(&rcUpdate, &rcWnd, &rcLine))
     1822            EDIT_UpdateText(hwnd, es, &rcUpdate, FALSE);
     1823        for (l = sl + 1 ; l < el ; l++) {
     1824            EDIT_GetLineRect(hwnd, es, l, 0,
     1825                EDIT_EM_LineLength(es,
     1826                    EDIT_EM_LineIndex(es, l)),
     1827                &rcLine);
     1828            if (IntersectRect(&rcUpdate, &rcWnd, &rcLine))
     1829                EDIT_UpdateText(hwnd, es, &rcUpdate, FALSE);
     1830        }
     1831        EDIT_GetLineRect(hwnd, es, el, 0, ec, &rcLine);
     1832        if (IntersectRect(&rcUpdate, &rcWnd, &rcLine))
     1833            EDIT_UpdateText(hwnd, es, &rcUpdate, FALSE);
     1834    }
     1835}
     1836
     1837
     1838/*********************************************************************
     1839 *
     1840 *  EDIT_InvalidateText
     1841 *
     1842 *  Invalidate the text from offset start upto, but not including,
     1843 *  offset end.  Useful for (re)painting the selection.
     1844 *  Regions outside the linewidth are not invalidated.
     1845 *  end == -1 means end == TextLength.
     1846 *  start and end need not be ordered.
    18141847 *
    18151848 */
    18161849static void EDIT_InvalidateText(HWND hwnd, EDITSTATE *es, INT start, INT end)
    18171850{
    1818         if (end == start)
    1819                 return;
    1820 
    1821         if (end == -1)
    1822                 end = strlenW(es->text);
    1823 
    1824         ORDER_INT(start, end);
    1825 
    1826         if (es->style & ES_MULTILINE)
    1827                 EDIT_ML_InvalidateText(hwnd, es, start, end);
    1828         else
    1829                 EDIT_SL_InvalidateText(hwnd, es, start, end);
    1830 }
    1831 
    1832 
    1833 /*********************************************************************
    1834  *
    1835  *      EDIT_MakeFit
    1836  *
    1837  *      Try to fit size + 1 characters in the buffer. Constrain to limits.
     1851    if (end == start)
     1852        return;
     1853
     1854    if (end == -1)
     1855        end = strlenW(es->text);
     1856
     1857    ORDER_INT(start, end);
     1858
     1859    if (es->style & ES_MULTILINE)
     1860        EDIT_ML_InvalidateText(hwnd, es, start, end);
     1861    else
     1862        EDIT_SL_InvalidateText(hwnd, es, start, end);
     1863}
     1864
     1865
     1866/*********************************************************************
     1867 *
     1868 *  EDIT_MakeFit
     1869 *
     1870 *  Try to fit size + 1 characters in the buffer. Constrain to limits.
    18381871 *
    18391872 */
    18401873static BOOL EDIT_MakeFit(HWND hwnd, EDITSTATE *es, UINT size)
    18411874{
    1842         HLOCAL hNew32W;
    1843 
    1844         if (size <= es->buffer_size)
    1845                 return TRUE;
     1875    HLOCAL hNew32W;
     1876
     1877    if (size <= es->buffer_size)
     1878        return TRUE;
    18461879#ifndef __WIN32OS2__
    1847 //SvL: EM_SETTEXTLIMIT has no effect in 
     1880//SvL: EM_SETTEXTLIMIT has no effect in
    18481881//     NT4, SP6 (EM_GETTEXTLIMIT only returns that value).
    18491882//     Limits are simply ignored, no EN_MAXTEXT notification is ever sent.
    18501883//     (fixes license edit control in Microsoft Visual C++ 4.2 install)
    18511884
    1852         if (size > es->buffer_limit) {
    1853                 EDIT_NOTIFY_PARENT(hwnd, es, EN_MAXTEXT, "EN_MAXTEXT");
    1854                 return FALSE;
    1855         }
    1856         if (size > es->buffer_limit)
    1857                 size = es->buffer_limit;
     1885    if (size > es->buffer_limit) {
     1886        EDIT_NOTIFY_PARENT(hwnd, es, EN_MAXTEXT, "EN_MAXTEXT");
     1887        return FALSE;
     1888    }
     1889    if (size > es->buffer_limit)
     1890        size = es->buffer_limit;
    18581891#endif
    18591892
    1860         TRACE("trying to ReAlloc to %d+1 characters\n", size);
    1861 
    1862         /* Force edit to unlock it's buffer. es->text now NULL */
    1863         EDIT_UnlockBuffer(hwnd, es, TRUE);
    1864 
    1865         if (es->hloc32W) {
    1866             UINT alloc_size = ROUND_TO_GROW((size + 1) * sizeof(WCHAR));
    1867             if ((hNew32W = LocalReAlloc(es->hloc32W, alloc_size, LMEM_MOVEABLE | LMEM_ZEROINIT))) {
    1868                 TRACE("Old 32 bit handle %08x, new handle %08x\n", es->hloc32W, hNew32W);
    1869                 es->hloc32W = hNew32W;
    1870                 es->buffer_size = LocalSize(hNew32W)/sizeof(WCHAR) - 1;
    1871             }
    1872         }
    1873 
    1874         EDIT_LockBuffer(hwnd, es);
    1875 
    1876         if (es->buffer_size < size) {
    1877                 WARN("FAILED !  We now have %d+1\n", es->buffer_size);
    1878                 EDIT_NOTIFY_PARENT(hwnd, es, EN_ERRSPACE, "EN_ERRSPACE");
    1879                 return FALSE;
    1880         } else {
    1881                 TRACE("We now have %d+1\n", es->buffer_size);
    1882                 return TRUE;
    1883         }
    1884 }
    1885 
    1886 
    1887 /*********************************************************************
    1888  *
    1889  *      EDIT_MakeUndoFit
    1890  *
    1891  *      Try to fit size + 1 bytes in the undo buffer.
     1893    TRACE("trying to ReAlloc to %d+1 characters\n", size);
     1894
     1895    /* Force edit to unlock it's buffer. es->text now NULL */
     1896    EDIT_UnlockBuffer(hwnd, es, TRUE);
     1897
     1898    if (es->hloc32W) {
     1899        UINT alloc_size = ROUND_TO_GROW((size + 1) * sizeof(WCHAR));
     1900        if ((hNew32W = LocalReAlloc(es->hloc32W, alloc_size, LMEM_MOVEABLE | LMEM_ZEROINIT))) {
     1901        TRACE("Old 32 bit handle %08x, new handle %08x\n", es->hloc32W, hNew32W);
     1902        es->hloc32W = hNew32W;
     1903        es->buffer_size = LocalSize(hNew32W)/sizeof(WCHAR) - 1;
     1904        }
     1905    }
     1906
     1907    EDIT_LockBuffer(hwnd, es);
     1908
     1909    if (es->buffer_size < size) {
     1910        WARN("FAILED !  We now have %d+1\n", es->buffer_size);
     1911        EDIT_NOTIFY_PARENT(hwnd, es, EN_ERRSPACE, "EN_ERRSPACE");
     1912        return FALSE;
     1913    } else {
     1914        TRACE("We now have %d+1\n", es->buffer_size);
     1915        return TRUE;
     1916    }
     1917}
     1918
     1919
     1920/*********************************************************************
     1921 *
     1922 *  EDIT_MakeUndoFit
     1923 *
     1924 *  Try to fit size + 1 bytes in the undo buffer.
    18921925 *
    18931926 */
    18941927static BOOL EDIT_MakeUndoFit(EDITSTATE *es, UINT size)
    18951928{
    1896         UINT alloc_size;
    1897 
    1898         if (size <= es->undo_buffer_size)
    1899                 return TRUE;
    1900 
    1901         TRACE("trying to ReAlloc to %d+1\n", size);
    1902 
    1903         alloc_size = ROUND_TO_GROW((size + 1) * sizeof(WCHAR));
    1904         if ((es->undo_text = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, es->undo_text, alloc_size))) {
     1929    UINT alloc_size;
     1930
     1931    if (size <= es->undo_buffer_size)
     1932        return TRUE;
     1933
     1934    TRACE("trying to ReAlloc to %d+1\n", size);
     1935
     1936    alloc_size = ROUND_TO_GROW((size + 1) * sizeof(WCHAR));
     1937    if ((es->undo_text = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, es->undo_text, alloc_size))) {
    19051938#ifdef __WIN32OS2__
    1906                 es->undo_buffer_size = alloc_size/sizeof(WCHAR) - 1;
     1939        es->undo_buffer_size = alloc_size/sizeof(WCHAR) - 1;
    19071940#else
    1908                 es->undo_buffer_size = alloc_size/sizeof(WCHAR);
     1941        es->undo_buffer_size = alloc_size/sizeof(WCHAR);
    19091942#endif
    1910                 return TRUE;
    1911         }
    1912         else
    1913         {
    1914                 WARN("FAILED !  We now have %d+1\n", es->undo_buffer_size);
    1915                 return FALSE;
    1916         }
    1917 }
    1918 
    1919 
    1920 /*********************************************************************
    1921  *
    1922  *      EDIT_MoveBackward
     1943        return TRUE;
     1944    }
     1945    else
     1946    {
     1947        WARN("FAILED !  We now have %d+1\n", es->undo_buffer_size);
     1948        return FALSE;
     1949    }
     1950}
     1951
     1952
     1953/*********************************************************************
     1954 *
     1955 *  EDIT_MoveBackward
    19231956 *
    19241957 */
    19251958static void EDIT_MoveBackward(HWND hwnd, EDITSTATE *es, BOOL extend)
    19261959{
    1927         INT e = es->selection_end;
    1928 
    1929         if (e) {
    1930                 e--;
    1931                 if ((es->style & ES_MULTILINE) && e &&
    1932                                 (es->text[e - 1] == '\r') && (es->text[e] == '\n')) {
    1933                         e--;
    1934                         if (e && (es->text[e - 1] == '\r'))
    1935                                 e--;
    1936                 }
    1937         }
    1938         EDIT_EM_SetSel(hwnd, es, extend ? es->selection_start : e, e, FALSE);
    1939         EDIT_EM_ScrollCaret(hwnd, es);
    1940 }
    1941 
    1942 
    1943 /*********************************************************************
    1944  *
    1945  *      EDIT_MoveDown_ML
    1946  *
    1947  *      Only for multi line controls
    1948  *      Move the caret one line down, on a column with the nearest
    1949  *      x coordinate on the screen (might be a different column).
     1960    INT e = es->selection_end;
     1961
     1962    if (e) {
     1963        e--;
     1964        if ((es->style & ES_MULTILINE) && e &&
     1965                (es->text[e - 1] == '\r') && (es->text[e] == '\n')) {
     1966            e--;
     1967            if (e && (es->text[e - 1] == '\r'))
     1968                e--;
     1969        }
     1970    }
     1971    EDIT_EM_SetSel(hwnd, es, extend ? es->selection_start : e, e, FALSE);
     1972    EDIT_EM_ScrollCaret(hwnd, es);
     1973}
     1974
     1975
     1976/*********************************************************************
     1977 *
     1978 *  EDIT_MoveDown_ML
     1979 *
     1980 *  Only for multi line controls
     1981 *  Move the caret one line down, on a column with the nearest
     1982 *  x coordinate on the screen (might be a different column).
    19501983 *
    19511984 */
    19521985static void EDIT_MoveDown_ML(HWND hwnd, EDITSTATE *es, BOOL extend)
    19531986{
    1954         INT s = es->selection_start;
    1955         INT e = es->selection_end;
    1956         BOOL after_wrap = (es->flags & EF_AFTER_WRAP);
    1957         LRESULT pos = EDIT_EM_PosFromChar(hwnd, es, e, after_wrap);
    1958         INT x = SLOWORD(pos);
    1959         INT y = SHIWORD(pos);
    1960 
    1961         e = EDIT_CharFromPos(hwnd, es, x, y + es->line_height, &after_wrap);
    1962         if (!extend)
    1963                 s = e;
    1964         EDIT_EM_SetSel(hwnd, es, s, e, after_wrap);
    1965         EDIT_EM_ScrollCaret(hwnd, es);
    1966 }
    1967 
    1968 
    1969 /*********************************************************************
    1970  *
    1971  *      EDIT_MoveEnd
     1987    INT s = es->selection_start;
     1988    INT e = es->selection_end;
     1989    BOOL after_wrap = (es->flags & EF_AFTER_WRAP);
     1990    LRESULT pos = EDIT_EM_PosFromChar(hwnd, es, e, after_wrap);
     1991    INT x = SLOWORD(pos);
     1992    INT y = SHIWORD(pos);
     1993
     1994    e = EDIT_CharFromPos(hwnd, es, x, y + es->line_height, &after_wrap);
     1995    if (!extend)
     1996        s = e;
     1997    EDIT_EM_SetSel(hwnd, es, s, e, after_wrap);
     1998    EDIT_EM_ScrollCaret(hwnd, es);
     1999}
     2000
     2001
     2002/*********************************************************************
     2003 *
     2004 *  EDIT_MoveEnd
    19722005 *
    19732006 */
    19742007static void EDIT_MoveEnd(HWND hwnd, EDITSTATE *es, BOOL extend)
    19752008{
    1976         BOOL after_wrap = FALSE;
    1977         INT e;
    1978 
    1979         /* Pass a high value in x to make sure of receiving the end of the line */
    1980         if (es->style & ES_MULTILINE)
    1981                 e = EDIT_CharFromPos(hwnd, es, 0x3fffffff,
    1982                         HIWORD(EDIT_EM_PosFromChar(hwnd, es, es->selection_end, es->flags & EF_AFTER_WRAP)), &after_wrap);
    1983         else
    1984                 e = strlenW(es->text);
    1985         EDIT_EM_SetSel(hwnd, es, extend ? es->selection_start : e, e, after_wrap);
    1986         EDIT_EM_ScrollCaret(hwnd, es);
    1987 }
    1988 
    1989 
    1990 /*********************************************************************
    1991  *
    1992  *      EDIT_MoveForward
     2009    BOOL after_wrap = FALSE;
     2010    INT e;
     2011
     2012    /* Pass a high value in x to make sure of receiving the end of the line */
     2013    if (es->style & ES_MULTILINE)
     2014        e = EDIT_CharFromPos(hwnd, es, 0x3fffffff,
     2015            HIWORD(EDIT_EM_PosFromChar(hwnd, es, es->selection_end, es->flags & EF_AFTER_WRAP)), &after_wrap);
     2016    else
     2017        e = strlenW(es->text);
     2018    EDIT_EM_SetSel(hwnd, es, extend ? es->selection_start : e, e, after_wrap);
     2019    EDIT_EM_ScrollCaret(hwnd, es);
     2020}
     2021
     2022
     2023/*********************************************************************
     2024 *
     2025 *  EDIT_MoveForward
    19932026 *
    19942027 */
    19952028static void EDIT_MoveForward(HWND hwnd, EDITSTATE *es, BOOL extend)
    19962029{
    1997         INT e = es->selection_end;
    1998 
    1999         if (es->text[e]) {
    2000                 e++;
    2001                 if ((es->style & ES_MULTILINE) && (es->text[e - 1] == '\r')) {
    2002                         if (es->text[e] == '\n')
    2003                                 e++;
    2004                         else if ((es->text[e] == '\r') && (es->text[e + 1] == '\n'))
    2005                                 e += 2;
    2006                 }
    2007         }
    2008         EDIT_EM_SetSel(hwnd, es, extend ? es->selection_start : e, e, FALSE);
    2009         EDIT_EM_ScrollCaret(hwnd, es);
    2010 }
    2011 
    2012 
    2013 /*********************************************************************
    2014  *
    2015  *      EDIT_MoveHome
    2016  *
    2017  *      Home key: move to beginning of line.
     2030    INT e = es->selection_end;
     2031
     2032    if (es->text[e]) {
     2033        e++;
     2034        if ((es->style & ES_MULTILINE) && (es->text[e - 1] == '\r')) {
     2035            if (es->text[e] == '\n')
     2036                e++;
     2037            else if ((es->text[e] == '\r') && (es->text[e + 1] == '\n'))
     2038                e += 2;
     2039        }
     2040    }
     2041    EDIT_EM_SetSel(hwnd, es, extend ? es->selection_start : e, e, FALSE);
     2042    EDIT_EM_ScrollCaret(hwnd, es);
     2043}
     2044
     2045
     2046/*********************************************************************
     2047 *
     2048 *  EDIT_MoveHome
     2049 *
     2050 *  Home key: move to beginning of line.
    20182051 *
    20192052 */
    20202053static void EDIT_MoveHome(HWND hwnd, EDITSTATE *es, BOOL extend)
    20212054{
    2022         INT e;
    2023 
    2024         /* Pass the x_offset in x to make sure of receiving the first position of the line */
    2025         if (es->style & ES_MULTILINE)
    2026                 e = EDIT_CharFromPos(hwnd, es, -es->x_offset,
    2027                         HIWORD(EDIT_EM_PosFromChar(hwnd, es, es->selection_end, es->flags & EF_AFTER_WRAP)), NULL);
    2028         else
    2029                 e = 0;
    2030         EDIT_EM_SetSel(hwnd, es, extend ? es->selection_start : e, e, FALSE);
    2031         EDIT_EM_ScrollCaret(hwnd, es);
    2032 }
    2033 
    2034 
    2035 /*********************************************************************
    2036  *
    2037  *      EDIT_MovePageDown_ML
    2038  *
    2039  *      Only for multi line controls
    2040  *      Move the caret one page down, on a column with the nearest
    2041  *      x coordinate on the screen (might be a different column).
     2055    INT e;
     2056
     2057    /* Pass the x_offset in x to make sure of receiving the first position of the line */
     2058    if (es->style & ES_MULTILINE)
     2059        e = EDIT_CharFromPos(hwnd, es, -es->x_offset,
     2060            HIWORD(EDIT_EM_PosFromChar(hwnd, es, es->selection_end, es->flags & EF_AFTER_WRAP)), NULL);
     2061    else
     2062        e = 0;
     2063    EDIT_EM_SetSel(hwnd, es, extend ? es->selection_start : e, e, FALSE);
     2064    EDIT_EM_ScrollCaret(hwnd, es);
     2065}
     2066
     2067
     2068/*********************************************************************
     2069 *
     2070 *  EDIT_MovePageDown_ML
     2071 *
     2072 *  Only for multi line controls
     2073 *  Move the caret one page down, on a column with the nearest
     2074 *  x coordinate on the screen (might be a different column).
    20422075 *
    20432076 */
    20442077static void EDIT_MovePageDown_ML(HWND hwnd, EDITSTATE *es, BOOL extend)
    20452078{
    2046         INT s = es->selection_start;
    2047         INT e = es->selection_end;
    2048         BOOL after_wrap = (es->flags & EF_AFTER_WRAP);
    2049         LRESULT pos = EDIT_EM_PosFromChar(hwnd, es, e, after_wrap);
    2050         INT x = SLOWORD(pos);
    2051         INT y = SHIWORD(pos);
    2052 
    2053         e = EDIT_CharFromPos(hwnd, es, x,
    2054                 y + (es->format_rect.bottom - es->format_rect.top),
    2055                 &after_wrap);
    2056         if (!extend)
    2057                 s = e;
    2058         EDIT_EM_SetSel(hwnd, es, s, e, after_wrap);
    2059         EDIT_EM_ScrollCaret(hwnd, es);
    2060 }
    2061 
    2062 
    2063 /*********************************************************************
    2064  *
    2065  *      EDIT_MovePageUp_ML
    2066  *
    2067  *      Only for multi line controls
    2068  *      Move the caret one page up, on a column with the nearest
    2069  *      x coordinate on the screen (might be a different column).
     2079    INT s = es->selection_start;
     2080    INT e = es->selection_end;
     2081    BOOL after_wrap = (es->flags & EF_AFTER_WRAP);
     2082    LRESULT pos = EDIT_EM_PosFromChar(hwnd, es, e, after_wrap);
     2083    INT x = SLOWORD(pos);
     2084    INT y = SHIWORD(pos);
     2085
     2086    e = EDIT_CharFromPos(hwnd, es, x,
     2087        y + (es->format_rect.bottom - es->format_rect.top),
     2088        &after_wrap);
     2089    if (!extend)
     2090        s = e;
     2091    EDIT_EM_SetSel(hwnd, es, s, e, after_wrap);
     2092    EDIT_EM_ScrollCaret(hwnd, es);
     2093}
     2094
     2095
     2096/*********************************************************************
     2097 *
     2098 *  EDIT_MovePageUp_ML
     2099 *
     2100 *  Only for multi line controls
     2101 *  Move the caret one page up, on a column with the nearest
     2102 *  x coordinate on the screen (might be a different column).
    20702103 *
    20712104 */
    20722105static void EDIT_MovePageUp_ML(HWND hwnd, EDITSTATE *es, BOOL extend)
    20732106{
    2074         INT s = es->selection_start;
    2075         INT e = es->selection_end;
    2076         BOOL after_wrap = (es->flags & EF_AFTER_WRAP);
    2077         LRESULT pos = EDIT_EM_PosFromChar(hwnd, es, e, after_wrap);
    2078         INT x = SLOWORD(pos);
    2079         INT y = SHIWORD(pos);
    2080 
    2081         e = EDIT_CharFromPos(hwnd, es, x,
    2082                 y - (es->format_rect.bottom - es->format_rect.top),
    2083                 &after_wrap);
    2084         if (!extend)
    2085                 s = e;
    2086         EDIT_EM_SetSel(hwnd, es, s, e, after_wrap);
    2087         EDIT_EM_ScrollCaret(hwnd, es);
    2088 }
    2089 
    2090 
    2091 /*********************************************************************
    2092  *
    2093  *      EDIT_MoveUp_ML
    2094  *
    2095  *      Only for multi line controls
    2096  *      Move the caret one line up, on a column with the nearest
    2097  *      x coordinate on the screen (might be a different column).
     2107    INT s = es->selection_start;
     2108    INT e = es->selection_end;
     2109    BOOL after_wrap = (es->flags & EF_AFTER_WRAP);
     2110    LRESULT pos = EDIT_EM_PosFromChar(hwnd, es, e, after_wrap);
     2111    INT x = SLOWORD(pos);
     2112    INT y = SHIWORD(pos);
     2113
     2114    e = EDIT_CharFromPos(hwnd, es, x,
     2115        y - (es->format_rect.bottom - es->format_rect.top),
     2116        &after_wrap);
     2117    if (!extend)
     2118        s = e;
     2119    EDIT_EM_SetSel(hwnd, es, s, e, after_wrap);
     2120    EDIT_EM_ScrollCaret(hwnd, es);
     2121}
     2122
     2123
     2124/*********************************************************************
     2125 *
     2126 *  EDIT_MoveUp_ML
     2127 *
     2128 *  Only for multi line controls
     2129 *  Move the caret one line up, on a column with the nearest
     2130 *  x coordinate on the screen (might be a different column).
    20982131 *
    20992132 */
    21002133static void EDIT_MoveUp_ML(HWND hwnd, EDITSTATE *es, BOOL extend)
    21012134{
    2102         INT s = es->selection_start;
    2103         INT e = es->selection_end;
    2104         BOOL after_wrap = (es->flags & EF_AFTER_WRAP);
    2105         LRESULT pos = EDIT_EM_PosFromChar(hwnd, es, e, after_wrap);
    2106         INT x = SLOWORD(pos);
    2107         INT y = SHIWORD(pos);
    2108 
    2109         e = EDIT_CharFromPos(hwnd, es, x, y - es->line_height, &after_wrap);
    2110         if (!extend)
    2111                 s = e;
    2112         EDIT_EM_SetSel(hwnd, es, s, e, after_wrap);
    2113         EDIT_EM_ScrollCaret(hwnd, es);
    2114 }
    2115 
    2116 
    2117 /*********************************************************************
    2118  *
    2119  *      EDIT_MoveWordBackward
     2135    INT s = es->selection_start;
     2136    INT e = es->selection_end;
     2137    BOOL after_wrap = (es->flags & EF_AFTER_WRAP);
     2138    LRESULT pos = EDIT_EM_PosFromChar(hwnd, es, e, after_wrap);
     2139    INT x = SLOWORD(pos);
     2140    INT y = SHIWORD(pos);
     2141
     2142    e = EDIT_CharFromPos(hwnd, es, x, y - es->line_height, &after_wrap);
     2143    if (!extend)
     2144        s = e;
     2145    EDIT_EM_SetSel(hwnd, es, s, e, after_wrap);
     2146    EDIT_EM_ScrollCaret(hwnd, es);
     2147}
     2148
     2149
     2150/*********************************************************************
     2151 *
     2152 *  EDIT_MoveWordBackward
    21202153 *
    21212154 */
    21222155static void EDIT_MoveWordBackward(HWND hwnd, EDITSTATE *es, BOOL extend)
    21232156{
    2124         INT s = es->selection_start;
    2125         INT e = es->selection_end;
    2126         INT l;
    2127         INT ll;
    2128         INT li;
    2129 
    2130         l = EDIT_EM_LineFromChar(es, e);
    2131         ll = EDIT_EM_LineLength(es, e);
    2132         li = EDIT_EM_LineIndex(es, l);
    2133         if (e - li == 0) {
    2134                 if (l) {
    2135                         li = EDIT_EM_LineIndex(es, l - 1);
    2136                         e = li + EDIT_EM_LineLength(es, li);
    2137                 }
    2138         } else {
    2139                 e = li + (INT)EDIT_CallWordBreakProc(es,
    2140                                 li, e - li, ll, WB_LEFT);
    2141         }
    2142         if (!extend)
    2143                 s = e;
    2144         EDIT_EM_SetSel(hwnd, es, s, e, FALSE);
    2145         EDIT_EM_ScrollCaret(hwnd, es);
    2146 }
    2147 
    2148 
    2149 /*********************************************************************
    2150  *
    2151  *      EDIT_MoveWordForward
     2157    INT s = es->selection_start;
     2158    INT e = es->selection_end;
     2159    INT l;
     2160    INT ll;
     2161    INT li;
     2162
     2163    l = EDIT_EM_LineFromChar(es, e);
     2164    ll = EDIT_EM_LineLength(es, e);
     2165    li = EDIT_EM_LineIndex(es, l);
     2166    if (e - li == 0) {
     2167        if (l) {
     2168            li = EDIT_EM_LineIndex(es, l - 1);
     2169            e = li + EDIT_EM_LineLength(es, li);
     2170        }
     2171    } else {
     2172        e = li + (INT)EDIT_CallWordBreakProc(es,
     2173                li, e - li, ll, WB_LEFT);
     2174    }
     2175    if (!extend)
     2176        s = e;
     2177    EDIT_EM_SetSel(hwnd, es, s, e, FALSE);
     2178    EDIT_EM_ScrollCaret(hwnd, es);
     2179}
     2180
     2181
     2182/*********************************************************************
     2183 *
     2184 *  EDIT_MoveWordForward
    21522185 *
    21532186 */
    21542187static void EDIT_MoveWordForward(HWND hwnd, EDITSTATE *es, BOOL extend)
    21552188{
    2156         INT s = es->selection_start;
    2157         INT e = es->selection_end;
    2158         INT l;
    2159         INT ll;
    2160         INT li;
    2161 
    2162         l = EDIT_EM_LineFromChar(es, e);
    2163         ll = EDIT_EM_LineLength(es, e);
    2164         li = EDIT_EM_LineIndex(es, l);
    2165         if (e - li == ll) {
    2166                 if ((es->style & ES_MULTILINE) && (l != es->line_count - 1))
    2167                         e = EDIT_EM_LineIndex(es, l + 1);
    2168         } else {
    2169                 e = li + EDIT_CallWordBreakProc(es,
    2170                                 li, e - li + 1, ll, WB_RIGHT);
    2171         }
    2172         if (!extend)
    2173                 s = e;
    2174         EDIT_EM_SetSel(hwnd, es, s, e, FALSE);
    2175         EDIT_EM_ScrollCaret(hwnd, es);
    2176 }
    2177 
    2178 
    2179 /*********************************************************************
    2180  *
    2181  *      EDIT_PaintLine
     2189    INT s = es->selection_start;
     2190    INT e = es->selection_end;
     2191    INT l;
     2192    INT ll;
     2193    INT li;
     2194
     2195    l = EDIT_EM_LineFromChar(es, e);
     2196    ll = EDIT_EM_LineLength(es, e);
     2197    li = EDIT_EM_LineIndex(es, l);
     2198    if (e - li == ll) {
     2199        if ((es->style & ES_MULTILINE) && (l != es->line_count - 1))
     2200            e = EDIT_EM_LineIndex(es, l + 1);
     2201    } else {
     2202        e = li + EDIT_CallWordBreakProc(es,
     2203                li, e - li + 1, ll, WB_RIGHT);
     2204    }
     2205    if (!extend)
     2206        s = e;
     2207    EDIT_EM_SetSel(hwnd, es, s, e, FALSE);
     2208    EDIT_EM_ScrollCaret(hwnd, es);
     2209}
     2210
     2211
     2212/*********************************************************************
     2213 *
     2214 *  EDIT_PaintLine
    21822215 *
    21832216 */
    21842217static void EDIT_PaintLine(HWND hwnd, EDITSTATE *es, HDC dc, INT line, BOOL rev)
    21852218{
    2186         INT s = es->selection_start;
    2187         INT e = es->selection_end;
    2188         INT li;
    2189         INT ll;
    2190         INT x;
    2191         INT y;
    2192         LRESULT pos;
    2193 
    2194         if (es->style & ES_MULTILINE) {
    2195                 INT vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
    2196                 if ((line < es->y_offset) || (line > es->y_offset + vlc) || (line >= es->line_count))
    2197                         return;
    2198         } else if (line)
    2199                 return;
    2200 
    2201         TRACE("line=%d\n", line);
    2202 
    2203         pos = EDIT_EM_PosFromChar(hwnd, es, EDIT_EM_LineIndex(es, line), FALSE);
    2204         x = SLOWORD(pos);
    2205         y = SHIWORD(pos);
    2206         li = EDIT_EM_LineIndex(es, line);
    2207         ll = EDIT_EM_LineLength(es, li);
    2208         s = es->selection_start;
    2209         e = es->selection_end;
    2210         ORDER_INT(s, e);
    2211         s = min(li + ll, max(li, s));
    2212         e = min(li + ll, max(li, e));
    2213         if (rev && (s != e) &&
    2214                         ((es->flags & EF_FOCUSED) || (es->style & ES_NOHIDESEL))) {
    2215                 x += EDIT_PaintText(es, dc, x, y, line, 0, s - li, FALSE);
    2216                 x += EDIT_PaintText(es, dc, x, y, line, s - li, e - s, TRUE);
    2217                 x += EDIT_PaintText(es, dc, x, y, line, e - li, li + ll - e, FALSE);
    2218         } else
    2219                 x += EDIT_PaintText(es, dc, x, y, line, 0, ll, FALSE);
    2220 }
    2221 
    2222 
    2223 /*********************************************************************
    2224  *
    2225  *      EDIT_PaintText
     2219    INT s = es->selection_start;
     2220    INT e = es->selection_end;
     2221    INT li;
     2222    INT ll;
     2223    INT x;
     2224    INT y;
     2225    LRESULT pos;
     2226
     2227    if (es->style & ES_MULTILINE) {
     2228        INT vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
     2229        if ((line < es->y_offset) || (line > es->y_offset + vlc) || (line >= es->line_count))
     2230            return;
     2231    } else if (line)
     2232        return;
     2233
     2234    TRACE("line=%d\n", line);
     2235
     2236    pos = EDIT_EM_PosFromChar(hwnd, es, EDIT_EM_LineIndex(es, line), FALSE);
     2237    x = SLOWORD(pos);
     2238    y = SHIWORD(pos);
     2239    li = EDIT_EM_LineIndex(es, line);
     2240    ll = EDIT_EM_LineLength(es, li);
     2241    s = es->selection_start;
     2242    e = es->selection_end;
     2243    ORDER_INT(s, e);
     2244    s = min(li + ll, max(li, s));
     2245    e = min(li + ll, max(li, e));
     2246    if (rev && (s != e) &&
     2247            ((es->flags & EF_FOCUSED) || (es->style & ES_NOHIDESEL))) {
     2248        x += EDIT_PaintText(es, dc, x, y, line, 0, s - li, FALSE);
     2249        x += EDIT_PaintText(es, dc, x, y, line, s - li, e - s, TRUE);
     2250        x += EDIT_PaintText(es, dc, x, y, line, e - li, li + ll - e, FALSE);
     2251    } else
     2252        x += EDIT_PaintText(es, dc, x, y, line, 0, ll, FALSE);
     2253}
     2254
     2255
     2256/*********************************************************************
     2257 *
     2258 *  EDIT_PaintText
    22262259 *
    22272260 */
    22282261static INT EDIT_PaintText(EDITSTATE *es, HDC dc, INT x, INT y, INT line, INT col, INT count, BOOL rev)
    22292262{
    2230         COLORREF BkColor;
    2231         COLORREF TextColor;
    2232         INT ret;
    2233         INT li;
    2234         INT BkMode;
    2235         SIZE size;
    2236 
    2237         if (!count)
    2238                 return 0;
    2239         BkMode = GetBkMode(dc);
    2240         BkColor = GetBkColor(dc);
    2241         TextColor = GetTextColor(dc);
    2242         if (rev) {
    2243                 SetBkColor(dc, GetSysColor(COLOR_HIGHLIGHT));
    2244                 SetTextColor(dc, GetSysColor(COLOR_HIGHLIGHTTEXT));
    2245                 SetBkMode( dc, OPAQUE);
    2246         }
    2247         li = EDIT_EM_LineIndex(es, line);
    2248         if (es->style & ES_MULTILINE) {
    2249                 ret = (INT)LOWORD(TabbedTextOutW(dc, x, y, es->text + li + col, count,
    2250                                         es->tabs_count, es->tabs, es->format_rect.left - es->x_offset));
    2251         } else {
    2252                 LPWSTR text = EDIT_GetPasswordPointer_SL(es);
    2253                 TextOutW(dc, x, y, text + li + col, count);
    2254                 GetTextExtentPoint32W(dc, text + li + col, count, &size);
    2255                 ret = size.cx;
    2256                 if (es->style & ES_PASSWORD)
    2257                         HeapFree(GetProcessHeap(), 0, text);
    2258         }
    2259         if (rev) {
    2260                 SetBkColor(dc, BkColor);
    2261                 SetTextColor(dc, TextColor);
    2262                 SetBkMode( dc, BkMode);
    2263         }
    2264         return ret;
    2265 }
    2266 
    2267 
    2268 /*********************************************************************
    2269  *
    2270  *      EDIT_SetCaretPos
     2263    COLORREF BkColor;
     2264    COLORREF TextColor;
     2265    INT ret;
     2266    INT li;
     2267    INT BkMode;
     2268    SIZE size;
     2269
     2270    if (!count)
     2271        return 0;
     2272    BkMode = GetBkMode(dc);
     2273    BkColor = GetBkColor(dc);
     2274    TextColor = GetTextColor(dc);
     2275    if (rev) {
     2276        SetBkColor(dc, GetSysColor(COLOR_HIGHLIGHT));
     2277        SetTextColor(dc, GetSysColor(COLOR_HIGHLIGHTTEXT));
     2278        SetBkMode( dc, OPAQUE);
     2279    }
     2280    li = EDIT_EM_LineIndex(es, line);
     2281    if (es->style & ES_MULTILINE) {
     2282        ret = (INT)LOWORD(TabbedTextOutW(dc, x, y, es->text + li + col, count,
     2283                    es->tabs_count, es->tabs, es->format_rect.left - es->x_offset));
     2284    } else {
     2285        LPWSTR text = EDIT_GetPasswordPointer_SL(es);
     2286        TextOutW(dc, x, y, text + li + col, count);
     2287        GetTextExtentPoint32W(dc, text + li + col, count, &size);
     2288        ret = size.cx;
     2289        if (es->style & ES_PASSWORD)
     2290            HeapFree(GetProcessHeap(), 0, text);
     2291    }
     2292    if (rev) {
     2293        SetBkColor(dc, BkColor);
     2294        SetTextColor(dc, TextColor);
     2295        SetBkMode( dc, BkMode);
     2296    }
     2297    return ret;
     2298}
     2299
     2300
     2301/*********************************************************************
     2302 *
     2303 *  EDIT_SetCaretPos
    22712304 *
    22722305 */
    22732306static void EDIT_SetCaretPos(HWND hwnd, EDITSTATE *es, INT pos,
    2274                              BOOL after_wrap)
    2275 {
    2276         LRESULT res = EDIT_EM_PosFromChar(hwnd, es, pos, after_wrap);
    2277         SetCaretPos(SLOWORD(res), SHIWORD(res));
    2278 }
    2279 
    2280 
    2281 /*********************************************************************
    2282  *
    2283  *      EDIT_SetRectNP
    2284  *
    2285  *      note:   this is not (exactly) the handler called on EM_SETRECTNP
    2286  *              it is also used to set the rect of a single line control
     2307                 BOOL after_wrap)
     2308{
     2309    LRESULT res = EDIT_EM_PosFromChar(hwnd, es, pos, after_wrap);
     2310    SetCaretPos(SLOWORD(res), SHIWORD(res));
     2311}
     2312
     2313
     2314/*********************************************************************
     2315 *
     2316 *  EDIT_SetRectNP
     2317 *
     2318 *  note:   this is not (exactly) the handler called on EM_SETRECTNP
     2319 *      it is also used to set the rect of a single line control
    22872320 *
    22882321 */
    22892322static void EDIT_SetRectNP(HWND hwnd, EDITSTATE *es, LPRECT rc)
    22902323{
    2291         CopyRect(&es->format_rect, rc);
    2292         if (es->style & WS_BORDER) {
    2293                 INT bw = GetSystemMetrics(SM_CXBORDER) + 1;
    2294                 if(TWEAK_WineLook == WIN31_LOOK)
    2295                         bw += 2;
    2296                 es->format_rect.left += bw;
    2297                 es->format_rect.top += bw;
    2298                 es->format_rect.right -= bw;
    2299                 es->format_rect.bottom -= bw;
    2300         }
    2301         es->format_rect.left += es->left_margin;
    2302         es->format_rect.right -= es->right_margin;
    2303         es->format_rect.right = max(es->format_rect.right, es->format_rect.left + es->char_width);
    2304         if (es->style & ES_MULTILINE)
    2305         {
    2306             INT fw, vlc, max_x_offset, max_y_offset;
    2307 
    2308             vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
    2309             es->format_rect.bottom = es->format_rect.top + max(1, vlc) * es->line_height;
    2310 
    2311             /* correct es->x_offset */
    2312             fw = es->format_rect.right - es->format_rect.left;
    2313             max_x_offset = es->text_width - fw;
    2314             if(max_x_offset < 0) max_x_offset = 0;
    2315             if(es->x_offset > max_x_offset)
    2316                 es->x_offset = max_x_offset;
    2317 
    2318             /* correct es->y_offset */
    2319             max_y_offset = es->line_count - vlc;
    2320             if(max_y_offset < 0) max_y_offset = 0;
    2321             if(es->y_offset > max_y_offset)
    2322                 es->y_offset = max_y_offset;
    2323 
    2324             /* force scroll info update */
    2325             EDIT_UpdateScrollInfo(hwnd, es);
    2326         }
    2327         else
    2328         /* Windows doesn't care to fix text placement for SL controls */
    2329                 es->format_rect.bottom = es->format_rect.top + es->line_height;
    2330 
    2331         if ((es->style & ES_MULTILINE) && !(es->style & ES_AUTOHSCROLL))
    2332                 EDIT_BuildLineDefs_ML(hwnd, es, 0, strlenW(es->text), 0, (HRGN)0);
    2333 }
    2334 
    2335 
    2336 /*********************************************************************
    2337  *
    2338  *      EDIT_UnlockBuffer
     2324    CopyRect(&es->format_rect, rc);
     2325    if (es->style & WS_BORDER) {
     2326        INT bw = GetSystemMetrics(SM_CXBORDER) + 1;
     2327        if(TWEAK_WineLook == WIN31_LOOK)
     2328            bw += 2;
     2329        es->format_rect.left += bw;
     2330        es->format_rect.top += bw;
     2331        es->format_rect.right -= bw;
     2332        es->format_rect.bottom -= bw;
     2333    }
     2334    es->format_rect.left += es->left_margin;
     2335    es->format_rect.right -= es->right_margin;
     2336    es->format_rect.right = max(es->format_rect.right, es->format_rect.left + es->char_width);
     2337    if (es->style & ES_MULTILINE)
     2338    {
     2339        INT fw, vlc, max_x_offset, max_y_offset;
     2340
     2341        vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
     2342        es->format_rect.bottom = es->format_rect.top + max(1, vlc) * es->line_height;
     2343
     2344        /* correct es->x_offset */
     2345        fw = es->format_rect.right - es->format_rect.left;
     2346        max_x_offset = es->text_width - fw;
     2347        if(max_x_offset < 0) max_x_offset = 0;
     2348        if(es->x_offset > max_x_offset)
     2349        es->x_offset = max_x_offset;
     2350
     2351        /* correct es->y_offset */
     2352        max_y_offset = es->line_count - vlc;
     2353        if(max_y_offset < 0) max_y_offset = 0;
     2354        if(es->y_offset > max_y_offset)
     2355        es->y_offset = max_y_offset;
     2356
     2357        /* force scroll info update */
     2358        EDIT_UpdateScrollInfo(hwnd, es);
     2359    }
     2360    else
     2361    /* Windows doesn't care to fix text placement for SL controls */
     2362        es->format_rect.bottom = es->format_rect.top + es->line_height;
     2363
     2364    if ((es->style & ES_MULTILINE) && !(es->style & ES_AUTOHSCROLL))
     2365        EDIT_BuildLineDefs_ML(hwnd, es, 0, strlenW(es->text), 0, (HRGN)0);
     2366}
     2367
     2368
     2369/*********************************************************************
     2370 *
     2371 *  EDIT_UnlockBuffer
    23392372 *
    23402373 */
     
    23462379    if(!IsWindow(hwnd))
    23472380    {
    2348         WARN("edit hwnd %04x already destroyed\n", hwnd);
    2349         return;
    2350     }
    2351 
    2352         if (!es) {
    2353                 ERR("no EDITSTATE ... please report\n");
    2354                 return;
    2355         }
    2356         if (!es->lock_count) {
    2357                 ERR("lock_count == 0 ... please report\n");
    2358                 return;
    2359         }
    2360         if (!es->text) {
    2361                 ERR("es->text == 0 ... please report\n");
    2362                 return;
    2363         }
    2364 
    2365         if (force || (es->lock_count == 1)) {
    2366             if (es->hloc32W) {
    2367                 CHAR *textA = NULL;
    2368                 BOOL _16bit = FALSE;
    2369                 UINT countA = 0;
    2370                 UINT countW = strlenW(es->text) + 1;
    2371 
    2372                 if(es->hloc32A)
    2373                 {
    2374                     UINT countA_new = WideCharToMultiByte(CP_ACP, 0, es->text, countW, NULL, 0, NULL, NULL);
    2375                     TRACE("Synchronizing with 32-bit ANSI buffer\n");
    2376                     TRACE("%d WCHARs translated to %d bytes\n", countW, countA_new);
    2377                     countA = LocalSize(es->hloc32A);
    2378                     if(countA_new > countA)
    2379                     {
    2380                         HLOCAL hloc32A_new;
    2381                         UINT alloc_size = ROUND_TO_GROW(countA_new);
    2382                         TRACE("Resizing 32-bit ANSI buffer from %d to %d bytes\n", countA, alloc_size);
    2383                         hloc32A_new = LocalReAlloc(es->hloc32A, alloc_size, LMEM_MOVEABLE | LMEM_ZEROINIT);
    2384                         if(hloc32A_new)
    2385                         {
    2386                             es->hloc32A = hloc32A_new;
    2387                             countA = LocalSize(hloc32A_new);
    2388                             TRACE("Real new size %d bytes\n", countA);
    2389                         }
    2390                         else
    2391                             WARN("FAILED! Will synchronize partially\n");
    2392                     }
    2393                     textA = LocalLock(es->hloc32A);
    2394                 }
    2395                 else if(es->hloc16)
    2396                 {
    2397                     UINT countA_new = WideCharToMultiByte(CP_ACP, 0, es->text, countW, NULL, 0, NULL, NULL);
    2398                     TRACE("Synchronizing with 16-bit ANSI buffer\n");
    2399                     TRACE("%d WCHARs translated to %d bytes\n", countW, countA_new);
    2400                     countA = LOCAL_Size(hInstance, es->hloc16);
    2401                     if(countA_new > countA)
    2402                     {
    2403                         HLOCAL16 hloc16_new;
    2404                         UINT alloc_size = ROUND_TO_GROW(countA_new);
    2405                         TRACE("Resizing 16-bit ANSI buffer from %d to %d bytes\n", countA, alloc_size);
    2406                         hloc16_new = LOCAL_ReAlloc(hInstance, es->hloc16, alloc_size, LMEM_MOVEABLE | LMEM_ZEROINIT);
    2407                         if(hloc16_new)
    2408                         {
    2409                             es->hloc16 = hloc16_new;
    2410                             countA = LOCAL_Size(hInstance, hloc16_new);
    2411                             TRACE("Real new size %d bytes\n", countA);
    2412                         }
    2413                         else
    2414                             WARN("FAILED! Will synchronize partially\n");
    2415                     }
    2416                     textA = LOCAL_Lock(hInstance, es->hloc16);
    2417                     _16bit = TRUE;
    2418                 }
    2419                 if(textA)
    2420                 {
    2421                     WideCharToMultiByte(CP_ACP, 0, es->text, countW, textA, countA, NULL, NULL);
    2422                     if(_16bit)
    2423                         LOCAL_Unlock(hInstance, es->hloc16);
    2424                     else
    2425                         LocalUnlock(es->hloc32A);
    2426                 }
    2427 
    2428                 LocalUnlock(es->hloc32W);
    2429                 es->text = NULL;
    2430             }
    2431             else {
    2432                 ERR("no buffer ... please report\n");
    2433                 return;
    2434             }
    2435         }
    2436         es->lock_count--;
    2437 }
    2438 
    2439 
    2440 /*********************************************************************
    2441  *
    2442  *      EDIT_UpdateScrollInfo
     2381    WARN("edit hwnd %04x already destroyed\n", hwnd);
     2382    return;
     2383    }
     2384
     2385    if (!es) {
     2386        ERR("no EDITSTATE ... please report\n");
     2387        return;
     2388    }
     2389    if (!es->lock_count) {
     2390        ERR("lock_count == 0 ... please report\n");
     2391        return;
     2392    }
     2393    if (!es->text) {
     2394        ERR("es->text == 0 ... please report\n");
     2395        return;
     2396    }
     2397
     2398    if (force || (es->lock_count == 1)) {
     2399        if (es->hloc32W) {
     2400        CHAR *textA = NULL;
     2401        BOOL _16bit = FALSE;
     2402        UINT countA = 0;
     2403        UINT countW = strlenW(es->text) + 1;
     2404
     2405        if(es->hloc32A)
     2406        {
     2407            UINT countA_new = WideCharToMultiByte(CP_ACP, 0, es->text, countW, NULL, 0, NULL, NULL);
     2408            TRACE("Synchronizing with 32-bit ANSI buffer\n");
     2409            TRACE("%d WCHARs translated to %d bytes\n", countW, countA_new);
     2410            countA = LocalSize(es->hloc32A);
     2411            if(countA_new > countA)
     2412            {
     2413            HLOCAL hloc32A_new;
     2414            UINT alloc_size = ROUND_TO_GROW(countA_new);
     2415            TRACE("Resizing 32-bit ANSI buffer from %d to %d bytes\n", countA, alloc_size);
     2416            hloc32A_new = LocalReAlloc(es->hloc32A, alloc_size, LMEM_MOVEABLE | LMEM_ZEROINIT);
     2417            if(hloc32A_new)
     2418            {
     2419                es->hloc32A = hloc32A_new;
     2420                countA = LocalSize(hloc32A_new);
     2421                TRACE("Real new size %d bytes\n", countA);
     2422            }
     2423            else
     2424                WARN("FAILED! Will synchronize partially\n");
     2425            }
     2426            textA = LocalLock(es->hloc32A);
     2427        }
     2428        else if(es->hloc16)
     2429        {
     2430            UINT countA_new = WideCharToMultiByte(CP_ACP, 0, es->text, countW, NULL, 0, NULL, NULL);
     2431            TRACE("Synchronizing with 16-bit ANSI buffer\n");
     2432            TRACE("%d WCHARs translated to %d bytes\n", countW, countA_new);
     2433            countA = LOCAL_Size(hInstance, es->hloc16);
     2434            if(countA_new > countA)
     2435            {
     2436            HLOCAL16 hloc16_new;
     2437            UINT alloc_size = ROUND_TO_GROW(countA_new);
     2438            TRACE("Resizing 16-bit ANSI buffer from %d to %d bytes\n", countA, alloc_size);
     2439            hloc16_new = LOCAL_ReAlloc(hInstance, es->hloc16, alloc_size, LMEM_MOVEABLE | LMEM_ZEROINIT);
     2440            if(hloc16_new)
     2441            {
     2442                es->hloc16 = hloc16_new;
     2443                countA = LOCAL_Size(hInstance, hloc16_new);
     2444                TRACE("Real new size %d bytes\n", countA);
     2445            }
     2446            else
     2447                WARN("FAILED! Will synchronize partially\n");
     2448            }
     2449            textA = LOCAL_Lock(hInstance, es->hloc16);
     2450            _16bit = TRUE;
     2451        }
     2452        if(textA)
     2453        {
     2454            WideCharToMultiByte(CP_ACP, 0, es->text, countW, textA, countA, NULL, NULL);
     2455            if(_16bit)
     2456            LOCAL_Unlock(hInstance, es->hloc16);
     2457            else
     2458            LocalUnlock(es->hloc32A);
     2459        }
     2460
     2461        LocalUnlock(es->hloc32W);
     2462        es->text = NULL;
     2463        }
     2464        else {
     2465        ERR("no buffer ... please report\n");
     2466        return;
     2467        }
     2468    }
     2469    es->lock_count--;
     2470}
     2471
     2472
     2473/*********************************************************************
     2474 *
     2475 *  EDIT_UpdateScrollInfo
    24432476 *
    24442477 */
     
    24472480    if ((es->style & WS_VSCROLL) && !(es->flags & EF_VSCROLL_TRACK))
    24482481    {
    2449         SCROLLINFO si;
    2450         si.cbSize       = sizeof(SCROLLINFO);
    2451         si.fMask        = SIF_PAGE | SIF_POS | SIF_RANGE | SIF_DISABLENOSCROLL;
    2452         si.nMin         = 0;
    2453         si.nMax         = es->line_count - 1;
    2454         si.nPage        = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
    2455         si.nPos         = es->y_offset;
    2456         TRACE("SB_VERT, nMin=%d, nMax=%d, nPage=%d, nPos=%d\n",
    2457                 si.nMin, si.nMax, si.nPage, si.nPos);
    2458         SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
     2482    SCROLLINFO si;
     2483    si.cbSize   = sizeof(SCROLLINFO);
     2484    si.fMask    = SIF_PAGE | SIF_POS | SIF_RANGE | SIF_DISABLENOSCROLL;
     2485    si.nMin     = 0;
     2486    si.nMax     = es->line_count - 1;
     2487    si.nPage    = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
     2488    si.nPos     = es->y_offset;
     2489    TRACE("SB_VERT, nMin=%d, nMax=%d, nPage=%d, nPos=%d\n",
     2490        si.nMin, si.nMax, si.nPage, si.nPos);
     2491    SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
    24592492    }
    24602493
    24612494    if ((es->style & WS_HSCROLL) && !(es->flags & EF_HSCROLL_TRACK))
    24622495    {
    2463         SCROLLINFO si;
    2464         si.cbSize       = sizeof(SCROLLINFO);
    2465         si.fMask        = SIF_PAGE | SIF_POS | SIF_RANGE | SIF_DISABLENOSCROLL;
    2466         si.nMin         = 0;
    2467         si.nMax         = es->text_width - 1;
    2468         si.nPage        = es->format_rect.right - es->format_rect.left;
    2469         si.nPos         = es->x_offset;
    2470         TRACE("SB_HORZ, nMin=%d, nMax=%d, nPage=%d, nPos=%d\n",
    2471                 si.nMin, si.nMax, si.nPage, si.nPos);
    2472         SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
    2473     }
    2474 }
    2475 
    2476 /*********************************************************************
    2477  *
    2478  *      EDIT_WordBreakProc
    2479  *
    2480  *      Find the beginning of words.
    2481  *      Note:   unlike the specs for a WordBreakProc, this function only
    2482  *              allows to be called without linebreaks between s[0] upto
    2483  *              s[count - 1].  Remember it is only called
    2484  *              internally, so we can decide this for ourselves.
     2496    SCROLLINFO si;
     2497    si.cbSize   = sizeof(SCROLLINFO);
     2498    si.fMask    = SIF_PAGE | SIF_POS | SIF_RANGE | SIF_DISABLENOSCROLL;
     2499    si.nMin     = 0;
     2500    si.nMax     = es->text_width - 1;
     2501    si.nPage    = es->format_rect.right - es->format_rect.left;
     2502    si.nPos     = es->x_offset;
     2503    TRACE("SB_HORZ, nMin=%d, nMax=%d, nPage=%d, nPos=%d\n",
     2504        si.nMin, si.nMax, si.nPage, si.nPos);
     2505    SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
     2506    }
     2507}
     2508
     2509/*********************************************************************
     2510 *
     2511 *  EDIT_WordBreakProc
     2512 *
     2513 *  Find the beginning of words.
     2514 *  Note:   unlike the specs for a WordBreakProc, this function only
     2515 *      allows to be called without linebreaks between s[0] upto
     2516 *      s[count - 1].  Remember it is only called
     2517 *      internally, so we can decide this for ourselves.
    24852518 *
    24862519 */
    24872520static INT CALLBACK EDIT_WordBreakProc(LPWSTR s, INT index, INT count, INT action)
    24882521{
    2489         INT ret = 0;
    2490 
    2491         TRACE("s=%p, index=%d, count=%d, action=%d\n", s, index, count, action);
    2492 
    2493         if(!s) return 0;
    2494 
    2495         switch (action) {
    2496         case WB_LEFT:
    2497                 if (!count)
    2498                         break;
    2499                 if (index)
    2500                         index--;
    2501                 if (s[index] == ' ') {
    2502                         while (index && (s[index] == ' '))
    2503                                 index--;
    2504                         if (index) {
    2505                                 while (index && (s[index] != ' '))
    2506                                         index--;
    2507                                 if (s[index] == ' ')
    2508                                         index++;
    2509                         }
    2510                 } else {
    2511                         while (index && (s[index] != ' '))
    2512                                 index--;
    2513                         if (s[index] == ' ')
    2514                                 index++;
    2515                 }
    2516                 ret = index;
    2517                 break;
    2518         case WB_RIGHT:
    2519                 if (!count)
    2520                         break;
    2521                 if (index)
    2522                         index--;
    2523                 if (s[index] == ' ')
    2524                         while ((index < count) && (s[index] == ' ')) index++;
    2525                 else {
    2526                         while (s[index] && (s[index] != ' ') && (index < count))
    2527                                 index++;
    2528                         while ((s[index] == ' ') && (index < count)) index++;
    2529                 }
    2530                 ret = index;
    2531                 break;
    2532         case WB_ISDELIMITER:
    2533                 ret = (s[index] == ' ');
    2534                 break;
    2535         default:
    2536                 ERR("unknown action code, please report !\n");
    2537                 break;
    2538         }
    2539         return ret;
    2540 }
    2541 
    2542 
    2543 /*********************************************************************
    2544  *
    2545  *      EM_CHARFROMPOS
     2522    INT ret = 0;
     2523
     2524    TRACE("s=%p, index=%d, count=%d, action=%d\n", s, index, count, action);
     2525
     2526    if(!s) return 0;
     2527
     2528    switch (action) {
     2529    case WB_LEFT:
     2530        if (!count)
     2531            break;
     2532        if (index)
     2533            index--;
     2534        if (s[index] == ' ') {
     2535            while (index && (s[index] == ' '))
     2536                index--;
     2537            if (index) {
     2538                while (index && (s[index] != ' '))
     2539                    index--;
     2540                if (s[index] == ' ')
     2541                    index++;
     2542            }
     2543        } else {
     2544            while (index && (s[index] != ' '))
     2545                index--;
     2546            if (s[index] == ' ')
     2547                index++;
     2548        }
     2549        ret = index;
     2550        break;
     2551    case WB_RIGHT:
     2552        if (!count)
     2553            break;
     2554        if (index)
     2555            index--;
     2556        if (s[index] == ' ')
     2557            while ((index < count) && (s[index] == ' ')) index++;
     2558        else {
     2559            while (s[index] && (s[index] != ' ') && (index < count))
     2560                index++;
     2561            while ((s[index] == ' ') && (index < count)) index++;
     2562        }
     2563        ret = index;
     2564        break;
     2565    case WB_ISDELIMITER:
     2566        ret = (s[index] == ' ');
     2567        break;
     2568    default:
     2569        ERR("unknown action code, please report !\n");
     2570        break;
     2571    }
     2572    return ret;
     2573}
     2574
     2575
     2576/*********************************************************************
     2577 *
     2578 *  EM_CHARFROMPOS
    25462579 *
    25472580 *      returns line number (not index) in high-order word of result.
    25482581 *      NB : Q137805 is unclear about this. POINT * pointer in lParam apply
    25492582 *      to Richedit, not to the edit control. Original documentation is valid.
    2550  *      FIXME: do the specs mean to return -1 if outside client area or
    2551  *              if outside formatting rectangle ???
     2583 *  FIXME: do the specs mean to return -1 if outside client area or
     2584 *      if outside formatting rectangle ???
    25522585 *
    25532586 */
    25542587static LRESULT EDIT_EM_CharFromPos(HWND hwnd, EDITSTATE *es, INT x, INT y)
    25552588{
    2556         POINT pt;
    2557         RECT rc;
    2558         INT index;
    2559 
    2560         pt.x = x;
    2561         pt.y = y;
    2562         GetClientRect(hwnd, &rc);
    2563         if (!PtInRect(&rc, pt))
    2564                 return -1;
    2565 
    2566         index = EDIT_CharFromPos(hwnd, es, x, y, NULL);
    2567         return MAKELONG(index, EDIT_EM_LineFromChar(es, index));
    2568 }
    2569 
    2570 
    2571 /*********************************************************************
    2572  *
    2573  *      EM_FMTLINES
     2589    POINT pt;
     2590    RECT rc;
     2591    INT index;
     2592
     2593    pt.x = x;
     2594    pt.y = y;
     2595    GetClientRect(hwnd, &rc);
     2596    if (!PtInRect(&rc, pt))
     2597        return -1;
     2598
     2599    index = EDIT_CharFromPos(hwnd, es, x, y, NULL);
     2600    return MAKELONG(index, EDIT_EM_LineFromChar(es, index));
     2601}
     2602
     2603
     2604/*********************************************************************
     2605 *
     2606 *  EM_FMTLINES
    25742607 *
    25752608 * Enable or disable soft breaks.
     
    25772610static BOOL EDIT_EM_FmtLines(EDITSTATE *es, BOOL add_eol)
    25782611{
    2579         es->flags &= ~EF_USE_SOFTBRK;
    2580         if (add_eol) {
    2581                 es->flags |= EF_USE_SOFTBRK;
    2582                 FIXME("soft break enabled, not implemented\n");
    2583         }
    2584         return add_eol;
    2585 }
    2586 
    2587 
    2588 /*********************************************************************
    2589  *
    2590  *      EM_GETHANDLE
    2591  *
    2592  *      Hopefully this won't fire back at us.
    2593  *      We always start with a fixed buffer in the local heap.
    2594  *      Despite of the documentation says that the local heap is used
    2595  *      only if DS_LOCALEDIT flag is set, NT and 2000 always allocate
    2596  *      buffer on the local heap.
     2612    es->flags &= ~EF_USE_SOFTBRK;
     2613    if (add_eol) {
     2614        es->flags |= EF_USE_SOFTBRK;
     2615        FIXME("soft break enabled, not implemented\n");
     2616    }
     2617    return add_eol;
     2618}
     2619
     2620
     2621/*********************************************************************
     2622 *
     2623 *  EM_GETHANDLE
     2624 *
     2625 *  Hopefully this won't fire back at us.
     2626 *  We always start with a fixed buffer in the local heap.
     2627 *  Despite of the documentation says that the local heap is used
     2628 *  only if DS_LOCALEDIT flag is set, NT and 2000 always allocate
     2629 *  buffer on the local heap.
    25972630 *
    25982631 */
    25992632static HLOCAL EDIT_EM_GetHandle(EDITSTATE *es)
    26002633{
    2601         HLOCAL hLocal;
    2602 
    2603         if (!(es->style & ES_MULTILINE))
    2604                 return 0;
    2605 
    2606         if(es->is_unicode)
    2607             hLocal = es->hloc32W;
    2608         else
    2609         {
    2610             if(!es->hloc32A)
    2611             {
    2612                 CHAR *textA;
    2613                 UINT countA, alloc_size;
    2614                 TRACE("Allocating 32-bit ANSI alias buffer\n");
    2615                 countA = WideCharToMultiByte(CP_ACP, 0, es->text, -1, NULL, 0, NULL, NULL);
    2616                 alloc_size = ROUND_TO_GROW(countA);
    2617                 if(!(es->hloc32A = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT, alloc_size)))
    2618                 {
    2619                     ERR("Could not allocate %d bytes for 32-bit ANSI alias buffer\n", alloc_size);
    2620                     return 0;
    2621                 }
    2622                 textA = LocalLock(es->hloc32A);
    2623                 WideCharToMultiByte(CP_ACP, 0, es->text, -1, textA, countA, NULL, NULL);
    2624                 LocalUnlock(es->hloc32A);
    2625             }
    2626             hLocal = es->hloc32A;
    2627         }
    2628 
    2629         TRACE("Returning %04X, LocalSize() = %d\n", hLocal, LocalSize(hLocal));
    2630         return hLocal;
     2634    HLOCAL hLocal;
     2635
     2636    if (!(es->style & ES_MULTILINE))
     2637        return 0;
     2638
     2639    if(es->is_unicode)
     2640        hLocal = es->hloc32W;
     2641    else
     2642    {
     2643        if(!es->hloc32A)
     2644        {
     2645        CHAR *textA;
     2646        UINT countA, alloc_size;
     2647        TRACE("Allocating 32-bit ANSI alias buffer\n");
     2648        countA = WideCharToMultiByte(CP_ACP, 0, es->text, -1, NULL, 0, NULL, NULL);
     2649        alloc_size = ROUND_TO_GROW(countA);
     2650        if(!(es->hloc32A = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT, alloc_size)))
     2651        {
     2652            ERR("Could not allocate %d bytes for 32-bit ANSI alias buffer\n", alloc_size);
     2653            return 0;
     2654        }
     2655        textA = LocalLock(es->hloc32A);
     2656        WideCharToMultiByte(CP_ACP, 0, es->text, -1, textA, countA, NULL, NULL);
     2657        LocalUnlock(es->hloc32A);
     2658        }
     2659        hLocal = es->hloc32A;
     2660    }
     2661
     2662    TRACE("Returning %04X, LocalSize() = %d\n", hLocal, LocalSize(hLocal));
     2663    return hLocal;
    26312664}
    26322665
     
    26342667/*********************************************************************
    26352668 *
    2636  *      EM_GETHANDLE16
    2637  *
    2638  *      Hopefully this won't fire back at us.
    2639  *      We always start with a buffer in 32 bit linear memory.
    2640  *      However, with this message a 16 bit application requests
    2641  *      a handle of 16 bit local heap memory, where it expects to find
    2642  *      the text.
    2643  *      It's a pitty that from this moment on we have to use this
    2644  *      local heap, because applications may rely on the handle
    2645  *      in the future.
    2646  *
    2647  *      In this function we'll try to switch to local heap.
     2669 *  EM_GETHANDLE16
     2670 *
     2671 *  Hopefully this won't fire back at us.
     2672 *  We always start with a buffer in 32 bit linear memory.
     2673 *  However, with this message a 16 bit application requests
     2674 *  a handle of 16 bit local heap memory, where it expects to find
     2675 *  the text.
     2676 *  It's a pitty that from this moment on we have to use this
     2677 *  local heap, because applications may rely on the handle
     2678 *  in the future.
     2679 *
     2680 *  In this function we'll try to switch to local heap.
    26482681 */
    26492682static HLOCAL16 EDIT_EM_GetHandle16(HWND hwnd, EDITSTATE *es)
    26502683{
    26512684    HINSTANCE hInstance = GetWindowLongA( hwnd, GWL_HINSTANCE );
    2652         CHAR *textA;
    2653         UINT countA, alloc_size;
    2654 
    2655         if (!(es->style & ES_MULTILINE))
    2656                 return 0;
    2657 
    2658         if (es->hloc16)
    2659                 return es->hloc16;
    2660 
    2661         if (!LOCAL_HeapSize(hInstance)) {
    2662                 if (!LocalInit16(hInstance, 0,
    2663                                 GlobalSize16(hInstance))) {
    2664                         ERR("could not initialize local heap\n");
    2665                         return 0;
    2666                 }
    2667                 TRACE("local heap initialized\n");
    2668         }
    2669 
    2670         countA = WideCharToMultiByte(CP_ACP, 0, es->text, -1, NULL, 0, NULL, NULL);
    2671         alloc_size = ROUND_TO_GROW(countA);
    2672 
    2673         TRACE("Allocating 16-bit ANSI alias buffer\n");
    2674         if (!(es->hloc16 = LOCAL_Alloc(hInstance, LMEM_MOVEABLE | LMEM_ZEROINIT, alloc_size))) {
    2675                 ERR("could not allocate new 16 bit buffer\n");
    2676                 return 0;
    2677         }
    2678 
    2679         if (!(textA = (LPSTR)LOCAL_Lock(hInstance, es->hloc16))) {
    2680                 ERR("could not lock new 16 bit buffer\n");
    2681                 LOCAL_Free(hInstance, es->hloc16);
    2682                 es->hloc16 = 0;
    2683                 return 0;
    2684         }
    2685 
    2686         WideCharToMultiByte(CP_ACP, 0, es->text, -1, textA, countA, NULL, NULL);
    2687         LOCAL_Unlock(hInstance, es->hloc16);
    2688 
    2689         TRACE("Returning %04X, LocalSize() = %d\n", es->hloc16, LOCAL_Size(hInstance, es->hloc16));
    2690         return es->hloc16;
     2685    CHAR *textA;
     2686    UINT countA, alloc_size;
     2687
     2688    if (!(es->style & ES_MULTILINE))
     2689        return 0;
     2690
     2691    if (es->hloc16)
     2692        return es->hloc16;
     2693
     2694    if (!LOCAL_HeapSize(hInstance)) {
     2695        if (!LocalInit16(hInstance, 0,
     2696                GlobalSize16(hInstance))) {
     2697            ERR("could not initialize local heap\n");
     2698            return 0;
     2699        }
     2700        TRACE("local heap initialized\n");
     2701    }
     2702
     2703    countA = WideCharToMultiByte(CP_ACP, 0, es->text, -1, NULL, 0, NULL, NULL);
     2704    alloc_size = ROUND_TO_GROW(countA);
     2705
     2706    TRACE("Allocating 16-bit ANSI alias buffer\n");
     2707    if (!(es->hloc16 = LOCAL_Alloc(hInstance, LMEM_MOVEABLE | LMEM_ZEROINIT, alloc_size))) {
     2708        ERR("could not allocate new 16 bit buffer\n");
     2709        return 0;
     2710    }
     2711
     2712    if (!(textA = (LPSTR)LOCAL_Lock(hInstance, es->hloc16))) {
     2713        ERR("could not lock new 16 bit buffer\n");
     2714        LOCAL_Free(hInstance, es->hloc16);
     2715        es->hloc16 = 0;
     2716        return 0;
     2717    }
     2718
     2719    WideCharToMultiByte(CP_ACP, 0, es->text, -1, textA, countA, NULL, NULL);
     2720    LOCAL_Unlock(hInstance, es->hloc16);
     2721
     2722    TRACE("Returning %04X, LocalSize() = %d\n", es->hloc16, LOCAL_Size(hInstance, es->hloc16));
     2723    return es->hloc16;
    26912724}
    26922725#endif
     
    26942727/*********************************************************************
    26952728 *
    2696  *      EM_GETLINE
     2729 *  EM_GETLINE
    26972730 *
    26982731 */
    26992732static INT EDIT_EM_GetLine(EDITSTATE *es, INT line, LPARAM lParam, BOOL unicode)
    27002733{
    2701         LPWSTR src;
    2702         INT line_len, dst_len;
    2703         INT i;
    2704 
    2705         if (es->style & ES_MULTILINE) {
    2706                 if (line >= es->line_count)
    2707                         return 0;
    2708         } else
    2709                 line = 0;
    2710         i = EDIT_EM_LineIndex(es, line);
    2711         src = es->text + i;
    2712         line_len = EDIT_EM_LineLength(es, i);
    2713         dst_len = *(WORD *)lParam;
    2714         if(unicode)
    2715         {
    2716             LPWSTR dst = (LPWSTR)lParam;
    2717             if(dst_len <= line_len)
    2718             {
    2719                 memcpy(dst, src, dst_len * sizeof(WCHAR));
    2720                 return dst_len;
    2721             }
    2722             else /* Append 0 if enough space */
    2723             {
    2724                 memcpy(dst, src, line_len * sizeof(WCHAR));
    2725                 dst[line_len] = 0;
    2726                 return line_len;
    2727             }
    2728         }
    2729         else
    2730         {
    2731             LPSTR dst = (LPSTR)lParam;
    2732             INT ret;
    2733             ret = WideCharToMultiByte(CP_ACP, 0, src, line_len, dst, dst_len, NULL, NULL);
    2734             if(!ret) /* Insufficient buffer size */
    2735                 return dst_len;
    2736             if(ret < dst_len) /* Append 0 if enough space */
    2737                 dst[ret] = 0;
    2738             return ret;
    2739         }
    2740 }
    2741 
    2742 
    2743 /*********************************************************************
    2744  *
    2745  *      EM_GETSEL
     2734    LPWSTR src;
     2735    INT line_len, dst_len;
     2736    INT i;
     2737
     2738    if (es->style & ES_MULTILINE) {
     2739        if (line >= es->line_count)
     2740            return 0;
     2741    } else
     2742        line = 0;
     2743    i = EDIT_EM_LineIndex(es, line);
     2744    src = es->text + i;
     2745    line_len = EDIT_EM_LineLength(es, i);
     2746    dst_len = *(WORD *)lParam;
     2747    if(unicode)
     2748    {
     2749        LPWSTR dst = (LPWSTR)lParam;
     2750        if(dst_len <= line_len)
     2751        {
     2752        memcpy(dst, src, dst_len * sizeof(WCHAR));
     2753        return dst_len;
     2754        }
     2755        else /* Append 0 if enough space */
     2756        {
     2757        memcpy(dst, src, line_len * sizeof(WCHAR));
     2758        dst[line_len] = 0;
     2759        return line_len;
     2760        }
     2761    }
     2762    else
     2763    {
     2764        LPSTR dst = (LPSTR)lParam;
     2765        INT ret;
     2766        ret = WideCharToMultiByte(CP_ACP, 0, src, line_len, dst, dst_len, NULL, NULL);
     2767        if(!ret) /* Insufficient buffer size */
     2768        return dst_len;
     2769        if(ret < dst_len) /* Append 0 if enough space */
     2770        dst[ret] = 0;
     2771        return ret;
     2772    }
     2773}
     2774
     2775
     2776/*********************************************************************
     2777 *
     2778 *  EM_GETSEL
    27462779 *
    27472780 */
    27482781static LRESULT EDIT_EM_GetSel(EDITSTATE *es, LPUINT start, LPUINT end)
    27492782{
    2750         UINT s = es->selection_start;
    2751         UINT e = es->selection_end;
    2752 
    2753         ORDER_UINT(s, e);
    2754         if (start)
    2755                 *start = s;
    2756         if (end)
    2757                 *end = e;
    2758         return MAKELONG(s, e);
    2759 }
    2760 
    2761 
    2762 /*********************************************************************
    2763  *
    2764  *      EM_GETTHUMB
    2765  *
    2766  *      FIXME: is this right ?  (or should it be only VSCROLL)
    2767  *      (and maybe only for edit controls that really have their
    2768  *      own scrollbars) (and maybe only for multiline controls ?)
    2769  *      All in all: very poorly documented
     2783    UINT s = es->selection_start;
     2784    UINT e = es->selection_end;
     2785
     2786    ORDER_UINT(s, e);
     2787    if (start)
     2788        *start = s;
     2789    if (end)
     2790        *end = e;
     2791    return MAKELONG(s, e);
     2792}
     2793
     2794
     2795/*********************************************************************
     2796 *
     2797 *  EM_GETTHUMB
     2798 *
     2799 *  FIXME: is this right ?  (or should it be only VSCROLL)
     2800 *  (and maybe only for edit controls that really have their
     2801 *  own scrollbars) (and maybe only for multiline controls ?)
     2802 *  All in all: very poorly documented
    27702803 *
    27712804 */
    27722805static LRESULT EDIT_EM_GetThumb(HWND hwnd, EDITSTATE *es)
    27732806{
    2774         return MAKELONG(EDIT_WM_VScroll(hwnd, es, EM_GETTHUMB16, 0),
    2775                 EDIT_WM_HScroll(hwnd, es, EM_GETTHUMB16, 0));
    2776 }
    2777 
    2778 
    2779 /*********************************************************************
    2780  *
    2781  *      EM_LINEFROMCHAR
     2807    return MAKELONG(EDIT_WM_VScroll(hwnd, es, EM_GETTHUMB16, 0),
     2808        EDIT_WM_HScroll(hwnd, es, EM_GETTHUMB16, 0));
     2809}
     2810
     2811
     2812/*********************************************************************
     2813 *
     2814 *  EM_LINEFROMCHAR
    27822815 *
    27832816 */
    27842817static INT EDIT_EM_LineFromChar(EDITSTATE *es, INT index)
    27852818{
    2786         INT line;
    2787         LINEDEF *line_def;
    2788 
    2789         if (!(es->style & ES_MULTILINE))
    2790                 return 0;
    2791         if (index > (INT)strlenW(es->text))
    2792                 return es->line_count - 1;
    2793         if (index == -1)
    2794                 index = min(es->selection_start, es->selection_end);
    2795 
    2796         line = 0;
    2797         line_def = es->first_line_def;
    2798         index -= line_def->length;
    2799         while ((index >= 0) && line_def->next) {
    2800                 line++;
    2801                 line_def = line_def->next;
    2802                 index -= line_def->length;
    2803         }
    2804         return line;
    2805 }
    2806 
    2807 
    2808 /*********************************************************************
    2809  *
    2810  *      EM_LINEINDEX
     2819    INT line;
     2820    LINEDEF *line_def;
     2821
     2822    if (!(es->style & ES_MULTILINE))
     2823        return 0;
     2824    if (index > (INT)strlenW(es->text))
     2825        return es->line_count - 1;
     2826    if (index == -1)
     2827        index = min(es->selection_start, es->selection_end);
     2828
     2829    line = 0;
     2830    line_def = es->first_line_def;
     2831    index -= line_def->length;
     2832    while ((index >= 0) && line_def->next) {
     2833        line++;
     2834        line_def = line_def->next;
     2835        index -= line_def->length;
     2836    }
     2837    return line;
     2838}
     2839
     2840
     2841/*********************************************************************
     2842 *
     2843 *  EM_LINEINDEX
    28112844 *
    28122845 */
    28132846static INT EDIT_EM_LineIndex(EDITSTATE *es, INT line)
    28142847{
    2815         INT line_index;
    2816         LINEDEF *line_def;
    2817 
    2818         if (!(es->style & ES_MULTILINE))
    2819                 return 0;
    2820         if (line >= es->line_count)
    2821                 return -1;
    2822 
    2823         line_index = 0;
    2824         line_def = es->first_line_def;
    2825         if (line == -1) {
    2826                 INT index = es->selection_end - line_def->length;
    2827                 while ((index >= 0) && line_def->next) {
    2828                         line_index += line_def->length;
    2829                         line_def = line_def->next;
    2830                         index -= line_def->length;
    2831                 }
    2832         } else {
    2833                 while (line > 0) {
    2834                         line_index += line_def->length;
    2835                         line_def = line_def->next;
    2836                         line--;
    2837                 }
    2838         }
    2839         return line_index;
    2840 }
    2841 
    2842 
    2843 /*********************************************************************
    2844  *
    2845  *      EM_LINELENGTH
     2848    INT line_index;
     2849    LINEDEF *line_def;
     2850
     2851    if (!(es->style & ES_MULTILINE))
     2852        return 0;
     2853    if (line >= es->line_count)
     2854        return -1;
     2855
     2856    line_index = 0;
     2857    line_def = es->first_line_def;
     2858    if (line == -1) {
     2859        INT index = es->selection_end - line_def->length;
     2860        while ((index >= 0) && line_def->next) {
     2861            line_index += line_def->length;
     2862            line_def = line_def->next;
     2863            index -= line_def->length;
     2864        }
     2865    } else {
     2866        while (line > 0) {
     2867            line_index += line_def->length;
     2868            line_def = line_def->next;
     2869            line--;
     2870        }
     2871    }
     2872    return line_index;
     2873}
     2874
     2875
     2876/*********************************************************************
     2877 *
     2878 *  EM_LINELENGTH
    28462879 *
    28472880 */
    28482881static INT EDIT_EM_LineLength(EDITSTATE *es, INT index)
    28492882{
    2850         LINEDEF *line_def;
    2851 
    2852         if (!(es->style & ES_MULTILINE))
    2853                 return strlenW(es->text);
    2854 
    2855         if (index == -1) {
    2856                 /* get the number of remaining non-selected chars of selected lines */
    2857                 INT32 l; /* line number */
    2858                 INT32 li; /* index of first char in line */
    2859                 INT32 count;
    2860                 l = EDIT_EM_LineFromChar(es, es->selection_start);
    2861                 /* # chars before start of selection area */
    2862                 count = es->selection_start - EDIT_EM_LineIndex(es, l);
    2863                 l = EDIT_EM_LineFromChar(es, es->selection_end);
    2864                 /* # chars after end of selection */
    2865                 li = EDIT_EM_LineIndex(es, l);
    2866                 count += li + EDIT_EM_LineLength(es, li) - es->selection_end;
    2867                 return count;
    2868         }
    2869         line_def = es->first_line_def;
    2870         index -= line_def->length;
    2871         while ((index >= 0) && line_def->next) {
    2872                 line_def = line_def->next;
    2873                 index -= line_def->length;
    2874         }
    2875         return line_def->net_length;
    2876 }
    2877 
    2878 
    2879 /*********************************************************************
    2880  *
    2881  *      EM_LINESCROLL
    2882  *
    2883  *      NOTE: dx is in average character widths, dy - in lines;
     2883    LINEDEF *line_def;
     2884
     2885    if (!(es->style & ES_MULTILINE))
     2886        return strlenW(es->text);
     2887
     2888    if (index == -1) {
     2889        /* get the number of remaining non-selected chars of selected lines */
     2890        INT32 l; /* line number */
     2891        INT32 li; /* index of first char in line */
     2892        INT32 count;
     2893        l = EDIT_EM_LineFromChar(es, es->selection_start);
     2894        /* # chars before start of selection area */
     2895        count = es->selection_start - EDIT_EM_LineIndex(es, l);
     2896        l = EDIT_EM_LineFromChar(es, es->selection_end);
     2897        /* # chars after end of selection */
     2898        li = EDIT_EM_LineIndex(es, l);
     2899        count += li + EDIT_EM_LineLength(es, li) - es->selection_end;
     2900        return count;
     2901    }
     2902    line_def = es->first_line_def;
     2903    index -= line_def->length;
     2904    while ((index >= 0) && line_def->next) {
     2905        line_def = line_def->next;
     2906        index -= line_def->length;
     2907    }
     2908    return line_def->net_length;
     2909}
     2910
     2911
     2912/*********************************************************************
     2913 *
     2914 *  EM_LINESCROLL
     2915 *
     2916 *  NOTE: dx is in average character widths, dy - in lines;
    28842917 *
    28852918 */
    28862919static BOOL EDIT_EM_LineScroll(HWND hwnd, EDITSTATE *es, INT dx, INT dy)
    28872920{
    2888         if (!(es->style & ES_MULTILINE))
    2889                 return FALSE;
    2890 
    2891         dx *= es->char_width;
    2892         return EDIT_EM_LineScroll_internal(hwnd, es, dx, dy);
    2893 }
    2894 
    2895 /*********************************************************************
    2896  *
    2897  *      EDIT_EM_LineScroll_internal
    2898  *
    2899  *      Version of EDIT_EM_LineScroll for internal use.
    2900  *      It doesn't refuse if ES_MULTILINE is set and assumes that
    2901  *      dx is in pixels, dy - in lines.
     2921    if (!(es->style & ES_MULTILINE))
     2922        return FALSE;
     2923
     2924    dx *= es->char_width;
     2925    return EDIT_EM_LineScroll_internal(hwnd, es, dx, dy);
     2926}
     2927
     2928/*********************************************************************
     2929 *
     2930 *  EDIT_EM_LineScroll_internal
     2931 *
     2932 *  Version of EDIT_EM_LineScroll for internal use.
     2933 *  It doesn't refuse if ES_MULTILINE is set and assumes that
     2934 *  dx is in pixels, dy - in lines.
    29022935 *
    29032936 */
    29042937static BOOL EDIT_EM_LineScroll_internal(HWND hwnd, EDITSTATE *es, INT dx, INT dy)
    29052938{
    2906         INT nyoff;
    2907         INT x_offset_in_pixels;
    2908 
    2909         if (es->style & ES_MULTILINE)
    2910         {
    2911             x_offset_in_pixels = es->x_offset;
    2912         }
    2913         else
    2914         {
    2915             dy = 0;
    2916             x_offset_in_pixels = SLOWORD(EDIT_EM_PosFromChar(hwnd, es, es->x_offset, FALSE));
    2917         }
    2918 
    2919         if (-dx > x_offset_in_pixels)
    2920                 dx = -x_offset_in_pixels;
    2921         if (dx > es->text_width - x_offset_in_pixels)
    2922                 dx = es->text_width - x_offset_in_pixels;
    2923         nyoff = max(0, es->y_offset + dy);
    2924         if (nyoff >= es->line_count)
    2925                 nyoff = es->line_count - 1;
    2926         dy = (es->y_offset - nyoff) * es->line_height;
    2927         if (dx || dy) {
    2928                 RECT rc1;
    2929                 RECT rc;
    2930 
    2931                 es->y_offset = nyoff;
    2932                 if(es->style & ES_MULTILINE)
    2933                     es->x_offset += dx;
    2934                 else
    2935                     es->x_offset += dx / es->char_width;
    2936 
    2937                 GetClientRect(hwnd, &rc1);
    2938                 IntersectRect(&rc, &rc1, &es->format_rect);
    2939                 ScrollWindowEx(hwnd, -dx, dy,
    2940                                 NULL, &rc, (HRGN)NULL, NULL, SW_INVALIDATE);
    2941                 /* force scroll info update */
    2942                 EDIT_UpdateScrollInfo(hwnd, es);
    2943         }
    2944         if (dx && !(es->flags & EF_HSCROLL_TRACK))
    2945                 EDIT_NOTIFY_PARENT(hwnd, es, EN_HSCROLL, "EN_HSCROLL");
    2946         if (dy && !(es->flags & EF_VSCROLL_TRACK))
    2947                 EDIT_NOTIFY_PARENT(hwnd, es, EN_VSCROLL, "EN_VSCROLL");
    2948         return TRUE;
    2949 }
    2950 
    2951 
    2952 /*********************************************************************
    2953  *
    2954  *      EM_POSFROMCHAR
     2939    INT nyoff;
     2940    INT x_offset_in_pixels;
     2941
     2942    if (es->style & ES_MULTILINE)
     2943    {
     2944        x_offset_in_pixels = es->x_offset;
     2945    }
     2946    else
     2947    {
     2948        dy = 0;
     2949        x_offset_in_pixels = SLOWORD(EDIT_EM_PosFromChar(hwnd, es, es->x_offset, FALSE));
     2950    }
     2951
     2952    if (-dx > x_offset_in_pixels)
     2953        dx = -x_offset_in_pixels;
     2954    if (dx > es->text_width - x_offset_in_pixels)
     2955        dx = es->text_width - x_offset_in_pixels;
     2956    nyoff = max(0, es->y_offset + dy);
     2957    if (nyoff >= es->line_count)
     2958        nyoff = es->line_count - 1;
     2959    dy = (es->y_offset - nyoff) * es->line_height;
     2960    if (dx || dy) {
     2961        RECT rc1;
     2962        RECT rc;
     2963
     2964        es->y_offset = nyoff;
     2965        if(es->style & ES_MULTILINE)
     2966            es->x_offset += dx;
     2967        else
     2968            es->x_offset += dx / es->char_width;
     2969
     2970        GetClientRect(hwnd, &rc1);
     2971        IntersectRect(&rc, &rc1, &es->format_rect);
     2972        ScrollWindowEx(hwnd, -dx, dy,
     2973                NULL, &rc, (HRGN)NULL, NULL, SW_INVALIDATE);
     2974        /* force scroll info update */
     2975        EDIT_UpdateScrollInfo(hwnd, es);
     2976    }
     2977    if (dx && !(es->flags & EF_HSCROLL_TRACK))
     2978        EDIT_NOTIFY_PARENT(hwnd, es, EN_HSCROLL, "EN_HSCROLL");
     2979    if (dy && !(es->flags & EF_VSCROLL_TRACK))
     2980        EDIT_NOTIFY_PARENT(hwnd, es, EN_VSCROLL, "EN_VSCROLL");
     2981    return TRUE;
     2982}
     2983
     2984
     2985/*********************************************************************
     2986 *
     2987 *  EM_POSFROMCHAR
    29552988 *
    29562989 */
    29572990static LRESULT EDIT_EM_PosFromChar(HWND hwnd, EDITSTATE *es, INT index, BOOL after_wrap)
    29582991{
    2959         INT len = strlenW(es->text);
    2960         INT l;
    2961         INT li;
    2962         INT x;
    2963         INT y = 0;
    2964         HDC dc;
    2965         HFONT old_font = 0;
    2966         SIZE size;
    2967 
    2968         index = min(index, len);
    2969         dc = GetDC(hwnd);
    2970         if (es->font)
    2971                 old_font = SelectObject(dc, es->font);
    2972         if (es->style & ES_MULTILINE) {
    2973                 l = EDIT_EM_LineFromChar(es, index);
    2974                 y = (l - es->y_offset) * es->line_height;
    2975                 li = EDIT_EM_LineIndex(es, l);
    2976                 if (after_wrap && (li == index) && l) {
    2977                         INT l2 = l - 1;
    2978                         LINEDEF *line_def = es->first_line_def;
    2979                         while (l2) {
    2980                                 line_def = line_def->next;
    2981                                 l2--;
    2982                         }
    2983                         if (line_def->ending == END_WRAP) {
    2984                                 l--;
    2985                                 y -= es->line_height;
    2986                                 li = EDIT_EM_LineIndex(es, l);
    2987                         }
    2988                 }
    2989                 x = LOWORD(GetTabbedTextExtentW(dc, es->text + li, index - li,
    2990                                 es->tabs_count, es->tabs)) - es->x_offset;
    2991         } else {
    2992                 LPWSTR text = EDIT_GetPasswordPointer_SL(es);
    2993                 if (index < es->x_offset) {
    2994                         GetTextExtentPoint32W(dc, text + index,
    2995                                         es->x_offset - index, &size);
    2996                         x = -size.cx;
    2997                 } else {
    2998                         GetTextExtentPoint32W(dc, text + es->x_offset,
    2999                                         index - es->x_offset, &size);
    3000                         x = size.cx;
    3001                 }
    3002                 y = 0;
    3003                 if (es->style & ES_PASSWORD)
    3004                         HeapFree(GetProcessHeap(), 0, text);
    3005         }
    3006         x += es->format_rect.left;
    3007         y += es->format_rect.top;
    3008         if (es->font)
    3009                 SelectObject(dc, old_font);
    3010         ReleaseDC(hwnd, dc);
    3011         return MAKELONG((INT16)x, (INT16)y);
    3012 }
    3013 
    3014 
    3015 /*********************************************************************
    3016  *
    3017  *      EM_REPLACESEL
    3018  *
    3019  *      FIXME: handle ES_NUMBER and ES_OEMCONVERT here
     2992    INT len = strlenW(es->text);
     2993    INT l;
     2994    INT li;
     2995    INT x;
     2996    INT y = 0;
     2997    HDC dc;
     2998    HFONT old_font = 0;
     2999    SIZE size;
     3000
     3001    index = min(index, len);
     3002    dc = GetDC(hwnd);
     3003    if (es->font)
     3004        old_font = SelectObject(dc, es->font);
     3005    if (es->style & ES_MULTILINE) {
     3006        l = EDIT_EM_LineFromChar(es, index);
     3007        y = (l - es->y_offset) * es->line_height;
     3008        li = EDIT_EM_LineIndex(es, l);
     3009        if (after_wrap && (li == index) && l) {
     3010            INT l2 = l - 1;
     3011            LINEDEF *line_def = es->first_line_def;
     3012            while (l2) {
     3013                line_def = line_def->next;
     3014                l2--;
     3015            }
     3016            if (line_def->ending == END_WRAP) {
     3017                l--;
     3018                y -= es->line_height;
     3019                li = EDIT_EM_LineIndex(es, l);
     3020            }
     3021        }
     3022        x = LOWORD(GetTabbedTextExtentW(dc, es->text + li, index - li,
     3023                es->tabs_count, es->tabs)) - es->x_offset;
     3024    } else {
     3025        LPWSTR text = EDIT_GetPasswordPointer_SL(es);
     3026        if (index < es->x_offset) {
     3027            GetTextExtentPoint32W(dc, text + index,
     3028                    es->x_offset - index, &size);
     3029            x = -size.cx;
     3030        } else {
     3031            GetTextExtentPoint32W(dc, text + es->x_offset,
     3032                    index - es->x_offset, &size);
     3033            x = size.cx;
     3034        }
     3035        y = 0;
     3036        if (es->style & ES_PASSWORD)
     3037            HeapFree(GetProcessHeap(), 0, text);
     3038    }
     3039    x += es->format_rect.left;
     3040    y += es->format_rect.top;
     3041    if (es->font)
     3042        SelectObject(dc, old_font);
     3043    ReleaseDC(hwnd, dc);
     3044    return MAKELONG((INT16)x, (INT16)y);
     3045}
     3046
     3047
     3048/*********************************************************************
     3049 *
     3050 *  EM_REPLACESEL
     3051 *
     3052 *  FIXME: handle ES_NUMBER and ES_OEMCONVERT here
    30203053 *
    30213054 */
    30223055static void EDIT_EM_ReplaceSel(HWND hwnd, EDITSTATE *es, BOOL can_undo, LPCWSTR lpsz_replace, BOOL send_update)
    30233056{
    3024         UINT strl = strlenW(lpsz_replace);
    3025         UINT tl = strlenW(es->text);
    3026         UINT utl;
    3027         UINT s;
    3028         UINT e;
    3029         UINT i;
    3030         LPWSTR p;
    3031         HRGN hrgn = 0;
    3032 
    3033         TRACE("%s, can_undo %d, send_update %d\n",
    3034             debugstr_w(lpsz_replace), can_undo, send_update);
    3035 
    3036         s = es->selection_start;
    3037         e = es->selection_end;
    3038 
    3039         if ((s == e) && !strl)
    3040                 return;
    3041 
    3042         ORDER_UINT(s, e);
    3043 
    3044         if (!EDIT_MakeFit(hwnd, es, tl - (e - s) + strl))
    3045                 return;
    3046 
    3047         if (e != s) {
    3048                 /* there is something to be deleted */
    3049                 TRACE("deleting stuff.\n");
    3050                 if (can_undo) {
    3051                         utl = strlenW(es->undo_text);
    3052                         if (!es->undo_insert_count && (*es->undo_text && (s == es->undo_position))) {
    3053                                 /* undo-buffer is extended to the right */
    3054                                 EDIT_MakeUndoFit(es, utl + e - s);
    3055                                 strncpyW(es->undo_text + utl, es->text + s, e - s + 1);
    3056                                 (es->undo_text + utl)[e - s] = 0; /* ensure 0 termination */
    3057                         } else if (!es->undo_insert_count && (*es->undo_text && (e == es->undo_position))) {
    3058                                 /* undo-buffer is extended to the left */
    3059                                 EDIT_MakeUndoFit(es, utl + e - s);
    3060                                 for (p = es->undo_text + utl ; p >= es->undo_text ; p--)
    3061                                         p[e - s] = p[0];
    3062                                 for (i = 0 , p = es->undo_text ; i < e - s ; i++)
    3063                                         p[i] = (es->text + s)[i];
    3064                                 es->undo_position = s;
    3065                         } else {
    3066                                 /* new undo-buffer */
    3067                                 EDIT_MakeUndoFit(es, e - s);
    3068                                 strncpyW(es->undo_text, es->text + s, e - s + 1);
    3069                                 es->undo_text[e - s] = 0; /* ensure 0 termination */
    3070                                 es->undo_position = s;
    3071                         }
    3072                         /* any deletion makes the old insertion-undo invalid */
    3073                         es->undo_insert_count = 0;
    3074                 } else
    3075                         EDIT_EM_EmptyUndoBuffer(es);
    3076 
    3077                 /* now delete */
    3078                 strcpyW(es->text + s, es->text + e);
    3079         }
    3080         if (strl) {
    3081                 /* there is an insertion */
    3082                 if (can_undo) {
    3083                         if ((s == es->undo_position) ||
    3084                                         ((es->undo_insert_count) &&
    3085                                         (s == es->undo_position + es->undo_insert_count)))
    3086                                 /*
    3087                                 * insertion is new and at delete position or
    3088                                 * an extension to either left or right
    3089                                 */
    3090                                 es->undo_insert_count += strl;
    3091                         else {
    3092                                 /* new insertion undo */
    3093                                 es->undo_position = s;
    3094                                 es->undo_insert_count = strl;
    3095                                 /* new insertion makes old delete-buffer invalid */
    3096                                 *es->undo_text = '\0';
    3097                         }
    3098                 } else
    3099                         EDIT_EM_EmptyUndoBuffer(es);
    3100 
    3101                 /* now insert */
    3102                 tl = strlenW(es->text);
    3103                 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));
    3104                 for (p = es->text + tl ; p >= es->text + s ; p--)
    3105                         p[strl] = p[0];
    3106                 for (i = 0 , p = es->text + s ; i < strl ; i++)
    3107                         p[i] = lpsz_replace[i];
    3108                 if(es->style & ES_UPPERCASE)
    3109                         CharUpperBuffW(p, strl);
    3110                 else if(es->style & ES_LOWERCASE)
    3111                         CharLowerBuffW(p, strl);
    3112                 s += strl;
    3113         }
    3114         if (es->style & ES_MULTILINE)
    3115         {
    3116                 INT s = min(es->selection_start, es->selection_end);
    3117 
    3118                 hrgn = CreateRectRgn(0, 0, 0, 0);
    3119                 EDIT_BuildLineDefs_ML(hwnd, es, s, s + strl,
    3120                                 strl - abs(es->selection_end - es->selection_start), hrgn);
    3121         }
    3122         else
    3123             EDIT_CalcLineWidth_SL(hwnd, es);
    3124 
    3125         EDIT_EM_SetSel(hwnd, es, s, s, FALSE);
    3126         es->flags |= EF_MODIFIED;
    3127         if (send_update) es->flags |= EF_UPDATE;
    3128         EDIT_EM_ScrollCaret(hwnd, es);
    3129 
    3130         /* force scroll info update */
    3131         EDIT_UpdateScrollInfo(hwnd, es);
    3132 
    3133         if (hrgn)
    3134         {
    3135                 EDIT_UpdateTextRegion(hwnd, es, hrgn, TRUE);
    3136                 DeleteObject(hrgn);
    3137         }
    3138         else
    3139         EDIT_UpdateText(hwnd, es, NULL, TRUE);
    3140 
    3141         if(es->flags & EF_UPDATE)
    3142         {
    3143             es->flags &= ~EF_UPDATE;
    3144             EDIT_NOTIFY_PARENT(hwnd, es, EN_CHANGE, "EN_CHANGE");
    3145         }
    3146 }
    3147 
    3148 
    3149 /*********************************************************************
    3150  *
    3151  *      EM_SCROLL
     3057    UINT strl = strlenW(lpsz_replace);
     3058    UINT tl = strlenW(es->text);
     3059    UINT utl;
     3060    UINT s;
     3061    UINT e;
     3062    UINT i;
     3063    LPWSTR p;
     3064    HRGN hrgn = 0;
     3065
     3066    TRACE("%s, can_undo %d, send_update %d\n",
     3067        debugstr_w(lpsz_replace), can_undo, send_update);
     3068
     3069    s = es->selection_start;
     3070    e = es->selection_end;
     3071
     3072    if ((s == e) && !strl)
     3073        return;
     3074
     3075    ORDER_UINT(s, e);
     3076
     3077    if (!EDIT_MakeFit(hwnd, es, tl - (e - s) + strl))
     3078        return;
     3079
     3080    if (e != s) {
     3081        /* there is something to be deleted */
     3082        TRACE("deleting stuff.\n");
     3083        if (can_undo) {
     3084            utl = strlenW(es->undo_text);
     3085            if (!es->undo_insert_count && (*es->undo_text && (s == es->undo_position))) {
     3086                /* undo-buffer is extended to the right */
     3087                EDIT_MakeUndoFit(es, utl + e - s);
     3088                strncpyW(es->undo_text + utl, es->text + s, e - s + 1);
     3089                (es->undo_text + utl)[e - s] = 0; /* ensure 0 termination */
     3090            } else if (!es->undo_insert_count && (*es->undo_text && (e == es->undo_position))) {
     3091                /* undo-buffer is extended to the left */
     3092                EDIT_MakeUndoFit(es, utl + e - s);
     3093                for (p = es->undo_text + utl ; p >= es->undo_text ; p--)
     3094                    p[e - s] = p[0];
     3095                for (i = 0 , p = es->undo_text ; i < e - s ; i++)
     3096                    p[i] = (es->text + s)[i];
     3097                es->undo_position = s;
     3098            } else {
     3099                /* new undo-buffer */
     3100                EDIT_MakeUndoFit(es, e - s);
     3101                strncpyW(es->undo_text, es->text + s, e - s + 1);
     3102                es->undo_text[e - s] = 0; /* ensure 0 termination */
     3103                es->undo_position = s;
     3104            }
     3105            /* any deletion makes the old insertion-undo invalid */
     3106            es->undo_insert_count = 0;
     3107        } else
     3108            EDIT_EM_EmptyUndoBuffer(es);
     3109
     3110        /* now delete */
     3111        strcpyW(es->text + s, es->text + e);
     3112    }
     3113    if (strl) {
     3114        /* there is an insertion */
     3115        if (can_undo) {
     3116            if ((s == es->undo_position) ||
     3117                    ((es->undo_insert_count) &&
     3118                    (s == es->undo_position + es->undo_insert_count)))
     3119                /*
     3120                * insertion is new and at delete position or
     3121                * an extension to either left or right
     3122                */
     3123                es->undo_insert_count += strl;
     3124            else {
     3125                /* new insertion undo */
     3126                es->undo_position = s;
     3127                es->undo_insert_count = strl;
     3128                /* new insertion makes old delete-buffer invalid */
     3129                *es->undo_text = '\0';
     3130            }
     3131        } else
     3132            EDIT_EM_EmptyUndoBuffer(es);
     3133
     3134        /* now insert */
     3135        tl = strlenW(es->text);
     3136        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));
     3137        for (p = es->text + tl ; p >= es->text + s ; p--)
     3138            p[strl] = p[0];
     3139        for (i = 0 , p = es->text + s ; i < strl ; i++)
     3140            p[i] = lpsz_replace[i];
     3141        if(es->style & ES_UPPERCASE)
     3142            CharUpperBuffW(p, strl);
     3143        else if(es->style & ES_LOWERCASE)
     3144            CharLowerBuffW(p, strl);
     3145        s += strl;
     3146    }
     3147    if (es->style & ES_MULTILINE)
     3148    {
     3149        INT s = min(es->selection_start, es->selection_end);
     3150
     3151        hrgn = CreateRectRgn(0, 0, 0, 0);
     3152        EDIT_BuildLineDefs_ML(hwnd, es, s, s + strl,
     3153                strl - abs(es->selection_end - es->selection_start), hrgn);
     3154    }
     3155    else
     3156        EDIT_CalcLineWidth_SL(hwnd, es);
     3157
     3158    EDIT_EM_SetSel(hwnd, es, s, s, FALSE);
     3159    es->flags |= EF_MODIFIED;
     3160    if (send_update) es->flags |= EF_UPDATE;
     3161    EDIT_EM_ScrollCaret(hwnd, es);
     3162
     3163    /* force scroll info update */
     3164    EDIT_UpdateScrollInfo(hwnd, es);
     3165
     3166    if (hrgn)
     3167    {
     3168        EDIT_UpdateTextRegion(hwnd, es, hrgn, TRUE);
     3169        DeleteObject(hrgn);
     3170    }
     3171    else
     3172    EDIT_UpdateText(hwnd, es, NULL, TRUE);
     3173
     3174    if(es->flags & EF_UPDATE)
     3175    {
     3176        es->flags &= ~EF_UPDATE;
     3177        EDIT_NOTIFY_PARENT(hwnd, es, EN_CHANGE, "EN_CHANGE");
     3178    }
     3179}
     3180
     3181
     3182/*********************************************************************
     3183 *
     3184 *  EM_SCROLL
    31523185 *
    31533186 */
    31543187static LRESULT EDIT_EM_Scroll(HWND hwnd, EDITSTATE *es, INT action)
    31553188{
    3156         INT dy;
    3157 
    3158         if (!(es->style & ES_MULTILINE))
    3159                 return (LRESULT)FALSE;
    3160 
    3161         dy = 0;
    3162 
    3163         switch (action) {
    3164         case SB_LINEUP:
    3165                 if (es->y_offset)
    3166                         dy = -1;
    3167                 break;
    3168         case SB_LINEDOWN:
    3169                 if (es->y_offset < es->line_count - 1)
    3170                         dy = 1;
    3171                 break;
    3172         case SB_PAGEUP:
    3173                 if (es->y_offset)
    3174                         dy = -(es->format_rect.bottom - es->format_rect.top) / es->line_height;
    3175                 break;
    3176         case SB_PAGEDOWN:
    3177                 if (es->y_offset < es->line_count - 1)
    3178                         dy = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
    3179                 break;
    3180         default:
    3181                 return (LRESULT)FALSE;
    3182         }
    3183         if (dy) {
    3184             INT vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
    3185             /* check if we are going to move too far */
    3186             if(es->y_offset + dy > es->line_count - vlc)
    3187                 dy = es->line_count - vlc - es->y_offset;
    3188 
    3189             /* Notification is done in EDIT_EM_LineScroll */
    3190             if(dy)
    3191                 EDIT_EM_LineScroll(hwnd, es, 0, dy);
    3192         }
    3193         return MAKELONG((INT16)dy, (BOOL16)TRUE);
    3194 }
    3195 
    3196 
    3197 /*********************************************************************
    3198  *
    3199  *      EM_SCROLLCARET
     3189    INT dy;
     3190
     3191    if (!(es->style & ES_MULTILINE))
     3192        return (LRESULT)FALSE;
     3193
     3194    dy = 0;
     3195
     3196    switch (action) {
     3197    case SB_LINEUP:
     3198        if (es->y_offset)
     3199            dy = -1;
     3200        break;
     3201    case SB_LINEDOWN:
     3202        if (es->y_offset < es->line_count - 1)
     3203            dy = 1;
     3204        break;
     3205    case SB_PAGEUP:
     3206        if (es->y_offset)
     3207            dy = -(es->format_rect.bottom - es->format_rect.top) / es->line_height;
     3208        break;
     3209    case SB_PAGEDOWN:
     3210        if (es->y_offset < es->line_count - 1)
     3211            dy = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
     3212        break;
     3213    default:
     3214        return (LRESULT)FALSE;
     3215    }
     3216    if (dy) {
     3217        INT vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
     3218        /* check if we are going to move too far */
     3219        if(es->y_offset + dy > es->line_count - vlc)
     3220        dy = es->line_count - vlc - es->y_offset;
     3221
     3222        /* Notification is done in EDIT_EM_LineScroll */
     3223        if(dy)
     3224        EDIT_EM_LineScroll(hwnd, es, 0, dy);
     3225    }
     3226    return MAKELONG((INT16)dy, (BOOL16)TRUE);
     3227}
     3228
     3229
     3230/*********************************************************************
     3231 *
     3232 *  EM_SCROLLCARET
    32003233 *
    32013234 */
    32023235static void EDIT_EM_ScrollCaret(HWND hwnd, EDITSTATE *es)
    32033236{
    3204         if (es->style & ES_MULTILINE) {
    3205                 INT l;
    3206                 INT li;
    3207                 INT vlc;
    3208                 INT ww;
    3209                 INT cw = es->char_width;
    3210                 INT x;
    3211                 INT dy = 0;
    3212                 INT dx = 0;
    3213 
    3214                 l = EDIT_EM_LineFromChar(es, es->selection_end);
    3215                 li = EDIT_EM_LineIndex(es, l);
    3216                 x = SLOWORD(EDIT_EM_PosFromChar(hwnd, es, es->selection_end, es->flags & EF_AFTER_WRAP));
    3217                 vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
    3218                 if (l >= es->y_offset + vlc)
    3219                         dy = l - vlc + 1 - es->y_offset;
    3220                 if (l < es->y_offset)
    3221                         dy = l - es->y_offset;
    3222                 ww = es->format_rect.right - es->format_rect.left;
    3223                 if (x < es->format_rect.left)
    3224                         dx = x - es->format_rect.left - ww / HSCROLL_FRACTION / cw * cw;
    3225                 if (x > es->format_rect.right)
    3226                         dx = x - es->format_rect.left - (HSCROLL_FRACTION - 1) * ww / HSCROLL_FRACTION / cw * cw;
    3227                 if (dy || dx)
    3228                 {
    3229                     /* check if we are going to move too far */
    3230                     if(es->x_offset + dx + ww > es->text_width)
    3231                         dx = es->text_width - ww - es->x_offset;
    3232                     if(dx || dy)
    3233                         EDIT_EM_LineScroll_internal(hwnd, es, dx, dy);
    3234                 }
    3235         } else {
    3236                 INT x;
    3237                 INT goal;
    3238                 INT format_width;
    3239 
    3240                 if (!(es->style & ES_AUTOHSCROLL))
    3241                         return;
    3242 
    3243                 x = SLOWORD(EDIT_EM_PosFromChar(hwnd, es, es->selection_end, FALSE));
    3244                 format_width = es->format_rect.right - es->format_rect.left;
    3245                 if (x < es->format_rect.left) {
    3246                         goal = es->format_rect.left + format_width / HSCROLL_FRACTION;
    3247                         do {
    3248                                 es->x_offset--;
    3249                                 x = SLOWORD(EDIT_EM_PosFromChar(hwnd, es, es->selection_end, FALSE));
    3250                         } while ((x < goal) && es->x_offset);
    3251                         /* FIXME: use ScrollWindow() somehow to improve performance */
    3252                         EDIT_UpdateText(hwnd, es, NULL, TRUE);
    3253                 } else if (x > es->format_rect.right) {
    3254                         INT x_last;
    3255                         INT len = strlenW(es->text);
    3256                         goal = es->format_rect.right - format_width / HSCROLL_FRACTION;
    3257                         do {
    3258                                 es->x_offset++;
    3259                                 x = SLOWORD(EDIT_EM_PosFromChar(hwnd, es, es->selection_end, FALSE));
    3260                                 x_last = SLOWORD(EDIT_EM_PosFromChar(hwnd, es, len, FALSE));
    3261                         } while ((x > goal) && (x_last > es->format_rect.right));
    3262                         /* FIXME: use ScrollWindow() somehow to improve performance */
    3263                         EDIT_UpdateText(hwnd, es, NULL, TRUE);
    3264                 }
    3265         }
     3237    if (es->style & ES_MULTILINE) {
     3238        INT l;
     3239        INT li;
     3240        INT vlc;
     3241        INT ww;
     3242        INT cw = es->char_width;
     3243        INT x;
     3244        INT dy = 0;
     3245        INT dx = 0;
     3246
     3247        l = EDIT_EM_LineFromChar(es, es->selection_end);
     3248        li = EDIT_EM_LineIndex(es, l);
     3249        x = SLOWORD(EDIT_EM_PosFromChar(hwnd, es, es->selection_end, es->flags & EF_AFTER_WRAP));
     3250        vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
     3251        if (l >= es->y_offset + vlc)
     3252            dy = l - vlc + 1 - es->y_offset;
     3253        if (l < es->y_offset)
     3254            dy = l - es->y_offset;
     3255        ww = es->format_rect.right - es->format_rect.left;
     3256        if (x < es->format_rect.left)
     3257            dx = x - es->format_rect.left - ww / HSCROLL_FRACTION / cw * cw;
     3258        if (x > es->format_rect.right)
     3259            dx = x - es->format_rect.left - (HSCROLL_FRACTION - 1) * ww / HSCROLL_FRACTION / cw * cw;
     3260        if (dy || dx)
     3261        {
     3262            /* check if we are going to move too far */
     3263            if(es->x_offset + dx + ww > es->text_width)
     3264            dx = es->text_width - ww - es->x_offset;
     3265            if(dx || dy)
     3266            EDIT_EM_LineScroll_internal(hwnd, es, dx, dy);
     3267        }
     3268    } else {
     3269        INT x;
     3270        INT goal;
     3271        INT format_width;
     3272
     3273        if (!(es->style & ES_AUTOHSCROLL))
     3274            return;
     3275
     3276        x = SLOWORD(EDIT_EM_PosFromChar(hwnd, es, es->selection_end, FALSE));
     3277        format_width = es->format_rect.right - es->format_rect.left;
     3278        if (x < es->format_rect.left) {
     3279            goal = es->format_rect.left + format_width / HSCROLL_FRACTION;
     3280            do {
     3281                es->x_offset--;
     3282                x = SLOWORD(EDIT_EM_PosFromChar(hwnd, es, es->selection_end, FALSE));
     3283            } while ((x < goal) && es->x_offset);
     3284            /* FIXME: use ScrollWindow() somehow to improve performance */
     3285            EDIT_UpdateText(hwnd, es, NULL, TRUE);
     3286        } else if (x > es->format_rect.right) {
     3287            INT x_last;
     3288            INT len = strlenW(es->text);
     3289            goal = es->format_rect.right - format_width / HSCROLL_FRACTION;
     3290            do {
     3291                es->x_offset++;
     3292                x = SLOWORD(EDIT_EM_PosFromChar(hwnd, es, es->selection_end, FALSE));
     3293                x_last = SLOWORD(EDIT_EM_PosFromChar(hwnd, es, len, FALSE));
     3294            } while ((x > goal) && (x_last > es->format_rect.right));
     3295            /* FIXME: use ScrollWindow() somehow to improve performance */
     3296            EDIT_UpdateText(hwnd, es, NULL, TRUE);
     3297        }
     3298    }
    32663299
    32673300    if(es->flags & EF_FOCUSED)
    3268         EDIT_SetCaretPos(hwnd, es, es->selection_end, es->flags & EF_AFTER_WRAP);
    3269 }
    3270 
    3271 
    3272 /*********************************************************************
    3273  *
    3274  *      EM_SETHANDLE
    3275  *
    3276  *      FIXME:  ES_LOWERCASE, ES_UPPERCASE, ES_OEMCONVERT, ES_NUMBER ???
     3301    EDIT_SetCaretPos(hwnd, es, es->selection_end, es->flags & EF_AFTER_WRAP);
     3302}
     3303
     3304
     3305/*********************************************************************
     3306 *
     3307 *  EM_SETHANDLE
     3308 *
     3309 *  FIXME:  ES_LOWERCASE, ES_UPPERCASE, ES_OEMCONVERT, ES_NUMBER ???
    32773310 *
    32783311 */
     
    32813314    HINSTANCE hInstance = GetWindowLongA( hwnd, GWL_HINSTANCE );
    32823315
    3283         if (!(es->style & ES_MULTILINE))
    3284                 return;
    3285 
    3286         if (!hloc) {
    3287                 WARN("called with NULL handle\n");
    3288                 return;
    3289         }
    3290 
    3291         EDIT_UnlockBuffer(hwnd, es, TRUE);
     3316    if (!(es->style & ES_MULTILINE))
     3317        return;
     3318
     3319    if (!hloc) {
     3320        WARN("called with NULL handle\n");
     3321        return;
     3322    }
     3323
     3324    EDIT_UnlockBuffer(hwnd, es, TRUE);
    32923325
    32933326#ifndef __WIN32OS2__
    3294         if(es->hloc16)
    3295         {
    3296             LOCAL_Free(hInstance, es->hloc16);
    3297             es->hloc16 = (HLOCAL16)NULL;
    3298         }
     3327    if(es->hloc16)
     3328    {
     3329        LOCAL_Free(hInstance, es->hloc16);
     3330        es->hloc16 = (HLOCAL16)NULL;
     3331    }
    32993332#endif
    3300         if(es->is_unicode)
    3301         {
    3302             if(es->hloc32A)
    3303             {
    3304                 LocalFree(es->hloc32A);
    3305                 es->hloc32A = (HLOCAL)NULL;
    3306             }
    3307             es->hloc32W = hloc;
    3308         }
    3309         else
    3310         {
    3311             INT countW, countA;
    3312             HLOCAL hloc32W_new;
    3313             WCHAR *textW;
    3314             CHAR *textA;
    3315 
    3316             countA = LocalSize(hloc);
    3317             textA = LocalLock(hloc);
    3318             countW = MultiByteToWideChar(CP_ACP, 0, textA, countA, NULL, 0);
    3319             if(!(hloc32W_new = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT, countW * sizeof(WCHAR))))
    3320             {
    3321                 ERR("Could not allocate new unicode buffer\n");
    3322                 return;
    3323             }
    3324             textW = LocalLock(hloc32W_new);
    3325             MultiByteToWideChar(CP_ACP, 0, textA, countA, textW, countW);
    3326             LocalUnlock(hloc32W_new);
    3327             LocalUnlock(hloc);
    3328 
    3329             if(es->hloc32W)
    3330                 LocalFree(es->hloc32W);
    3331 
    3332             es->hloc32W = hloc32W_new;
    3333             es->hloc32A = hloc;
    3334         }
    3335 
    3336         es->buffer_size = LocalSize(es->hloc32W)/sizeof(WCHAR) - 1;
    3337 
    3338         EDIT_LockBuffer(hwnd, es);
    3339 
    3340         es->x_offset = es->y_offset = 0;
    3341         es->selection_start = es->selection_end = 0;
    3342         EDIT_EM_EmptyUndoBuffer(es);
    3343         es->flags &= ~EF_MODIFIED;
    3344         es->flags &= ~EF_UPDATE;
    3345         EDIT_BuildLineDefs_ML(hwnd, es, 0, strlenW(es->text), 0, (HRGN)0);
    3346         EDIT_UpdateText(hwnd, es, NULL, TRUE);
    3347         EDIT_EM_ScrollCaret(hwnd, es);
    3348         /* force scroll info update */
    3349         EDIT_UpdateScrollInfo(hwnd, es);
     3333    if(es->is_unicode)
     3334    {
     3335        if(es->hloc32A)
     3336        {
     3337        LocalFree(es->hloc32A);
     3338        es->hloc32A = (HLOCAL)NULL;
     3339        }
     3340        es->hloc32W = hloc;
     3341    }
     3342    else
     3343    {
     3344        INT countW, countA;
     3345        HLOCAL hloc32W_new;
     3346        WCHAR *textW;
     3347        CHAR *textA;
     3348
     3349        countA = LocalSize(hloc);
     3350        textA = LocalLock(hloc);
     3351        countW = MultiByteToWideChar(CP_ACP, 0, textA, countA, NULL, 0);
     3352        if(!(hloc32W_new = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT, countW * sizeof(WCHAR))))
     3353        {
     3354        ERR("Could not allocate new unicode buffer\n");
     3355        return;
     3356        }
     3357        textW = LocalLock(hloc32W_new);
     3358        MultiByteToWideChar(CP_ACP, 0, textA, countA, textW, countW);
     3359        LocalUnlock(hloc32W_new);
     3360        LocalUnlock(hloc);
     3361
     3362        if(es->hloc32W)
     3363        LocalFree(es->hloc32W);
     3364
     3365        es->hloc32W = hloc32W_new;
     3366        es->hloc32A = hloc;
     3367    }
     3368
     3369    es->buffer_size = LocalSize(es->hloc32W)/sizeof(WCHAR) - 1;
     3370
     3371    EDIT_LockBuffer(hwnd, es);
     3372
     3373    es->x_offset = es->y_offset = 0;
     3374    es->selection_start = es->selection_end = 0;
     3375    EDIT_EM_EmptyUndoBuffer(es);
     3376    es->flags &= ~EF_MODIFIED;
     3377    es->flags &= ~EF_UPDATE;
     3378    EDIT_BuildLineDefs_ML(hwnd, es, 0, strlenW(es->text), 0, (HRGN)0);
     3379    EDIT_UpdateText(hwnd, es, NULL, TRUE);
     3380    EDIT_EM_ScrollCaret(hwnd, es);
     3381    /* force scroll info update */
     3382    EDIT_UpdateScrollInfo(hwnd, es);
    33503383}
    33513384
     
    33543387/*********************************************************************
    33553388 *
    3356  *      EM_SETHANDLE16
    3357  *
    3358  *      FIXME:  ES_LOWERCASE, ES_UPPERCASE, ES_OEMCONVERT, ES_NUMBER ???
     3389 *  EM_SETHANDLE16
     3390 *
     3391 *  FIXME:  ES_LOWERCASE, ES_UPPERCASE, ES_OEMCONVERT, ES_NUMBER ???
    33593392 *
    33603393 */
     
    33623395{
    33633396    HINSTANCE hInstance = GetWindowLongA( hwnd, GWL_HINSTANCE );
    3364         INT countW, countA;
    3365         HLOCAL hloc32W_new;
    3366         WCHAR *textW;
    3367         CHAR *textA;
    3368 
    3369         if (!(es->style & ES_MULTILINE))
    3370                 return;
    3371 
    3372         if (!hloc) {
    3373                 WARN("called with NULL handle\n");
    3374                 return;
    3375         }
    3376 
    3377         EDIT_UnlockBuffer(hwnd, es, TRUE);
    3378 
    3379         if(es->hloc32A)
    3380         {
    3381             LocalFree(es->hloc32A);
    3382             es->hloc32A = (HLOCAL)NULL;
    3383         }
    3384 
    3385         countA = LOCAL_Size(hInstance, hloc);
    3386         textA = LOCAL_Lock(hInstance, hloc);
    3387         countW = MultiByteToWideChar(CP_ACP, 0, textA, countA, NULL, 0);
    3388         if(!(hloc32W_new = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT, countW * sizeof(WCHAR))))
    3389         {
    3390             ERR("Could not allocate new unicode buffer\n");
    3391             return;
    3392         }
    3393         textW = LocalLock(hloc32W_new);
    3394         MultiByteToWideChar(CP_ACP, 0, textA, countA, textW, countW);
    3395         LocalUnlock(hloc32W_new);
    3396         LOCAL_Unlock(hInstance, hloc);
    3397 
    3398         if(es->hloc32W)
    3399             LocalFree(es->hloc32W);
    3400 
    3401         es->hloc32W = hloc32W_new;
    3402         es->hloc16 = hloc;
    3403 
    3404         es->buffer_size = LocalSize(es->hloc32W)/sizeof(WCHAR) - 1;
    3405 
    3406         EDIT_LockBuffer(hwnd, es);
    3407 
    3408         es->x_offset = es->y_offset = 0;
    3409         es->selection_start = es->selection_end = 0;
    3410         EDIT_EM_EmptyUndoBuffer(es);
    3411         es->flags &= ~EF_MODIFIED;
    3412         es->flags &= ~EF_UPDATE;
    3413         EDIT_BuildLineDefs_ML(hwnd, es, 0, strlenW(es->text), 0, (HRGN)0);
    3414         EDIT_UpdateText(hwnd, es, NULL, TRUE);
    3415         EDIT_EM_ScrollCaret(hwnd, es);
    3416         /* force scroll info update */
    3417         EDIT_UpdateScrollInfo(hwnd, es);
     3397    INT countW, countA;
     3398    HLOCAL hloc32W_new;
     3399    WCHAR *textW;
     3400    CHAR *textA;
     3401
     3402    if (!(es->style & ES_MULTILINE))
     3403        return;
     3404
     3405    if (!hloc) {
     3406        WARN("called with NULL handle\n");
     3407        return;
     3408    }
     3409
     3410    EDIT_UnlockBuffer(hwnd, es, TRUE);
     3411
     3412    if(es->hloc32A)
     3413    {
     3414        LocalFree(es->hloc32A);
     3415        es->hloc32A = (HLOCAL)NULL;
     3416    }
     3417
     3418    countA = LOCAL_Size(hInstance, hloc);
     3419    textA = LOCAL_Lock(hInstance, hloc);
     3420    countW = MultiByteToWideChar(CP_ACP, 0, textA, countA, NULL, 0);
     3421    if(!(hloc32W_new = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT, countW * sizeof(WCHAR))))
     3422    {
     3423        ERR("Could not allocate new unicode buffer\n");
     3424        return;
     3425    }
     3426    textW = LocalLock(hloc32W_new);
     3427    MultiByteToWideChar(CP_ACP, 0, textA, countA, textW, countW);
     3428    LocalUnlock(hloc32W_new);
     3429    LOCAL_Unlock(hInstance, hloc);
     3430
     3431    if(es->hloc32W)
     3432        LocalFree(es->hloc32W);
     3433
     3434    es->hloc32W = hloc32W_new;
     3435    es->hloc16 = hloc;
     3436
     3437    es->buffer_size = LocalSize(es->hloc32W)/sizeof(WCHAR) - 1;
     3438
     3439    EDIT_LockBuffer(hwnd, es);
     3440
     3441    es->x_offset = es->y_offset = 0;
     3442    es->selection_start = es->selection_end = 0;
     3443    EDIT_EM_EmptyUndoBuffer(es);
     3444    es->flags &= ~EF_MODIFIED;
     3445    es->flags &= ~EF_UPDATE;
     3446    EDIT_BuildLineDefs_ML(hwnd, es, 0, strlenW(es->text), 0, (HRGN)0);
     3447    EDIT_UpdateText(hwnd, es, NULL, TRUE);
     3448    EDIT_EM_ScrollCaret(hwnd, es);
     3449    /* force scroll info update */
     3450    EDIT_UpdateScrollInfo(hwnd, es);
    34183451}
    34193452#endif
     
    34213454/*********************************************************************
    34223455 *
    3423  *      EM_SETLIMITTEXT
    3424  *
    3425  *      FIXME: in WinNT maxsize is 0x7FFFFFFF / 0xFFFFFFFF
    3426  *      However, the windows version is not complied to yet in all of edit.c
     3456 *  EM_SETLIMITTEXT
     3457 *
     3458 *  FIXME: in WinNT maxsize is 0x7FFFFFFF / 0xFFFFFFFF
     3459 *  However, the windows version is not complied to yet in all of edit.c
    34273460 *
    34283461 */
    34293462static void EDIT_EM_SetLimitText(EDITSTATE *es, INT limit)
    34303463{
    3431         if (es->style & ES_MULTILINE) {
    3432                 if (limit)
    3433                         es->buffer_limit = min(limit, BUFLIMIT_MULTI);
    3434                 else
    3435                         es->buffer_limit = BUFLIMIT_MULTI;
    3436         } else {
    3437                 if (limit)
    3438                         es->buffer_limit = min(limit, BUFLIMIT_SINGLE);
    3439                 else
    3440                         es->buffer_limit = BUFLIMIT_SINGLE;
    3441         }
    3442 }
    3443 
    3444 
    3445 /*********************************************************************
    3446  *
    3447  *      EM_SETMARGINS
     3464    if (es->style & ES_MULTILINE) {
     3465        if (limit)
     3466            es->buffer_limit = min(limit, BUFLIMIT_MULTI);
     3467        else
     3468            es->buffer_limit = BUFLIMIT_MULTI;
     3469    } else {
     3470        if (limit)
     3471            es->buffer_limit = min(limit, BUFLIMIT_SINGLE);
     3472        else
     3473            es->buffer_limit = BUFLIMIT_SINGLE;
     3474    }
     3475}
     3476
     3477
     3478/*********************************************************************
     3479 *
     3480 *  EM_SETMARGINS
    34483481 *
    34493482 * EC_USEFONTINFO is used as a left or right value i.e. lParam and not as an
     
    34533486 */
    34543487static void EDIT_EM_SetMargins(EDITSTATE *es, INT action,
    3455                                INT left, INT right)
    3456 {
    3457         if (action & EC_LEFTMARGIN) {
    3458                 if (left != EC_USEFONTINFO)
    3459                         es->left_margin = left;
    3460                 else
    3461                         es->left_margin = es->char_width / 3;
    3462         }
    3463 
    3464         if (action & EC_RIGHTMARGIN) {
    3465                 if (right != EC_USEFONTINFO)
    3466                         es->right_margin = right;
    3467                 else
    3468                         es->right_margin = es->char_width / 3;
    3469         }
    3470         TRACE("left=%d, right=%d\n", es->left_margin, es->right_margin);
    3471 }
    3472 
    3473 
    3474 /*********************************************************************
    3475  *
    3476  *      EM_SETPASSWORDCHAR
     3488                   INT left, INT right)
     3489{
     3490    if (action & EC_LEFTMARGIN) {
     3491        if (left != EC_USEFONTINFO)
     3492            es->left_margin = left;
     3493        else
     3494            es->left_margin = es->char_width / 3;
     3495    }
     3496
     3497    if (action & EC_RIGHTMARGIN) {
     3498        if (right != EC_USEFONTINFO)
     3499            es->right_margin = right;
     3500        else
     3501            es->right_margin = es->char_width / 3;
     3502    }
     3503    TRACE("left=%d, right=%d\n", es->left_margin, es->right_margin);
     3504}
     3505
     3506
     3507/*********************************************************************
     3508 *
     3509 *  EM_SETPASSWORDCHAR
    34773510 *
    34783511 */
     
    34813514    LONG style;
    34823515
    3483         if (es->style & ES_MULTILINE)
    3484                 return;
    3485 
    3486         if (es->password_char == c)
    3487                 return;
     3516    if (es->style & ES_MULTILINE)
     3517        return;
     3518
     3519    if (es->password_char == c)
     3520        return;
    34883521
    34893522        style = GetWindowLongA( hwnd, GWL_STYLE );
    3490         es->password_char = c;
    3491         if (c) {
     3523    es->password_char = c;
     3524    if (c) {
    34923525            SetWindowLongA( hwnd, GWL_STYLE, style | ES_PASSWORD );
    34933526            es->style |= ES_PASSWORD;
    3494         } else {
     3527    } else {
    34953528            SetWindowLongA( hwnd, GWL_STYLE, style & ~ES_PASSWORD );
    34963529            es->style &= ~ES_PASSWORD;
    3497         }
    3498         EDIT_UpdateText(hwnd, es, NULL, TRUE);
    3499 }
    3500 
    3501 
    3502 /*********************************************************************
    3503  *
    3504  *      EDIT_EM_SetSel
    3505  *
    3506  *      note:   unlike the specs say: the order of start and end
    3507  *              _is_ preserved in Windows.  (i.e. start can be > end)
    3508  *              In other words: this handler is OK
     3530    }
     3531    EDIT_UpdateText(hwnd, es, NULL, TRUE);
     3532}
     3533
     3534
     3535/*********************************************************************
     3536 *
     3537 *  EDIT_EM_SetSel
     3538 *
     3539 *  note:   unlike the specs say: the order of start and end
     3540 *      _is_ preserved in Windows.  (i.e. start can be > end)
     3541 *      In other words: this handler is OK
    35093542 *
    35103543 */
    35113544static void EDIT_EM_SetSel(HWND hwnd, EDITSTATE *es, UINT start, UINT end, BOOL after_wrap)
    35123545{
    3513         UINT old_start = es->selection_start;
    3514         UINT old_end = es->selection_end;
    3515         UINT len = strlenW(es->text);
    3516 
    3517         if (start == (UINT)-1) {
    3518                 start = es->selection_end;
    3519                 end = es->selection_end;
    3520         } else {
    3521                 start = min(start, len);
    3522                 end = min(end, len);
    3523         }
    3524         es->selection_start = start;
    3525         es->selection_end = end;
    3526         if (after_wrap)
    3527                 es->flags |= EF_AFTER_WRAP;
    3528         else
    3529                 es->flags &= ~EF_AFTER_WRAP;
     3546    UINT old_start = es->selection_start;
     3547    UINT old_end = es->selection_end;
     3548    UINT len = strlenW(es->text);
     3549
     3550    if (start == (UINT)-1) {
     3551        start = es->selection_end;
     3552        end = es->selection_end;
     3553    } else {
     3554        start = min(start, len);
     3555        end = min(end, len);
     3556    }
     3557    es->selection_start = start;
     3558    es->selection_end = end;
     3559    if (after_wrap)
     3560        es->flags |= EF_AFTER_WRAP;
     3561    else
     3562        es->flags &= ~EF_AFTER_WRAP;
    35303563/* This is a little bit more efficient than before, not sure if it can be improved. FIXME? */
    35313564        ORDER_UINT(start, end);
     
    35333566        ORDER_UINT(start, old_start);
    35343567        ORDER_UINT(old_start, old_end);
    3535         if (end != old_start)
     3568    if (end != old_start)
    35363569        {
    35373570/*
     
    35523585                EDIT_InvalidateText(hwnd, es, end, old_end);
    35533586            }
    3554         }
     3587    }
    35553588        else EDIT_InvalidateText(hwnd, es, start, old_end);
    35563589}
     
    35593592/*********************************************************************
    35603593 *
    3561  *      EM_SETTABSTOPS
     3594 *  EM_SETTABSTOPS
    35623595 *
    35633596 */
    35643597static BOOL EDIT_EM_SetTabStops(EDITSTATE *es, INT count, LPINT tabs)
    35653598{
    3566         if (!(es->style & ES_MULTILINE))
    3567                 return FALSE;
    3568         if (es->tabs)
    3569                 HeapFree(GetProcessHeap(), 0, es->tabs);
    3570         es->tabs_count = count;
    3571         if (!count)
    3572                 es->tabs = NULL;
    3573         else {
    3574                 es->tabs = HeapAlloc(GetProcessHeap(), 0, count * sizeof(INT));
    3575                 memcpy(es->tabs, tabs, count * sizeof(INT));
    3576         }
    3577         return TRUE;
    3578 }
    3579 
    3580 
    3581 /*********************************************************************
    3582  *
    3583  *      EM_SETTABSTOPS16
     3599    if (!(es->style & ES_MULTILINE))
     3600        return FALSE;
     3601    if (es->tabs)
     3602        HeapFree(GetProcessHeap(), 0, es->tabs);
     3603    es->tabs_count = count;
     3604    if (!count)
     3605        es->tabs = NULL;
     3606    else {
     3607        es->tabs = HeapAlloc(GetProcessHeap(), 0, count * sizeof(INT));
     3608        memcpy(es->tabs, tabs, count * sizeof(INT));
     3609    }
     3610    return TRUE;
     3611}
     3612
     3613
     3614/*********************************************************************
     3615 *
     3616 *  EM_SETTABSTOPS16
    35843617 *
    35853618 */
    35863619static BOOL EDIT_EM_SetTabStops16(EDITSTATE *es, INT count, LPINT16 tabs)
    35873620{
    3588         if (!(es->style & ES_MULTILINE))
    3589                 return FALSE;
    3590         if (es->tabs)
    3591                 HeapFree(GetProcessHeap(), 0, es->tabs);
    3592         es->tabs_count = count;
    3593         if (!count)
    3594                 es->tabs = NULL;
    3595         else {
    3596                 INT i;
    3597                 es->tabs = HeapAlloc(GetProcessHeap(), 0, count * sizeof(INT));
    3598                 for (i = 0 ; i < count ; i++)
    3599                         es->tabs[i] = *tabs++;
    3600         }
    3601         return TRUE;
    3602 }
    3603 
    3604 
    3605 /*********************************************************************
    3606  *
    3607  *      EM_SETWORDBREAKPROC
     3621    if (!(es->style & ES_MULTILINE))
     3622        return FALSE;
     3623    if (es->tabs)
     3624        HeapFree(GetProcessHeap(), 0, es->tabs);
     3625    es->tabs_count = count;
     3626    if (!count)
     3627        es->tabs = NULL;
     3628    else {
     3629        INT i;
     3630        es->tabs = HeapAlloc(GetProcessHeap(), 0, count * sizeof(INT));
     3631        for (i = 0 ; i < count ; i++)
     3632            es->tabs[i] = *tabs++;
     3633    }
     3634    return TRUE;
     3635}
     3636
     3637
     3638/*********************************************************************
     3639 *
     3640 *  EM_SETWORDBREAKPROC
    36083641 *
    36093642 */
    36103643static void EDIT_EM_SetWordBreakProc(HWND hwnd, EDITSTATE *es, LPARAM lParam)
    36113644{
    3612         if (es->word_break_proc == (void *)lParam)
    3613                 return;
    3614 
    3615         es->word_break_proc = (void *)lParam;
    3616         es->word_break_proc16 = NULL;
    3617 
    3618         if ((es->style & ES_MULTILINE) && !(es->style & ES_AUTOHSCROLL)) {
    3619                 EDIT_BuildLineDefs_ML(hwnd, es, 0, strlenW(es->text), 0, (HRGN)0);
    3620                 EDIT_UpdateText(hwnd, es, NULL, TRUE);
    3621         }
     3645    if (es->word_break_proc == (void *)lParam)
     3646        return;
     3647
     3648    es->word_break_proc = (void *)lParam;
     3649    es->word_break_proc16 = NULL;
     3650
     3651    if ((es->style & ES_MULTILINE) && !(es->style & ES_AUTOHSCROLL)) {
     3652        EDIT_BuildLineDefs_ML(hwnd, es, 0, strlenW(es->text), 0, (HRGN)0);
     3653        EDIT_UpdateText(hwnd, es, NULL, TRUE);
     3654    }
    36223655}
    36233656
     
    36263659/*********************************************************************
    36273660 *
    3628  *      EM_SETWORDBREAKPROC16
     3661 *  EM_SETWORDBREAKPROC16
    36293662 *
    36303663 */
    36313664static void EDIT_EM_SetWordBreakProc16(HWND hwnd, EDITSTATE *es, EDITWORDBREAKPROC16 wbp)
    36323665{
    3633         if (es->word_break_proc16 == wbp)
    3634                 return;
    3635 
    3636         es->word_break_proc = NULL;
    3637         es->word_break_proc16 = wbp;
    3638         if ((es->style & ES_MULTILINE) && !(es->style & ES_AUTOHSCROLL)) {
    3639                 EDIT_BuildLineDefs_ML(hwnd, es, 0, strlenW(es->text), 0, (HRGN)0);
    3640                 EDIT_UpdateText(hwnd, es, NULL, TRUE);
    3641         }
     3666    if (es->word_break_proc16 == wbp)
     3667        return;
     3668
     3669    es->word_break_proc = NULL;
     3670    es->word_break_proc16 = wbp;
     3671    if ((es->style & ES_MULTILINE) && !(es->style & ES_AUTOHSCROLL)) {
     3672        EDIT_BuildLineDefs_ML(hwnd, es, 0, strlenW(es->text), 0, (HRGN)0);
     3673        EDIT_UpdateText(hwnd, es, NULL, TRUE);
     3674    }
    36423675}
    36433676#endif
     
    36453678/*********************************************************************
    36463679 *
    3647  *      EM_UNDO / WM_UNDO
     3680 *  EM_UNDO / WM_UNDO
    36483681 *
    36493682 */
    36503683static BOOL EDIT_EM_Undo(HWND hwnd, EDITSTATE *es)
    36513684{
    3652         INT ulength;
    3653         LPWSTR utext;
    3654 
    3655         /* Protect read-only edit control from modification */
    3656         if(es->style & ES_READONLY)
    3657             return FALSE;
    3658 
    3659         ulength = strlenW(es->undo_text);
    3660         utext = HeapAlloc(GetProcessHeap(), 0, (ulength + 1) * sizeof(WCHAR));
    3661 
    3662         strcpyW(utext, es->undo_text);
    3663 
    3664         TRACE("before UNDO:insertion length = %d, deletion buffer = %s\n",
    3665                      es->undo_insert_count, debugstr_w(utext));
    3666 
    3667         EDIT_EM_SetSel(hwnd, es, es->undo_position, es->undo_position + es->undo_insert_count, FALSE);
    3668         EDIT_EM_EmptyUndoBuffer(es);
    3669         EDIT_EM_ReplaceSel(hwnd, es, TRUE, utext, FALSE);
    3670         EDIT_EM_SetSel(hwnd, es, es->undo_position, es->undo_position + es->undo_insert_count, FALSE);
     3685    INT ulength;
     3686    LPWSTR utext;
     3687
     3688    /* Protect read-only edit control from modification */
     3689    if(es->style & ES_READONLY)
     3690        return FALSE;
     3691
     3692    ulength = strlenW(es->undo_text);
     3693    utext = HeapAlloc(GetProcessHeap(), 0, (ulength + 1) * sizeof(WCHAR));
     3694
     3695    strcpyW(utext, es->undo_text);
     3696
     3697    TRACE("before UNDO:insertion length = %d, deletion buffer = %s\n",
     3698             es->undo_insert_count, debugstr_w(utext));
     3699
     3700    EDIT_EM_SetSel(hwnd, es, es->undo_position, es->undo_position + es->undo_insert_count, FALSE);
     3701    EDIT_EM_EmptyUndoBuffer(es);
     3702    EDIT_EM_ReplaceSel(hwnd, es, TRUE, utext, FALSE);
     3703    EDIT_EM_SetSel(hwnd, es, es->undo_position, es->undo_position + es->undo_insert_count, FALSE);
    36713704        /* send the notification after the selection start and end are set */
    36723705        EDIT_NOTIFY_PARENT(hwnd, es, EN_CHANGE, "EN_CHANGE");
    3673         EDIT_EM_ScrollCaret(hwnd, es);
    3674         HeapFree(GetProcessHeap(), 0, utext);
    3675 
    3676         TRACE("after UNDO:insertion length = %d, deletion buffer = %s\n",
    3677                         es->undo_insert_count, debugstr_w(es->undo_text));
    3678         return TRUE;
    3679 }
    3680 
    3681 
    3682 /*********************************************************************
    3683  *
    3684  *      WM_CHAR
     3706    EDIT_EM_ScrollCaret(hwnd, es);
     3707    HeapFree(GetProcessHeap(), 0, utext);
     3708
     3709    TRACE("after UNDO:insertion length = %d, deletion buffer = %s\n",
     3710            es->undo_insert_count, debugstr_w(es->undo_text));
     3711    return TRUE;
     3712}
     3713
     3714
     3715/*********************************************************************
     3716 *
     3717 *  WM_CHAR
    36853718 *
    36863719 */
     
    36893722        BOOL control;
    36903723
    3691         /* Protect read-only edit control from modification */
    3692         if(es->style & ES_READONLY)
    3693             return;
    3694 
    3695         control = GetKeyState(VK_CONTROL) & 0x8000;
    3696 
    3697         switch (c) {
    3698         case '\r':
    3699             /* If the edit doesn't want the return and it's not a multiline edit, do nothing */
    3700             if(!(es->style & ES_MULTILINE) && !(es->style & ES_WANTRETURN))
    3701                 break;
    3702         case '\n':
    3703                 if (es->style & ES_MULTILINE) {
    3704                         if (es->style & ES_READONLY) {
    3705                                 EDIT_MoveHome(hwnd, es, FALSE);
    3706                                 EDIT_MoveDown_ML(hwnd, es, FALSE);
    3707                         } else {
    3708                                 static const WCHAR cr_lfW[] = {'\r','\n',0};
    3709                                 EDIT_EM_ReplaceSel(hwnd, es, TRUE, cr_lfW, TRUE);
    3710                         }
    3711                 }
    3712                 break;
    3713         case '\t':
    3714                 if ((es->style & ES_MULTILINE) && !(es->style & ES_READONLY))
    3715                 {
    3716                         static const WCHAR tabW[] = {'\t',0};
    3717                         EDIT_EM_ReplaceSel(hwnd, es, TRUE, tabW, TRUE);
    3718                 }
    3719                 break;
    3720         case VK_BACK:
    3721                 if (!(es->style & ES_READONLY) && !control) {
    3722                         if (es->selection_start != es->selection_end)
    3723                                 EDIT_WM_Clear(hwnd, es);
    3724                         else {
    3725                                 /* delete character left of caret */
    3726                                 EDIT_EM_SetSel(hwnd, es, (UINT)-1, 0, FALSE);
    3727                                 EDIT_MoveBackward(hwnd, es, TRUE);
    3728                                 EDIT_WM_Clear(hwnd, es);
    3729                         }
    3730                 }
    3731                 break;
    3732         case 0x03: /* ^C */
    3733                 SendMessageW(hwnd, WM_COPY, 0, 0);
    3734                 break;
    3735         case 0x16: /* ^V */
    3736                 SendMessageW(hwnd, WM_PASTE, 0, 0);
    3737                 break;
    3738         case 0x18: /* ^X */
    3739                 SendMessageW(hwnd, WM_CUT, 0, 0);
    3740                 break;
    3741 
    3742         default:
    3743                 if (!(es->style & ES_READONLY) && (c >= ' ') && (c != 127)) {
    3744                         WCHAR str[2];
    3745                         str[0] = c;
    3746                         str[1] = '\0';
    3747                         EDIT_EM_ReplaceSel(hwnd, es, TRUE, str, TRUE);
    3748                 }
    3749                 break;
    3750         }
    3751 }
    3752 
    3753 
    3754 /*********************************************************************
    3755  *
    3756  *      WM_COMMAND
     3724    /* Protect read-only edit control from modification */
     3725    if(es->style & ES_READONLY)
     3726        return;
     3727
     3728    control = GetKeyState(VK_CONTROL) & 0x8000;
     3729
     3730    switch (c) {
     3731    case '\r':
     3732        /* If the edit doesn't want the return and it's not a multiline edit, do nothing */
     3733        if(!(es->style & ES_MULTILINE) && !(es->style & ES_WANTRETURN))
     3734        break;
     3735    case '\n':
     3736        if (es->style & ES_MULTILINE) {
     3737            if (es->style & ES_READONLY) {
     3738                EDIT_MoveHome(hwnd, es, FALSE);
     3739                EDIT_MoveDown_ML(hwnd, es, FALSE);
     3740            } else {
     3741                static const WCHAR cr_lfW[] = {'\r','\n',0};
     3742                EDIT_EM_ReplaceSel(hwnd, es, TRUE, cr_lfW, TRUE);
     3743            }
     3744        }
     3745        break;
     3746    case '\t':
     3747        if ((es->style & ES_MULTILINE) && !(es->style & ES_READONLY))
     3748        {
     3749            static const WCHAR tabW[] = {'\t',0};
     3750            EDIT_EM_ReplaceSel(hwnd, es, TRUE, tabW, TRUE);
     3751        }
     3752        break;
     3753    case VK_BACK:
     3754        if (!(es->style & ES_READONLY) && !control) {
     3755            if (es->selection_start != es->selection_end)
     3756                EDIT_WM_Clear(hwnd, es);
     3757            else {
     3758                /* delete character left of caret */
     3759                EDIT_EM_SetSel(hwnd, es, (UINT)-1, 0, FALSE);
     3760                EDIT_MoveBackward(hwnd, es, TRUE);
     3761                EDIT_WM_Clear(hwnd, es);
     3762            }
     3763        }
     3764        break;
     3765    case 0x03: /* ^C */
     3766        SendMessageW(hwnd, WM_COPY, 0, 0);
     3767        break;
     3768    case 0x16: /* ^V */
     3769        SendMessageW(hwnd, WM_PASTE, 0, 0);
     3770        break;
     3771    case 0x18: /* ^X */
     3772        SendMessageW(hwnd, WM_CUT, 0, 0);
     3773        break;
     3774
     3775    default:
     3776        if (!(es->style & ES_READONLY) && (c >= ' ') && (c != 127)) {
     3777            WCHAR str[2];
     3778            str[0] = c;
     3779            str[1] = '\0';
     3780            EDIT_EM_ReplaceSel(hwnd, es, TRUE, str, TRUE);
     3781        }
     3782        break;
     3783    }
     3784}
     3785
     3786
     3787/*********************************************************************
     3788 *
     3789 *  WM_COMMAND
    37573790 *
    37583791 */
    37593792static void EDIT_WM_Command(HWND hwnd, EDITSTATE *es, INT code, INT id, HWND control)
    37603793{
    3761         if (code || control)
    3762                 return;
    3763 
    3764         switch (id) {
    3765                 case EM_UNDO:
    3766                         EDIT_EM_Undo(hwnd, es);
    3767                         break;
    3768                 case WM_CUT:
    3769                         EDIT_WM_Cut(hwnd, es);
    3770                         break;
    3771                 case WM_COPY:
    3772                         EDIT_WM_Copy(hwnd, es);
    3773                         break;
    3774                 case WM_PASTE:
    3775                         EDIT_WM_Paste(hwnd, es);
    3776                         break;
    3777                 case WM_CLEAR:
    3778                         EDIT_WM_Clear(hwnd, es);
    3779                         break;
    3780                 case EM_SETSEL:
    3781                         EDIT_EM_SetSel(hwnd, es, 0, (UINT)-1, FALSE);
    3782                         EDIT_EM_ScrollCaret(hwnd, es);
    3783                         break;
    3784                 default:
    3785                         ERR("unknown menu item, please report\n");
    3786                         break;
    3787         }
    3788 }
    3789 
    3790 
    3791 /*********************************************************************
    3792  *
    3793  *      WM_CONTEXTMENU
    3794  *
    3795  *      Note: the resource files resource/sysres_??.rc cannot define a
    3796  *              single popup menu.  Hence we use a (dummy) menubar
    3797  *              containing the single popup menu as its first item.
    3798  *
    3799  *      FIXME: the message identifiers have been chosen arbitrarily,
    3800  *              hence we use MF_BYPOSITION.
    3801  *              We might as well use the "real" values (anybody knows ?)
    3802  *              The menu definition is in resources/sysres_??.rc.
    3803  *              Once these are OK, we better use MF_BYCOMMAND here
    3804  *              (as we do in EDIT_WM_Command()).
     3794    if (code || control)
     3795        return;
     3796
     3797    switch (id) {
     3798        case EM_UNDO:
     3799            EDIT_EM_Undo(hwnd, es);
     3800            break;
     3801        case WM_CUT:
     3802            EDIT_WM_Cut(hwnd, es);
     3803            break;
     3804        case WM_COPY:
     3805            EDIT_WM_Copy(hwnd, es);
     3806            break;
     3807        case WM_PASTE:
     3808            EDIT_WM_Paste(hwnd, es);
     3809            break;
     3810        case WM_CLEAR:
     3811            EDIT_WM_Clear(hwnd, es);
     3812            break;
     3813        case EM_SETSEL:
     3814            EDIT_EM_SetSel(hwnd, es, 0, (UINT)-1, FALSE);
     3815            EDIT_EM_ScrollCaret(hwnd, es);
     3816            break;
     3817        default:
     3818            ERR("unknown menu item, please report\n");
     3819            break;
     3820    }
     3821}
     3822
     3823
     3824/*********************************************************************
     3825 *
     3826 *  WM_CONTEXTMENU
     3827 *
     3828 *  Note: the resource files resource/sysres_??.rc cannot define a
     3829 *      single popup menu.  Hence we use a (dummy) menubar
     3830 *      containing the single popup menu as its first item.
     3831 *
     3832 *  FIXME: the message identifiers have been chosen arbitrarily,
     3833 *      hence we use MF_BYPOSITION.
     3834 *      We might as well use the "real" values (anybody knows ?)
     3835 *      The menu definition is in resources/sysres_??.rc.
     3836 *      Once these are OK, we better use MF_BYCOMMAND here
     3837 *      (as we do in EDIT_WM_Command()).
    38053838 *
    38063839 */
    38073840static void EDIT_WM_ContextMenu(HWND hwnd, EDITSTATE *es, INT x, INT y)
    38083841{
    3809         HMENU menu = LoadMenuA(GetModuleHandleA("USER32"), "EDITMENU");
    3810         HMENU popup = GetSubMenu(menu, 0);
    3811         UINT start = es->selection_start;
    3812         UINT end = es->selection_end;
    3813 
    3814         ORDER_UINT(start, end);
    3815 
    3816         /* undo */
    3817         EnableMenuItem(popup, 0, MF_BYPOSITION | (EDIT_EM_CanUndo(es) && !(es->style & ES_READONLY) ? MF_ENABLED : MF_GRAYED));
    3818         /* cut */
    3819         EnableMenuItem(popup, 2, MF_BYPOSITION | ((end - start) && !(es->style & ES_PASSWORD) && !(es->style & ES_READONLY) ? MF_ENABLED : MF_GRAYED));
    3820         /* copy */
    3821         EnableMenuItem(popup, 3, MF_BYPOSITION | ((end - start) && !(es->style & ES_PASSWORD) ? MF_ENABLED : MF_GRAYED));
    3822         /* paste */
    3823         EnableMenuItem(popup, 4, MF_BYPOSITION | (IsClipboardFormatAvailable(CF_UNICODETEXT) && !(es->style & ES_READONLY) ? MF_ENABLED : MF_GRAYED));
    3824         /* delete */
    3825         EnableMenuItem(popup, 5, MF_BYPOSITION | ((end - start) && !(es->style & ES_READONLY) ? MF_ENABLED : MF_GRAYED));
    3826         /* select all */
    3827         EnableMenuItem(popup, 7, MF_BYPOSITION | (start || (end != strlenW(es->text)) ? MF_ENABLED : MF_GRAYED));
    3828 
    3829         TrackPopupMenu(popup, TPM_LEFTALIGN | TPM_RIGHTBUTTON, x, y, 0, hwnd, NULL);
    3830         DestroyMenu(menu);
    3831 }
    3832 
    3833 
    3834 /*********************************************************************
    3835  *
    3836  *      WM_COPY
     3842    HMENU menu = LoadMenuA(GetModuleHandleA("USER32"), "EDITMENU");
     3843    HMENU popup = GetSubMenu(menu, 0);
     3844    UINT start = es->selection_start;
     3845    UINT end = es->selection_end;
     3846
     3847    ORDER_UINT(start, end);
     3848
     3849    /* undo */
     3850    EnableMenuItem(popup, 0, MF_BYPOSITION | (EDIT_EM_CanUndo(es) && !(es->style & ES_READONLY) ? MF_ENABLED : MF_GRAYED));
     3851    /* cut */
     3852    EnableMenuItem(popup, 2, MF_BYPOSITION | ((end - start) && !(es->style & ES_PASSWORD) && !(es->style & ES_READONLY) ? MF_ENABLED : MF_GRAYED));
     3853    /* copy */
     3854    EnableMenuItem(popup, 3, MF_BYPOSITION | ((end - start) && !(es->style & ES_PASSWORD) ? MF_ENABLED : MF_GRAYED));
     3855    /* paste */
     3856    EnableMenuItem(popup, 4, MF_BYPOSITION | (IsClipboardFormatAvailable(CF_UNICODETEXT) && !(es->style & ES_READONLY) ? MF_ENABLED : MF_GRAYED));
     3857    /* delete */
     3858    EnableMenuItem(popup, 5, MF_BYPOSITION | ((end - start) && !(es->style & ES_READONLY) ? MF_ENABLED : MF_GRAYED));
     3859    /* select all */
     3860    EnableMenuItem(popup, 7, MF_BYPOSITION | (start || (end != strlenW(es->text)) ? MF_ENABLED : MF_GRAYED));
     3861
     3862    TrackPopupMenu(popup, TPM_LEFTALIGN | TPM_RIGHTBUTTON, x, y, 0, hwnd, NULL);
     3863    DestroyMenu(menu);
     3864}
     3865
     3866
     3867/*********************************************************************
     3868 *
     3869 *  WM_COPY
    38373870 *
    38383871 */
    38393872static void EDIT_WM_Copy(HWND hwnd, EDITSTATE *es)
    38403873{
    3841         INT s = es->selection_start;
    3842         INT e = es->selection_end;
    3843         HGLOBAL hdst;
    3844         LPWSTR dst;
    3845 
    3846         if (e == s)
    3847                 return;
    3848         ORDER_INT(s, e);
    3849         hdst = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, (DWORD)(e - s + 1) * sizeof(WCHAR));
    3850         dst = GlobalLock(hdst);
    3851         strncpyW(dst, es->text + s, e - s);
    3852         dst[e - s] = 0; /* ensure 0 termination */
    3853         TRACE("%s\n", debugstr_w(dst));
    3854         GlobalUnlock(hdst);
    3855         OpenClipboard(hwnd);
    3856         EmptyClipboard();
    3857         SetClipboardData(CF_UNICODETEXT, hdst);
    3858         CloseClipboard();
    3859 }
    3860 
    3861 
    3862 /*********************************************************************
    3863  *
    3864  *      WM_CREATE
     3874    INT s = es->selection_start;
     3875    INT e = es->selection_end;
     3876    HGLOBAL hdst;
     3877    LPWSTR dst;
     3878
     3879    if (e == s)
     3880        return;
     3881    ORDER_INT(s, e);
     3882    hdst = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, (DWORD)(e - s + 1) * sizeof(WCHAR));
     3883    dst = GlobalLock(hdst);
     3884    strncpyW(dst, es->text + s, e - s);
     3885    dst[e - s ] = 0; /* ensure 0 termination */
     3886    TRACE("%s\n", debugstr_w(dst));
     3887
     3888    GlobalUnlock(hdst);
     3889    OpenClipboard(hwnd);
     3890    EmptyClipboard();
     3891    SetClipboardData(CF_UNICODETEXT, hdst);
     3892    CloseClipboard();
     3893}
     3894
     3895
     3896/*********************************************************************
     3897 *
     3898 *  WM_CREATE
    38653899 *
    38663900 */
    38673901static LRESULT EDIT_WM_Create(HWND hwnd, EDITSTATE *es, LPCWSTR name)
    38683902{
    3869         TRACE("%s\n", debugstr_w(name));
     3903    TRACE("%s\n", debugstr_w(name));
    38703904       /*
    3871         *       To initialize some final structure members, we call some helper
    3872         *       functions.  However, since the EDITSTATE is not consistent (i.e.
    3873         *       not fully initialized), we should be very careful which
    3874         *       functions can be called, and in what order.
     3905        *   To initialize some final structure members, we call some helper
     3906        *   functions.  However, since the EDITSTATE is not consistent (i.e.
     3907        *   not fully initialized), we should be very careful which
     3908        *   functions can be called, and in what order.
    38753909        */
    38763910        EDIT_WM_SetFont(hwnd, es, 0, FALSE);
     
    38783912
    38793913       if (name && *name) {
    3880            EDIT_EM_ReplaceSel(hwnd, es, FALSE, name, FALSE);
    3881            /* if we insert text to the editline, the text scrolls out
     3914       EDIT_EM_ReplaceSel(hwnd, es, FALSE, name, FALSE);
     3915       /* if we insert text to the editline, the text scrolls out
    38823916            * of the window, as the caret is placed after the insert
    38833917            * pos normally; thus we reset es->selection... to 0 and
    38843918            * update caret
    38853919            */
    3886            es->selection_start = es->selection_end = 0;
     3920       es->selection_start = es->selection_end = 0;
    38873921           /* send the notification after the selection start and end are set */
    38883922           EDIT_NOTIFY_PARENT(hwnd, es, EN_CHANGE, "EN_CHANGE");
    3889            EDIT_EM_ScrollCaret(hwnd, es);
     3923       EDIT_EM_ScrollCaret(hwnd, es);
    38903924       }
    38913925       /* force scroll info update */
     
    38973931/*********************************************************************
    38983932 *
    3899  *      WM_DESTROY
     3933 *  WM_DESTROY
    39003934 *
    39013935 */
     
    39033937{
    39043938    HINSTANCE hInstance = GetWindowLongA( hwnd, GWL_HINSTANCE );
    3905         LINEDEF *pc, *pp;
    3906 
    3907         if (es->hloc32W) {
    3908                 while (LocalUnlock(es->hloc32W)) ;
    3909                 LocalFree(es->hloc32W);
    3910         }
    3911         if (es->hloc32A) {
    3912                 while (LocalUnlock(es->hloc32A)) ;
    3913                 LocalFree(es->hloc32A);
    3914         }
     3939    LINEDEF *pc, *pp;
     3940
     3941    if (es->hloc32W) {
     3942        while (LocalUnlock(es->hloc32W)) ;
     3943        LocalFree(es->hloc32W);
     3944    }
     3945    if (es->hloc32A) {
     3946        while (LocalUnlock(es->hloc32A)) ;
     3947        LocalFree(es->hloc32A);
     3948    }
    39153949#ifndef __WIN32OS2__
    3916         if (es->hloc16) {
    3917                 while (LOCAL_Unlock(hInstance, es->hloc16)) ;
    3918                 LOCAL_Free(hInstance, es->hloc16);
    3919         }
     3950    if (es->hloc16) {
     3951        while (LOCAL_Unlock(hInstance, es->hloc16)) ;
     3952        LOCAL_Free(hInstance, es->hloc16);
     3953    }
    39203954#endif
    3921         pc = es->first_line_def;
    3922         while (pc)
    3923         {
    3924                 pp = pc->next;
    3925                 HeapFree(GetProcessHeap(), 0, pc);
    3926                 pc = pp;
    3927         }
     3955    pc = es->first_line_def;
     3956    while (pc)
     3957    {
     3958        pp = pc->next;
     3959        HeapFree(GetProcessHeap(), 0, pc);
     3960        pc = pp;
     3961    }
    39283962
    39293963        SetWindowLongA( hwnd, 0, 0 );
    3930         HeapFree(GetProcessHeap(), 0, es);
    3931 }
    3932 
    3933 
    3934 /*********************************************************************
    3935  *
    3936  *      WM_ERASEBKGND
     3964    HeapFree(GetProcessHeap(), 0, es);
     3965}
     3966
     3967
     3968/*********************************************************************
     3969 *
     3970 *  WM_ERASEBKGND
    39373971 *
    39383972 */
    39393973static LRESULT EDIT_WM_EraseBkGnd(HWND hwnd, EDITSTATE *es, HDC dc)
    39403974{
    3941         HBRUSH brush;
    3942         RECT rc;
     3975    HBRUSH brush;
     3976    RECT rc;
    39433977
    39443978        if ( get_app_version() >= 0x40000 &&(
     
    39513985                brush = (HBRUSH)GetStockObject(WHITE_BRUSH);
    39523986
    3953         GetClientRect(hwnd, &rc);
    3954         IntersectClipRect(dc, rc.left, rc.top, rc.right, rc.bottom);
    3955         GetClipBox(dc, &rc);
    3956         /*
    3957          *      FIXME:  specs say that we should UnrealizeObject() the brush,
    3958          *              but the specs of UnrealizeObject() say that we shouldn't
    3959          *              unrealize a stock object.  The default brush that
    3960          *              DefWndProc() returns is ... a stock object.
    3961         */
    3962         FillRect(dc, &rc, brush);
    3963         return -1;
    3964 }
    3965 
    3966 
    3967 /*********************************************************************
    3968  *
    3969  *      WM_GETTEXT
     3987    GetClientRect(hwnd, &rc);
     3988    IntersectClipRect(dc, rc.left, rc.top, rc.right, rc.bottom);
     3989    GetClipBox(dc, &rc);
     3990    /*
     3991     *  FIXME:  specs say that we should UnrealizeObject() the brush,
     3992     *      but the specs of UnrealizeObject() say that we shouldn't
     3993     *      unrealize a stock object.  The default brush that
     3994     *      DefWndProc() returns is ... a stock object.
     3995    */
     3996    FillRect(dc, &rc, brush);
     3997    return -1;
     3998}
     3999
     4000
     4001/*********************************************************************
     4002 *
     4003 *  WM_GETTEXT
    39704004 *
    39714005 */
     
    39764010    if(unicode)
    39774011    {
    3978         LPWSTR textW = (LPWSTR)lParam;
    3979         strncpyW(textW, es->text, count);
    3980         textW[count - 1] = 0; /* ensure 0 termination */
    3981         return strlenW(textW);
     4012    LPWSTR textW = (LPWSTR)lParam;
     4013    strncpyW(textW, es->text, count);
     4014    textW[count - 1] = 0; /* ensure 0 termination */
     4015    return strlenW(textW);
    39824016    }
    39834017    else
    39844018    {
    3985         LPSTR textA = (LPSTR)lParam;
    3986         WideCharToMultiByte(CP_ACP, 0, es->text, -1, textA, count, NULL, NULL);
    3987         textA[count - 1] = 0; /* ensure 0 termination */
    3988         return strlen(textA);
    3989     }
    3990 }
    3991 
    3992 /*********************************************************************
    3993  *
    3994  *      WM_HSCROLL
     4019    LPSTR textA = (LPSTR)lParam;
     4020    WideCharToMultiByte(CP_ACP, 0, es->text, -1, textA, count, NULL, NULL);
     4021#ifdef __WIN32OS2__
     4022    lstrtrunc( textA, count );
     4023#else
     4024    textA[count - 1] = 0; /* ensure 0 termination */
     4025#endif
     4026    return strlen(textA);
     4027    }
     4028}
     4029
     4030/*********************************************************************
     4031 *
     4032 *  WM_HSCROLL
    39954033 *
    39964034 */
    39974035static LRESULT EDIT_WM_HScroll(HWND hwnd, EDITSTATE *es, INT action, INT pos)
    39984036{
    3999         INT dx;
    4000         INT fw;
    4001 
    4002         if (!(es->style & ES_MULTILINE))
    4003                 return 0;
    4004 
    4005         if (!(es->style & ES_AUTOHSCROLL))
    4006                 return 0;
    4007 
    4008         dx = 0;
    4009         fw = es->format_rect.right - es->format_rect.left;
    4010         switch (action) {
    4011         case SB_LINELEFT:
    4012                 TRACE("SB_LINELEFT\n");
    4013                 if (es->x_offset)
    4014                         dx = -es->char_width;
    4015                 break;
    4016         case SB_LINERIGHT:
    4017                 TRACE("SB_LINERIGHT\n");
    4018                 if (es->x_offset < es->text_width)
    4019                         dx = es->char_width;
    4020                 break;
    4021         case SB_PAGELEFT:
    4022                 TRACE("SB_PAGELEFT\n");
    4023                 if (es->x_offset)
    4024                         dx = -fw / HSCROLL_FRACTION / es->char_width * es->char_width;
    4025                 break;
    4026         case SB_PAGERIGHT:
    4027                 TRACE("SB_PAGERIGHT\n");
    4028                 if (es->x_offset < es->text_width)
    4029                         dx = fw / HSCROLL_FRACTION / es->char_width * es->char_width;
    4030                 break;
    4031         case SB_LEFT:
    4032                 TRACE("SB_LEFT\n");
    4033                 if (es->x_offset)
    4034                         dx = -es->x_offset;
    4035                 break;
    4036         case SB_RIGHT:
    4037                 TRACE("SB_RIGHT\n");
    4038                 if (es->x_offset < es->text_width)
    4039                         dx = es->text_width - es->x_offset;
    4040                 break;
    4041         case SB_THUMBTRACK:
    4042                 TRACE("SB_THUMBTRACK %d\n", pos);
    4043                 es->flags |= EF_HSCROLL_TRACK;
    4044                 if(es->style & WS_HSCROLL)
    4045                     dx = pos - es->x_offset;
    4046                 else
    4047                 {
    4048                     INT fw, new_x;
    4049                     /* Sanity check */
    4050                     if(pos < 0 || pos > 100) return 0;
    4051                     /* Assume default scroll range 0-100 */
    4052                     fw = es->format_rect.right - es->format_rect.left;
    4053                     new_x = pos * (es->text_width - fw) / 100;
    4054                     dx = es->text_width ? (new_x - es->x_offset) : 0;
    4055                 }
    4056                 break;
    4057         case SB_THUMBPOSITION:
    4058                 TRACE("SB_THUMBPOSITION %d\n", pos);
    4059                 es->flags &= ~EF_HSCROLL_TRACK;
    4060                 if(GetWindowLongA( hwnd, GWL_STYLE ) & WS_HSCROLL)
    4061                     dx = pos - es->x_offset;
    4062                 else
    4063                 {
    4064                     INT fw, new_x;
    4065                     /* Sanity check */
    4066                     if(pos < 0 || pos > 100) return 0;
    4067                     /* Assume default scroll range 0-100 */
    4068                     fw = es->format_rect.right - es->format_rect.left;
    4069                     new_x = pos * (es->text_width - fw) / 100;
    4070                     dx = es->text_width ? (new_x - es->x_offset) : 0;
    4071                 }
    4072                 if (!dx) {
    4073                         /* force scroll info update */
    4074                         EDIT_UpdateScrollInfo(hwnd, es);
    4075                         EDIT_NOTIFY_PARENT(hwnd, es, EN_HSCROLL, "EN_HSCROLL");
    4076                 }
    4077                 break;
    4078         case SB_ENDSCROLL:
    4079                 TRACE("SB_ENDSCROLL\n");
    4080                 break;
    4081         /*
    4082          *      FIXME : the next two are undocumented !
    4083          *      Are we doing the right thing ?
    4084          *      At least Win 3.1 Notepad makes use of EM_GETTHUMB this way,
    4085          *      although it's also a regular control message.
    4086         */
    4087         case EM_GETTHUMB: /* this one is used by NT notepad */
    4088         case EM_GETTHUMB16:
    4089         {
    4090                 LRESULT ret;
    4091                 if(GetWindowLongA( hwnd, GWL_STYLE ) & WS_HSCROLL)
    4092                     ret = GetScrollPos(hwnd, SB_HORZ);
    4093                 else
    4094                 {
    4095                     /* Assume default scroll range 0-100 */
    4096                     INT fw = es->format_rect.right - es->format_rect.left;
    4097                     ret = es->text_width ? es->x_offset * 100 / (es->text_width - fw) : 0;
    4098                 }
    4099                 TRACE("EM_GETTHUMB: returning %ld\n", ret);
    4100                 return ret;
    4101         }
    4102         case EM_LINESCROLL16:
    4103                 TRACE("EM_LINESCROLL16\n");
    4104                 dx = pos;
    4105                 break;
    4106 
    4107         default:
    4108                 ERR("undocumented WM_HSCROLL action %d (0x%04x), please report\n",
     4037    INT dx;
     4038    INT fw;
     4039
     4040    if (!(es->style & ES_MULTILINE))
     4041        return 0;
     4042
     4043    if (!(es->style & ES_AUTOHSCROLL))
     4044        return 0;
     4045
     4046    dx = 0;
     4047    fw = es->format_rect.right - es->format_rect.left;
     4048    switch (action) {
     4049    case SB_LINELEFT:
     4050        TRACE("SB_LINELEFT\n");
     4051        if (es->x_offset)
     4052            dx = -es->char_width;
     4053        break;
     4054    case SB_LINERIGHT:
     4055        TRACE("SB_LINERIGHT\n");
     4056        if (es->x_offset < es->text_width)
     4057            dx = es->char_width;
     4058        break;
     4059    case SB_PAGELEFT:
     4060        TRACE("SB_PAGELEFT\n");
     4061        if (es->x_offset)
     4062            dx = -fw / HSCROLL_FRACTION / es->char_width * es->char_width;
     4063        break;
     4064    case SB_PAGERIGHT:
     4065        TRACE("SB_PAGERIGHT\n");
     4066        if (es->x_offset < es->text_width)
     4067            dx = fw / HSCROLL_FRACTION / es->char_width * es->char_width;
     4068        break;
     4069    case SB_LEFT:
     4070        TRACE("SB_LEFT\n");
     4071        if (es->x_offset)
     4072            dx = -es->x_offset;
     4073        break;
     4074    case SB_RIGHT:
     4075        TRACE("SB_RIGHT\n");
     4076        if (es->x_offset < es->text_width)
     4077            dx = es->text_width - es->x_offset;
     4078        break;
     4079    case SB_THUMBTRACK:
     4080        TRACE("SB_THUMBTRACK %d\n", pos);
     4081        es->flags |= EF_HSCROLL_TRACK;
     4082        if(es->style & WS_HSCROLL)
     4083            dx = pos - es->x_offset;
     4084        else
     4085        {
     4086            INT fw, new_x;
     4087            /* Sanity check */
     4088            if(pos < 0 || pos > 100) return 0;
     4089            /* Assume default scroll range 0-100 */
     4090            fw = es->format_rect.right - es->format_rect.left;
     4091            new_x = pos * (es->text_width - fw) / 100;
     4092            dx = es->text_width ? (new_x - es->x_offset) : 0;
     4093        }
     4094        break;
     4095    case SB_THUMBPOSITION:
     4096        TRACE("SB_THUMBPOSITION %d\n", pos);
     4097        es->flags &= ~EF_HSCROLL_TRACK;
     4098        if(GetWindowLongA( hwnd, GWL_STYLE ) & WS_HSCROLL)
     4099            dx = pos - es->x_offset;
     4100        else
     4101        {
     4102            INT fw, new_x;
     4103            /* Sanity check */
     4104            if(pos < 0 || pos > 100) return 0;
     4105            /* Assume default scroll range 0-100 */
     4106            fw = es->format_rect.right - es->format_rect.left;
     4107            new_x = pos * (es->text_width - fw) / 100;
     4108            dx = es->text_width ? (new_x - es->x_offset) : 0;
     4109        }
     4110        if (!dx) {
     4111            /* force scroll info update */
     4112            EDIT_UpdateScrollInfo(hwnd, es);
     4113            EDIT_NOTIFY_PARENT(hwnd, es, EN_HSCROLL, "EN_HSCROLL");
     4114        }
     4115        break;
     4116    case SB_ENDSCROLL:
     4117        TRACE("SB_ENDSCROLL\n");
     4118        break;
     4119    /*
     4120     *  FIXME : the next two are undocumented !
     4121     *  Are we doing the right thing ?
     4122     *  At least Win 3.1 Notepad makes use of EM_GETTHUMB this way,
     4123     *  although it's also a regular control message.
     4124    */
     4125    case EM_GETTHUMB: /* this one is used by NT notepad */
     4126    case EM_GETTHUMB16:
     4127    {
     4128        LRESULT ret;
     4129        if(GetWindowLongA( hwnd, GWL_STYLE ) & WS_HSCROLL)
     4130            ret = GetScrollPos(hwnd, SB_HORZ);
     4131        else
     4132        {
     4133            /* Assume default scroll range 0-100 */
     4134            INT fw = es->format_rect.right - es->format_rect.left;
     4135            ret = es->text_width ? es->x_offset * 100 / (es->text_width - fw) : 0;
     4136        }
     4137        TRACE("EM_GETTHUMB: returning %ld\n", ret);
     4138        return ret;
     4139    }
     4140    case EM_LINESCROLL16:
     4141        TRACE("EM_LINESCROLL16\n");
     4142        dx = pos;
     4143        break;
     4144
     4145    default:
     4146        ERR("undocumented WM_HSCROLL action %d (0x%04x), please report\n",
    41094147                    action, action);
    4110                 return 0;
    4111         }
    4112         if (dx)
    4113         {
    4114             INT fw = es->format_rect.right - es->format_rect.left;
    4115             /* check if we are going to move too far */
    4116             if(es->x_offset + dx + fw > es->text_width)
    4117                 dx = es->text_width - fw - es->x_offset;
    4118             if(dx)
    4119                 EDIT_EM_LineScroll_internal(hwnd, es, dx, 0);
    4120         }
    4121         return 0;
    4122 }
    4123 
    4124 
    4125 /*********************************************************************
    4126  *
    4127  *      EDIT_CheckCombo
     4148        return 0;
     4149    }
     4150    if (dx)
     4151    {
     4152        INT fw = es->format_rect.right - es->format_rect.left;
     4153        /* check if we are going to move too far */
     4154        if(es->x_offset + dx + fw > es->text_width)
     4155        dx = es->text_width - fw - es->x_offset;
     4156        if(dx)
     4157        EDIT_EM_LineScroll_internal(hwnd, es, dx, 0);
     4158    }
     4159    return 0;
     4160}
     4161
     4162
     4163/*********************************************************************
     4164 *
     4165 *  EDIT_CheckCombo
    41284166 *
    41294167 */
     
    41434181
    41444182   TRACE_(combo)("[%04x]: handling msg %04x (%04x)\n",
    4145                      hwnd, (UINT16)msg, (UINT16)key);
     4183                 hwnd, (UINT16)msg, (UINT16)key);
    41464184
    41474185   if (key == VK_UP || key == VK_DOWN)
     
    41854223/*********************************************************************
    41864224 *
    4187  *      WM_KEYDOWN
    4188  *
    4189  *      Handling of special keys that don't produce a WM_CHAR
    4190  *      (i.e. non-printable keys) & Backspace & Delete
     4225 *  WM_KEYDOWN
     4226 *
     4227 *  Handling of special keys that don't produce a WM_CHAR
     4228 *  (i.e. non-printable keys) & Backspace & Delete
    41914229 *
    41924230 */
    41934231static LRESULT EDIT_WM_KeyDown(HWND hwnd, EDITSTATE *es, INT key)
    41944232{
    4195         BOOL shift;
    4196         BOOL control;
    4197 
    4198         if (GetKeyState(VK_MENU) & 0x8000)
    4199                 return 0;
    4200 
    4201         shift = GetKeyState(VK_SHIFT) & 0x8000;
    4202         control = GetKeyState(VK_CONTROL) & 0x8000;
    4203 
    4204         switch (key) {
    4205         case VK_F4:
    4206         case VK_UP:
    4207                 if (EDIT_CheckCombo(hwnd, es, WM_KEYDOWN, key) || key == VK_F4)
    4208                         break;
    4209 
    4210                 /* fall through */
    4211         case VK_LEFT:
    4212                 if ((es->style & ES_MULTILINE) && (key == VK_UP))
    4213                         EDIT_MoveUp_ML(hwnd, es, shift);
    4214                 else
    4215                         if (control)
    4216                                 EDIT_MoveWordBackward(hwnd, es, shift);
    4217                         else
    4218                                 EDIT_MoveBackward(hwnd, es, shift);
    4219                 break;
    4220         case VK_DOWN:
    4221                 if (EDIT_CheckCombo(hwnd, es, WM_KEYDOWN, key))
    4222                         break;
    4223                 /* fall through */
    4224         case VK_RIGHT:
    4225                 if ((es->style & ES_MULTILINE) && (key == VK_DOWN))
    4226                         EDIT_MoveDown_ML(hwnd, es, shift);
    4227                 else if (control)
    4228                         EDIT_MoveWordForward(hwnd, es, shift);
    4229                 else
    4230                         EDIT_MoveForward(hwnd, es, shift);
    4231                 break;
    4232         case VK_HOME:
    4233                 EDIT_MoveHome(hwnd, es, shift);
    4234                 break;
    4235         case VK_END:
    4236                 EDIT_MoveEnd(hwnd, es, shift);
    4237                 break;
    4238         case VK_PRIOR:
    4239                 if (es->style & ES_MULTILINE)
    4240                         EDIT_MovePageUp_ML(hwnd, es, shift);
    4241                 else
    4242                         EDIT_CheckCombo(hwnd, es, WM_KEYDOWN, key);
    4243                 break;
    4244         case VK_NEXT:
    4245                 if (es->style & ES_MULTILINE)
    4246                         EDIT_MovePageDown_ML(hwnd, es, shift);
    4247                 else
    4248                         EDIT_CheckCombo(hwnd, es, WM_KEYDOWN, key);
    4249                 break;
    4250         case VK_DELETE:
    4251                 if (!(es->style & ES_READONLY) && !(shift && control)) {
    4252                         if (es->selection_start != es->selection_end) {
    4253                                 if (shift)
    4254                                         EDIT_WM_Cut(hwnd, es);
    4255                                 else
    4256                                         EDIT_WM_Clear(hwnd, es);
    4257                         } else {
    4258                                 if (shift) {
    4259                                         /* delete character left of caret */
    4260                                         EDIT_EM_SetSel(hwnd, es, (UINT)-1, 0, FALSE);
    4261                                         EDIT_MoveBackward(hwnd, es, TRUE);
    4262                                         EDIT_WM_Clear(hwnd, es);
    4263                                 } else if (control) {
    4264                                         /* delete to end of line */
    4265                                         EDIT_EM_SetSel(hwnd, es, (UINT)-1, 0, FALSE);
    4266                                         EDIT_MoveEnd(hwnd, es, TRUE);
    4267                                         EDIT_WM_Clear(hwnd, es);
    4268                                 } else {
    4269                                         /* delete character right of caret */
    4270                                         EDIT_EM_SetSel(hwnd, es, (UINT)-1, 0, FALSE);
    4271                                         EDIT_MoveForward(hwnd, es, TRUE);
    4272                                         EDIT_WM_Clear(hwnd, es);
    4273                                 }
    4274                         }
    4275                 }
    4276                 break;
    4277         case VK_INSERT:
    4278                 if (shift) {
    4279                         if (!(es->style & ES_READONLY))
    4280                                 EDIT_WM_Paste(hwnd, es);
    4281                 } else if (control)
    4282                         EDIT_WM_Copy(hwnd, es);
    4283                 break;
    4284         case VK_RETURN:
    4285             /* If the edit doesn't want the return send a message to the default object */
    4286             if(!(es->style & ES_WANTRETURN))
    4287             {
    4288                 HWND hwndParent = GetParent(hwnd);
    4289                 DWORD dw = SendMessageW( hwndParent, DM_GETDEFID, 0, 0 );
    4290                 if (HIWORD(dw) == DC_HASDEFID)
    4291                 {
    4292                     SendMessageW( hwndParent, WM_COMMAND,
    4293                                   MAKEWPARAM( LOWORD(dw), BN_CLICKED ),
    4294                               (LPARAM)GetDlgItem( hwndParent, LOWORD(dw) ) );
    4295                 }
    4296             }
    4297             break;
    4298         }
    4299         return 0;
    4300 }
    4301 
    4302 
    4303 /*********************************************************************
    4304  *
    4305  *      WM_KILLFOCUS
     4233    BOOL shift;
     4234    BOOL control;
     4235
     4236    if (GetKeyState(VK_MENU) & 0x8000)
     4237        return 0;
     4238
     4239    shift = GetKeyState(VK_SHIFT) & 0x8000;
     4240    control = GetKeyState(VK_CONTROL) & 0x8000;
     4241
     4242    switch (key) {
     4243    case VK_F4:
     4244    case VK_UP:
     4245        if (EDIT_CheckCombo(hwnd, es, WM_KEYDOWN, key) || key == VK_F4)
     4246            break;
     4247
     4248        /* fall through */
     4249    case VK_LEFT:
     4250        if ((es->style & ES_MULTILINE) && (key == VK_UP))
     4251            EDIT_MoveUp_ML(hwnd, es, shift);
     4252        else
     4253            if (control)
     4254                EDIT_MoveWordBackward(hwnd, es, shift);
     4255            else
     4256                EDIT_MoveBackward(hwnd, es, shift);
     4257        break;
     4258    case VK_DOWN:
     4259        if (EDIT_CheckCombo(hwnd, es, WM_KEYDOWN, key))
     4260            break;
     4261        /* fall through */
     4262    case VK_RIGHT:
     4263        if ((es->style & ES_MULTILINE) && (key == VK_DOWN))
     4264            EDIT_MoveDown_ML(hwnd, es, shift);
     4265        else if (control)
     4266            EDIT_MoveWordForward(hwnd, es, shift);
     4267        else
     4268            EDIT_MoveForward(hwnd, es, shift);
     4269        break;
     4270    case VK_HOME:
     4271        EDIT_MoveHome(hwnd, es, shift);
     4272        break;
     4273    case VK_END:
     4274        EDIT_MoveEnd(hwnd, es, shift);
     4275        break;
     4276    case VK_PRIOR:
     4277        if (es->style & ES_MULTILINE)
     4278            EDIT_MovePageUp_ML(hwnd, es, shift);
     4279        else
     4280            EDIT_CheckCombo(hwnd, es, WM_KEYDOWN, key);
     4281        break;
     4282    case VK_NEXT:
     4283        if (es->style & ES_MULTILINE)
     4284            EDIT_MovePageDown_ML(hwnd, es, shift);
     4285        else
     4286            EDIT_CheckCombo(hwnd, es, WM_KEYDOWN, key);
     4287        break;
     4288    case VK_DELETE:
     4289        if (!(es->style & ES_READONLY) && !(shift && control)) {
     4290            if (es->selection_start != es->selection_end) {
     4291                if (shift)
     4292                    EDIT_WM_Cut(hwnd, es);
     4293                else
     4294                    EDIT_WM_Clear(hwnd, es);
     4295            } else {
     4296                if (shift) {
     4297                    /* delete character left of caret */
     4298                    EDIT_EM_SetSel(hwnd, es, (UINT)-1, 0, FALSE);
     4299                    EDIT_MoveBackward(hwnd, es, TRUE);
     4300                    EDIT_WM_Clear(hwnd, es);
     4301                } else if (control) {
     4302                    /* delete to end of line */
     4303                    EDIT_EM_SetSel(hwnd, es, (UINT)-1, 0, FALSE);
     4304                    EDIT_MoveEnd(hwnd, es, TRUE);
     4305                    EDIT_WM_Clear(hwnd, es);
     4306                } else {
     4307                    /* delete character right of caret */
     4308                    EDIT_EM_SetSel(hwnd, es, (UINT)-1, 0, FALSE);
     4309                    EDIT_MoveForward(hwnd, es, TRUE);
     4310                    EDIT_WM_Clear(hwnd, es);
     4311                }
     4312            }
     4313        }
     4314        break;
     4315    case VK_INSERT:
     4316        if (shift) {
     4317            if (!(es->style & ES_READONLY))
     4318                EDIT_WM_Paste(hwnd, es);
     4319        } else if (control)
     4320            EDIT_WM_Copy(hwnd, es);
     4321        break;
     4322    case VK_RETURN:
     4323        /* If the edit doesn't want the return send a message to the default object */
     4324        if(!(es->style & ES_WANTRETURN))
     4325        {
     4326        HWND hwndParent = GetParent(hwnd);
     4327        DWORD dw = SendMessageW( hwndParent, DM_GETDEFID, 0, 0 );
     4328        if (HIWORD(dw) == DC_HASDEFID)
     4329        {
     4330            SendMessageW( hwndParent, WM_COMMAND,
     4331                  MAKEWPARAM( LOWORD(dw), BN_CLICKED ),
     4332                  (LPARAM)GetDlgItem( hwndParent, LOWORD(dw) ) );
     4333        }
     4334        }
     4335        break;
     4336    }
     4337    return 0;
     4338}
     4339
     4340
     4341/*********************************************************************
     4342 *
     4343 *  WM_KILLFOCUS
    43064344 *
    43074345 */
    43084346static LRESULT EDIT_WM_KillFocus(HWND hwnd, EDITSTATE *es)
    43094347{
    4310         es->flags &= ~EF_FOCUSED;
    4311         DestroyCaret();
    4312         if(!(es->style & ES_NOHIDESEL))
    4313                 EDIT_InvalidateText(hwnd, es, es->selection_start, es->selection_end);
    4314         EDIT_NOTIFY_PARENT(hwnd, es, EN_KILLFOCUS, "EN_KILLFOCUS");
    4315         return 0;
    4316 }
    4317 
    4318 
    4319 /*********************************************************************
    4320  *
    4321  *      WM_LBUTTONDBLCLK
    4322  *
    4323  *      The caret position has been set on the WM_LBUTTONDOWN message
     4348    es->flags &= ~EF_FOCUSED;
     4349    DestroyCaret();
     4350    if(!(es->style & ES_NOHIDESEL))
     4351        EDIT_InvalidateText(hwnd, es, es->selection_start, es->selection_end);
     4352    EDIT_NOTIFY_PARENT(hwnd, es, EN_KILLFOCUS, "EN_KILLFOCUS");
     4353    return 0;
     4354}
     4355
     4356
     4357/*********************************************************************
     4358 *
     4359 *  WM_LBUTTONDBLCLK
     4360 *
     4361 *  The caret position has been set on the WM_LBUTTONDOWN message
    43244362 *
    43254363 */
    43264364static LRESULT EDIT_WM_LButtonDblClk(HWND hwnd, EDITSTATE *es)
    43274365{
    4328         INT s;
    4329         INT e = es->selection_end;
    4330         INT l;
    4331         INT li;
    4332         INT ll;
    4333 
    4334         if (!(es->flags & EF_FOCUSED))
    4335                 return 0;
    4336 
    4337         l = EDIT_EM_LineFromChar(es, e);
    4338         li = EDIT_EM_LineIndex(es, l);
    4339         ll = EDIT_EM_LineLength(es, e);
    4340         s = li + EDIT_CallWordBreakProc(es, li, e - li, ll, WB_LEFT);
    4341         e = li + EDIT_CallWordBreakProc(es, li, e - li, ll, WB_RIGHT);
    4342         EDIT_EM_SetSel(hwnd, es, s, e, FALSE);
    4343         EDIT_EM_ScrollCaret(hwnd, es);
    4344         return 0;
    4345 }
    4346 
    4347 
    4348 /*********************************************************************
    4349  *
    4350  *      WM_LBUTTONDOWN
     4366    INT s;
     4367    INT e = es->selection_end;
     4368    INT l;
     4369    INT li;
     4370    INT ll;
     4371
     4372    if (!(es->flags & EF_FOCUSED))
     4373        return 0;
     4374
     4375    l = EDIT_EM_LineFromChar(es, e);
     4376    li = EDIT_EM_LineIndex(es, l);
     4377    ll = EDIT_EM_LineLength(es, e);
     4378    s = li + EDIT_CallWordBreakProc(es, li, e - li, ll, WB_LEFT);
     4379    e = li + EDIT_CallWordBreakProc(es, li, e - li, ll, WB_RIGHT);
     4380    EDIT_EM_SetSel(hwnd, es, s, e, FALSE);
     4381    EDIT_EM_ScrollCaret(hwnd, es);
     4382    return 0;
     4383}
     4384
     4385
     4386/*********************************************************************
     4387 *
     4388 *  WM_LBUTTONDOWN
    43514389 *
    43524390 */
    43534391static LRESULT EDIT_WM_LButtonDown(HWND hwnd, EDITSTATE *es, DWORD keys, INT x, INT y)
    43544392{
    4355         INT e;
    4356         BOOL after_wrap;
    4357 
    4358         if (!(es->flags & EF_FOCUSED))
    4359                 return 0;
    4360 
    4361         es->bCaptureState = TRUE;
    4362         SetCapture(hwnd);
    4363         EDIT_ConfinePoint(es, &x, &y);
    4364         e = EDIT_CharFromPos(hwnd, es, x, y, &after_wrap);
    4365         EDIT_EM_SetSel(hwnd, es, (keys & MK_SHIFT) ? es->selection_start : e, e, after_wrap);
    4366         EDIT_EM_ScrollCaret(hwnd, es);
    4367         es->region_posx = es->region_posy = 0;
    4368         SetTimer(hwnd, 0, 100, NULL);
    4369         return 0;
    4370 }
    4371 
    4372 
    4373 /*********************************************************************
    4374  *
    4375  *      WM_LBUTTONUP
     4393    INT e;
     4394    BOOL after_wrap;
     4395
     4396    if (!(es->flags & EF_FOCUSED))
     4397        return 0;
     4398
     4399    es->bCaptureState = TRUE;
     4400    SetCapture(hwnd);
     4401    EDIT_ConfinePoint(es, &x, &y);
     4402    e = EDIT_CharFromPos(hwnd, es, x, y, &after_wrap);
     4403    EDIT_EM_SetSel(hwnd, es, (keys & MK_SHIFT) ? es->selection_start : e, e, after_wrap);
     4404    EDIT_EM_ScrollCaret(hwnd, es);
     4405    es->region_posx = es->region_posy = 0;
     4406    SetTimer(hwnd, 0, 100, NULL);
     4407    return 0;
     4408}
     4409
     4410
     4411/*********************************************************************
     4412 *
     4413 *  WM_LBUTTONUP
    43764414 *
    43774415 */
     
    43794417{
    43804418#ifdef __WIN32OS2__
    4381         if (es->bCaptureState) {
    4382                 KillTimer(hwndSelf, 0);
    4383                 if(GetCapture() == hwndSelf) ReleaseCapture();
    4384         }
     4419    if (es->bCaptureState) {
     4420        KillTimer(hwndSelf, 0);
     4421        if(GetCapture() == hwndSelf) ReleaseCapture();
     4422    }
    43854423#else
    4386         if (es->bCaptureState && GetCapture() == hwndSelf) {
    4387                 KillTimer(hwndSelf, 0);
    4388                 ReleaseCapture();
    4389         }
     4424    if (es->bCaptureState && GetCapture() == hwndSelf) {
     4425        KillTimer(hwndSelf, 0);
     4426        ReleaseCapture();
     4427    }
    43904428#endif
    4391         es->bCaptureState = FALSE;
    4392         return 0;
    4393 }
    4394 
    4395 
    4396 /*********************************************************************
    4397  *
    4398  *      WM_MBUTTONDOWN
     4429    es->bCaptureState = FALSE;
     4430    return 0;
     4431}
     4432
     4433
     4434/*********************************************************************
     4435 *
     4436 *  WM_MBUTTONDOWN
    43994437 *
    44004438 */
     
    44084446/*********************************************************************
    44094447 *
    4410  *      WM_MOUSEMOVE
     4448 *  WM_MOUSEMOVE
    44114449 *
    44124450 */
    44134451static LRESULT EDIT_WM_MouseMove(HWND hwnd, EDITSTATE *es, INT x, INT y)
    44144452{
    4415         INT e;
    4416         BOOL after_wrap;
    4417         INT prex, prey;
    4418 
    4419         if (GetCapture() != hwnd)
    4420                 return 0;
    4421 
    4422         /*
    4423          *      FIXME: gotta do some scrolling if outside client
    4424          *              area.  Maybe reset the timer ?
    4425         */
    4426         prex = x; prey = y;
    4427         EDIT_ConfinePoint(es, &x, &y);
    4428         es->region_posx = (prex < x) ? -1 : ((prex > x) ? 1 : 0);
    4429         es->region_posy = (prey < y) ? -1 : ((prey > y) ? 1 : 0);
    4430         e = EDIT_CharFromPos(hwnd, es, x, y, &after_wrap);
    4431         EDIT_EM_SetSel(hwnd, es, es->selection_start, e, after_wrap);
    4432         return 0;
    4433 }
    4434 
    4435 
    4436 /*********************************************************************
    4437  *
    4438  *      WM_NCCREATE
     4453    INT e;
     4454    BOOL after_wrap;
     4455    INT prex, prey;
     4456
     4457    if (GetCapture() != hwnd)
     4458        return 0;
     4459
     4460    /*
     4461     *  FIXME: gotta do some scrolling if outside client
     4462     *      area.  Maybe reset the timer ?
     4463    */
     4464    prex = x; prey = y;
     4465    EDIT_ConfinePoint(es, &x, &y);
     4466    es->region_posx = (prex < x) ? -1 : ((prex > x) ? 1 : 0);
     4467    es->region_posy = (prey < y) ? -1 : ((prey > y) ? 1 : 0);
     4468    e = EDIT_CharFromPos(hwnd, es, x, y, &after_wrap);
     4469    EDIT_EM_SetSel(hwnd, es, es->selection_start, e, after_wrap);
     4470    return 0;
     4471}
     4472
     4473
     4474/*********************************************************************
     4475 *
     4476 *  WM_NCCREATE
    44394477 *
    44404478 * See also EDIT_WM_StyleChanged
     
    44424480static LRESULT EDIT_WM_NCCreate(HWND hwnd, DWORD style, HWND hwndParent, BOOL unicode)
    44434481{
    4444         EDITSTATE *es;
    4445         UINT alloc_size;
    4446 
    4447         TRACE("Creating %s edit control, style = %08lx\n",
    4448                 unicode ? "Unicode" : "ANSI", style);
    4449 
    4450         if (!(es = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*es))))
    4451                 return FALSE;
     4482    EDITSTATE *es;
     4483    UINT alloc_size;
     4484
     4485    TRACE("Creating %s edit control, style = %08lx\n",
     4486        unicode ? "Unicode" : "ANSI", style);
     4487
     4488    if (!(es = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*es))))
     4489        return FALSE;
    44524490        SetWindowLongA( hwnd, 0, (LONG)es );
    44534491
     
    44584496        */
    44594497
    4460         es->is_unicode = unicode;
    4461         es->style = style;
     4498    es->is_unicode = unicode;
     4499    es->style = style;
    44624500
    44634501        es->bEnableState = !(style & WS_DISABLED);
    44644502
    4465         /* Save parent, which will be notified by EN_* messages */
    4466         es->hwndParent = hwndParent;
    4467 
    4468         if (es->style & ES_COMBO)
    4469            es->hwndListBox = GetDlgItem(hwndParent, ID_CB_LISTBOX);
     4503    /* Save parent, which will be notified by EN_* messages */
     4504    es->hwndParent = hwndParent;
     4505
     4506    if (es->style & ES_COMBO)
     4507       es->hwndListBox = GetDlgItem(hwndParent, ID_CB_LISTBOX);
    44704508
    44714509        /* Number overrides lowercase overrides uppercase (at least it
     
    44784516                es->style &= ~ES_UPPERCASE;
    44794517        }
    4480         if (es->style & ES_MULTILINE) {
    4481                 es->buffer_limit = BUFLIMIT_MULTI;
    4482                 if (es->style & WS_VSCROLL)
    4483                         es->style |= ES_AUTOVSCROLL;
    4484                 if (es->style & WS_HSCROLL)
    4485                         es->style |= ES_AUTOHSCROLL;
    4486                 es->style &= ~ES_PASSWORD;
    4487                 if ((es->style & ES_CENTER) || (es->style & ES_RIGHT)) {
     4518    if (es->style & ES_MULTILINE) {
     4519        es->buffer_limit = BUFLIMIT_MULTI;
     4520        if (es->style & WS_VSCROLL)
     4521            es->style |= ES_AUTOVSCROLL;
     4522        if (es->style & WS_HSCROLL)
     4523            es->style |= ES_AUTOHSCROLL;
     4524        es->style &= ~ES_PASSWORD;
     4525        if ((es->style & ES_CENTER) || (es->style & ES_RIGHT)) {
    44884526                        /* Confirmed - RIGHT overrides CENTER */
    4489                         if (es->style & ES_RIGHT)
    4490                                 es->style &= ~ES_CENTER;
    4491                         es->style &= ~WS_HSCROLL;
    4492                         es->style &= ~ES_AUTOHSCROLL;
    4493                 }
    4494 
    4495                 /* FIXME: for now, all multi line controls are AUTOVSCROLL */
    4496                 es->style |= ES_AUTOVSCROLL;
    4497         } else {
    4498                 es->buffer_limit = BUFLIMIT_SINGLE;
     4527            if (es->style & ES_RIGHT)
     4528                es->style &= ~ES_CENTER;
     4529            es->style &= ~WS_HSCROLL;
     4530            es->style &= ~ES_AUTOHSCROLL;
     4531        }
     4532
     4533        /* FIXME: for now, all multi line controls are AUTOVSCROLL */
     4534        es->style |= ES_AUTOVSCROLL;
     4535    } else {
     4536        es->buffer_limit = BUFLIMIT_SINGLE;
    44994537                if (WIN31_LOOK == TWEAK_WineLook ||
    45004538                    WIN95_LOOK == TWEAK_WineLook) {
    4501                         es->style &= ~ES_CENTER;
    4502                         es->style &= ~ES_RIGHT;
     4539                es->style &= ~ES_CENTER;
     4540                es->style &= ~ES_RIGHT;
    45034541                } else {
    4504                         if (es->style & ES_RIGHT)
    4505                                 es->style &= ~ES_CENTER;
     4542            if (es->style & ES_RIGHT)
     4543                es->style &= ~ES_CENTER;
    45064544                }
    4507                 es->style &= ~WS_HSCROLL;
    4508                 es->style &= ~WS_VSCROLL;
    4509                 es->style &= ~ES_AUTOVSCROLL;
    4510                 es->style &= ~ES_WANTRETURN;
    4511                 if (es->style & ES_PASSWORD)
    4512                         es->password_char = '*';
    4513 
    4514                 /* FIXME: for now, all single line controls are AUTOHSCROLL */
    4515                 es->style |= ES_AUTOHSCROLL;
    4516         }
    4517 
    4518         alloc_size = ROUND_TO_GROW((es->buffer_size + 1) * sizeof(WCHAR));
    4519         if(!(es->hloc32W = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT, alloc_size)))
    4520             return FALSE;
    4521         es->buffer_size = LocalSize(es->hloc32W)/sizeof(WCHAR) - 1;
    4522 
    4523         if (!(es->undo_text = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (es->buffer_size + 1) * sizeof(WCHAR))))
    4524                 return FALSE;
    4525         es->undo_buffer_size = es->buffer_size;
    4526 
    4527         if (es->style & ES_MULTILINE)
    4528                 if (!(es->first_line_def = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LINEDEF))))
    4529                         return FALSE;
    4530         es->line_count = 1;
    4531 
    4532         /*
    4533         * In Win95 look and feel, the WS_BORDER style is replaced by the
    4534         * WS_EX_CLIENTEDGE style for the edit control. This gives the edit
    4535         * control a non client area.  Not always.  This coordinates in some
     4545        es->style &= ~WS_HSCROLL;
     4546        es->style &= ~WS_VSCROLL;
     4547        es->style &= ~ES_AUTOVSCROLL;
     4548        es->style &= ~ES_WANTRETURN;
     4549        if (es->style & ES_PASSWORD)
     4550            es->password_char = '*';
     4551
     4552        /* FIXME: for now, all single line controls are AUTOHSCROLL */
     4553        es->style |= ES_AUTOHSCROLL;
     4554    }
     4555
     4556    alloc_size = ROUND_TO_GROW((es->buffer_size + 1) * sizeof(WCHAR));
     4557    if(!(es->hloc32W = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT, alloc_size)))
     4558        return FALSE;
     4559    es->buffer_size = LocalSize(es->hloc32W)/sizeof(WCHAR) - 1;
     4560
     4561    if (!(es->undo_text = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (es->buffer_size + 1) * sizeof(WCHAR))))
     4562        return FALSE;
     4563    es->undo_buffer_size = es->buffer_size;
     4564
     4565    if (es->style & ES_MULTILINE)
     4566        if (!(es->first_line_def = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LINEDEF))))
     4567            return FALSE;
     4568    es->line_count = 1;
     4569
     4570    /*
     4571    * In Win95 look and feel, the WS_BORDER style is replaced by the
     4572    * WS_EX_CLIENTEDGE style for the edit control. This gives the edit
     4573    * control a non client area.  Not always.  This coordinates in some
    45364574         * way with the window creation code in dialog.c  When making
    45374575         * modifications please ensure that the code still works for edit
    45384576         * controls created directly with style 0x50800000, exStyle 0 (
    45394577         * which should have a single pixel border)
    4540         */
    4541         if (TWEAK_WineLook != WIN31_LOOK)
    4542         {
    4543           es->style      &= ~WS_BORDER;
    4544         }
    4545         else
    4546         {
    4547           if ((es->style & WS_BORDER) && !(es->style & WS_DLGFRAME))
     4578    */
     4579    if (TWEAK_WineLook != WIN31_LOOK)
     4580    {
     4581      es->style      &= ~WS_BORDER;
     4582    }
     4583    else
     4584    {
     4585      if ((es->style & WS_BORDER) && !(es->style & WS_DLGFRAME))
    45484586              SetWindowLongA( hwnd, GWL_STYLE,
    45494587                              GetWindowLongA( hwnd, GWL_STYLE ) & ~WS_BORDER );
    4550         }
    4551 
    4552         return TRUE;
    4553 }
    4554 
    4555 /*********************************************************************
    4556  *
    4557  *      WM_PAINT
     4588    }
     4589
     4590    return TRUE;
     4591}
     4592
     4593/*********************************************************************
     4594 *
     4595 *  WM_PAINT
    45584596 *
    45594597 */
    45604598static void EDIT_WM_Paint(HWND hwnd, EDITSTATE *es, WPARAM wParam)
    45614599{
    4562         PAINTSTRUCT ps;
    4563         INT i;
    4564         HDC dc;
    4565         HFONT old_font = 0;
    4566         RECT rc;
    4567         RECT rcLine;
    4568         RECT rcRgn;
    4569         BOOL rev = es->bEnableState &&
    4570                                 ((es->flags & EF_FOCUSED) ||
    4571                                         (es->style & ES_NOHIDESEL));
     4600    PAINTSTRUCT ps;
     4601    INT i;
     4602    HDC dc;
     4603    HFONT old_font = 0;
     4604    RECT rc;
     4605    RECT rcLine;
     4606    RECT rcRgn;
     4607    BOOL rev = es->bEnableState &&
     4608                ((es->flags & EF_FOCUSED) ||
     4609                    (es->style & ES_NOHIDESEL));
    45724610        if (!wParam)
    45734611            dc = BeginPaint(hwnd, &ps);
    45744612        else
    45754613            dc = (HDC) wParam;
    4576         if(es->style & WS_BORDER) {
    4577                 GetClientRect(hwnd, &rc);
    4578                 if(es->style & ES_MULTILINE) {
    4579                         if(es->style & WS_HSCROLL) rc.bottom++;
    4580                         if(es->style & WS_VSCROLL) rc.right++;
    4581                 }
    4582                 Rectangle(dc, rc.left, rc.top, rc.right, rc.bottom);
    4583         }
    4584         IntersectClipRect(dc, es->format_rect.left,
    4585                                 es->format_rect.top,
    4586                                 es->format_rect.right,
    4587                                 es->format_rect.bottom);
    4588         if (es->style & ES_MULTILINE) {
    4589                 GetClientRect(hwnd, &rc);
    4590                 IntersectClipRect(dc, rc.left, rc.top, rc.right, rc.bottom);
    4591         }
    4592         if (es->font)
    4593                 old_font = SelectObject(dc, es->font);
     4614    if(es->style & WS_BORDER) {
     4615        GetClientRect(hwnd, &rc);
     4616        if(es->style & ES_MULTILINE) {
     4617            if(es->style & WS_HSCROLL) rc.bottom++;
     4618            if(es->style & WS_VSCROLL) rc.right++;
     4619        }
     4620        Rectangle(dc, rc.left, rc.top, rc.right, rc.bottom);
     4621    }
     4622    IntersectClipRect(dc, es->format_rect.left,
     4623                es->format_rect.top,
     4624                es->format_rect.right,
     4625                es->format_rect.bottom);
     4626    if (es->style & ES_MULTILINE) {
     4627        GetClientRect(hwnd, &rc);
     4628        IntersectClipRect(dc, rc.left, rc.top, rc.right, rc.bottom);
     4629    }
     4630    if (es->font)
     4631        old_font = SelectObject(dc, es->font);
    45944632        if ( get_app_version() >= 0x40000 &&(
    45954633                    !es->bEnableState || (es->style & ES_READONLY)))
     
    45984636                EDIT_SEND_CTLCOLOR(hwnd, dc);
    45994637
    4600         if (!es->bEnableState)
    4601                 SetTextColor(dc, GetSysColor(COLOR_GRAYTEXT));
    4602         GetClipBox(dc, &rcRgn);
    4603         if (es->style & ES_MULTILINE) {
    4604                 INT vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
    4605                 for (i = es->y_offset ; i <= min(es->y_offset + vlc, es->y_offset + es->line_count - 1) ; i++) {
    4606                         EDIT_GetLineRect(hwnd, es, i, 0, -1, &rcLine);
    4607                         if (IntersectRect(&rc, &rcRgn, &rcLine))
    4608                                 EDIT_PaintLine(hwnd, es, dc, i, rev);
    4609                 }
    4610         } else {
    4611                 EDIT_GetLineRect(hwnd, es, 0, 0, -1, &rcLine);
    4612                 if (IntersectRect(&rc, &rcRgn, &rcLine))
    4613                         EDIT_PaintLine(hwnd, es, dc, 0, rev);
    4614         }
    4615         if (es->font)
    4616                 SelectObject(dc, old_font);
     4638    if (!es->bEnableState)
     4639        SetTextColor(dc, GetSysColor(COLOR_GRAYTEXT));
     4640    GetClipBox(dc, &rcRgn);
     4641    if (es->style & ES_MULTILINE) {
     4642        INT vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
     4643        for (i = es->y_offset ; i <= min(es->y_offset + vlc, es->y_offset + es->line_count - 1) ; i++) {
     4644            EDIT_GetLineRect(hwnd, es, i, 0, -1, &rcLine);
     4645            if (IntersectRect(&rc, &rcRgn, &rcLine))
     4646                EDIT_PaintLine(hwnd, es, dc, i, rev);
     4647        }
     4648    } else {
     4649        EDIT_GetLineRect(hwnd, es, 0, 0, -1, &rcLine);
     4650        if (IntersectRect(&rc, &rcRgn, &rcLine))
     4651            EDIT_PaintLine(hwnd, es, dc, 0, rev);
     4652    }
     4653    if (es->font)
     4654        SelectObject(dc, old_font);
    46174655
    46184656        if (!wParam)
     
    46234661/*********************************************************************
    46244662 *
    4625  *      WM_PASTE
     4663 *  WM_PASTE
    46264664 *
    46274665 */
    46284666static void EDIT_WM_Paste(HWND hwnd, EDITSTATE *es)
    46294667{
    4630         HGLOBAL hsrc;
    4631         LPWSTR src;
    4632 
    4633         /* Protect read-only edit control from modification */
    4634         if(es->style & ES_READONLY)
    4635             return;
    4636 
    4637         OpenClipboard(hwnd);
    4638         if ((hsrc = GetClipboardData(CF_UNICODETEXT))) {
    4639                 src = (LPWSTR)GlobalLock(hsrc);
    4640                 EDIT_EM_ReplaceSel(hwnd, es, TRUE, src, TRUE);
    4641                 GlobalUnlock(hsrc);
    4642         }
    4643         CloseClipboard();
    4644 }
    4645 
    4646 
    4647 /*********************************************************************
    4648  *
    4649  *      WM_SETFOCUS
     4668    HGLOBAL hsrc;
     4669    LPWSTR src;
     4670
     4671    /* Protect read-only edit control from modification */
     4672    if(es->style & ES_READONLY)
     4673        return;
     4674
     4675    OpenClipboard(hwnd);
     4676    if ((hsrc = GetClipboardData(CF_UNICODETEXT))) {
     4677        src = (LPWSTR)GlobalLock(hsrc);
     4678        EDIT_EM_ReplaceSel(hwnd, es, TRUE, src, TRUE);
     4679        GlobalUnlock(hsrc);
     4680    }
     4681    CloseClipboard();
     4682}
     4683
     4684
     4685/*********************************************************************
     4686 *
     4687 *  WM_SETFOCUS
    46504688 *
    46514689 */
    46524690static void EDIT_WM_SetFocus(HWND hwnd, EDITSTATE *es)
    46534691{
    4654         es->flags |= EF_FOCUSED;
    4655         CreateCaret(hwnd, 0, 2, es->line_height);
    4656         EDIT_SetCaretPos(hwnd, es, es->selection_end,
    4657                         es->flags & EF_AFTER_WRAP);
    4658         if(!(es->style & ES_NOHIDESEL))
    4659                 EDIT_InvalidateText(hwnd, es, es->selection_start, es->selection_end);
    4660         ShowCaret(hwnd);
    4661         EDIT_NOTIFY_PARENT(hwnd, es, EN_SETFOCUS, "EN_SETFOCUS");
    4662 }
    4663 
    4664 
    4665 /*********************************************************************
    4666  *
    4667  *      WM_SETFONT
     4692    es->flags |= EF_FOCUSED;
     4693    CreateCaret(hwnd, 0, 2, es->line_height);
     4694    EDIT_SetCaretPos(hwnd, es, es->selection_end,
     4695            es->flags & EF_AFTER_WRAP);
     4696    if(!(es->style & ES_NOHIDESEL))
     4697        EDIT_InvalidateText(hwnd, es, es->selection_start, es->selection_end);
     4698    ShowCaret(hwnd);
     4699    EDIT_NOTIFY_PARENT(hwnd, es, EN_SETFOCUS, "EN_SETFOCUS");
     4700}
     4701
     4702
     4703/*********************************************************************
     4704 *
     4705 *  WM_SETFONT
    46684706 *
    46694707 * With Win95 look the margins are set to default font value unless
     
    46744712static void EDIT_WM_SetFont(HWND hwnd, EDITSTATE *es, HFONT font, BOOL redraw)
    46754713{
    4676         TEXTMETRICW tm;
    4677         HDC dc;
    4678         HFONT old_font = 0;
    4679         RECT r;
    4680 
    4681         es->font = font;
    4682         dc = GetDC(hwnd);
    4683         if (font)
    4684                 old_font = SelectObject(dc, font);
    4685         GetTextMetricsW(dc, &tm);
    4686         es->line_height = tm.tmHeight;
    4687         es->char_width = tm.tmAveCharWidth;
    4688         if (font)
    4689                 SelectObject(dc, old_font);
    4690         ReleaseDC(hwnd, dc);
    4691         if (font && (TWEAK_WineLook > WIN31_LOOK))
    4692                 EDIT_EM_SetMargins(es, EC_LEFTMARGIN | EC_RIGHTMARGIN,
    4693                                    EC_USEFONTINFO, EC_USEFONTINFO);
    4694 
    4695         /* Force the recalculation of the format rect for each font change */
    4696         GetClientRect(hwnd, &r);
    4697         EDIT_SetRectNP(hwnd, es, &r);
    4698 
    4699         if (es->style & ES_MULTILINE)
    4700                 EDIT_BuildLineDefs_ML(hwnd, es, 0, strlenW(es->text), 0, (HRGN)0);
    4701         else
    4702             EDIT_CalcLineWidth_SL(hwnd, es);
    4703 
    4704         if (redraw)
    4705                 EDIT_UpdateText(hwnd, es, NULL, TRUE);
    4706         if (es->flags & EF_FOCUSED) {
    4707                 DestroyCaret();
    4708                 CreateCaret(hwnd, 0, 2, es->line_height);
    4709                 EDIT_SetCaretPos(hwnd, es, es->selection_end,
    4710                                 es->flags & EF_AFTER_WRAP);
    4711                 ShowCaret(hwnd);
    4712         }
    4713 }
    4714 
    4715 
    4716 /*********************************************************************
    4717  *
    4718  *      WM_SETTEXT
     4714    TEXTMETRICW tm;
     4715    HDC dc;
     4716    HFONT old_font = 0;
     4717    RECT r;
     4718
     4719    es->font = font;
     4720    dc = GetDC(hwnd);
     4721    if (font)
     4722        old_font = SelectObject(dc, font);
     4723    GetTextMetricsW(dc, &tm);
     4724    es->line_height = tm.tmHeight;
     4725    es->char_width = tm.tmAveCharWidth;
     4726    if (font)
     4727        SelectObject(dc, old_font);
     4728    ReleaseDC(hwnd, dc);
     4729    if (font && (TWEAK_WineLook > WIN31_LOOK))
     4730        EDIT_EM_SetMargins(es, EC_LEFTMARGIN | EC_RIGHTMARGIN,
     4731                   EC_USEFONTINFO, EC_USEFONTINFO);
     4732
     4733    /* Force the recalculation of the format rect for each font change */
     4734    GetClientRect(hwnd, &r);
     4735    EDIT_SetRectNP(hwnd, es, &r);
     4736
     4737    if (es->style & ES_MULTILINE)
     4738        EDIT_BuildLineDefs_ML(hwnd, es, 0, strlenW(es->text), 0, (HRGN)0);
     4739    else
     4740        EDIT_CalcLineWidth_SL(hwnd, es);
     4741
     4742    if (redraw)
     4743        EDIT_UpdateText(hwnd, es, NULL, TRUE);
     4744    if (es->flags & EF_FOCUSED) {
     4745        DestroyCaret();
     4746        CreateCaret(hwnd, 0, 2, es->line_height);
     4747        EDIT_SetCaretPos(hwnd, es, es->selection_end,
     4748                es->flags & EF_AFTER_WRAP);
     4749        ShowCaret(hwnd);
     4750    }
     4751}
     4752
     4753
     4754/*********************************************************************
     4755 *
     4756 *  WM_SETTEXT
    47194757 *
    47204758 * NOTES
     
    47314769
    47324770    if(unicode)
    4733         text = (LPWSTR)lParam;
     4771    text = (LPWSTR)lParam;
    47344772    else if (lParam)
    47354773    {
    4736         LPCSTR textA = (LPCSTR)lParam;
    4737         INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0);
    4738         if((text = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR))))
    4739             MultiByteToWideChar(CP_ACP, 0, textA, -1, text, countW);
    4740     }
    4741 
    4742         EDIT_EM_SetSel(hwnd, es, 0, (UINT)-1, FALSE);
    4743         if (text) {
    4744                 TRACE("%s\n", debugstr_w(text));
    4745                 EDIT_EM_ReplaceSel(hwnd, es, FALSE, text, FALSE);
    4746                 if(!unicode)
    4747                     HeapFree(GetProcessHeap(), 0, text);
    4748         } else {
    4749                 static const WCHAR empty_stringW[] = {0};
    4750                 TRACE("<NULL>\n");
    4751                 EDIT_EM_ReplaceSel(hwnd, es, FALSE, empty_stringW, FALSE);
    4752         }
    4753         es->x_offset = 0;
    4754         es->flags &= ~EF_MODIFIED;
    4755         EDIT_EM_SetSel(hwnd, es, 0, 0, FALSE);
     4774    LPCSTR textA = (LPCSTR)lParam;
     4775    INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0);
     4776    if((text = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR))))
     4777        MultiByteToWideChar(CP_ACP, 0, textA, -1, text, countW);
     4778    }
     4779
     4780    EDIT_EM_SetSel(hwnd, es, 0, (UINT)-1, FALSE);
     4781    if (text) {
     4782        TRACE("%s\n", debugstr_w(text));
     4783        EDIT_EM_ReplaceSel(hwnd, es, FALSE, text, FALSE);
     4784        if(!unicode)
     4785            HeapFree(GetProcessHeap(), 0, text);
     4786    } else {
     4787        static const WCHAR empty_stringW[] = {0};
     4788        TRACE("<NULL>\n");
     4789        EDIT_EM_ReplaceSel(hwnd, es, FALSE, empty_stringW, FALSE);
     4790    }
     4791    es->x_offset = 0;
     4792    es->flags &= ~EF_MODIFIED;
     4793    EDIT_EM_SetSel(hwnd, es, 0, 0, FALSE);
    47564794        /* Send the notification after the selection start and end have been set
    47574795         * edit control doesn't send notification on WM_SETTEXT
    47584796         * if it is multiline, or it is part of combobox
    47594797         */
    4760         if( !((es->style & ES_MULTILINE) || es->hwndListBox))
     4798    if( !((es->style & ES_MULTILINE) || es->hwndListBox))
    47614799       {
    4762             EDIT_NOTIFY_PARENT(hwnd, es, EN_CHANGE, "EN_CHANGE");
     4800        EDIT_NOTIFY_PARENT(hwnd, es, EN_CHANGE, "EN_CHANGE");
    47634801           EDIT_NOTIFY_PARENT(hwnd, es, EN_UPDATE, "EN_UPDATE");
    47644802       }
    4765         EDIT_EM_ScrollCaret(hwnd, es);
    4766 }
    4767 
    4768 
    4769 /*********************************************************************
    4770  *
    4771  *      WM_SIZE
     4803    EDIT_EM_ScrollCaret(hwnd, es);
     4804}
     4805
     4806
     4807/*********************************************************************
     4808 *
     4809 *  WM_SIZE
    47724810 *
    47734811 */
    47744812static void EDIT_WM_Size(HWND hwnd, EDITSTATE *es, UINT action, INT width, INT height)
    47754813{
    4776         if ((action == SIZE_MAXIMIZED) || (action == SIZE_RESTORED)) {
    4777                 RECT rc;
    4778                 TRACE("width = %d, height = %d\n", width, height);
    4779                 SetRect(&rc, 0, 0, width, height);
    4780                 EDIT_SetRectNP(hwnd, es, &rc);
    4781                 EDIT_UpdateText(hwnd, es, NULL, TRUE);
    4782         }
    4783 }
    4784 
    4785 
    4786 /*********************************************************************
    4787  *
    4788  *      WM_STYLECHANGED
     4814    if ((action == SIZE_MAXIMIZED) || (action == SIZE_RESTORED)) {
     4815        RECT rc;
     4816        TRACE("width = %d, height = %d\n", width, height);
     4817        SetRect(&rc, 0, 0, width, height);
     4818        EDIT_SetRectNP(hwnd, es, &rc);
     4819        EDIT_UpdateText(hwnd, es, NULL, TRUE);
     4820    }
     4821}
     4822
     4823
     4824/*********************************************************************
     4825 *
     4826 *  WM_STYLECHANGED
    47894827 *
    47904828 * This message is sent by SetWindowLong on having changed either the Style
     
    48464884/*********************************************************************
    48474885 *
    4848  *      WM_SYSKEYDOWN
     4886 *  WM_SYSKEYDOWN
    48494887 *
    48504888 */
    48514889static LRESULT EDIT_WM_SysKeyDown(HWND hwnd, EDITSTATE *es, INT key, DWORD key_data)
    48524890{
    4853         if ((key == VK_BACK) && (key_data & 0x2000)) {
    4854                 if (EDIT_EM_CanUndo(es))
    4855                         EDIT_EM_Undo(hwnd, es);
    4856                 return 0;
    4857         } else if (key == VK_UP || key == VK_DOWN) {
    4858                 if (EDIT_CheckCombo(hwnd, es, WM_SYSKEYDOWN, key))
    4859                         return 0;
    4860         }
    4861         return DefWindowProcW(hwnd, WM_SYSKEYDOWN, (WPARAM)key, (LPARAM)key_data);
    4862 }
    4863 
    4864 
    4865 /*********************************************************************
    4866  *
    4867  *      WM_TIMER
     4891    if ((key == VK_BACK) && (key_data & 0x2000)) {
     4892        if (EDIT_EM_CanUndo(es))
     4893            EDIT_EM_Undo(hwnd, es);
     4894        return 0;
     4895    } else if (key == VK_UP || key == VK_DOWN) {
     4896        if (EDIT_CheckCombo(hwnd, es, WM_SYSKEYDOWN, key))
     4897            return 0;
     4898    }
     4899    return DefWindowProcW(hwnd, WM_SYSKEYDOWN, (WPARAM)key, (LPARAM)key_data);
     4900}
     4901
     4902
     4903/*********************************************************************
     4904 *
     4905 *  WM_TIMER
    48684906 *
    48694907 */
    48704908static void EDIT_WM_Timer(HWND hwnd, EDITSTATE *es)
    48714909{
    4872         if (es->region_posx < 0) {
    4873                 EDIT_MoveBackward(hwnd, es, TRUE);
    4874         } else if (es->region_posx > 0) {
    4875                 EDIT_MoveForward(hwnd, es, TRUE);
    4876         }
     4910    if (es->region_posx < 0) {
     4911        EDIT_MoveBackward(hwnd, es, TRUE);
     4912    } else if (es->region_posx > 0) {
     4913        EDIT_MoveForward(hwnd, es, TRUE);
     4914    }
    48774915/*
    4878  *      FIXME: gotta do some vertical scrolling here, like
    4879  *              EDIT_EM_LineScroll(hwnd, 0, 1);
    4880  */
    4881 }
    4882 
    4883 /*********************************************************************
    4884  *
    4885  *      WM_VSCROLL
     4916 *  FIXME: gotta do some vertical scrolling here, like
     4917 *      EDIT_EM_LineScroll(hwnd, 0, 1);
     4918 */
     4919}
     4920
     4921/*********************************************************************
     4922 *
     4923 *  WM_VSCROLL
    48864924 *
    48874925 */
    48884926static LRESULT EDIT_WM_VScroll(HWND hwnd, EDITSTATE *es, INT action, INT pos)
    48894927{
    4890         INT dy;
    4891 
    4892         if (!(es->style & ES_MULTILINE))
    4893                 return 0;
    4894 
    4895         if (!(es->style & ES_AUTOVSCROLL))
    4896                 return 0;
    4897 
    4898         dy = 0;
    4899         switch (action) {
    4900         case SB_LINEUP:
    4901         case SB_LINEDOWN:
    4902         case SB_PAGEUP:
    4903         case SB_PAGEDOWN:
    4904                 TRACE("action %d\n", action);
    4905                 EDIT_EM_Scroll(hwnd, es, action);
    4906                 return 0;
    4907         case SB_TOP:
    4908                 TRACE("SB_TOP\n");
    4909                 dy = -es->y_offset;
    4910                 break;
    4911         case SB_BOTTOM:
    4912                 TRACE("SB_BOTTOM\n");
    4913                 dy = es->line_count - 1 - es->y_offset;
    4914                 break;
    4915         case SB_THUMBTRACK:
    4916                 TRACE("SB_THUMBTRACK %d\n", pos);
    4917                 es->flags |= EF_VSCROLL_TRACK;
    4918                 if(es->style & WS_VSCROLL)
    4919                     dy = pos - es->y_offset;
    4920                 else
    4921                 {
    4922                     /* Assume default scroll range 0-100 */
    4923                     INT vlc, new_y;
    4924                     /* Sanity check */
    4925                     if(pos < 0 || pos > 100) return 0;
    4926                     vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
    4927                     new_y = pos * (es->line_count - vlc) / 100;
    4928                     dy = es->line_count ? (new_y - es->y_offset) : 0;
    4929                     TRACE("line_count=%d, y_offset=%d, pos=%d, dy = %d\n",
    4930                             es->line_count, es->y_offset, pos, dy);
    4931                 }
    4932                 break;
    4933         case SB_THUMBPOSITION:
    4934                 TRACE("SB_THUMBPOSITION %d\n", pos);
    4935                 es->flags &= ~EF_VSCROLL_TRACK;
    4936                 if(es->style & WS_VSCROLL)
    4937                     dy = pos - es->y_offset;
    4938                 else
    4939                 {
    4940                     /* Assume default scroll range 0-100 */
    4941                     INT vlc, new_y;
    4942                     /* Sanity check */
    4943                     if(pos < 0 || pos > 100) return 0;
    4944                     vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
    4945                     new_y = pos * (es->line_count - vlc) / 100;
    4946                     dy = es->line_count ? (new_y - es->y_offset) : 0;
    4947                     TRACE("line_count=%d, y_offset=%d, pos=%d, dy = %d\n",
    4948                             es->line_count, es->y_offset, pos, dy);
    4949                 }
    4950                 if (!dy)
    4951                 {
    4952                         /* force scroll info update */
    4953                         EDIT_UpdateScrollInfo(hwnd, es);
    4954                         EDIT_NOTIFY_PARENT(hwnd, es, EN_VSCROLL, "EN_VSCROLL");
    4955                 }
    4956                 break;
    4957         case SB_ENDSCROLL:
    4958                 TRACE("SB_ENDSCROLL\n");
    4959                 break;
    4960         /*
    4961          *      FIXME : the next two are undocumented !
    4962          *      Are we doing the right thing ?
    4963          *      At least Win 3.1 Notepad makes use of EM_GETTHUMB this way,
    4964          *      although it's also a regular control message.
    4965         */
    4966         case EM_GETTHUMB: /* this one is used by NT notepad */
    4967         case EM_GETTHUMB16:
    4968         {
    4969                 LRESULT ret;
    4970                 if(GetWindowLongA( hwnd, GWL_STYLE ) & WS_VSCROLL)
    4971                     ret = GetScrollPos(hwnd, SB_VERT);
    4972                 else
    4973                 {
    4974                     /* Assume default scroll range 0-100 */
    4975                     INT vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
    4976                     ret = es->line_count ? es->y_offset * 100 / (es->line_count - vlc) : 0;
    4977                 }
    4978                 TRACE("EM_GETTHUMB: returning %ld\n", ret);
    4979                 return ret;
    4980         }
    4981         case EM_LINESCROLL16:
    4982                 TRACE("EM_LINESCROLL16 %d\n", pos);
    4983                 dy = pos;
    4984                 break;
    4985 
    4986         default:
    4987                 ERR("undocumented WM_VSCROLL action %d (0x%04x), please report\n",
     4928    INT dy;
     4929
     4930    if (!(es->style & ES_MULTILINE))
     4931        return 0;
     4932
     4933    if (!(es->style & ES_AUTOVSCROLL))
     4934        return 0;
     4935
     4936    dy = 0;
     4937    switch (action) {
     4938    case SB_LINEUP:
     4939    case SB_LINEDOWN:
     4940    case SB_PAGEUP:
     4941    case SB_PAGEDOWN:
     4942        TRACE("action %d\n", action);
     4943        EDIT_EM_Scroll(hwnd, es, action);
     4944        return 0;
     4945    case SB_TOP:
     4946        TRACE("SB_TOP\n");
     4947        dy = -es->y_offset;
     4948        break;
     4949    case SB_BOTTOM:
     4950        TRACE("SB_BOTTOM\n");
     4951        dy = es->line_count - 1 - es->y_offset;
     4952        break;
     4953    case SB_THUMBTRACK:
     4954        TRACE("SB_THUMBTRACK %d\n", pos);
     4955        es->flags |= EF_VSCROLL_TRACK;
     4956        if(es->style & WS_VSCROLL)
     4957            dy = pos - es->y_offset;
     4958        else
     4959        {
     4960            /* Assume default scroll range 0-100 */
     4961            INT vlc, new_y;
     4962            /* Sanity check */
     4963            if(pos < 0 || pos > 100) return 0;
     4964            vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
     4965            new_y = pos * (es->line_count - vlc) / 100;
     4966            dy = es->line_count ? (new_y - es->y_offset) : 0;
     4967            TRACE("line_count=%d, y_offset=%d, pos=%d, dy = %d\n",
     4968                es->line_count, es->y_offset, pos, dy);
     4969        }
     4970        break;
     4971    case SB_THUMBPOSITION:
     4972        TRACE("SB_THUMBPOSITION %d\n", pos);
     4973        es->flags &= ~EF_VSCROLL_TRACK;
     4974        if(es->style & WS_VSCROLL)
     4975            dy = pos - es->y_offset;
     4976        else
     4977        {
     4978            /* Assume default scroll range 0-100 */
     4979            INT vlc, new_y;
     4980            /* Sanity check */
     4981            if(pos < 0 || pos > 100) return 0;
     4982            vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
     4983            new_y = pos * (es->line_count - vlc) / 100;
     4984            dy = es->line_count ? (new_y - es->y_offset) : 0;
     4985            TRACE("line_count=%d, y_offset=%d, pos=%d, dy = %d\n",
     4986                es->line_count, es->y_offset, pos, dy);
     4987        }
     4988        if (!dy)
     4989        {
     4990            /* force scroll info update */
     4991            EDIT_UpdateScrollInfo(hwnd, es);
     4992            EDIT_NOTIFY_PARENT(hwnd, es, EN_VSCROLL, "EN_VSCROLL");
     4993        }
     4994        break;
     4995    case SB_ENDSCROLL:
     4996        TRACE("SB_ENDSCROLL\n");
     4997        break;
     4998    /*
     4999     *  FIXME : the next two are undocumented !
     5000     *  Are we doing the right thing ?
     5001     *  At least Win 3.1 Notepad makes use of EM_GETTHUMB this way,
     5002     *  although it's also a regular control message.
     5003    */
     5004    case EM_GETTHUMB: /* this one is used by NT notepad */
     5005    case EM_GETTHUMB16:
     5006    {
     5007        LRESULT ret;
     5008        if(GetWindowLongA( hwnd, GWL_STYLE ) & WS_VSCROLL)
     5009            ret = GetScrollPos(hwnd, SB_VERT);
     5010        else
     5011        {
     5012            /* Assume default scroll range 0-100 */
     5013            INT vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
     5014            ret = es->line_count ? es->y_offset * 100 / (es->line_count - vlc) : 0;
     5015        }
     5016        TRACE("EM_GETTHUMB: returning %ld\n", ret);
     5017        return ret;
     5018    }
     5019    case EM_LINESCROLL16:
     5020        TRACE("EM_LINESCROLL16 %d\n", pos);
     5021        dy = pos;
     5022        break;
     5023
     5024    default:
     5025        ERR("undocumented WM_VSCROLL action %d (0x%04x), please report\n",
    49885026                    action, action);
    4989                 return 0;
    4990         }
    4991         if (dy)
    4992                 EDIT_EM_LineScroll(hwnd, es, 0, dy);
    4993         return 0;
    4994 }
    4995 
    4996 /*********************************************************************
    4997  *
    4998  *      EDIT_UpdateText
     5027        return 0;
     5028    }
     5029    if (dy)
     5030        EDIT_EM_LineScroll(hwnd, es, 0, dy);
     5031    return 0;
     5032}
     5033
     5034/*********************************************************************
     5035 *
     5036 *  EDIT_UpdateText
    49995037 *
    50005038 */
     
    50085046/*********************************************************************
    50095047 *
    5010  *      EDIT_UpdateText
     5048 *  EDIT_UpdateText
    50115049 *
    50125050 */
  • trunk/src/user32/listbox.c

    r9619 r10195  
    7878    BOOL        caret_on;       /* Is caret on? */
    7979    BOOL        captured;       /* Is mouse captured? */
    80     BOOL        in_focus;
     80    BOOL    in_focus;
    8181    HFONT       font;           /* Current font */
    8282    LCID          locale;         /* Current locale for string comparisons */
    83     LPHEADCOMBO   lphc;           /* ComboLBox */
     83    LPHEADCOMBO   lphc;       /* ComboLBox */
    8484} LB_DESCR;
    8585
     
    151151
    152152#ifdef __WIN32OS2__
    153 #define is_old_app( hwnd )      0
     153#define is_old_app( hwnd )  0
    154154#else
    155155/* check whether app is a Win 3.1 app */
     
    550550        UINT id = GetWindowLongA( hwnd, GWL_ID );
    551551
    552         if (!item)
    553         {
    554             if (action == ODA_FOCUS)
    555                 DrawFocusRect( hdc, rect );
    556             else
    557                 FIXME("called with an out of bounds index %d(%d) in owner draw, Not good.\n",index,descr->nb_items);
    558             return;
    559         }
     552    if (!item)
     553    {
     554        if (action == ODA_FOCUS)
     555        DrawFocusRect( hdc, rect );
     556        else
     557            FIXME("called with an out of bounds index %d(%d) in owner draw, Not good.\n",index,descr->nb_items);
     558        return;
     559    }
    560560
    561561        /* some programs mess with the clipping region when
     
    613613                         strlenW(item->str), NULL );
    614614        else
    615         {
    616             /* Output empty string to paint background in the full width. */
     615    {
     616        /* Output empty string to paint background in the full width. */
    617617            ExtTextOutW( hdc, rect->left + 1, rect->top,
    618618                         ETO_OPAQUE | ETO_CLIPPED, rect, NULL, 0, NULL );
     
    620620                            item->str, strlenW(item->str),
    621621                            descr->nb_tabs, descr->tabs, 0);
    622         }
     622    }
    623623        if (item && item->selected)
    624624        {
     
    742742        TRACE("[%04x]: settabstops ", hwnd );
    743743        for (i = 0; i < descr->nb_tabs; i++) {
    744             descr->tabs[i] = *p++<<1; /* FIXME */
     744        descr->tabs[i] = *p++<<1; /* FIXME */
    745745            if (TRACE_ON(listbox)) DPRINTF("%hd ", descr->tabs[i]);
    746         }
     746    }
    747747        if (TRACE_ON(listbox)) DPRINTF("\n");
    748748    }
     
    764764            return strlenW(descr->items[index].str);
    765765
    766         TRACE("index %d (0x%04x) %s\n", index, index, debugstr_w(descr->items[index].str));
     766    TRACE("index %d (0x%04x) %s\n", index, index, debugstr_w(descr->items[index].str));
    767767
    768768        if(unicode)
     
    10311031        if (i == descr->focus_item)
    10321032        {
    1033             /* keep the focus rect, to paint the focus item after */
    1034             focusRect.left = rect.left;
    1035             focusRect.right = rect.right;
    1036             focusRect.top = rect.top;
    1037             focusRect.bottom = rect.bottom;
     1033        /* keep the focus rect, to paint the focus item after */
     1034        focusRect.left = rect.left;
     1035        focusRect.right = rect.right;
     1036        focusRect.top = rect.top;
     1037        focusRect.bottom = rect.bottom;
    10381038        }
    10391039        LISTBOX_PaintItem( hwnd, descr, hdc, &rect, i, ODA_DRAWENTIRE, TRUE );
     
    11541154        descr->items[index].height = height;
    11551155        LISTBOX_UpdateScroll( hwnd, descr );
    1156         if (repaint)
    1157             LISTBOX_InvalidateItems( hwnd, descr, index );
     1156    if (repaint)
     1157        LISTBOX_InvalidateItems( hwnd, descr, index );
    11581158    }
    11591159    else if (height != descr->item_height)
     
    11631163        LISTBOX_UpdatePage( hwnd, descr );
    11641164        LISTBOX_UpdateScroll( hwnd, descr );
    1165         if (repaint)
    1166             InvalidateRect( hwnd, 0, TRUE );
     1165    if (repaint)
     1166        InvalidateRect( hwnd, 0, TRUE );
    11671167    }
    11681168    return LB_OKAY;
     
    13931393        if (send_notify && descr->nb_items) SEND_NOTIFICATION( hwnd, descr,
    13941394                               (index != -1) ? LBN_SELCHANGE : LBN_SELCANCEL );
    1395         else
    1396             if( descr->lphc ) /* set selection change flag for parent combo */
    1397                 descr->lphc->wState |= CBF_SELCHANGE;
     1395    else
     1396        if( descr->lphc ) /* set selection change flag for parent combo */
     1397        descr->lphc->wState |= CBF_SELCHANGE;
    13981398    }
    13991399    return LB_OKAY;
     
    17501750                {
    17511751#ifdef __WIN32OS2__
    1752 //SvL: Must check for FILE_ATTRIBUTE_NORMAL or else files are removed from 
     1752//SvL: Must check for FILE_ATTRIBUTE_NORMAL or else files are removed from
    17531753//     the directory listing in common file dialogs
    17541754#define ATTRIBS (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | \
     
    20012001            POINT pt;
    20022002
    2003             pt.x = x;
    2004             pt.y = y;
     2003        pt.x = x;
     2004        pt.y = y;
    20052005
    20062006            if (DragDetect( hwnd, pt ))
     
    20722072#ifdef __WIN32OS2__
    20732073            COMBO_RollupListbox(pDescr->lphc);
    2074  
     2074
    20752075             /* @@PF Previous code is all wrong here. Here we are supposed to close
    20762076                and only close dropdown, instead flip, flips it. This happens because
    20772077                previous code did not pay attention to the fact that combobox can be
    2078                 closed with SendMessage by application, as MFC apps do     
     2078                closed with SendMessage by application, as MFC apps do
    20792079                COMBO_FlipListbox( pDescr->lphc, FALSE, FALSE ); */
    20802080#else
     
    23412341        if (descr->style & LBS_NOTIFY)
    23422342        {
    2343             if( descr->lphc )
     2343        if( descr->lphc )
    23442344            {
    2345                 /* make sure that combo parent doesn't hide us */
    2346                 descr->lphc->wState |= CBF_NOROLLUP;
    2347             }
     2345        /* make sure that combo parent doesn't hide us */
     2346        descr->lphc->wState |= CBF_NOROLLUP;
     2347        }
    23482348            if (descr->nb_items) SEND_NOTIFICATION( hwnd, descr, LBN_SELCHANGE );
    23492349        }
     
    24172417    descr->caret_on      = lphc ? FALSE : TRUE;
    24182418    if (descr->style & LBS_NOSEL) descr->caret_on = FALSE;
    2419     descr->in_focus     = FALSE;
     2419    descr->in_focus     = FALSE;
    24202420    descr->captured      = FALSE;
    24212421    descr->font          = 0;
    24222422    descr->locale        = 0;  /* FIXME */
    2423     descr->lphc          = lphc;
     2423    descr->lphc      = lphc;
    24242424
    24252425    if (is_old_app(hwnd) && ( descr->style & ( WS_VSCROLL | WS_HSCROLL ) ) )
    24262426    {
    2427         /* Win95 document "List Box Differences" from MSDN:
    2428            If a list box in a version 3.x application has either the
    2429            WS_HSCROLL or WS_VSCROLL style, the list box receives both
    2430            horizontal and vertical scroll bars.
    2431         */
    2432         descr->style |= WS_VSCROLL | WS_HSCROLL;
     2427    /* Win95 document "List Box Differences" from MSDN:
     2428       If a list box in a version 3.x application has either the
     2429       WS_HSCROLL or WS_VSCROLL style, the list box receives both
     2430       horizontal and vertical scroll bars.
     2431    */
     2432    descr->style |= WS_VSCROLL | WS_HSCROLL;
    24332433    }
    24342434
    24352435    if( lphc )
    24362436    {
    2437         TRACE_(combo)("[%04x]: resetting owner %04x -> %04x\n",
     2437    TRACE_(combo)("[%04x]: resetting owner %04x -> %04x\n",
    24382438                      hwnd, descr->owner, lphc->self );
    24392439        descr->owner = lphc->self;
     
    24512451    if (descr->style & LBS_OWNERDRAWFIXED)
    24522452    {
    2453         if( descr->lphc && (descr->lphc->dwStyle & CBS_DROPDOWN))
    2454         {
    2455             /* WinWord gets VERY unhappy if we send WM_MEASUREITEM from here */
    2456           descr->item_height = lphc->fixedOwnerDrawHeight;
    2457         }
    2458         else
    2459         {
     2453    if( descr->lphc && (descr->lphc->dwStyle & CBS_DROPDOWN))
     2454    {
     2455        /* WinWord gets VERY unhappy if we send WM_MEASUREITEM from here */
     2456      descr->item_height = lphc->fixedOwnerDrawHeight;
     2457    }
     2458    else
     2459    {
    24602460            UINT id = GetWindowLongA( hwnd, GWL_ID );
    24612461            mis.CtlType    = ODT_LISTBOX;
     
    24672467            SendMessageW( descr->owner, WM_MEASUREITEM, id, (LPARAM)&mis );
    24682468            descr->item_height = mis.itemHeight ? mis.itemHeight : 1;
    2469         }
     2469    }
    24702470    }
    24712471
     
    26312631    case LB_GETCURSEL:
    26322632        if (descr->nb_items==0)
    2633           return LB_ERR;
     2633      return LB_ERR;
    26342634        if (!IS_MULTISELECT(descr))
    26352635          return descr->selected_item;
    2636         /* else */
    2637         if (descr->selected_item!=-1)
    2638           return descr->selected_item;
    2639         /* else */
    2640         return descr->focus_item;
     2636    /* else */
     2637    if (descr->selected_item!=-1)
     2638      return descr->selected_item;
     2639    /* else */
     2640    return descr->focus_item;
    26412641        /* otherwise, if the user tries to move the selection with the    */
    26422642        /* arrow keys, we will give the application something to choke on */
     
    26602660            RECT rect;
    26612661
    2662             pt.x = LOWORD(lParam);
    2663             pt.y = HIWORD(lParam);
    2664             rect.left = 0;
    2665             rect.top = 0;
    2666             rect.right = descr->width;
    2667             rect.bottom = descr->height;
     2662        pt.x = LOWORD(lParam);
     2663        pt.y = HIWORD(lParam);
     2664        rect.left = 0;
     2665        rect.top = 0;
     2666        rect.right = descr->width;
     2667        rect.bottom = descr->height;
    26682668
    26692669            return MAKELONG( LISTBOX_GetItemFromPoint(descr, pt.x, pt.y),
     
    26992699            CONV_RECT32TO16( &rect, MapSL(lParam) );
    27002700        }
    2701         return ret;
     2701    return ret;
    27022702
    27032703    case LB_GETITEMRECT:
     
    27592759        LPWSTR textW;
    27602760
    2761         if(HAS_STRINGS(descr))
    2762             TRACE("LB_SELECTSTRING: %s\n", unicode ? debugstr_w((LPWSTR)lParam) :
    2763                                                      debugstr_a((LPSTR)lParam));
     2761    if(HAS_STRINGS(descr))
     2762        TRACE("LB_SELECTSTRING: %s\n", unicode ? debugstr_w((LPWSTR)lParam) :
     2763                             debugstr_a((LPSTR)lParam));
    27642764        if(unicode || !HAS_STRINGS(descr))
    27652765            textW = (LPWSTR)lParam;
     
    27752775            HeapFree(GetProcessHeap(), 0, textW);
    27762776        if (index != LB_ERR)
    2777         {
     2777    {
    27782778            LISTBOX_SetCaretIndex( hwnd, descr, index, TRUE );
    27792779            LISTBOX_SetSelection( hwnd, descr, index, TRUE, FALSE );
    2780         }
     2780    }
    27812781        return index;
    27822782    }
     
    28552855         * be set automatically (this is different in Win32) */
    28562856        if (wParam & DDL_DRIVES) wParam |= DDL_EXCLUSIVE;
    2857         lParam = (LPARAM)MapSL(lParam);
     2857    lParam = (LPARAM)MapSL(lParam);
    28582858        /* fall through */
    28592859    case LB_DIR:
     
    29922992    case WM_CHAR:
    29932993    {
     2994#ifdef __WIN32OS2__
     2995        static BOOL bDbcsLead = FALSE;
     2996        static CHAR cDbcsLead = 0;
     2997
    29942998        WCHAR charW;
    29952999        if(unicode)
     
    29973001        else
    29983002        {
     3003            WCHAR charA = bDbcsLead ? (( wParam << 8 ) | cDbcsLead ) : wParam;
     3004            int   size = bDbcsLead ? 2 : 1;
     3005
     3006            bDbcsLead = !bDbcsLead && IsDBCSLeadByte( wParam );
     3007
     3008            if( bDbcsLead )
     3009                cDbcsLead = wParam;
     3010            else
     3011                MultiByteToWideChar(CP_ACP, 0, (LPSTR)&charA, size, &charW, 1);
     3012        }
     3013        return bDbcsLead ? 0 : LISTBOX_HandleChar( hwnd, descr, charW );
     3014#else
     3015        WCHAR charW;
     3016        if(unicode)
     3017            charW = (WCHAR)wParam;
     3018        else
     3019        {
    29993020            CHAR charA = (CHAR)wParam;
    30003021            MultiByteToWideChar(CP_ACP, 0, &charA, 1, &charW, 1);
    30013022        }
    30023023        return LISTBOX_HandleChar( hwnd, descr, charW );
    3003     }
     3024#endif
     3025    }
     3026
    30043027    case WM_SYSTIMER:
    30053028        return LISTBOX_HandleSystemTimer( hwnd, descr );
     
    30103033            HBRUSH hbrush = SendMessageW( descr->owner, WM_CTLCOLORLISTBOX,
    30113034                                              wParam, (LPARAM)hwnd );
    3012             TRACE("hbrush = %04x\n", hbrush);
    3013             if(!hbrush)
    3014                 hbrush = GetSysColorBrush(COLOR_WINDOW);
    3015             if(hbrush)
    3016             {
    3017                 GetClientRect(hwnd, &rect);
    3018                 FillRect((HDC)wParam, &rect, hbrush);
    3019             }
     3035        TRACE("hbrush = %04x\n", hbrush);
     3036        if(!hbrush)
     3037        hbrush = GetSysColorBrush(COLOR_WINDOW);
     3038        if(hbrush)
     3039        {
     3040        GetClientRect(hwnd, &rect);
     3041        FillRect((HDC)wParam, &rect, hbrush);
     3042        }
    30203043        }
    30213044        return 1;
     
    30303053    case WM_DRAGSELECT:
    30313054    case WM_DRAGMOVE:
    3032         if( !descr->lphc )
     3055    if( !descr->lphc )
    30333056        {
    30343057            LPDRAGINFO16 dragInfo = MapSL( lParam );
     
    30373060            return SendMessage16( descr->owner, msg, wParam, lParam );
    30383061        }
    3039         break;
     3062    break;
    30403063
    30413064    default:
     
    32223245 *
    32233246 *  NOTE: in Windows, winproc address of the ComboLBox is the same
    3224  *        as that of the Listbox.
     3247 *    as that of the Listbox.
    32253248 */
    32263249LRESULT WINAPI ComboLBWndProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
Note: See TracChangeset for help on using the changeset viewer.