Sync to Wine-20050628:
Phil Krylov <phil@newstar.rinet.ru>
- Implemented EM_GETTEXTLENGTHEX RichEdit message.
Krzysztof Foltman <wdev@foltman.com>
- added support for \ulnone (turning underline off)
- support for basic subscript and superscript
- untested support for text offset
- Emit \tx for user-defined TABs.
Dmitry Timoshkov <dmitry@codeweavers.com>
- Make remaining OLE interface vtables const.
Stefan Huehner <stefan@huehner.org>
- Fix some more -Wstrict-prototypes warnings.
Vitaly Lipatov <lav@etersoft.ru>
- Allow null pointers for EM_GETSEL message (as MSDN says).
Robert Shearman <rob@codeweavers.com>
- Richedit classes should be global.
Modified: trunk/reactos/lib/riched20/caret.c
Modified: trunk/reactos/lib/riched20/editor.c
Modified: trunk/reactos/lib/riched20/editor.h
Modified: trunk/reactos/lib/riched20/paint.c
Modified: trunk/reactos/lib/riched20/richole.c
Modified: trunk/reactos/lib/riched20/style.c
Modified: trunk/reactos/lib/riched20/writer.c

Modified: trunk/reactos/lib/riched20/caret.c
--- trunk/reactos/lib/riched20/caret.c	2005-08-04 00:16:41 UTC (rev 17040)
+++ trunk/reactos/lib/riched20/caret.c	2005-08-04 06:52:58 UTC (rev 17041)
@@ -41,6 +41,38 @@
   return ME_CharOfsFromRunOfs(editor, ME_FindItemBack(editor->pBuffer->pLast, diRun), 0);   
 }
 
