Author: tkreuzer
Date: Mon Jan 12 16:03:00 2009
New Revision: 38739
URL:
http://svn.reactos.org/svn/reactos?rev=38739&view=rev
Log:
Sync edit.c with wine head (Wine-1_1_12)
Reduces failures from 18 to 13 and test doesn't keep a window open anymore.
(Partly) revert 29649, 33848, 33909, 33910 as it's now implemented by wine
1.4 Francois Gouget <fgouget(a)free.fr>
Don't put single quotes around '%s' when using the debugstr_*() functions.
1.5 Huw Davies <huw(a)codeweavers.com>
user32: Keep track of whether the app has asked for the text buffer handle.
1.9 Dmitry Timoshkov <dmitry(a)codeweavers.com>
user32: Fix some compilation warnings in 64-bit mode.
1.15 Alexandre Julliard <julliard(a)winehq.org>
user32: Store the builtin class names in Unicode.
1.16 Andrew Talbot <andrew.talbot(a)talbotville.com>
user32: Constify some variables.
1.17 Gerald Pfeifer <gerald(a)pfeifer.com>
user32: Factor in EDIT_WM_EraseBkGnd().
1.18 Andrew Talbot <andrew.talbot(a)talbotville.com>
user32: Remove unneeded casts.
1.19 Marcus Meissner <marcus(a)jet.franken.de>
user32: Handle error returns from ImmGetCompositionString.
1.20 Lei Zhang <thestig(a)google.com>
user32: Tweak how the edit control handles WM_GETDLGCODE.
1.21 Lei Zhang <thestig(a)google.com>
user32: Handle WM_CHAR messages better in edit controls.
1.22 Lei Zhang <thestig(a)google.com>
user32: Correctly handle VK_RETURN for edit controls with ES_WANTRETURN style.
1.23 Lei Zhang <thestig(a)google.com>
user32: Fix WM_CHAR return value for edit controls.
1.24 Lei Zhang <thestig(a)google.com>
user32: Handle ES_MULTILINE correctly for WM_KEYDOWN/VK_RETURN.
1.25 Lei Zhang <thestig(a)google.com>
user32: Handle VK_ESCAPE correctly in EDIT_WM_KeyDown.
1.26 Lei Zhang <thestig(a)google.com>
user32: Add edit control check to see if its in a dialog on WM_CHAR/VK_RETURN.
1.27 Lei Zhang <thestig(a)google.com>
user32: Add edit control check to see if its in a dialog on WM_CHAR/VK_TAB.
1.28 Lei Zhang <thestig(a)google.com>
user32: Fix a typo.
1.29 Lei Zhang <thestig(a)google.com>
user32: Handle VK_TAB in EDIT_WM_KeyDown.
1.30 Lei Zhang <thestig(a)google.com>
user32: Do checks in the right order in EDIT_BuildLineDefs_ML.
1.31 Lei Zhang <thestig(a)google.com>
user32: Handle ctrl + home in edit control.
1.32 Lei Zhang <thestig(a)google.com>
user32: Handle ctrl + end in edit control.
1.33 Alexandre Julliard <julliard(a)winehq.org>
user32: Added support for WS_EX_RIGHT in the edit control.
1.34 Kusanagi Kouichi <slash(a)ma.neweb.ne.jp>
user32: Handle IME messages more gracefully.
1.35 Alexandre Julliard <julliard(a)winehq.org>
user32: Remove redundant LocalUnlock calls.
1.36 Austin English <austinenglish(a)gmail.com>
Spelling fixes.
1.37 Lei Zhang <thestig(a)google.com>
user32: Handle VK_RETURN WM_KEYDOWN events better in edit controls.
Elias Benali wrote the initial version of this patch.
1.38 Lei Zhang <thestig(a)google.com>
user32: Edit controls should ignore WM_KEYDOWN on control + enter.
1.39 Andrew Talbot <andrew.talbot(a)talbotville.com>
user32: Remove unused variables.
1.40 Hongbo Ni <hongbo(a)njstar.com>
user32: Implement WM_UNICHAR for edit control.
1.41 Lei Zhang <thestig(a)google.com>
user32: Send messages for edit control context menu operations.
1.42 Aric Stewart <aric(a)codeweavers.com>
user32: Make sure our vertical line count is at least 1 even if there is an oversized font
in the edit control.
1.43 Michael Stefaniuc <mstefani(a)redhat.de>
user32: Remove superfluous casts of void pointers.
1.44 Francois Gouget <fgouget(a)codeweavers.com>
user32: Remove WINAPI/CALLBACK on static functions where not needed.
Modified:
trunk/reactos/dll/win32/user32/controls/edit.c
trunk/reactos/dll/win32/user32/include/user32p.h
Modified: trunk/reactos/dll/win32/user32/controls/edit.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/controls/…
==============================================================================
--- trunk/reactos/dll/win32/user32/controls/edit.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/user32/controls/edit.c [iso-8859-1] Mon Jan 12 16:03:00 2009
@@ -24,7 +24,7 @@
*
* This code was audited for completeness against the documented features
* of Comctl32.dll version 6.0 on Oct. 8, 2004, by Dimitrie O. Paun.
- *
+ *
* Unless otherwise noted, we believe this code to be complete, as per
* the specification mentioned above.
* If you discover missing features, or bugs, please note them below.
@@ -171,12 +171,12 @@
/*
* These functions have trivial implementations
* We still like to call them internally
- * "static __inline" makes them more like macro's
- */
-static __inline BOOL EDIT_EM_CanUndo(EDITSTATE *es);
-static __inline void EDIT_EM_EmptyUndoBuffer(EDITSTATE *es);
-static __inline void EDIT_WM_Clear(EDITSTATE *es);
-static __inline void EDIT_WM_Cut(EDITSTATE *es);
+ * "static inline" makes them more like macro's
+ */
+static inline BOOL EDIT_EM_CanUndo(const EDITSTATE *es);
+static inline void EDIT_EM_EmptyUndoBuffer(EDITSTATE *es);
+static inline void EDIT_WM_Clear(EDITSTATE *es);
+static inline void EDIT_WM_Cut(EDITSTATE *es);
/*
* Helper functions only valid for one type of control
@@ -193,28 +193,26 @@
*/
static INT EDIT_CallWordBreakProc(EDITSTATE *es, INT start, INT index, INT count, INT
action);
static INT EDIT_CharFromPos(EDITSTATE *es, INT x, INT y, LPBOOL after_wrap);
-static void EDIT_ConfinePoint(EDITSTATE *es, LPINT x, LPINT y);
+static void EDIT_ConfinePoint(const EDITSTATE *es, LPINT x, LPINT y);
static void EDIT_GetLineRect(EDITSTATE *es, INT line, INT scol, INT ecol, LPRECT rc);
static void EDIT_InvalidateText(EDITSTATE *es, INT start, INT end);
static void EDIT_LockBuffer(EDITSTATE *es);
static BOOL EDIT_MakeFit(EDITSTATE *es, UINT size);
static BOOL EDIT_MakeUndoFit(EDITSTATE *es, UINT size);
static void EDIT_MoveBackward(EDITSTATE *es, BOOL extend);
-static void EDIT_MoveEnd(EDITSTATE *es, BOOL extend);
-static void EDIT_MoveEndOfText(EDITSTATE *es, BOOL extend);
+static void EDIT_MoveEnd(EDITSTATE *es, BOOL extend, BOOL ctrl);
static void EDIT_MoveForward(EDITSTATE *es, BOOL extend);
-static void EDIT_MoveStartOfText(EDITSTATE *es, BOOL extend);
-static void EDIT_MoveHome(EDITSTATE *es, BOOL extend);
+static void EDIT_MoveHome(EDITSTATE *es, BOOL extend, BOOL ctrl);
static void EDIT_MoveWordBackward(EDITSTATE *es, BOOL extend);
static void EDIT_MoveWordForward(EDITSTATE *es, BOOL extend);
static void EDIT_PaintLine(EDITSTATE *es, HDC hdc, INT line, BOOL rev);
static INT EDIT_PaintText(EDITSTATE *es, HDC hdc, INT x, INT y, INT line, INT col, INT
count, BOOL rev);
static void EDIT_SetCaretPos(EDITSTATE *es, INT pos, BOOL after_wrap);
static void EDIT_AdjustFormatRect(EDITSTATE *es);
-static void EDIT_SetRectNP(EDITSTATE *es, LPRECT lprc);
+static void EDIT_SetRectNP(EDITSTATE *es, const RECT *lprc);
static void EDIT_UnlockBuffer(EDITSTATE *es, BOOL force);
static void EDIT_UpdateScrollInfo(EDITSTATE *es);
-static INT CALLBACK EDIT_WordBreakProc(LPWSTR s, INT index, INT count, INT action);
+static INT EDIT_WordBreakProc(LPWSTR s, INT index, INT count, INT action);
/*
* EM_XXX message handlers
*/
@@ -225,10 +223,10 @@
static HLOCAL16 EDIT_EM_GetHandle16(EDITSTATE *es);
#endif
static INT EDIT_EM_GetLine(EDITSTATE *es, INT line, LPWSTR dst, BOOL unicode);
-static LRESULT EDIT_EM_GetSel(EDITSTATE *es, PUINT start, PUINT end);
+static LRESULT EDIT_EM_GetSel(const EDITSTATE *es, PUINT start, PUINT end);
static LRESULT EDIT_EM_GetThumb(EDITSTATE *es);
static INT EDIT_EM_LineFromChar(EDITSTATE *es, INT index);
-static INT EDIT_EM_LineIndex(EDITSTATE *es, INT line);
+static INT EDIT_EM_LineIndex(const EDITSTATE *es, INT line);
static INT EDIT_EM_LineLength(EDITSTATE *es, INT index);
static BOOL EDIT_EM_LineScroll(EDITSTATE *es, INT dx, INT dy);
static BOOL EDIT_EM_LineScroll_internal(EDITSTATE *es, INT dx, INT dy);
@@ -244,9 +242,9 @@
static void EDIT_EM_SetMargins(EDITSTATE *es, INT action, WORD left, WORD right, BOOL
repaint);
static void EDIT_EM_SetPasswordChar(EDITSTATE *es, WCHAR c);
static void EDIT_EM_SetSel(EDITSTATE *es, UINT start, UINT end, BOOL after_wrap);
-static BOOL EDIT_EM_SetTabStops(EDITSTATE *es, INT count, LPINT tabs);
+static BOOL EDIT_EM_SetTabStops(EDITSTATE *es, INT count, const INT *tabs);
#ifndef __REACTOS__
-static BOOL EDIT_EM_SetTabStops16(EDITSTATE *es, INT count, LPINT16 tabs);
+static BOOL EDIT_EM_SetTabStops16(EDITSTATE *es, INT count, const INT16 *tabs);
#endif
static void EDIT_EM_SetWordBreakProc(EDITSTATE *es, void *wbp);
#ifndef __REACTOS__
@@ -256,14 +254,13 @@
/*
* WM_XXX message handlers
*/
-static BOOL EDIT_WM_Char(EDITSTATE *es, WCHAR c);
+static LRESULT EDIT_WM_Char(EDITSTATE *es, WCHAR c);
static void EDIT_WM_Command(EDITSTATE *es, INT code, INT id, HWND conrtol);
static void EDIT_WM_ContextMenu(EDITSTATE *es, INT x, INT y);
static void EDIT_WM_Copy(EDITSTATE *es);
static LRESULT EDIT_WM_Create(EDITSTATE *es, LPCWSTR name);
static LRESULT EDIT_WM_Destroy(EDITSTATE *es);
-static LRESULT EDIT_WM_EraseBkGnd(EDITSTATE *es, HDC dc);
-static INT EDIT_WM_GetText(EDITSTATE *es, INT count, LPWSTR dst, BOOL unicode);
+static INT EDIT_WM_GetText(const EDITSTATE *es, INT count, LPWSTR dst, BOOL unicode);
static LRESULT EDIT_WM_HScroll(EDITSTATE *es, INT action, INT pos);
static LRESULT EDIT_WM_KeyDown(EDITSTATE *es, INT key);
static LRESULT EDIT_WM_KillFocus(EDITSTATE *es);
@@ -283,7 +280,7 @@
static LRESULT EDIT_WM_SysKeyDown(EDITSTATE *es, INT key, DWORD key_data);
static void EDIT_WM_Timer(EDITSTATE *es);
static LRESULT EDIT_WM_VScroll(EDITSTATE *es, INT action, INT pos);
-static void EDIT_UpdateText(EDITSTATE *es, LPRECT rc, BOOL bErase);
+static void EDIT_UpdateText(EDITSTATE *es, const RECT *rc, BOOL bErase);
static void EDIT_UpdateTextRegion(EDITSTATE *es, HRGN hrgn, BOOL bErase);
static void EDIT_ImeComposition(HWND hwnd, LPARAM CompFlag, EDITSTATE *es);
@@ -293,9 +290,10 @@
/*********************************************************************
* edit class descriptor
*/
+static const WCHAR editW[] = {'E','d','i','t',0};
const struct builtin_class_descr EDIT_builtin_class =
{
- L"Edit", /* name */
+ editW, /* name */
CS_DBLCLKS | CS_PARENTDC, /* style */
EditWndProcA, /* procA */
EditWndProcW, /* procW */
@@ -310,7 +308,7 @@
* EM_CANUNDO
*
*/
-static __inline BOOL EDIT_EM_CanUndo(EDITSTATE *es)
+static inline BOOL EDIT_EM_CanUndo(const EDITSTATE *es)
{
return (es->undo_insert_count || strlenW(es->undo_text));
}
@@ -321,7 +319,7 @@
* EM_EMPTYUNDOBUFFER
*
*/
-static __inline void EDIT_EM_EmptyUndoBuffer(EDITSTATE *es)
+static inline void EDIT_EM_EmptyUndoBuffer(EDITSTATE *es)
{
es->undo_insert_count = 0;
*es->undo_text = '\0';
@@ -333,7 +331,7 @@
* WM_CLEAR
*
*/
-static __inline void EDIT_WM_Clear(EDITSTATE *es)
+static inline void EDIT_WM_Clear(EDITSTATE *es)
{
static const WCHAR empty_stringW[] = {0};
@@ -350,7 +348,7 @@
* WM_CUT
*
*/
-static __inline void EDIT_WM_Cut(EDITSTATE *es)
+static inline void EDIT_WM_Cut(EDITSTATE *es)
{
EDIT_WM_Copy(es);
EDIT_WM_Clear(es);
@@ -392,14 +390,14 @@
return version;
}
-static __inline UINT get_text_length(EDITSTATE *es)
+static inline UINT get_text_length(EDITSTATE *es)
{
if(es->text_length == (UINT)-1)
es->text_length = strlenW(es->text);
return es->text_length;
}
-static __inline void text_buffer_changed(EDITSTATE *es)
+static inline void text_buffer_changed(EDITSTATE *es)
{
es->text_length = (UINT)-1;
}
@@ -421,12 +419,18 @@
return hbrush;
}
-static __inline LRESULT DefWindowProcT(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
BOOL unicode)
+static inline LRESULT DefWindowProcT(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
BOOL unicode)
{
if(unicode)
return DefWindowProcW(hwnd, msg, wParam, lParam);
else
return DefWindowProcA(hwnd, msg, wParam, lParam);
+}
+
+static inline INT get_vertical_line_count(EDITSTATE *es)
+{
+ INT vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
+ return max(1,vlc);
}
/*********************************************************************
@@ -442,14 +446,14 @@
* names).
*
*/
-static LRESULT WINAPI EditWndProc_common( HWND hwnd, UINT msg,
- WPARAM wParam, LPARAM lParam, BOOL unicode )
+static LRESULT EditWndProc_common( HWND hwnd, UINT msg,
+ WPARAM wParam, LPARAM lParam, BOOL unicode )
{
EDITSTATE *es = (EDITSTATE *)GetWindowLongPtrW( hwnd, 0 );
LRESULT result = 0;
- TRACE("hwnd=%p msg=%x (%s) wparam=%lx lparam=%lx\n", hwnd, msg,
SPY_GetMsgName(msg, hwnd), wParam, lParam);
-
+ TRACE("hwnd=%p msg=%x (%s) wparam=%lx lparam=%lx\n", hwnd, msg,
SPY_GetMsgName(msg, hwnd), wParam, lParam);
+
if (!es && msg != WM_NCCREATE)
return DefWindowProcT(hwnd, msg, wParam, lParam, unicode);
@@ -486,7 +490,13 @@
#ifndef __REACTOS__
case EM_GETRECT16:
if (lParam)
- CONV_RECT32TO16(&es->format_rect, MapSL(lParam));
+ {
+ RECT16 *r16 = MapSL(lParam);
+ r16->left = es->format_rect.left;
+ r16->top = es->format_rect.top;
+ r16->right = es->format_rect.right;
+ r16->bottom = es->format_rect.bottom;
+ }
break;
#endif
case EM_GETRECT:
@@ -498,7 +508,11 @@
case EM_SETRECT16:
if ((es->style & ES_MULTILINE) && lParam) {
RECT rc;
- CONV_RECT16TO32(MapSL(lParam), &rc);
+ RECT16 *r16 = MapSL(lParam);
+ rc.left = r16->left;
+ rc.top = r16->top;
+ rc.right = r16->right;
+ rc.bottom = r16->bottom;
EDIT_SetRectNP(es, &rc);
EDIT_UpdateText(es, NULL, TRUE);
}
@@ -515,7 +529,11 @@
case EM_SETRECTNP16:
if ((es->style & ES_MULTILINE) && lParam) {
RECT rc;
- CONV_RECT16TO32(MapSL(lParam), &rc);
+ RECT16 *r16 = MapSL(lParam);
+ rc.left = r16->left;
+ rc.top = r16->top;
+ rc.right = r16->right;
+ rc.bottom = r16->bottom;
EDIT_SetRectNP(es, &rc);
}
break;
@@ -646,7 +664,7 @@
LPSTR textA = (LPSTR)lParam;
INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0);
if((textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR))))
- MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW);
+ MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW);
}
EDIT_EM_ReplaceSel(es, (BOOL)wParam, textW, TRUE, TRUE);
@@ -817,7 +835,7 @@
break;
case EM_POSFROMCHAR:
- if ((INT)wParam >= get_text_length(es)) result = -1;
+ if ((INT)wParam >= get_text_length(es)) result = -1;
else result = EDIT_EM_PosFromChar(es, (INT)wParam, FALSE);
break;
@@ -840,39 +858,48 @@
case WM_GETDLGCODE:
result = DLGC_HASSETSEL | DLGC_WANTCHARS | DLGC_WANTARROWS;
-
+
if (es->style & ES_MULTILINE)
- {
result |= DLGC_WANTALLKEYS;
- break;
- }
if (lParam && (((LPMSG)lParam)->message == WM_KEYDOWN))
{
int vk = (int)((LPMSG)lParam)->wParam;
- if (es->hwndListBox && (vk == VK_RETURN || vk == VK_ESCAPE))
- {
- if (SendMessageW(GetParent(hwnd), CB_GETDROPPEDSTATE, 0, 0))
- result |= DLGC_WANTMESSAGE;
- }
- }
- break;
-
- case WM_IME_CHAR:
- if (!unicode)
- {
- WCHAR charW;
- CHAR strng[2];
-
- strng[0] = wParam >> 8;
- strng[1] = wParam & 0xff;
- if (strng[0]) MultiByteToWideChar(CP_ACP, 0, strng, 2, &charW, 1);
- else MultiByteToWideChar(CP_ACP, 0, &strng[1], 1, &charW, 1);
- result = EDIT_WM_Char(es, charW);
- break;
- }
- /* fall through */
+ if (es->hwndListBox)
+ {
+ if (vk == VK_RETURN || vk == VK_ESCAPE)
+ if (SendMessageW(GetParent(hwnd), CB_GETDROPPEDSTATE, 0, 0))
+ result |= DLGC_WANTMESSAGE;
+ }
+ else
+ {
+ switch (vk)
+ {
+ case VK_ESCAPE:
+ SendMessageW(GetParent(hwnd), WM_CLOSE, 0, 0);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ break;
+
+ case WM_IME_CHAR:
+ if (!unicode)
+ {
+ WCHAR charW;
+ CHAR strng[2];
+
+ strng[0] = wParam >> 8;
+ strng[1] = wParam & 0xff;
+ if (strng[0]) MultiByteToWideChar(CP_ACP, 0, strng, 2, &charW, 1);
+ else MultiByteToWideChar(CP_ACP, 0, &strng[1], 1, &charW, 1);
+ result = EDIT_WM_Char(es, charW);
+ break;
+ }
+ /* fall through */
case WM_CHAR:
{
WCHAR charW;
@@ -885,15 +912,36 @@
MultiByteToWideChar(CP_ACP, 0, &charA, 1, &charW, 1);
}
- if ((charW == VK_RETURN || charW == VK_ESCAPE) && es->hwndListBox)
- {
- if (SendMessageW(GetParent(hwnd), CB_GETDROPPEDSTATE, 0, 0))
- SendMessageW(GetParent(hwnd), WM_KEYDOWN, charW, 0);
- break;
- }
+ if (es->hwndListBox)
+ {
+ if (charW == VK_RETURN || charW == VK_ESCAPE)
+ {
+ if (SendMessageW(GetParent(hwnd), CB_GETDROPPEDSTATE, 0, 0))
+ SendMessageW(GetParent(hwnd), WM_KEYDOWN, charW, 0);
+ break;
+ }
+ }
result = EDIT_WM_Char(es, charW);
break;
}
+
+ case WM_UNICHAR:
+ if (unicode)
+ {
+ if (wParam == UNICODE_NOCHAR) return TRUE;
+ if (wParam <= 0x000fffff)
+ {
+ if(wParam > 0xffff) /* convert to surrogates */
+ {
+ wParam -= 0x10000;
+ EDIT_WM_Char(es, (wParam >> 10) + 0xd800);
+ EDIT_WM_Char(es, (wParam & 0x03ff) + 0xdc00);
+ }
+ else EDIT_WM_Char(es, wParam);
+ }
+ return 0;
+ }
+ break;
case WM_CLEAR:
EDIT_WM_Clear(es);
@@ -920,12 +968,12 @@
LPWSTR nameW = NULL;
if(nameA)
{
- INT countW = MultiByteToWideChar(CP_ACP, 0, nameA, -1, NULL, 0);
- if((nameW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR))))
- MultiByteToWideChar(CP_ACP, 0, nameA, -1, nameW, countW);
+ INT countW = MultiByteToWideChar(CP_ACP, 0, nameA, -1, NULL, 0);
+ if((nameW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR))))
+ MultiByteToWideChar(CP_ACP, 0, nameA, -1, nameW, countW);
}
result = EDIT_WM_Create(es, nameW);
- HeapFree(GetProcessHeap(), 0, nameW);
+ HeapFree(GetProcessHeap(), 0, nameW);
}
break;
@@ -939,7 +987,8 @@
break;
case WM_ERASEBKGND:
- result = EDIT_WM_EraseBkGnd(es, (HDC)wParam);
+ /* we do the proper erase in EDIT_WM_Paint */
+ result = 1;
break;
case WM_GETFONT:
@@ -1058,44 +1107,28 @@
}
break;
-
- /* IME messages to make the edit control IME aware */
+
+ /* IME messages to make the edit control IME aware */
case WM_IME_SETCONTEXT:
break;
case WM_IME_STARTCOMPOSITION:
- /*
- * FIXME in IME: This message is not always sent like it should be
- */
- if (es->selection_start != es->selection_end)
- {
- static const WCHAR empty_stringW[] = {0};
- EDIT_EM_ReplaceSel(es, TRUE, empty_stringW, TRUE, TRUE);
- }
es->composition_start = es->selection_end;
es->composition_len = 0;
break;
case WM_IME_COMPOSITION:
- {
- int caret_pos = es->selection_end;
- if (es->composition_len == 0)
- {
- if (es->selection_start != es->selection_end)
- {
- static const WCHAR empty_stringW[] = {0};
- EDIT_EM_ReplaceSel(es, TRUE, empty_stringW, TRUE, TRUE);
- }
-
- es->composition_start = es->selection_end;
- }
- EDIT_ImeComposition(hwnd,lParam,es);
- EDIT_SetCaretPos(es, caret_pos, es->flags & EF_AFTER_WRAP);
- break;
- }
+ EDIT_ImeComposition(hwnd, lParam, es);
+ break;
case WM_IME_ENDCOMPOSITION:
- es->composition_len= 0;
+ if (es->composition_len > 0)
+ {
+ static const WCHAR empty_stringW[] = {0};
+ EDIT_EM_ReplaceSel(es, TRUE, empty_stringW, TRUE, TRUE);
+ es->selection_end = es->selection_start;
+ es->composition_len= 0;
+ }
break;
case WM_IME_COMPOSITIONFULL:
@@ -1106,15 +1139,15 @@
case WM_IME_CONTROL:
break;
-
+
default:
result = DefWindowProcT(hwnd, msg, wParam, lParam, unicode);
break;
}
-
+
if (es) EDIT_UnlockBuffer(es, FALSE);
- TRACE("hwnd=%p msg=%x (%s) -- 0x%08lx\n", hwnd, msg, SPY_GetMsgName(msg,
hwnd), result);
+ TRACE("hwnd=%p msg=%x (%s) -- 0x%08lx\n", hwnd, msg,
SPY_GetMsgName(msg, hwnd), result);
return result;
}
@@ -1232,7 +1265,7 @@
{
if (current_position - es->text > iend)
break; /* We reached end of line modifications */
- /* else recalulate this line */
+ /* else recalculate this line */
}
}
@@ -1313,9 +1346,9 @@
current_line->width = (INT)LOWORD(GetTabbedTextExtentW(dc, current_position,
current_line->net_length, es->tabs_count, es->tabs));
}
- else if (orig_net_length < current_line->net_length &&
- current_line == start_line &&
- current_line->index != nstart_index) {
+ else if (current_line == start_line &&
+ current_line->index != nstart_index &&
+ orig_net_length < current_line->net_length) {
/* The previous line expanded but it's still not as wide as the client rect */
/* The expansion is due to an upwards line wrap so we must partially include
it in the update region */
@@ -1464,7 +1497,7 @@
*/
static INT EDIT_CallWordBreakProc(EDITSTATE *es, INT start, INT index, INT count, INT
action)
{
- INT ret;
+ INT ret;
#ifndef __REACTOS__
if (es->word_break_proc16) {
@@ -1476,7 +1509,7 @@
countA = WideCharToMultiByte(CP_ACP, 0, es->text + start, count, NULL, 0, NULL,
NULL);
hglob16 = GlobalAlloc16(GMEM_MOVEABLE | GMEM_ZEROINIT, countA);
- segptr = K32WOWGlobalLock16(hglob16);
+ segptr = WOWGlobalLock16(hglob16);
WideCharToMultiByte(CP_ACP, 0, es->text + start, count, MapSL(segptr), countA,
NULL, NULL);
args[4] = SELECTOROF(segptr);
args[3] = OFFSETOF(segptr);
@@ -1521,7 +1554,7 @@
else
ret = EDIT_WordBreakProc(es->text + start, index, count, action);
- return ret;
+ return ret;
}
@@ -1676,7 +1709,7 @@
* (so CharFromPos returns the nearest _visible_ character)
*
*/
-static void EDIT_ConfinePoint(EDITSTATE *es, LPINT x, LPINT y)
+static void EDIT_ConfinePoint(const EDITSTATE *es, LPINT x, LPINT y)
{
*x = min(max(*x, es->format_rect.left), es->format_rect.right - 1);
*y = min(max(*y, es->format_rect.top), es->format_rect.bottom - 1);
@@ -1731,10 +1764,10 @@
*
* EDIT_LockBuffer
*
- * This acts as a LOCAL_Lock(), but it locks only once. This way
+ * This acts as a LocalLock16(), but it locks only once. This way
* you can call it whenever you like, without unlocking.
*
- * Initially the edit control allocates a HLOCAL32 buffer
+ * Initially the edit control allocates a HLOCAL32 buffer
* (32 bit linear memory handler). However, 16 bit application
* might send an EM_GETHANDLE message and expect a HLOCAL16 (16 bit SEG:OFF
* handler). From that moment on we have to keep using this 16 bit memory
@@ -1746,7 +1779,8 @@
static void EDIT_LockBuffer(EDITSTATE *es)
{
#ifndef __REACTOS__
- HINSTANCE16 hInstance = GetWindowLongW( es->hwndSelf, GWL_HINSTANCE );
+ STACK16FRAME* stack16 = MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved));
+ HINSTANCE16 hInstance = GetWindowLongPtrW( es->hwndSelf, GWLP_HINSTANCE );
#endif
if (!es->text) {
CHAR *textA = NULL;
@@ -1766,8 +1800,11 @@
#ifndef __REACTOS__
else if(es->hloc16)
{
+ HANDLE16 oldDS = stack16->ds;
TRACE("Synchronizing with 16-bit ANSI buffer\n");
- textA = LOCAL_Lock(hInstance, es->hloc16);
+ stack16->ds = hInstance;
+ textA = MapSL(LocalLock16(es->hloc16));
+ stack16->ds = oldDS;
countA = strlen(textA) + 1;
_16bit = TRUE;
}
@@ -1807,7 +1844,12 @@
MultiByteToWideChar(CP_ACP, 0, textA, countA, es->text, es->buffer_size + 1);
#ifndef __REACTOS__
if(_16bit)
- LOCAL_Unlock(hInstance, es->hloc16);
+ {
+ HANDLE16 oldDS = stack16->ds;
+ stack16->ds = hInstance;
+ LocalUnlock16(es->hloc16);
+ stack16->ds = oldDS;
+ }
else
#endif
LocalUnlock(es->hloc32A);
@@ -1847,7 +1889,7 @@
*/
static void EDIT_ML_InvalidateText(EDITSTATE *es, INT start, INT end)
{
- INT vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
+ INT vlc = get_vertical_line_count(es);
INT sl = EDIT_EM_LineFromChar(es, start);
INT el = EDIT_EM_LineFromChar(es, end);
INT sc;
@@ -2054,39 +2096,17 @@
* EDIT_MoveEnd
*
*/
-static void EDIT_MoveEnd(EDITSTATE *es, BOOL extend)
+static void EDIT_MoveEnd(EDITSTATE *es, BOOL extend, BOOL ctrl)
{
BOOL after_wrap = FALSE;
INT e;
/* Pass a high value in x to make sure of receiving the end of the line */
- if (es->style & ES_MULTILINE)
+ if (!ctrl && (es->style & ES_MULTILINE))
e = EDIT_CharFromPos(es, 0x3fffffff,
HIWORD(EDIT_EM_PosFromChar(es, es->selection_end, es->flags &
EF_AFTER_WRAP)), &after_wrap);
else
e = get_text_length(es);
- EDIT_EM_SetSel(es, extend ? es->selection_start : e, e, after_wrap);
- EDIT_EM_ScrollCaret(es);
-}
-
-
-/*********************************************************************
- *
- * EDIT_MoveEndOfText
- *
- * Handler for Ctrl+End. Move to end of text. Only for multiline.
- *
- */
-static void EDIT_MoveEndOfText(EDITSTATE *es, BOOL extend)
-{
- BOOL after_wrap = FALSE;
- INT e;
-
- assert(es->style & ES_MULTILINE);
-
- /* Just give it impossible high x&y to get the index of the last char */
- e = EDIT_CharFromPos(es, 0x3fffffff, 0x3fffffff, &after_wrap);
-
EDIT_EM_SetSel(es, extend ? es->selection_start : e, e, after_wrap);
EDIT_EM_ScrollCaret(es);
}
@@ -2117,39 +2137,17 @@
/*********************************************************************
*
- * EDIT_MoveStartOfText
- *
- * Handler for Ctr+Home. Move to start of text. Only for multiline.
- *
- */
-static void EDIT_MoveStartOfText(EDITSTATE *es, BOOL extend)
-{
- BOOL after_wrap = FALSE;
-
- assert(es->style & ES_MULTILINE);
-
- /* use CharFromPos instead of just plain zero, to get the wrap_flag */
- EDIT_CharFromPos(es, 0, 0, &after_wrap);
-
-
- EDIT_EM_SetSel(es, 0, extend ? es->selection_end : 0, FALSE);
- EDIT_EM_ScrollCaret(es);
-}
-
-
-/*********************************************************************
- *
* EDIT_MoveHome
*
* Home key: move to beginning of line.
*
*/
-static void EDIT_MoveHome(EDITSTATE *es, BOOL extend)
+static void EDIT_MoveHome(EDITSTATE *es, BOOL extend, BOOL ctrl)
{
INT e;
/* Pass the x_offset in x to make sure of receiving the first position of the line */
- if (es->style & ES_MULTILINE)
+ if (!ctrl && (es->style & ES_MULTILINE))
e = EDIT_CharFromPos(es, -es->x_offset,
HIWORD(EDIT_EM_PosFromChar(es, es->selection_end, es->flags &
EF_AFTER_WRAP)), NULL);
else
@@ -2263,8 +2261,7 @@
e = li + EDIT_EM_LineLength(es, li);
}
} else {
- e = li + (INT)EDIT_CallWordBreakProc(es,
- li, e - li, ll, WB_LEFT);
+ e = li + EDIT_CallWordBreakProc(es, li, e - li, ll, WB_LEFT);
}
if (!extend)
s = e;
@@ -2319,7 +2316,8 @@
LRESULT pos;
if (es->style & ES_MULTILINE) {
- INT vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
+ INT vlc = get_vertical_line_count(es);
+
if ((line < es->y_offset) || (line > es->y_offset + vlc) || (line >=
es->line_count))
return;
} else if (line)
@@ -2371,10 +2369,10 @@
if (rev) {
if (es->composition_len == 0)
{
- SetBkColor(dc, GetSysColor(COLOR_HIGHLIGHT));
- SetTextColor(dc, GetSysColor(COLOR_HIGHLIGHTTEXT));
- SetBkMode( dc, OPAQUE);
- }
+ SetBkColor(dc, GetSysColor(COLOR_HIGHLIGHT));
+ SetTextColor(dc, GetSysColor(COLOR_HIGHLIGHTTEXT));
+ SetBkMode( dc, OPAQUE);
+ }
else
{
HFONT current = GetCurrentObject(dc,OBJ_FONT);
@@ -2399,10 +2397,10 @@
if (rev) {
if (es->composition_len == 0)
{
- SetBkColor(dc, BkColor);
- SetTextColor(dc, TextColor);
- SetBkMode( dc, BkMode);
- }
+ SetBkColor(dc, BkColor);
+ SetTextColor(dc, TextColor);
+ SetBkMode( dc, BkMode);
+ }
else
{
if (old_font)
@@ -2446,8 +2444,8 @@
{
INT fw, vlc, max_x_offset, max_y_offset;
- vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
- es->format_rect.bottom = es->format_rect.top + max(1, vlc) *
es->line_height;
+ vlc = get_vertical_line_count(es);
+ es->format_rect.bottom = es->format_rect.top + vlc * es->line_height;
/* correct es->x_offset */
fw = es->format_rect.right - es->format_rect.left;
@@ -2475,7 +2473,7 @@
if ((es->style & ES_MULTILINE) && !(es->style & ES_AUTOHSCROLL))
EDIT_BuildLineDefs_ML(es, 0, get_text_length(es), 0, NULL);
-
+
EDIT_SetCaretPos(es, es->selection_end, es->flags & EF_AFTER_WRAP);
}
@@ -2488,18 +2486,18 @@
* it is also used to set the rect of a single line control
*
*/
-static void EDIT_SetRectNP(EDITSTATE *es, LPRECT rc)
+static void EDIT_SetRectNP(EDITSTATE *es, const RECT *rc)
{
LONG_PTR ExStyle;
INT bw, bh;
ExStyle = GetWindowLongPtrW(es->hwndSelf, GWL_EXSTYLE);
-
+
CopyRect(&es->format_rect, rc);
-
+
if (ExStyle & WS_EX_CLIENTEDGE) {
es->format_rect.left++;
es->format_rect.right--;
-
+
if (es->format_rect.bottom - es->format_rect.top
= es->line_height + 2)
{
@@ -2519,7 +2517,7 @@
es->format_rect.bottom -= bh;
}
}
-
+
es->format_rect.left += es->left_margin;
es->format_rect.right -= es->right_margin;
EDIT_AdjustFormatRect(es);
@@ -2587,26 +2585,31 @@
else if(es->hloc16)
{
UINT countA_new = WideCharToMultiByte(CP_ACP, 0, es->text, countW, NULL, 0,
NULL, NULL);
+
TRACE("Synchronizing with 16-bit ANSI buffer\n");
TRACE("%d WCHARs translated to %d bytes\n", countW, countA_new);
- countA = LOCAL_Size(hInstance, es->hloc16);
+
+ stack16 = MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved));
+ oldDS = stack16->ds;
+ stack16->ds = GetWindowLongPtrW( es->hwndSelf, GWLP_HINSTANCE );
+
+ countA = LocalSize16(es->hloc16);
if(countA_new > countA)
{
HLOCAL16 hloc16_new;
UINT alloc_size = ROUND_TO_GROW(countA_new);
TRACE("Resizing 16-bit ANSI buffer from %d to %d bytes\n", countA,
alloc_size);
- hloc16_new = LOCAL_ReAlloc(hInstance, es->hloc16, alloc_size, LMEM_MOVEABLE |
LMEM_ZEROINIT);
+ hloc16_new = LocalReAlloc16(es->hloc16, alloc_size, LMEM_MOVEABLE |
LMEM_ZEROINIT);
if(hloc16_new)
{
es->hloc16 = hloc16_new;
- countA = LOCAL_Size(hInstance, hloc16_new);
+ countA = LocalSize16(hloc16_new);
TRACE("Real new size %d bytes\n", countA);
}
else
WARN("FAILED! Will synchronize partially\n");
}
- textA = LOCAL_Lock(hInstance, es->hloc16);
- _16bit = TRUE;
+ textA = MapSL(LocalLock16(es->hloc16));
}
#endif
@@ -2614,13 +2617,16 @@
{
WideCharToMultiByte(CP_ACP, 0, es->text, countW, textA, countA, NULL, NULL);
#ifndef __REACTOS__
- if(_16bit)
- LOCAL_Unlock(hInstance, es->hloc16);
+ if(stack16)
+ LocalUnlock16(es->hloc16);
else
#endif
LocalUnlock(es->hloc32A);
}
+#ifndef __REACTOS__
+ if (stack16) stack16->ds = oldDS;
+#endif
LocalUnlock(es->hloc32W);
es->text = NULL;
}
@@ -2680,7 +2686,7 @@
* internally, so we can decide this for ourselves.
*
*/
-static INT CALLBACK EDIT_WordBreakProc(LPWSTR s, INT index, INT count, INT action)
+static INT EDIT_WordBreakProc(LPWSTR s, INT index, INT count, INT action)
{
INT ret = 0;
@@ -2769,11 +2775,11 @@
* EM_FMTLINES
*
* Enable or disable soft breaks.
- *
+ *
* This means: insert or remove the soft linebreak character (\r\r\n).
* Take care to check if the text still fits the buffer after insertion.
* If not, notify with EN_ERRSPACE.
- *
+ *
*/
static BOOL EDIT_EM_FmtLines(EDITSTATE *es, BOOL add_eol)
{
@@ -2827,6 +2833,7 @@
hLocal = es->hloc32A;
}
+ es->flags |= EF_APP_HAS_HANDLE;
TRACE("Returning %p, LocalSize() = %ld\n", hLocal, LocalSize(hLocal));
return hLocal;
}
@@ -2850,9 +2857,10 @@
*/
static HLOCAL16 EDIT_EM_GetHandle16(EDITSTATE *es)
{
- HINSTANCE16 hInstance = GetWindowLongW( es->hwndSelf, GWL_HINSTANCE );
CHAR *textA;
UINT countA, alloc_size;
+ STACK16FRAME* stack16;
+ HANDLE16 oldDS;
if (!(es->style & ES_MULTILINE))
return 0;
@@ -2860,11 +2868,15 @@
if (es->hloc16)
return es->hloc16;
- if (!LOCAL_HeapSize(hInstance)) {
- if (!LocalInit16(hInstance, 0,
- GlobalSize16(hInstance))) {
+ stack16 = MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved));
+ oldDS = stack16->ds;
+ stack16->ds = GetWindowLongPtrW( es->hwndSelf, GWLP_HINSTANCE );
+
+ if (!LocalHeapSize16()) {
+
+ if (!LocalInit16(stack16->ds, 0, GlobalSize16(stack16->ds))) {
ERR("could not initialize local heap\n");
- return 0;
+ goto done;
}
TRACE("local heap initialized\n");
}
@@ -2873,22 +2885,26 @@
alloc_size = ROUND_TO_GROW(countA);
TRACE("Allocating 16-bit ANSI alias buffer\n");
- if (!(es->hloc16 = LOCAL_Alloc(hInstance, LMEM_MOVEABLE | LMEM_ZEROINIT,
alloc_size))) {
+ if (!(es->hloc16 = LocalAlloc16(LMEM_MOVEABLE | LMEM_ZEROINIT, alloc_size))) {
ERR("could not allocate new 16 bit buffer\n");
- return 0;
- }
-
- if (!(textA = (LPSTR)LOCAL_Lock(hInstance, es->hloc16))) {
+ goto done;
+ }
+
+ if (!(textA = MapSL(LocalLock16( es->hloc16)))) {
ERR("could not lock new 16 bit buffer\n");
- LOCAL_Free(hInstance, es->hloc16);
+ LocalFree16(es->hloc16);
es->hloc16 = 0;
- return 0;
+ goto done;
}
WideCharToMultiByte(CP_ACP, 0, es->text, -1, textA, countA, NULL, NULL);
- LOCAL_Unlock(hInstance, es->hloc16);
-
- TRACE("Returning %04X, LocalSize() = %d\n", es->hloc16,
LOCAL_Size(hInstance, es->hloc16));
+ LocalUnlock16(es->hloc16);
+ es->flags |= EF_APP_HAS_HANDLE;
+
+ TRACE("Returning %04X, LocalSize() = %d\n", es->hloc16,
LocalSize16(es->hloc16));
+
+done:
+ stack16->ds = oldDS;
return es->hloc16;
}
#endif
@@ -2945,7 +2961,7 @@
* EM_GETSEL
*
*/
-static LRESULT EDIT_EM_GetSel(EDITSTATE *es, PUINT start, PUINT end)
+static LRESULT EDIT_EM_GetSel(const EDITSTATE *es, PUINT start, PUINT end)
{
UINT s = es->selection_start;
UINT e = es->selection_end;
@@ -3015,10 +3031,10 @@
* EM_LINEINDEX
*
*/
-static INT EDIT_EM_LineIndex(EDITSTATE *es, INT line)
+static INT EDIT_EM_LineIndex(const EDITSTATE *es, INT line)
{
INT line_index;
- LINEDEF *line_def;
+ const LINEDEF *line_def;
if (!(es->style & ES_MULTILINE))
return 0;
@@ -3299,11 +3315,11 @@
* such that buffer limit is honored. */
if ((honor_limit) && (size > es->buffer_limit)) {
EDIT_NOTIFY_PARENT(es, EN_MAXTEXT);
- /* Buffer limit can be smaller than the actual length of text in combobox
*/
- if (es->buffer_limit < (tl - (e-s)))
- strl = 0;
- else
- strl = es->buffer_limit - (tl - (e-s));
+ /* Buffer limit can be smaller than the actual length of text in combobox */
+ if (es->buffer_limit < (tl - (e-s)))
+ strl = 0;
+ else
+ strl = es->buffer_limit - (tl - (e-s));
}
if (!EDIT_MakeFit(es, tl - (e - s) + strl))
@@ -3324,7 +3340,7 @@
if (strl) {
/* there is an insertion */
tl = get_text_length(es);
- 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));
+ 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));
for (p = es->text + tl ; p >= es->text + s ; p--)
p[strl] = p[0];
for (i = 0 , p = es->text + s ; i < strl ; i++)
@@ -3338,7 +3354,7 @@
if (es->style & ES_MULTILINE)
{
INT st = min(es->selection_start, es->selection_end);
- INT vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
+ INT vlc = get_vertical_line_count(es);
hrgn = CreateRectRgn(0, 0, 0, 0);
EDIT_BuildLineDefs_ML(es, st, st + strl,
@@ -3351,7 +3367,7 @@
for (i = 0 , p = es->text ; i < e - s ; i++)
p[i + s] = buf[i];
text_buffer_changed(es);
- EDIT_BuildLineDefs_ML(es, s, e,
+ EDIT_BuildLineDefs_ML(es, s, e,
abs(es->selection_end - es->selection_start) - strl, hrgn);
strl = 0;
e = s;
@@ -3369,11 +3385,11 @@
strl--;
EDIT_CalcLineWidth_SL(es);
}
- text_buffer_changed(es);
+ text_buffer_changed(es);
EDIT_NOTIFY_PARENT(es, EN_MAXTEXT);
}
}
-
+
if (e != s) {
if (can_undo) {
utl = strlenW(es->undo_text);
@@ -3425,7 +3441,7 @@
if (bufl)
HeapFree(GetProcessHeap(), 0, buf);
-
+
s += strl;
/* If text has been deleted and we're right or center aligned then scroll rightward
*/
@@ -3502,7 +3518,7 @@
return (LRESULT)FALSE;
}
if (dy) {
- INT vlc = (es->format_rect.bottom - es->format_rect.top) /
es->line_height;
+ INT vlc = get_vertical_line_count(es);
/* check if we are going to move too far */
if(es->y_offset + dy > es->line_count - vlc)
dy = es->line_count - vlc - es->y_offset;
@@ -3528,7 +3544,6 @@
{
if (es->style & ES_MULTILINE) {
INT l;
- INT li;
INT vlc;
INT ww;
INT cw = es->char_width;
@@ -3537,9 +3552,8 @@
INT dx = 0;
l = EDIT_EM_LineFromChar(es, es->selection_end);
- li = EDIT_EM_LineIndex(es, l);
x = (short)LOWORD(EDIT_EM_PosFromChar(es, es->selection_end, es->flags &
EF_AFTER_WRAP));
- vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
+ vlc = get_vertical_line_count(es);
if (l >= es->y_offset + vlc)
dy = l - vlc + 1 - es->y_offset;
if (l < es->y_offset)
@@ -3613,8 +3627,13 @@
#ifndef __REACTOS__
if(es->hloc16)
{
- LOCAL_Free(hInstance, es->hloc16);
- es->hloc16 = (HLOCAL16)NULL;
+ STACK16FRAME* stack16 = MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved));
+ HANDLE16 oldDS = stack16->ds;
+
+ stack16->ds = GetWindowLongPtrW( es->hwndSelf, GWLP_HINSTANCE );
+ LocalFree16(es->hloc16);
+ stack16->ds = oldDS;
+ es->hloc16 = 0;
}
#endif
@@ -3682,7 +3701,9 @@
*/
static void EDIT_EM_SetHandle16(EDITSTATE *es, HLOCAL16 hloc)
{
- HINSTANCE16 hInstance = GetWindowLongW( es->hwndSelf, GWL_HINSTANCE );
+ STACK16FRAME* stack16 = MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved));
+ HINSTANCE16 hInstance = GetWindowLongPtrW( es->hwndSelf, GWLP_HINSTANCE );
+ HANDLE16 oldDS = stack16->ds;
INT countW, countA;
HLOCAL hloc32W_new;
WCHAR *textW;
@@ -3704,8 +3725,9 @@
es->hloc32A = NULL;
}
- countA = LOCAL_Size(hInstance, hloc);
- textA = LOCAL_Lock(hInstance, hloc);
+ stack16->ds = hInstance;
+ countA = LocalSize16(hloc);
+ textA = MapSL(LocalLock16(hloc));
countW = MultiByteToWideChar(CP_ACP, 0, textA, countA, NULL, 0);
if(!(hloc32W_new = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT, countW * sizeof(WCHAR))))
{
@@ -3715,7 +3737,8 @@
textW = LocalLock(hloc32W_new);
MultiByteToWideChar(CP_ACP, 0, textA, countA, textW, countW);
LocalUnlock(hloc32W_new);
- LOCAL_Unlock(hInstance, hloc);
+ LocalUnlock16(hloc);
+ stack16->ds = oldDS;
if(es->hloc32W)
LocalFree(es->hloc32W);
@@ -3725,6 +3748,7 @@
es->buffer_size = LocalSize(es->hloc32W)/sizeof(WCHAR) - 1;
+ es->flags |= EF_APP_HAS_HANDLE;
EDIT_LockBuffer(es);
es->x_offset = es->y_offset = 0;
@@ -3745,7 +3769,7 @@
*
* EM_SETLIMITTEXT
*
- * NOTE: this version currently implements WinNT limits
+ * NOTE: this version currently implements WinNT limits
*
*/
static void EDIT_EM_SetLimitText(EDITSTATE *es, UINT limit)
@@ -3831,12 +3855,12 @@
es->right_margin = default_right_margin;
es->format_rect.right -= es->right_margin;
}
-
+
if (action & (EC_LEFTMARGIN | EC_RIGHTMARGIN)) {
EDIT_AdjustFormatRect(es);
if (repaint) EDIT_UpdateText(es, NULL, TRUE);
}
-
+
TRACE("left=%d, right=%d\n", es->left_margin, es->right_margin);
}
@@ -3905,8 +3929,8 @@
* *sorting* the interval endpoints. Let's assume that we sort them
* in this order:
* start <= end <= old_start <= old_end
- * Knuth 5.3.1 (p 183) asssures us that this can be done optimally
- * in 5 comparisons; ie it's impossible to do better than the
+ * Knuth 5.3.1 (p 183) assures us that this can be done optimally
+ * in 5 comparisons; i.e. it is impossible to do better than the
* following: */
ORDER_UINT(end, old_end);
ORDER_UINT(start, old_start);
@@ -3944,11 +3968,11 @@
* EM_SETTABSTOPS
*
*/
-static BOOL EDIT_EM_SetTabStops(EDITSTATE *es, INT count, LPINT tabs)
+static BOOL EDIT_EM_SetTabStops(EDITSTATE *es, INT count, const INT *tabs)
{
if (!(es->style & ES_MULTILINE))
return FALSE;
- HeapFree(GetProcessHeap(), 0, es->tabs);
+ HeapFree(GetProcessHeap(), 0, es->tabs);
es->tabs_count = count;
if (!count)
es->tabs = NULL;
@@ -3971,12 +3995,11 @@
* EM_SETTABSTOPS16
*
*/
-static BOOL EDIT_EM_SetTabStops16(EDITSTATE *es, INT count, LPINT16 tabs)
+static BOOL EDIT_EM_SetTabStops16(EDITSTATE *es, INT count, const INT16 *tabs)
{
if (!(es->style & ES_MULTILINE))
return FALSE;
- if (es->tabs)
- HeapFree(GetProcessHeap(), 0, es->tabs);
+ HeapFree(GetProcessHeap(), 0, es->tabs);
es->tabs_count = count;
if (!count)
es->tabs = NULL;
@@ -4074,6 +4097,7 @@
return TRUE;
}
+
/* Helper function for WM_CHAR
*
* According to an MSDN blog article titled "Just because you're a control
@@ -4083,20 +4107,38 @@
*/
static BOOL EDIT_IsInsideDialog(EDITSTATE *es)
{
+#ifdef __REACTOS__
if (es->hwndParent && es->hwndParent != GetDesktopWindow())
{
if (GetClassLongW (es->hwndParent, GCW_ATOM) == (DWORD)MAKEINTATOM(32770))
return TRUE;
}
return FALSE;
-}
+#else
+ WND *pParent;
+ BOOL r = FALSE;
+
+ if (es->hwndParent)
+ {
+ pParent = WIN_GetPtr(es->hwndParent);
+ if (pParent && pParent != WND_OTHER_PROCESS && pParent !=
WND_DESKTOP)
+ {
+ if (pParent->flags & WIN_ISDIALOG)
+ r = TRUE;
+ WIN_ReleasePtr(pParent);
+ }
+ }
+ return r;
+#endif
+}
+
/*********************************************************************
*
* WM_CHAR
*
*/
-static BOOL EDIT_WM_Char(EDITSTATE *es, WCHAR c)
+static LRESULT EDIT_WM_Char(EDITSTATE *es, WCHAR c)
{
BOOL control;
@@ -4104,13 +4146,17 @@
switch (c) {
case '\r':
- /* If the edit doesn't want the return and it's not a multiline edit, do
nothing */
- if(!(es->style & ES_MULTILINE) && !(es->style &
ES_WANTRETURN))
- break;
+ /* If it's not a multiline edit box, it would be ignored below.
+ * For multiline edit without ES_WANTRETURN, we have to make a
+ * special case.
+ */
+ if ((es->style & ES_MULTILINE) && !(es->style &
ES_WANTRETURN))
+ if (EDIT_IsInsideDialog(es))
+ break;
case '\n':
if (es->style & ES_MULTILINE) {
if (es->style & ES_READONLY) {
- EDIT_MoveHome(es, FALSE);
+ EDIT_MoveHome(es, FALSE, FALSE);
EDIT_MoveDown_ML(es, FALSE);
} else {
static const WCHAR cr_lfW[] = {'\r','\n',0};
@@ -4122,8 +4168,8 @@
if ((es->style & ES_MULTILINE) && !(es->style & ES_READONLY))
{
static const WCHAR tabW[] = {'\t',0};
- if (EDIT_IsInsideDialog(es))
- break;
+ if (EDIT_IsInsideDialog(es))
+ break;
EDIT_EM_ReplaceSel(es, TRUE, tabW, TRUE, TRUE);
}
break;
@@ -4140,7 +4186,7 @@
}
break;
case 0x03: /* ^C */
- if (!(es->style & ES_PASSWORD))
+ if (!(es->style & ES_PASSWORD))
SendMessageW(es->hwndSelf, WM_COPY, 0, 0);
break;
case 0x16: /* ^V */
@@ -4151,16 +4197,16 @@
if (!((es->style & ES_READONLY) || (es->style & ES_PASSWORD)))
SendMessageW(es->hwndSelf, WM_CUT, 0, 0);
break;
- case 0x1A: /* ^Z */
- if (!(es->style & ES_READONLY))
- SendMessageW(es->hwndSelf, WM_UNDO, 0, 0);
- break;
+ case 0x1A: /* ^Z */
+ if (!(es->style & ES_READONLY))
+ SendMessageW(es->hwndSelf, WM_UNDO, 0, 0);
+ break;
default:
- /*If Edit control style is ES_NUMBER allow users to key in only numeric values*/
- if( (es->style & ES_NUMBER) && !( c >= '0' && c
<= '9') )
- break;
-
+ /*If Edit control style is ES_NUMBER allow users to key in only numeric values*/
+ if( (es->style & ES_NUMBER) && !( c >= '0' && c <=
'9') )
+ break;
+
if (!(es->style & ES_READONLY) && (c >= ' ') && (c !=
127)) {
WCHAR str[2];
str[0] = c;
@@ -4169,8 +4215,7 @@
}
break;
}
-
- return TRUE;
+ return 1;
}
@@ -4186,19 +4231,19 @@
switch (id) {
case EM_UNDO:
- EDIT_EM_Undo(es);
+ SendMessageW(es->hwndSelf, WM_UNDO, 0, 0);
break;
case WM_CUT:
- EDIT_WM_Cut(es);
+ SendMessageW(es->hwndSelf, WM_CUT, 0, 0);
break;
case WM_COPY:
- EDIT_WM_Copy(es);
+ SendMessageW(es->hwndSelf, WM_COPY, 0, 0);
break;
case WM_PASTE:
- EDIT_WM_Paste(es);
+ SendMessageW(es->hwndSelf, WM_PASTE, 0, 0);
break;
case WM_CLEAR:
- EDIT_WM_Clear(es);
+ SendMessageW(es->hwndSelf, WM_CLEAR, 0, 0);
break;
case EM_SETSEL:
EDIT_EM_SetSel(es, 0, (UINT)-1, FALSE);
@@ -4305,7 +4350,7 @@
static LRESULT EDIT_WM_Create(EDITSTATE *es, LPCWSTR name)
{
RECT clientRect;
-
+
TRACE("%s\n", debugstr_w(name));
/*
* To initialize some final structure members, we call some helper
@@ -4315,7 +4360,7 @@
*/
EDIT_WM_SetFont(es, 0, FALSE);
EDIT_EM_EmptyUndoBuffer(es);
-
+
/* We need to calculate the format rect
(applications may send EM_SETMARGINS before the control gets visible) */
GetClientRect(es->hwndSelf, &clientRect);
@@ -4357,18 +4402,20 @@
LINEDEF *pc, *pp;
if (es->hloc32W) {
- while (LocalUnlock(es->hloc32W)) ;
LocalFree(es->hloc32W);
}
if (es->hloc32A) {
- while (LocalUnlock(es->hloc32A)) ;
LocalFree(es->hloc32A);
}
#ifndef __REACTOS__
if (es->hloc16) {
- HINSTANCE16 hInstance = GetWindowWord( es->hwndSelf, GWL_HINSTANCE );
- while (LOCAL_Unlock(hInstance, es->hloc16)) ;
- LOCAL_Free(hInstance, es->hloc16);
+ STACK16FRAME* stack16 = MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved));
+ HANDLE16 oldDS = stack16->ds;
+
+ stack16->ds = GetWindowLongPtrW( es->hwndSelf, GWLP_HINSTANCE );
+ while (LocalUnlock16(es->hloc16)) ;
+ LocalFree16(es->hloc16);
+ stack16->ds = oldDS;
}
#endif
@@ -4389,22 +4436,10 @@
/*********************************************************************
*
- * WM_ERASEBKGND
- *
- */
-static LRESULT EDIT_WM_EraseBkGnd(EDITSTATE *es, HDC dc)
-{
- /* we do the proper erase in EDIT_WM_Paint */
- return 1;
-}
-
-
-/*********************************************************************
- *
* WM_GETTEXT
*
*/
-static INT EDIT_WM_GetText(EDITSTATE *es, INT count, LPWSTR dst, BOOL unicode)
+static INT EDIT_WM_GetText(const EDITSTATE *es, INT count, LPWSTR dst, BOOL unicode)
{
if(!count) return 0;
@@ -4666,18 +4701,10 @@
EDIT_MoveForward(es, shift);
break;
case VK_HOME:
- if (control && (es->style & ES_MULTILINE)) {
- EDIT_MoveStartOfText(es, shift);
- } else {
- EDIT_MoveHome(es, shift); /* start of line */
- }
+ EDIT_MoveHome(es, shift, control);
break;
case VK_END:
- if (control && (es->style & ES_MULTILINE)) {
- EDIT_MoveEndOfText(es, shift);
- } else {
- EDIT_MoveEnd(es, shift); /* end of line */
- }
+ EDIT_MoveEnd(es, shift, control);
break;
case VK_PRIOR:
if (es->style & ES_MULTILINE)
@@ -4707,7 +4734,7 @@
} else if (control) {
/* delete to end of line */
EDIT_EM_SetSel(es, (UINT)-1, 0, FALSE);
- EDIT_MoveEnd(es, TRUE);
+ EDIT_MoveEnd(es, TRUE, FALSE);
EDIT_WM_Clear(es);
} else {
/* delete character right of caret */
@@ -4725,36 +4752,36 @@
} else if (control)
EDIT_WM_Copy(es);
break;
- case VK_RETURN:
- /* If the edit doesn't want the return send a message to the default object
*/
- if(!(es->style & ES_MULTILINE) || !(es->style & ES_WANTRETURN))
+ case VK_RETURN:
+ /* If the edit doesn't want the return send a message to the default object */
+ if(!(es->style & ES_MULTILINE) || !(es->style & ES_WANTRETURN))
{
- HWND hwndParent;
- DWORD dw;
-
- if (!EDIT_IsInsideDialog(es)) return 1;
- if (control) break;
-
- hwndParent = GetParent(es->hwndSelf);
- dw = SendMessageW( hwndParent, DM_GETDEFID, 0, 0 );
- if (HIWORD(dw) == DC_HASDEFID)
- {
- SendMessageW( hwndParent, WM_COMMAND,
- MAKEWPARAM( LOWORD(dw), BN_CLICKED ),
- (LPARAM)GetDlgItem( hwndParent, LOWORD(dw) ) );
- }
- else
- SendMessageW( hwndParent, WM_COMMAND, IDOK, (LPARAM)GetDlgItem(
hwndParent, IDOK ) );
- }
- break;
- case VK_ESCAPE:
- if (!(es->style & ES_MULTILINE))
- SendMessageW(GetParent(es->hwndSelf), WM_COMMAND, IDCANCEL,
(LPARAM)GetDlgItem( GetParent(es->hwndSelf), IDCANCEL ) );
- break;
- case VK_TAB:
- SendMessageW(es->hwndParent, WM_NEXTDLGCTL, shift, 0);
- break;
- }
+ HWND hwndParent;
+ DWORD dw;
+
+ if (!EDIT_IsInsideDialog(es)) return 1;
+ if (control) break;
+
+ hwndParent = GetParent(es->hwndSelf);
+ dw = SendMessageW( hwndParent, DM_GETDEFID, 0, 0 );
+ if (HIWORD(dw) == DC_HASDEFID)
+ {
+ SendMessageW( hwndParent, WM_COMMAND,
+ MAKEWPARAM( LOWORD(dw), BN_CLICKED ),
+ (LPARAM)GetDlgItem( hwndParent, LOWORD(dw) ) );
+ }
+ else
+ SendMessageW( hwndParent, WM_COMMAND, IDOK, (LPARAM)GetDlgItem(
hwndParent, IDOK ) );
+ }
+ break;
+ case VK_ESCAPE:
+ if (!(es->style & ES_MULTILINE))
+ SendMessageW(GetParent(es->hwndSelf), WM_COMMAND, IDCANCEL,
(LPARAM)GetDlgItem( GetParent(es->hwndSelf), IDCANCEL ) );
+ break;
+ case VK_TAB:
+ SendMessageW(es->hwndParent, WM_NEXTDLGCTL, shift, 0);
+ break;
+ }
return 0;
}
@@ -4904,7 +4931,7 @@
EDITSTATE *es;
UINT alloc_size;
- TRACE("Creating %s edit control, style = %08lx\n",
+ TRACE("Creating %s edit control, style = %08x\n",
unicode ? "Unicode" : "ANSI", lpcs->style);
if (!(es = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*es))))
@@ -4928,6 +4955,9 @@
if (es->style & ES_COMBO)
es->hwndListBox = GetDlgItem(es->hwndParent, ID_CB_LISTBOX);
+
+ /* FIXME: should we handle changes to WS_EX_RIGHT style after creation? */
+ if (lpcs->dwExStyle & WS_EX_RIGHT) es->style |= ES_RIGHT;
/* Number overrides lowercase overrides uppercase (at least it
* does in Win95). However I'll bet that ES_NUMBER would be
@@ -4983,7 +5013,7 @@
* If WS_BORDER without WS_EX_CLIENTEDGE is specified we shouldn't have
* a nonclient area and we should handle painting the border ourselves.
*
- * When making modifications please ensure that the code still works
+ * When making modifications please ensure that the code still works
* for edit controls created directly with style 0x50800000, exStyle 0
* (which should have a single pixel border)
*/
@@ -5025,7 +5055,7 @@
/* paint the border and the background */
IntersectClipRect(dc, rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);
-
+
if(es->style & WS_BORDER) {
bw = GetSystemMetrics(SM_CXBORDER);
bh = GetSystemMetrics(SM_CYBORDER);
@@ -5034,7 +5064,7 @@
if(es->style & WS_HSCROLL) rc.bottom+=bh;
if(es->style & WS_VSCROLL) rc.right+=bw;
}
-
+
/* Draw the frame. Same code as in nonclient.c */
old_brush = SelectObject(dc, GetSysColorBrush(COLOR_WINDOWFRAME));
PatBlt(dc, rc.left, rc.top, rc.right - rc.left, bh, PATCOPY);
@@ -5042,12 +5072,12 @@
PatBlt(dc, rc.left, rc.bottom - 1, rc.right - rc.left, -bw, PATCOPY);
PatBlt(dc, rc.right - 1, rc.top, -bw, rc.bottom - rc.top, PATCOPY);
SelectObject(dc, old_brush);
-
+
/* Keep the border clean */
IntersectClipRect(dc, rc.left+bw, rc.top+bh,
max(rc.right-bw, rc.left+bw), max(rc.bottom-bh, rc.top+bh));
}
-
+
GetClipBox(dc, &rc);
FillRect(dc, &rc, brush);
@@ -5066,7 +5096,7 @@
SetTextColor(dc, GetSysColor(COLOR_GRAYTEXT));
GetClipBox(dc, &rcRgn);
if (es->style & ES_MULTILINE) {
- INT vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
+ INT vlc = get_vertical_line_count(es);
for (i = es->y_offset ; i <= min(es->y_offset + vlc, es->y_offset +
es->line_count - 1) ; i++) {
EDIT_GetLineRect(es, i, 0, -1, &rcLine);
if (IntersectRect(&rc, &rcRgn, &rcLine))
@@ -5101,14 +5131,14 @@
OpenClipboard(es->hwndSelf);
if ((hsrc = GetClipboardData(CF_UNICODETEXT))) {
- src = (LPWSTR)GlobalLock(hsrc);
+ src = GlobalLock(hsrc);
EDIT_EM_ReplaceSel(es, TRUE, src, TRUE, TRUE);
GlobalUnlock(hsrc);
}
else if (es->style & ES_PASSWORD) {
- /* clear selected text in password edit box even with empty clipboard */
- const WCHAR empty_strW[] = { 0 };
- EDIT_EM_ReplaceSel(es, TRUE, empty_strW, TRUE, TRUE);
+ /* clear selected text in password edit box even with empty clipboard */
+ const WCHAR empty_strW[] = { 0 };
+ EDIT_EM_ReplaceSel(es, TRUE, empty_strW, TRUE, TRUE);
}
CloseClipboard();
}
@@ -5168,7 +5198,7 @@
if (font)
SelectObject(dc, old_font);
ReleaseDC(es->hwndSelf, dc);
-
+
/* Reset the format rect and the margins */
GetClientRect(es->hwndSelf, &clientRect);
EDIT_SetRectNP(es, &clientRect);
@@ -5223,14 +5253,14 @@
"selection.\n");
EDIT_EM_SetSel(es, 0, (UINT)-1, FALSE);
- if (text)
+ if (text)
{
TRACE("%s\n", debugstr_w(text));
EDIT_EM_ReplaceSel(es, FALSE, text, FALSE, FALSE);
if(!unicode)
HeapFree(GetProcessHeap(), 0, textW);
- }
- else
+ }
+ else
{
static const WCHAR empty_stringW[] = {0};
TRACE("<NULL>\n");
@@ -5250,7 +5280,7 @@
EDIT_NOTIFY_PARENT(es, EN_CHANGE);
}
EDIT_EM_ScrollCaret(es);
- EDIT_UpdateScrollInfo(es);
+ EDIT_UpdateScrollInfo(es);
}
@@ -5411,7 +5441,7 @@
INT vlc, new_y;
/* Sanity check */
if(pos < 0 || pos > 100) return 0;
- vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
+ vlc = get_vertical_line_count(es);
new_y = pos * (es->line_count - vlc) / 100;
dy = es->line_count ? (new_y - es->y_offset) : 0;
TRACE("line_count=%d, y_offset=%d, pos=%d, dy = %d\n",
@@ -5429,7 +5459,7 @@
INT vlc, new_y;
/* Sanity check */
if(pos < 0 || pos > 100) return 0;
- vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
+ vlc = get_vertical_line_count(es);
new_y = pos * (es->line_count - vlc) / 100;
dy = es->line_count ? (new_y - es->y_offset) : 0;
TRACE("line_count=%d, y_offset=%d, pos=%d, dy = %d\n",
@@ -5462,7 +5492,7 @@
else
{
/* Assume default scroll range 0-100 */
- INT vlc = (es->format_rect.bottom - es->format_rect.top) /
es->line_height;
+ INT vlc = get_vertical_line_count(es);
ret = es->line_count ? es->y_offset * 100 / (es->line_count - vlc) : 0;
}
TRACE("EM_GETTHUMB: returning %ld\n", ret);
@@ -5505,7 +5535,7 @@
* EDIT_UpdateText
*
*/
-static void EDIT_UpdateText(EDITSTATE *es, LPRECT rc, BOOL bErase)
+static void EDIT_UpdateText(EDITSTATE *es, const RECT *rc, BOOL bErase)
{
if (es->flags & EF_UPDATE) {
es->flags &= ~EF_UPDATE;
@@ -5515,44 +5545,38 @@
}
/********************************************************************
- *
+ *
* The Following code is to handle inline editing from IMEs
*/
-static void EDIT_GetCompositionStr(HWND hwnd, LPARAM CompFlag, EDITSTATE *es)
-{
- DWORD dwBufLen;
+static void EDIT_GetCompositionStr(HIMC hIMC, LPARAM CompFlag, EDITSTATE *es)
+{
+ LONG buflen;
LPWSTR lpCompStr = NULL;
- HIMC hIMC;
LPSTR lpCompStrAttr = NULL;
DWORD dwBufLenAttr;
- if (!(hIMC = ImmGetContext(hwnd)))
- return;
-
- dwBufLen = ImmGetCompositionStringW(hIMC, GCS_COMPSTR, NULL, 0);
-
- if (dwBufLen <= 0)
+ buflen = ImmGetCompositionStringW(hIMC, GCS_COMPSTR, NULL, 0);
+
+ if (buflen < 0)
{
- ImmReleaseContext(hwnd, hIMC);
return;
}
- lpCompStr = HeapAlloc(GetProcessHeap(),0,dwBufLen);
+ lpCompStr = HeapAlloc(GetProcessHeap(),0,buflen + sizeof(WCHAR));
if (!lpCompStr)
{
ERR("Unable to allocate IME CompositionString\n");
- ImmReleaseContext(hwnd,hIMC);
return;
}
- if (dwBufLen)
- ImmGetCompositionStringW(hIMC, GCS_COMPSTR, lpCompStr, dwBufLen);
- lpCompStr[dwBufLen/sizeof(WCHAR)] = 0;
+ if (buflen)
+ ImmGetCompositionStringW(hIMC, GCS_COMPSTR, lpCompStr, buflen);
+ lpCompStr[buflen/sizeof(WCHAR)] = 0;
if (CompFlag & GCS_COMPATTR)
{
- /*
+ /*
* We do not use the attributes yet. it would tell us what characters
* are in transition and which are converted or decided upon
*/
@@ -5560,15 +5584,14 @@
if (dwBufLenAttr)
{
dwBufLenAttr ++;
- lpCompStrAttr = HeapAlloc(GetProcessHeap(),0,dwBufLenAttr);
+ lpCompStrAttr = HeapAlloc(GetProcessHeap(),0,dwBufLenAttr+1);
if (!lpCompStrAttr)
{
ERR("Unable to allocate IME Attribute String\n");
HeapFree(GetProcessHeap(),0,lpCompStr);
- ImmReleaseContext(hwnd,hIMC);
return;
}
- ImmGetCompositionStringW(hIMC,GCS_COMPATTR, lpCompStrAttr,
+ ImmGetCompositionStringW(hIMC,GCS_COMPATTR, lpCompStrAttr,
dwBufLenAttr);
lpCompStrAttr[dwBufLenAttr] = 0;
}
@@ -5579,7 +5602,7 @@
/* check for change in composition start */
if (es->selection_end < es->composition_start)
es->composition_start = es->selection_end;
-
+
/* replace existing selection string */
es->selection_start = es->composition_start;
@@ -5596,35 +5619,28 @@
HeapFree(GetProcessHeap(),0,lpCompStrAttr);
HeapFree(GetProcessHeap(),0,lpCompStr);
- ImmReleaseContext(hwnd,hIMC);
-}
-
-static void EDIT_GetResultStr(HWND hwnd, EDITSTATE *es)
-{
- DWORD dwBufLen;
+}
+
+static void EDIT_GetResultStr(HIMC hIMC, EDITSTATE *es)
+{
+ LONG buflen;
LPWSTR lpResultStr;
- HIMC hIMC;
-
- if ( !(hIMC = ImmGetContext(hwnd)))
- return;
-
- dwBufLen = ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, NULL, 0);
- if (dwBufLen <= 0)
+
+ buflen = ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, NULL, 0);
+ if (buflen <= 0)
{
- ImmReleaseContext(hwnd, hIMC);
return;
}
- lpResultStr = HeapAlloc(GetProcessHeap(),0, dwBufLen);
+ lpResultStr = HeapAlloc(GetProcessHeap(),0, buflen+sizeof(WCHAR));
if (!lpResultStr)
{
ERR("Unable to alloc buffer for IME string\n");
- ImmReleaseContext(hwnd, hIMC);
return;
}
- ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, lpResultStr, dwBufLen);
- lpResultStr[dwBufLen/sizeof(WCHAR)] = 0;
+ ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, lpResultStr, buflen);
+ lpResultStr[buflen/sizeof(WCHAR)] = 0;
/* check for change in composition start */
if (es->selection_end < es->composition_start)
@@ -5637,13 +5653,29 @@
es->composition_len = 0;
HeapFree(GetProcessHeap(),0,lpResultStr);
+}
+
+static void EDIT_ImeComposition(HWND hwnd, LPARAM CompFlag, EDITSTATE *es)
+{
+ HIMC hIMC;
+ int cursor;
+
+ if (es->composition_len == 0 && es->selection_start !=
es->selection_end)
+ {
+ static const WCHAR empty_stringW[] = {0};
+ EDIT_EM_ReplaceSel(es, TRUE, empty_stringW, TRUE, TRUE);
+ es->composition_start = es->selection_end;
+ }
+
+ hIMC = ImmGetContext(hwnd);
+ if (!hIMC)
+ return;
+
+ if (CompFlag & GCS_RESULTSTR)
+ EDIT_GetResultStr(hIMC, es);
+ if (CompFlag & GCS_COMPSTR)
+ EDIT_GetCompositionStr(hIMC, CompFlag, es);
+ cursor = ImmGetCompositionStringW(hIMC, GCS_CURSORPOS, 0, 0);
ImmReleaseContext(hwnd, hIMC);
-}
-
-static void EDIT_ImeComposition(HWND hwnd, LPARAM CompFlag, EDITSTATE *es)
-{
- if (CompFlag & GCS_RESULTSTR)
- EDIT_GetResultStr(hwnd,es);
- if (CompFlag & GCS_COMPSTR)
- EDIT_GetCompositionStr(hwnd, CompFlag, es);
-}
+ EDIT_SetCaretPos(es, es->selection_start + cursor, es->flags &
EF_AFTER_WRAP);
+}
Modified: trunk/reactos/dll/win32/user32/include/user32p.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/include/u…
==============================================================================
--- trunk/reactos/dll/win32/user32/include/user32p.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/user32/include/user32p.h [iso-8859-1] Mon Jan 12 16:03:00
2009
@@ -243,5 +243,11 @@
# endif
#endif
+#ifdef _MSC_VER
+#ifndef inline
+#define inline __inline
+#endif
+#endif
+
#endif
/* EOF */