[ros-diffs] [fireball] 22631: - Sync edit control with Wine code - Add imm32 dependency to user32, which is needed for edit control. This may not be a good solution, since Windows XP's user32.dll doesn't import imm32.dll. So maybe in future this should change to dynamic binding instead. But for now it works - Update Wine-sync doc This update reduces number of failing "user32_winetest.exe edit" tests from 44 to 43.

fireball at svn.reactos.org fireball at svn.reactos.org
Mon Jun 26 11:20:48 CEST 2006


Author: fireball
Date: Mon Jun 26 13:20:47 2006
New Revision: 22631

URL: http://svn.reactos.org/svn/reactos?rev=22631&view=rev
Log:
- Sync edit control with Wine code
- Add imm32 dependency to user32, which is needed for edit control. This may not be a good solution, since Windows XP's user32.dll doesn't import imm32.dll. So maybe in future this should change to dynamic binding instead. But for now it works
- Update Wine-sync doc

This update reduces number of failing "user32_winetest.exe edit" tests from 44 to 43.

Modified:
    trunk/reactos/dll/win32/user32/controls/edit.c
    trunk/reactos/dll/win32/user32/user32.rbuild
    trunk/reactos/media/doc/README.WINE

Modified: trunk/reactos/dll/win32/user32/controls/edit.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/controls/edit.c?rev=22631&r1=22630&r2=22631&view=diff
==============================================================================
--- trunk/reactos/dll/win32/user32/controls/edit.c (original)
+++ trunk/reactos/dll/win32/user32/controls/edit.c Mon Jun 26 13:20:47 2006
@@ -141,6 +141,11 @@
 #endif
 	HLOCAL hloc32A;			/* alias for ANSI control receiving EM_GETHANDLE
 				   	   or EM_SETHANDLE */
+	/*
+	 * IME Data
+	 */
+	UINT composition_len;   /* length of composition, 0 == no composition */
+	int composition_start;  /* the character position for the composition */
 } EDITSTATE;
 
 
@@ -203,6 +208,7 @@
 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_UnlockBuffer(EDITSTATE *es, BOOL force);
 static void	EDIT_UpdateScrollInfo(EDITSTATE *es);
@@ -277,6 +283,7 @@
 static LRESULT	EDIT_WM_VScroll(EDITSTATE *es, INT action, INT pos);
 static void	EDIT_UpdateText(EDITSTATE *es, LPRECT rc, BOOL bErase);
 static void	EDIT_UpdateTextRegion(EDITSTATE *es, HRGN hrgn, BOOL bErase);
+static void EDIT_ImeComposition(HWND hwnd, LPARAM CompFlag, EDITSTATE *es);
 
 LRESULT WINAPI EditWndProcA(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
 LRESULT WINAPI EditWndProcW(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
@@ -1048,12 +1055,60 @@
                     }
                 }
                 break;