+
+int ME_GetTextLengthEx(ME_TextEditor *editor, GETTEXTLENGTHEX *how)
+{
+  int length;
+  
+  if (how->flags & GTL_PRECISE && how->flags & GTL_CLOSE)
+    return E_INVALIDARG;
+  if (how->flags & GTL_NUMCHARS && how->flags & GTL_NUMBYTES)
+    return E_INVALIDARG;
+  
+  length = ME_GetTextLength(editor);
+  
+  if (how->flags & GTL_USECRLF)
+    length += editor->nParagraphs;
+  
+  if (how->flags & GTL_NUMBYTES)
+  {
+    CPINFO cpinfo;
+    
+    if (how->codepage == 1200)
+      return length * 2;
+    if (how->flags & GTL_PRECISE)
+      FIXME("GTL_PRECISE flag unsupported. Using GTL_CLOSE\n");
+    if (GetCPInfo(how->codepage, &cpinfo))
+      return length * cpinfo.MaxCharSize;
+    ERR("Invalid codepage %u\n", how->codepage);
+    return E_INVALIDARG;
+  }
+  return length; 
+}
+
+
 void ME_SetSelection(ME_TextEditor *editor, int from, int to)
 {
   if (from == 0 && to == -1)

Modified: trunk/reactos/lib/riched20/editor.c
--- trunk/reactos/lib/riched20/editor.c	2005-08-04 00:16:41 UTC (rev 17040)
+++ trunk/reactos/lib/riched20/editor.c	2005-08-04 06:52:58 UTC (rev 17041)
@@ -65,7 +65,7 @@
   - EM_GETSCROLLPOS 3.0
 ! - EM_GETTHUMB
   - EM_GETTEXTEX 2.0
-  - EM_GETTEXTLENGTHEX
+  + EM_GETTEXTLENGTHEX (GTL_PRECISE unimplemented)
   - EM_GETTEXTMODE 2.0
 ? + EM_GETTEXTRANGE (ANSI&Unicode)
   - EM_GETTYPOGRAPHYOPTIONS 3.0
@@ -231,7 +231,7 @@
 int me_debug = 0;
 HANDLE me_heap = NULL;
 
-ME_TextBuffer *ME_MakeText() {
+ME_TextBuffer *ME_MakeText(void) {
   
   ME_TextBuffer *buf = ALLOC_OBJ(ME_TextBuffer);
 
@@ -321,11 +321,26 @@
     case rtfUnderline:
       fmt.dwMask = CFM_UNDERLINE;
       fmt.dwEffects = info->rtfParam ? fmt.dwMask : 0;
+      fmt.bUnderlineType = CFU_CF1UNDERLINE;
       break;
+    case rtfNoUnderline:
+      fmt.dwMask = CFM_UNDERLINE;
+      fmt.dwEffects = 0;
+      break;
     case rtfStrikeThru:
       fmt.dwMask = CFM_STRIKEOUT;
       fmt.dwEffects = info->rtfParam ? fmt.dwMask : 0;
       break;
+    case rtfSubScript:
+    case rtfSuperScript:
+    case rtfSubScrShrink:
+    case rtfSuperScrShrink:
+    case rtfNoSuperSub:
+      fmt.dwMask = CFM_SUBSCRIPT|CFM_SUPERSCRIPT;
+      if (info->rtfMinor == rtfSubScrShrink) fmt.dwEffects = CFE_SUBSCRIPT;
+      if (info->rtfMinor == rtfSuperScrShrink) fmt.dwEffects = CFE_SUPERSCRIPT;
+      if (info->rtfMinor == rtfNoSuperSub) fmt.dwEffects = 0;
+      break;
     case rtfBackColor:
       fmt.dwMask = CFM_BACKCOLOR;
       fmt.dwEffects = 0;
@@ -831,7 +846,6 @@
   UNSUPPORTED_MSG(EM_GETREDONAME)
   UNSUPPORTED_MSG(EM_GETSCROLLPOS)
   UNSUPPORTED_MSG(EM_GETTEXTEX)
-  UNSUPPORTED_MSG(EM_GETTEXTLENGTHEX)
   UNSUPPORTED_MSG(EM_GETTEXTMODE)
   UNSUPPORTED_MSG(EM_GETTYPOGRAPHYOPTIONS)
   UNSUPPORTED_MSG(EM_GETUNDONAME)
@@ -901,10 +915,14 @@
     return 0;
   case EM_GETSEL:
   {
-    ME_GetSelection(editor, (int *)wParam, (int *)lParam);
-    if (!((wParam|lParam) & 0xFFFF0000))
-      return (lParam<<16)|wParam;
-    return -1;
+    /* Note: wParam/lParam can be NULL */
+    UINT from, to;
+    PUINT pfrom = wParam ? (PUINT)wParam : &from;
+    PUINT pto = lParam ? (PUINT)lParam : &to;
+    ME_GetSelection(editor, pfrom, pto);
+    if ((*pfrom|*pto) & 0xFFFF0000)
+      return -1;
+    return MAKELONG(*pfrom,*pto);
   }
   case EM_EXGETSEL:
   {
@@ -1156,6 +1174,8 @@
   }
   case WM_GETTEXTLENGTH:
     return ME_GetTextLength(editor);
+  case EM_GETTEXTLENGTHEX:
+    return ME_GetTextLengthEx(editor, (GETTEXTLENGTHEX *)wParam);
   case WM_GETTEXT:
   {
     TEXTRANGEW tr; /* W and A differ only by rng->lpstrText */
@@ -1464,7 +1484,7 @@
   WNDCLASSW wcW;
   WNDCLASSA wcA;
   
-  wcW.style = CS_HREDRAW | CS_VREDRAW;
+  wcW.style = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
   wcW.lpfnWndProc = RichEditANSIWndProc;
   wcW.cbClsExtra = 0;
   wcW.cbWndExtra = 4;
@@ -1480,7 +1500,7 @@
   bResult = RegisterClassW(&wcW);  
   assert(bResult);
 
-  wcA.style = CS_HREDRAW | CS_VREDRAW;
+  wcA.style = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
   wcA.lpfnWndProc = RichEditANSIWndProc;
   wcA.cbClsExtra = 0;
   wcA.cbWndExtra = 4;

Modified: trunk/reactos/lib/riched20/editor.h
--- trunk/reactos/lib/riched20/editor.h	2005-08-04 00:16:41 UTC (rev 17040)
+++ trunk/reactos/lib/riched20/editor.h	2005-08-04 06:52:58 UTC (rev 17041)
@@ -160,6 +160,7 @@
 void ME_InsertGraphicsFromCursor(ME_TextEditor *editor, int nCursor);
 void ME_InternalDeleteText(ME_TextEditor *editor, int nOfs, int nChars);
 int ME_GetTextLength(ME_TextEditor *editor);
+int ME_GetTextLengthEx(ME_TextEditor *editor, GETTEXTLENGTHEX *how);
 ME_Style *ME_GetSelectionInsertStyle(ME_TextEditor *editor);
 BOOL ME_UpdateSelection(ME_TextEditor *editor, ME_Cursor *pTempCursor);
 
@@ -202,7 +203,7 @@
 /* wintest.c */
 
 /* editor.c */
-void ME_RegisterEditorClass();
+void ME_RegisterEditorClass(HINSTANCE hInstance);
 ME_TextEditor *ME_MakeEditor(HWND hWnd);
 void ME_DestroyEditor(ME_TextEditor *editor);
 void ME_SendOldNotify(ME_TextEditor *editor, int nCode);

Modified: trunk/reactos/lib/riched20/paint.c
--- trunk/reactos/lib/riched20/paint.c	2005-08-04 00:16:41 UTC (rev 17040)
+++ trunk/reactos/lib/riched20/paint.c	2005-08-04 06:52:58 UTC (rev 17041)
@@ -178,13 +178,23 @@
   HDC hDC = c->hDC;
   HGDIOBJ hOldFont;
   COLORREF rgbOld, rgbBack;
+  int yOffset = 0, yTwipsOffset = 0;
   hOldFont = ME_SelectStyleFont(c->editor, hDC, s);
   rgbBack = ME_GetBackColor(c->editor);
   if ((s->fmt.dwMask & CFM_COLOR) && (s->fmt.dwEffects & CFE_AUTOCOLOR))
     rgbOld = SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT));
   else
     rgbOld = SetTextColor(hDC, s->fmt.crTextColor);
-  ExtTextOutW(hDC, x, y, 0, NULL, szText, nChars, NULL);
+  if ((s->fmt.dwMask & s->fmt.dwEffects) & CFM_OFFSET) {
+    yTwipsOffset = s->fmt.yOffset;
+  }
+  if ((s->fmt.dwMask & s->fmt.dwEffects) & (CFM_SUPERSCRIPT | CFM_SUBSCRIPT)) {
+    if (s->fmt.dwEffects & CFE_SUPERSCRIPT) yTwipsOffset = s->fmt.yHeight/3;
+    if (s->fmt.dwEffects & CFE_SUBSCRIPT) yTwipsOffset = -s->fmt.yHeight/12;
+  }
+  if (yTwipsOffset)
+    yOffset = yTwipsOffset*GetDeviceCaps(hDC, LOGPIXELSY)/1440;
+  ExtTextOutW(hDC, x, y-yOffset, 0, NULL, szText, nChars, NULL);
   if (width) {
     SIZE sz;
     GetTextExtentPoint32W(hDC, szText, nChars, &sz);

Modified: trunk/reactos/lib/riched20/richole.c
--- trunk/reactos/lib/riched20/richole.c	2005-08-04 00:16:41 UTC (rev 17040)
+++ trunk/reactos/lib/riched20/richole.c	2005-08-04 06:52:58 UTC (rev 17041)
@@ -36,7 +36,7 @@
 WINE_DEFAULT_DEBUG_CHANNEL(richedit);
 
 typedef struct IRichEditOleImpl {
-    IRichEditOleVtbl *lpVtbl;
+    const IRichEditOleVtbl *lpVtbl;
     DWORD ref;
 } IRichEditOleImpl;
 
@@ -228,7 +228,7 @@
     return E_NOTIMPL;
 }
 
-static IRichEditOleVtbl revt = {
+static const IRichEditOleVtbl revt = {
     IRichEditOle_fnQueryInterface,
     IRichEditOle_fnAddRef,
     IRichEditOle_fnRelease,

Modified: trunk/reactos/lib/riched20/style.c
--- trunk/reactos/lib/riched20/style.c	2005-08-04 00:16:41 UTC (rev 17040)
+++ trunk/reactos/lib/riched20/style.c	2005-08-04 06:52:58 UTC (rev 17041)
@@ -268,6 +268,8 @@
     lf->lfUnderline = 1;
   if (s->fmt.dwEffects & s->fmt.dwMask & CFM_STRIKEOUT)
     lf->lfStrikeOut = 1;
+  if (s->fmt.dwEffects & s->fmt.dwMask & (CFM_SUBSCRIPT|CFM_SUPERSCRIPT))
+    lf->lfHeight = (lf->lfHeight*2)/3;
 /*lf.lfQuality = PROOF_QUALITY; */
   lf->lfPitchAndFamily = s->fmt.bPitchAndFamily;
   lf->lfCharSet = s->fmt.bCharSet;

Modified: trunk/reactos/lib/riched20/writer.c
--- trunk/reactos/lib/riched20/writer.c	2005-08-04 00:16:41 UTC (rev 17040)
+++ trunk/reactos/lib/riched20/writer.c	2005-08-04 06:52:58 UTC (rev 17041)
@@ -45,11 +45,23 @@
 {
   LONG nStart = 0;
   LONG nWritten = 0;
+  LONG nRemaining = 0;
   EDITSTREAM *stream = editor->pStream->stream;
 
   do {
+    TRACE("sending %lu bytes\n", editor->pStream->pos - nStart);
+    /* Some apps seem not to set *pcb unless a problem arises, relying
+      on initial random nWritten value, which is usually >STREAMOUT_BUFFER_SIZE */
+    nRemaining = editor->pStream->pos - nStart;
+    nWritten = 0xDEADBEEF;
     stream->dwError = stream->pfnCallback(stream->dwCookie, editor->pStream->buffer + nStart,
                                           editor->pStream->pos - nStart, &nWritten);
+    TRACE("error=%lu written=%lu\n", stream->dwError, nWritten);
+    if (nWritten > (editor->pStream->pos - nStart) || nWritten<0) {
+      FIXME("Invalid returned written size *pcb: 0x%x (%ld) instead of %ld\n", 
+            (unsigned)nWritten, nWritten, nRemaining);
+      nWritten = nRemaining;
+    }
     if (nWritten == 0 || stream->dwError)
       return FALSE;
     editor->pStream->written += nWritten;
@@ -64,6 +76,7 @@
 ME_StreamOutFree(ME_TextEditor *editor)
 {
   LONG written = editor->pStream->written;
+  TRACE("total length = %lu\n", written);
 
   FREE_OBJ(editor->pStream);
   editor->pStream = NULL;
@@ -379,6 +392,7 @@
       }
       if (fmt->rgxTabs[i] >> 28 <= 5)
         strcat(props, leader[fmt->rgxTabs[i] >> 28]);
+      sprintf(props+strlen(props), "\\tx%ld", fmt->rgxTabs[i]&0x00FFFFFF);
     }
   }
     
@@ -781,7 +795,7 @@
     ME_StreamOutRTF(editor, nStart, nTo - nStart, dwFormat);
   else if (dwFormat & SF_TEXT || dwFormat & SF_TEXTIZED)
     ME_StreamOutText(editor, nStart, nTo - nStart, dwFormat);
-  
-  ME_StreamOutFlush(editor);
+  if (!editor->pStream->stream->dwError)
+    ME_StreamOutFlush(editor);
   return ME_StreamOutFree(editor);
 }