+
+            
+	/* 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:
+		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);
+		break;
+
+	case WM_IME_ENDCOMPOSITION:
+		es->composition_len= 0;
+		break;
+
+	case WM_IME_COMPOSITIONFULL:
+		break;
+
+	case WM_IME_SELECT:
+		break;
+
+	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);
 
 	return result;
 }
@@ -1300,7 +1355,7 @@
 			es->line_count--;
 		}
 	}
-	else
+	else if (delta != 0)
 	{
 		while (current_line)
 		{
@@ -1401,17 +1456,9 @@
  */
 static INT EDIT_CallWordBreakProc(EDITSTATE *es, INT start, INT index, INT count, INT action)
 {
-#ifdef __REACTOS__
     INT ret;
-#else
-    INT ret, iWndsLocks;
-#endif
-
-    /* To avoid any deadlocks, all the locks on the window structures
-       must be suspended before the control is passed to the application */
+
 #ifndef __REACTOS__
-    iWndsLocks = WIN_SuspendWndsLock();
-
 	if (es->word_break_proc16) {
 	    HGLOBAL16 hglob16;
 	    SEGPTR segptr;
@@ -1464,9 +1511,6 @@
 	else
             ret = EDIT_WordBreakProc(es->text + start, index, count, action);
 
-#ifndef __REACTOS__
-    WIN_RestoreWndsLock(iWndsLocks);
-#endif
     return ret;
 }
 
@@ -1680,7 +1724,7 @@
  *
  *	Initially the edit control allocates a HLOCAL32 buffer
  *	(32 bit linear memory handler).  However, 16 bit application
- *	might send a EM_GETHANDLE message and expect a HLOCAL16 (16 bit SEG:OFF
+ *	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
  *	handler, because it is supposed to be valid at all times after EM_GETHANDLE.
  *	What we do is create a HLOCAL16 buffer, copy the text, and do pointer
@@ -1846,7 +1890,7 @@
  *
  *	EDIT_InvalidateText
  *
- *	Invalidate the text from offset start upto, but not including,
+ *	Invalidate the text from offset start up to, but not including,
  *	offset end.  Useful for (re)painting the selection.
  *	Regions outside the linewidth are not invalidated.
  *	end == -1 means end == TextLength.
@@ -2254,6 +2298,9 @@
 {
 	COLORREF BkColor;
 	COLORREF TextColor;
+	LOGFONTW underline_font;
+	HFONT hUnderline = 0;
+	HFONT old_font = 0;
 	INT ret;
 	INT li;
 	INT BkMode;
@@ -2265,9 +2312,20 @@
 	BkColor = GetBkColor(dc);
 	TextColor = GetTextColor(dc);
 	if (rev) {
+	        if (es->composition_len == 0)
+	        {
 		SetBkColor(dc, GetSysColor(COLOR_HIGHLIGHT));
 		SetTextColor(dc, GetSysColor(COLOR_HIGHLIGHTTEXT));
 		SetBkMode( dc, OPAQUE);
+	}
+		else
+		{
+			HFONT current = GetCurrentObject(dc,OBJ_FONT);
+			GetObjectW(current,sizeof(LOGFONTW),&underline_font);
+			underline_font.lfUnderline = TRUE;
+	            	hUnderline = CreateFontIndirectW(&underline_font);
+			old_font = SelectObject(dc,hUnderline);
+	        }
 	}
 	li = EDIT_EM_LineIndex(es, line);
 	if (es->style & ES_MULTILINE) {
@@ -2282,9 +2340,19 @@
 			HeapFree(GetProcessHeap(), 0, text);
 	}
 	if (rev) {
+		if (es->composition_len == 0)
+		{
 		SetBkColor(dc, BkColor);
 		SetTextColor(dc, TextColor);
 		SetBkMode( dc, BkMode);
+	}
+		else
+		{
+			if (old_font)
+				SelectObject(dc,old_font);
+			if (hUnderline)
+				DeleteObject(hUnderline);
+	        }
 	}
 	return ret;
 }
@@ -2408,9 +2476,6 @@
  */
 static void EDIT_UnlockBuffer(EDITSTATE *es, BOOL force)
 {
-#ifndef __REACTOS__
-	HINSTANCE16 hInstance = GetWindowLongW( es->hwndSelf, GWL_HINSTANCE );
-#endif
 
 	/* Edit window might be already destroyed */
 	if(!IsWindow(es->hwndSelf))
@@ -2431,11 +2496,12 @@
 	if (force || (es->lock_count == 1)) {
 	    if (es->hloc32W) {
 		CHAR *textA = NULL;
-#ifndef __REACTOS__
-		BOOL _16bit = FALSE;
-#endif
 		UINT countA = 0;
 		UINT countW = strlenW(es->text) + 1;
+#ifndef __REACTOS__
+		STACK16FRAME* stack16 = NULL;
+	        HANDLE16 oldDS = 0;
+#endif
 
 		if(es->hloc32A)
 		{
@@ -2552,7 +2618,7 @@
  *
  *	Find the beginning of words.
  *	Note:	unlike the specs for a WordBreakProc, this function only
- *		allows to be called without linebreaks between s[0] upto
+ *		allows to be called without linebreaks between s[0] up to
  *		s[count - 1].  Remember it is only called
  *		internally, so we can decide this for ourselves.
  *
@@ -3006,7 +3072,7 @@
 		dx = es->text_width - x_offset_in_pixels;
 	nyoff = max(0, es->y_offset + dy);
 	if (nyoff >= es->line_count - lines_per_page)
-		nyoff = max(0,es->line_count - lines_per_page);
+		nyoff = max(0, es->line_count - lines_per_page);
 	dy = (es->y_offset - nyoff) * es->line_height;
 	if (dx || dy) {
 		RECT rc1;
@@ -3469,10 +3535,6 @@
  */
 static void EDIT_EM_SetHandle(EDITSTATE *es, HLOCAL hloc)
 {
-#ifndef __REACTOS__
-	HINSTANCE16 hInstance = GetWindowLongW( es->hwndSelf, GWL_HINSTANCE );
-#endif
-
 	if (!(es->style & ES_MULTILINE))
 		return;
 
@@ -4142,7 +4204,7 @@
         EDIT_SetRectNP(es, &clientRect);
 
        if (name && *name) {
-	   EDIT_EM_ReplaceSel(es, FALSE, name, FALSE, TRUE);
+	   EDIT_EM_ReplaceSel(es, FALSE, name, FALSE, FALSE);
 	   /* if we insert text to the editline, the text scrolls out
             * of the window, as the caret is placed after the insert
             * pos normally; thus we reset es->selection... to 0 and
@@ -4241,7 +4303,6 @@
 	return strlen(textA);
     }
 }
-
 
 /*********************************************************************
  *
@@ -4706,7 +4767,7 @@
 
 	if (!(es = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*es))))
 		return FALSE;
-        SetWindowLongPtrW( hwnd, 0, (LONG)es );
+        SetWindowLongPtrW( hwnd, 0, (LONG_PTR)es );
 
        /*
         *      Note: since the EDITSTATE has not been fully initialized yet,
@@ -5304,3 +5365,136 @@
     }
     InvalidateRect(es->hwndSelf, rc, bErase);
 }
+
+/********************************************************************
+ * 
+ * The Following code is to handle inline editing from IMEs
+ */
+
+static void EDIT_GetCompositionStr(HWND hwnd, LPARAM CompFlag, EDITSTATE *es)
+{
+    DWORD dwBufLen;
+    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)
+    {
+        ImmReleaseContext(hwnd, hIMC);
+        return;
+    }
+
+    lpCompStr = HeapAlloc(GetProcessHeap(),0,dwBufLen);
+    if (!lpCompStr)
+    {
+        ERR("Unable to allocate IME CompositionString\n");
+        ImmReleaseContext(hwnd,hIMC);
+        return;
+    }
+
+    ImmGetCompositionStringW(hIMC, GCS_COMPSTR, lpCompStr, dwBufLen);
+    lpCompStr[dwBufLen/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
+         */
+        dwBufLenAttr = ImmGetCompositionStringW(hIMC, GCS_COMPATTR, NULL, 0);
+        if (dwBufLenAttr)
+        {
+            dwBufLenAttr ++;
+            lpCompStrAttr = HeapAlloc(GetProcessHeap(),0,dwBufLenAttr);
+            if (!lpCompStrAttr)
+            {
+                ERR("Unable to allocate IME Attribute String\n");
+                HeapFree(GetProcessHeap(),0,lpCompStr);
+                ImmReleaseContext(hwnd,hIMC);
+                return;
+            }
+            ImmGetCompositionStringW(hIMC,GCS_COMPATTR, lpCompStrAttr, 
+                    dwBufLenAttr);
+            lpCompStrAttr[dwBufLenAttr] = 0;
+        }
+        else
+            lpCompStrAttr = NULL;
+    }
+
+    /* 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;
+
+    if (es->composition_len > 0)
+        es->selection_end = es->composition_start + es->composition_len;
+    else
+        es->selection_end = es->selection_start;
+
+    EDIT_EM_ReplaceSel(es, FALSE, lpCompStr, TRUE, TRUE);
+    es->composition_len = abs(es->composition_start - es->selection_end);
+
+    es->selection_start = es->composition_start;
+    es->selection_end = es->selection_start + es->composition_len;
+
+    HeapFree(GetProcessHeap(),0,lpCompStrAttr);
+    HeapFree(GetProcessHeap(),0,lpCompStr);
+    ImmReleaseContext(hwnd,hIMC);
+}
+
+static void EDIT_GetResultStr(HWND hwnd, EDITSTATE *es)
+{
+    DWORD dwBufLen;
+    LPWSTR lpResultStr;
+    HIMC    hIMC;
+
+    if ( !(hIMC = ImmGetContext(hwnd)))
+        return;
+
+    dwBufLen = ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, NULL, 0);
+    if (dwBufLen <= 0)
+    {
+        ImmReleaseContext(hwnd, hIMC);
+        return;
+    }
+
+    lpResultStr = HeapAlloc(GetProcessHeap(),0, dwBufLen);
+    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;
+
+    /* check for change in composition start */
+    if (es->selection_end < es->composition_start)
+        es->composition_start = es->selection_end;
+
+    es->selection_start = es->composition_start;
+    es->selection_end = es->composition_start + es->composition_len;
+    EDIT_EM_ReplaceSel(es, TRUE, lpResultStr, TRUE, TRUE);
+    es->composition_start = es->selection_end;
+    es->composition_len = 0;
+
+    HeapFree(GetProcessHeap(),0,lpResultStr);
+    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);
+}

Modified: trunk/reactos/dll/win32/user32/user32.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/user32.rbuild?rev=22631&r1=22630&r2=22631&view=diff
==============================================================================
--- trunk/reactos/dll/win32/user32/user32.rbuild (original)
+++ trunk/reactos/dll/win32/user32/user32.rbuild Mon Jun 26 13:20:47 2006
@@ -14,6 +14,7 @@
 	<library>gdi32</library>
 	<library>kernel32</library>
 	<library>advapi32</library>
+	<library>imm32</library>
 	<directory name="include">
 		<pch>user32.h</pch>
 	</directory>

Modified: trunk/reactos/media/doc/README.WINE
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/media/doc/README.WINE?rev=22631&r1=22630&r2=22631&view=diff
==============================================================================
--- trunk/reactos/media/doc/README.WINE (original)
+++ trunk/reactos/media/doc/README.WINE Mon Jun 26 13:20:47 2006
@@ -116,7 +116,7 @@
 User32 -
   reactos/dll/win32/user32/controls/button.c    # Synced at 20060621
   reactos/dll/win32/user32/controls/combo.c     # Synced at 20060617
-  reactos/dll/win32/user32/controls/edit.c      # Synced at 20051210
+  reactos/dll/win32/user32/controls/edit.c      # Synced at 20060623
   reactos/dll/win32/user32/controls/icontitle.c # Synced at 20060617
   reactos/dll/win32/user32/controls/listbox.c   # Synced at 20060616
   reactos/dll/win32/user32/controls/scrollbar.c # Forked




More information about the Ros-diffs mailing list