[PATCH 1/5] riched20: Move the window procs to txthost.c .

Huw Davies huw at codeweavers.com
Wed Mar 3 05:29:37 CST 2021


Signed-off-by: Huw Davies <huw at codeweavers.com>
---
 dlls/riched20/editor.c  | 477 +---------------------------------------
 dlls/riched20/editor.h  |   2 +-
 dlls/riched20/txthost.c | 372 ++++++++++++++++++++++++++++++-
 3 files changed, 378 insertions(+), 473 deletions(-)

diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c
index f0662682044..487d4137391 100644
--- a/dlls/riched20/editor.c
+++ b/dlls/riched20/editor.c
@@ -233,7 +233,6 @@
 #include "shlwapi.h"
 #include "rtf.h"
 #include "imm.h"
-#include "res.h"
 
 #define STACK_SIZE_DEFAULT  100
 #define STACK_SIZE_MAX     1000
@@ -242,21 +241,12 @@
  
 WINE_DEFAULT_DEBUG_CHANNEL(richedit);
 
-static BOOL ME_RegisterEditorClass(HINSTANCE);
 static BOOL ME_UpdateLinkAttribute(ME_TextEditor *editor, ME_Cursor *start, int nChars);
-static HCURSOR hLeft;
 
+HCURSOR cursor_reverse = NULL;
 BOOL me_debug = FALSE;
 HANDLE me_heap = NULL;
 
-static BOOL ME_ListBoxRegistered = FALSE;
-static BOOL ME_ComboBoxRegistered = FALSE;
-
-static inline BOOL is_version_nt(void)
-{
-    return !(GetVersion() & 0x80000000);
-}
-
 static ME_TextBuffer *ME_MakeText(void) {
   ME_TextBuffer *buf = heap_alloc(sizeof(*buf));
   ME_DisplayItem *p1 = ME_MakeDI(diTextStart);
@@ -2939,15 +2929,16 @@ static BOOL ME_SetCursor(ME_TextEditor *editor)
   }
   ITextHost_TxScreenToClient(editor->texthost, &pt);
 
-  if (editor->nSelectionType == stLine && editor->bMouseCaptured) {
-      ITextHost_TxSetCursor(editor->texthost, hLeft, FALSE);
+  if (editor->nSelectionType == stLine && editor->bMouseCaptured)
+  {
+      ITextHost_TxSetCursor( editor->texthost, cursor_reverse, FALSE );
       return TRUE;
   }
   if (!editor->bEmulateVersion10 /* v4.1 */ &&
       pt.y < editor->rcFormat.top &&
       pt.x < editor->rcFormat.left)
   {
-      ITextHost_TxSetCursor(editor->texthost, hLeft, FALSE);
+      ITextHost_TxSetCursor( editor->texthost, cursor_reverse, FALSE );
       return TRUE;
   }
   if (pt.y < editor->rcFormat.top || pt.y > editor->rcFormat.bottom)
@@ -2962,7 +2953,7 @@ static BOOL ME_SetCursor(ME_TextEditor *editor)
   }
   if (pt.x < editor->rcFormat.left)
   {
-      ITextHost_TxSetCursor(editor->texthost, hLeft, FALSE);
+      ITextHost_TxSetCursor( editor->texthost, cursor_reverse, FALSE );
       return TRUE;
   }
   ME_CharFromPos(editor, pt.x, pt.y, &cursor, &isExact);
@@ -3243,37 +3234,6 @@ void ME_DestroyEditor(ME_TextEditor *editor)
   heap_free(editor);
 }
 
-BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
-{
-    TRACE("\n");
-    switch (fdwReason)
-    {
-    case DLL_PROCESS_ATTACH:
-      DisableThreadLibraryCalls(hinstDLL);
-      me_heap = HeapCreate (0, 0x10000, 0);
-      if (!ME_RegisterEditorClass(hinstDLL)) return FALSE;
-      hLeft = LoadCursorW(hinstDLL, MAKEINTRESOURCEW(OCR_REVERSE));
-      LookupInit();
-      break;
-
-    case DLL_PROCESS_DETACH:
-      if (lpvReserved) break;
-      UnregisterClassW(RICHEDIT_CLASS20W, 0);
-      UnregisterClassW(MSFTEDIT_CLASS, 0);
-      UnregisterClassA(RICHEDIT_CLASS20A, 0);
-      UnregisterClassA("RichEdit50A", 0);
-      if (ME_ListBoxRegistered)
-          UnregisterClassW(L"REListBox20W", 0);
-      if (ME_ComboBoxRegistered)
-          UnregisterClassW(L"REComboBox20W", 0);
-      LookupCleanup();
-      HeapDestroy (me_heap);
-      release_typelib();
-      break;
-    }
-    return TRUE;
-}
-
 static inline int get_default_line_height( ME_TextEditor *editor )
 {
     int height = 0;
@@ -3292,142 +3252,6 @@ static inline int calc_wheel_change( int *remain, int amount_per_click )
     return change;
 }
 
-static const char * const edit_messages[] = {
-  "EM_GETSEL",
-  "EM_SETSEL",
-  "EM_GETRECT",
-  "EM_SETRECT",
-  "EM_SETRECTNP",
-  "EM_SCROLL",
-  "EM_LINESCROLL",
-  "EM_SCROLLCARET",
-  "EM_GETMODIFY",
-  "EM_SETMODIFY",
-  "EM_GETLINECOUNT",
-  "EM_LINEINDEX",
-  "EM_SETHANDLE",
-  "EM_GETHANDLE",
-  "EM_GETTHUMB",
-  "EM_UNKNOWN_BF",
-  "EM_UNKNOWN_C0",
-  "EM_LINELENGTH",
-  "EM_REPLACESEL",
-  "EM_UNKNOWN_C3",
-  "EM_GETLINE",
-  "EM_LIMITTEXT",
-  "EM_CANUNDO",
-  "EM_UNDO",
-  "EM_FMTLINES",
-  "EM_LINEFROMCHAR",
-  "EM_UNKNOWN_CA",
-  "EM_SETTABSTOPS",
-  "EM_SETPASSWORDCHAR",
-  "EM_EMPTYUNDOBUFFER",
-  "EM_GETFIRSTVISIBLELINE",
-  "EM_SETREADONLY",
-  "EM_SETWORDBREAKPROC",
-  "EM_GETWORDBREAKPROC",
-  "EM_GETPASSWORDCHAR",
-  "EM_SETMARGINS",
-  "EM_GETMARGINS",
-  "EM_GETLIMITTEXT",
-  "EM_POSFROMCHAR",
-  "EM_CHARFROMPOS",
-  "EM_SETIMESTATUS",
-  "EM_GETIMESTATUS"
-};
-
-static const char * const richedit_messages[] = {
-  "EM_CANPASTE",
-  "EM_DISPLAYBAND",
-  "EM_EXGETSEL",
-  "EM_EXLIMITTEXT",
-  "EM_EXLINEFROMCHAR",
-  "EM_EXSETSEL",
-  "EM_FINDTEXT",
-  "EM_FORMATRANGE",
-  "EM_GETCHARFORMAT",
-  "EM_GETEVENTMASK",
-  "EM_GETOLEINTERFACE",
-  "EM_GETPARAFORMAT",
-  "EM_GETSELTEXT",
-  "EM_HIDESELECTION", 
-  "EM_PASTESPECIAL",
-  "EM_REQUESTRESIZE",
-  "EM_SELECTIONTYPE",
-  "EM_SETBKGNDCOLOR",
-  "EM_SETCHARFORMAT",
-  "EM_SETEVENTMASK",
-  "EM_SETOLECALLBACK",
-  "EM_SETPARAFORMAT",
-  "EM_SETTARGETDEVICE",
-  "EM_STREAMIN",
-  "EM_STREAMOUT",
-  "EM_GETTEXTRANGE",
-  "EM_FINDWORDBREAK",
-  "EM_SETOPTIONS",
-  "EM_GETOPTIONS",
-  "EM_FINDTEXTEX",
-  "EM_GETWORDBREAKPROCEX",
-  "EM_SETWORDBREAKPROCEX",
-  "EM_SETUNDOLIMIT",
-  "EM_UNKNOWN_USER_83",
-  "EM_REDO",
-  "EM_CANREDO",
-  "EM_GETUNDONAME",
-  "EM_GETREDONAME",
-  "EM_STOPGROUPTYPING",
-  "EM_SETTEXTMODE",
-  "EM_GETTEXTMODE",
-  "EM_AUTOURLDETECT",
-  "EM_GETAUTOURLDETECT",
-  "EM_SETPALETTE",
-  "EM_GETTEXTEX",
-  "EM_GETTEXTLENGTHEX",
-  "EM_SHOWSCROLLBAR",
-  "EM_SETTEXTEX",
-  "EM_UNKNOWN_USER_98",
-  "EM_UNKNOWN_USER_99",
-  "EM_SETPUNCTUATION",
-  "EM_GETPUNCTUATION",
-  "EM_SETWORDWRAPMODE",
-  "EM_GETWORDWRAPMODE",
-  "EM_SETIMECOLOR",
-  "EM_GETIMECOLOR",
-  "EM_SETIMEOPTIONS",
-  "EM_GETIMEOPTIONS",
-  "EM_CONVPOSITION",
-  "EM_UNKNOWN_USER_109",
-  "EM_UNKNOWN_USER_110",
-  "EM_UNKNOWN_USER_111",
-  "EM_UNKNOWN_USER_112",
-  "EM_UNKNOWN_USER_113",
-  "EM_UNKNOWN_USER_114",
-  "EM_UNKNOWN_USER_115",
-  "EM_UNKNOWN_USER_116",
-  "EM_UNKNOWN_USER_117",
-  "EM_UNKNOWN_USER_118",
-  "EM_UNKNOWN_USER_119",
-  "EM_SETLANGOPTIONS",
-  "EM_GETLANGOPTIONS",
-  "EM_GETIMECOMPMODE",
-  "EM_FINDTEXTW",
-  "EM_FINDTEXTEXW",
-  "EM_RECONVERSION",
-  "EM_SETIMEMODEBIAS",
-  "EM_GETIMEMODEBIAS"
-};
-
-static const char *
-get_msg_name(UINT msg)
-{
-  if (msg >= EM_GETSEL && msg <= EM_CHARFROMPOS)
-    return edit_messages[msg - EM_GETSEL];
-  if (msg >= EM_CANPASTE && msg <= EM_GETIMEMODEBIAS)
-    return richedit_messages[msg - EM_CANPASTE];
-  return "";
-}
-
 static void ME_LinkNotify(ME_TextEditor *editor, UINT msg, WPARAM wParam, LPARAM lParam)
 {
   int x,y;
@@ -4935,187 +4759,6 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
   return 0L;
 }
 
-static BOOL create_windowed_editor(HWND hwnd, CREATESTRUCTW *create, BOOL emulate_10)
-{
-    ITextHost *host = ME_CreateTextHost( hwnd, create, emulate_10 );
-    ME_TextEditor *editor;
-
-    if (!host) return FALSE;
-
-    editor = ME_MakeEditor( host, emulate_10 );
-    if (!editor)
-    {
-        ITextHost_Release( host );
-        return FALSE;
-    }
-
-    editor->exStyleFlags = GetWindowLongW( hwnd, GWL_EXSTYLE );
-    editor->styleFlags |= GetWindowLongW( hwnd, GWL_STYLE ) & ES_WANTRETURN;
-    editor->hWnd = hwnd; /* FIXME: Remove editor's dependence on hWnd */
-    editor->hwndParent = create->hwndParent;
-
-    SetWindowLongPtrW( hwnd, 0, (LONG_PTR)editor );
-
-    return TRUE;
-}
-
-static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
-                                      LPARAM lParam, BOOL unicode)
-{
-  ME_TextEditor *editor;
-  HRESULT hresult;
-  LRESULT lresult = 0;
-
-  TRACE("enter hwnd %p msg %04x (%s) %lx %lx, unicode %d\n",
-        hWnd, msg, get_msg_name(msg), wParam, lParam, unicode);
-
-  editor = (ME_TextEditor *)GetWindowLongPtrW(hWnd, 0);
-  if (!editor)
-  {
-    if (msg == WM_NCCREATE)
-    {
-      CREATESTRUCTW *pcs = (CREATESTRUCTW *)lParam;
-
-      TRACE("WM_NCCREATE: hWnd %p style 0x%08x\n", hWnd, pcs->style);
-      return create_windowed_editor( hWnd, pcs, FALSE );
-    }
-    else
-    {
-      return DefWindowProcW(hWnd, msg, wParam, lParam);
-    }
-  }
-
-  switch (msg)
-  {
-    case WM_PAINT:
-    {
-      HDC hdc;
-      RECT rc;
-      PAINTSTRUCT ps;
-      HBRUSH old_brush;
-
-      update_caret(editor);
-      hdc = BeginPaint(editor->hWnd, &ps);
-      if (!editor->bEmulateVersion10 || (editor->nEventMask & ENM_UPDATE))
-        ME_SendOldNotify(editor, EN_UPDATE);
-      old_brush = SelectObject(hdc, editor->hbrBackground);
-
-      /* Erase area outside of the formatting rectangle */
-      if (ps.rcPaint.top < editor->rcFormat.top)
-      {
-        rc = ps.rcPaint;
-        rc.bottom = editor->rcFormat.top;
-        PatBlt(hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY);
-        ps.rcPaint.top = editor->rcFormat.top;
-      }
-      if (ps.rcPaint.bottom > editor->rcFormat.bottom) {
-        rc = ps.rcPaint;
-        rc.top = editor->rcFormat.bottom;
-        PatBlt(hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY);
-        ps.rcPaint.bottom = editor->rcFormat.bottom;
-      }
-      if (ps.rcPaint.left < editor->rcFormat.left) {
-        rc = ps.rcPaint;
-        rc.right = editor->rcFormat.left;
-        PatBlt(hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY);
-        ps.rcPaint.left = editor->rcFormat.left;
-      }
-      if (ps.rcPaint.right > editor->rcFormat.right) {
-        rc = ps.rcPaint;
-        rc.left = editor->rcFormat.right;
-        PatBlt(hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY);
-        ps.rcPaint.right = editor->rcFormat.right;
-      }
-
-      ME_PaintContent(editor, hdc, &ps.rcPaint);
-      SelectObject(hdc, old_brush);
-      EndPaint(editor->hWnd, &ps);
-      return 0;
-    }
-    case WM_ERASEBKGND:
-    {
-      HDC hDC = (HDC)wParam;
-      RECT rc;
-
-      if (GetUpdateRect(editor->hWnd, &rc, TRUE))
-        FillRect(hDC, &rc, editor->hbrBackground);
-      return 1;
-    }
-    case EM_SETOPTIONS:
-    {
-      DWORD dwStyle;
-      const DWORD mask = ECO_VERTICAL | ECO_AUTOHSCROLL | ECO_AUTOVSCROLL |
-                         ECO_NOHIDESEL | ECO_READONLY | ECO_WANTRETURN |
-                         ECO_SELECTIONBAR;
-      lresult = ME_HandleMessage(editor, msg, wParam, lParam, unicode, &hresult);
-      dwStyle = GetWindowLongW(hWnd, GWL_STYLE);
-      dwStyle = (dwStyle & ~mask) | (lresult & mask);
-      SetWindowLongW(hWnd, GWL_STYLE, dwStyle);
-      return lresult;
-    }
-    case EM_SETREADONLY:
-    {
-      DWORD dwStyle;
-      lresult = ME_HandleMessage(editor, msg, wParam, lParam, unicode, &hresult);
-      dwStyle = GetWindowLongW(hWnd, GWL_STYLE);
-      dwStyle &= ~ES_READONLY;
-      if (wParam)
-        dwStyle |= ES_READONLY;
-      SetWindowLongW(hWnd, GWL_STYLE, dwStyle);
-      return lresult;
-    }
-    default:
-      lresult = ME_HandleMessage(editor, msg, wParam, lParam, unicode, &hresult);
-  }
-
-  if (hresult == S_FALSE)
-    lresult = DefWindowProcW(hWnd, msg, wParam, lParam);
-
-  TRACE("exit hwnd %p msg %04x (%s) %lx %lx, unicode %d -> %lu\n",
-        hWnd, msg, get_msg_name(msg), wParam, lParam, unicode, lresult);
-
-  return lresult;
-}
-
-static LRESULT WINAPI RichEditWndProcW(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
-    BOOL unicode = TRUE;
-
-    /* Under Win9x RichEdit20W returns ANSI strings, see the tests. */
-    if (msg == WM_GETTEXT && (GetVersion() & 0x80000000))
-        unicode = FALSE;
-
-    return RichEditWndProc_common(hWnd, msg, wParam, lParam, unicode);
-}
-
-static LRESULT WINAPI RichEditWndProcA(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
-    return RichEditWndProc_common(hWnd, msg, wParam, lParam, FALSE);
-}
-
-/******************************************************************
- *        RichEditANSIWndProc (RICHED20.10)
- */
-LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
-    return RichEditWndProcA(hWnd, msg, wParam, lParam);
-}
-
-/******************************************************************
- *        RichEdit10ANSIWndProc (RICHED20.9)
- */
-LRESULT WINAPI RichEdit10ANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
-  if (msg == WM_NCCREATE && !GetWindowLongPtrW(hWnd, 0))
-  {
-    CREATESTRUCTW *pcs = (CREATESTRUCTW *)lParam;
-
-    TRACE("WM_NCCREATE: hWnd %p style 0x%08x\n", hWnd, pcs->style);
-    return create_windowed_editor( hWnd, pcs, TRUE );
-  }
-  return RichEditANSIWndProc(hWnd, msg, wParam, lParam);
-}
-
 void ME_SendOldNotify(ME_TextEditor *editor, int nCode)
 {
   ITextHost_TxNotify(editor->texthost, nCode, NULL);
@@ -5192,114 +4835,6 @@ int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int buflen,
   return buffer - pStart;
 }
 
-static BOOL ME_RegisterEditorClass(HINSTANCE hInstance)
-{
-  WNDCLASSW wcW;
-  WNDCLASSA wcA;
-  
-  wcW.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
-  wcW.lpfnWndProc = RichEditWndProcW;
-  wcW.cbClsExtra = 0;
-  wcW.cbWndExtra = sizeof(ME_TextEditor *);
-  wcW.hInstance = NULL; /* hInstance would register DLL-local class */
-  wcW.hIcon = NULL;
-  wcW.hCursor = LoadCursorW(NULL, (LPWSTR)IDC_IBEAM);
-  wcW.hbrBackground = GetStockObject(NULL_BRUSH);
-  wcW.lpszMenuName = NULL;
-
-  if (is_version_nt())
-  {
-    wcW.lpszClassName = RICHEDIT_CLASS20W;
-    if (!RegisterClassW(&wcW)) return FALSE;
-    wcW.lpszClassName = MSFTEDIT_CLASS;
-    if (!RegisterClassW(&wcW)) return FALSE;
-  }
-  else
-  {
-    /* WNDCLASSA/W have the same layout */
-    wcW.lpszClassName = (LPCWSTR)"RichEdit20W";
-    if (!RegisterClassA((WNDCLASSA *)&wcW)) return FALSE;
-    wcW.lpszClassName = (LPCWSTR)"RichEdit50W";
-    if (!RegisterClassA((WNDCLASSA *)&wcW)) return FALSE;
-  }
-
-  wcA.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
-  wcA.lpfnWndProc = RichEditWndProcA;
-  wcA.cbClsExtra = 0;
-  wcA.cbWndExtra = sizeof(ME_TextEditor *);
-  wcA.hInstance = NULL; /* hInstance would register DLL-local class */
-  wcA.hIcon = NULL;
-  wcA.hCursor = LoadCursorW(NULL, (LPWSTR)IDC_IBEAM);
-  wcA.hbrBackground = GetStockObject(NULL_BRUSH);
-  wcA.lpszMenuName = NULL;
-  wcA.lpszClassName = RICHEDIT_CLASS20A;
-  if (!RegisterClassA(&wcA)) return FALSE;
-  wcA.lpszClassName = "RichEdit50A";
-  if (!RegisterClassA(&wcA)) return FALSE;
-
-  return TRUE;
-}
-
-static LRESULT WINAPI REComboWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
-  /* FIXME: Not implemented */
-  TRACE("hWnd %p msg %04x (%s) %08lx %08lx\n",
-        hWnd, msg, get_msg_name(msg), wParam, lParam);
-  return DefWindowProcW(hWnd, msg, wParam, lParam);
-}
-
-static LRESULT WINAPI REListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
-  /* FIXME: Not implemented */
-  TRACE("hWnd %p msg %04x (%s) %08lx %08lx\n",
-        hWnd, msg, get_msg_name(msg), wParam, lParam);
-  return DefWindowProcW(hWnd, msg, wParam, lParam);
-}
-
-/******************************************************************
- *        REExtendedRegisterClass (RICHED20.8)
- *
- * FIXME undocumented
- * Need to check for errors and implement controls and callbacks 
- */
-LRESULT WINAPI REExtendedRegisterClass(void)
-{
-  WNDCLASSW wcW;
-  UINT result;
-
-  FIXME("semi stub\n");
-
-  wcW.cbClsExtra = 0;
-  wcW.cbWndExtra = 4;
-  wcW.hInstance = NULL;
-  wcW.hIcon = NULL;
-  wcW.hCursor = NULL;
-  wcW.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
-  wcW.lpszMenuName = NULL;
-
-  if (!ME_ListBoxRegistered)
-  {
-      wcW.style = CS_PARENTDC | CS_DBLCLKS | CS_GLOBALCLASS;
-      wcW.lpfnWndProc = REListWndProc;
-      wcW.lpszClassName = L"REListBox20W";
-      if (RegisterClassW(&wcW)) ME_ListBoxRegistered = TRUE;
-  }
-
-  if (!ME_ComboBoxRegistered)
-  {
-      wcW.style = CS_PARENTDC | CS_DBLCLKS | CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW;
-      wcW.lpfnWndProc = REComboWndProc;
-      wcW.lpszClassName = L"REComboBox20W";
-      if (RegisterClassW(&wcW)) ME_ComboBoxRegistered = TRUE;  
-  }
-
-  result = 0;
-  if (ME_ListBoxRegistered)
-      result += 1;
-  if (ME_ComboBoxRegistered)
-      result += 2;
-
-  return result;
-}
-
 static int __cdecl wchar_comp( const void *key, const void *elem )
 {
     return *(const WCHAR *)key - *(const WCHAR *)elem;
diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h
index 7a9d445f98f..e226bc02921 100644
--- a/dlls/riched20/editor.h
+++ b/dlls/riched20/editor.h
@@ -23,6 +23,7 @@
 struct _RTF_Info;
 
 extern HANDLE me_heap DECLSPEC_HIDDEN;
+extern HCURSOR cursor_reverse DECLSPEC_HIDDEN;
 
 #define RUN_IS_HIDDEN(run) ((run)->style->fmt.dwMask & CFM_HIDDEN \
                              && (run)->style->fmt.dwEffects & CFE_HIDDEN)
@@ -316,7 +317,6 @@ static inline ME_DisplayItem *cell_get_di(ME_Cell *cell)
 
 
 /* txthost.c */
-ITextHost *ME_CreateTextHost(HWND hwnd, CREATESTRUCTW *cs, BOOL bEmulateVersion10) DECLSPEC_HIDDEN;
 #ifdef __ASM_USE_THISCALL_WRAPPER
 #define TXTHOST_VTABLE(This) (&itextHostStdcallVtbl)
 #else /* __i386__ */
diff --git a/dlls/riched20/txthost.c b/dlls/riched20/txthost.c
index 99f446e5812..a193c7b0813 100644
--- a/dlls/riched20/txthost.c
+++ b/dlls/riched20/txthost.c
@@ -27,6 +27,8 @@
 #include "textserv.h"
 #include "wine/debug.h"
 #include "editstr.h"
+#include "rtf.h"
+#include "res.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(richedit);
 
@@ -40,7 +42,10 @@ typedef struct ITextHostImpl {
 
 static const ITextHostVtbl textHostVtbl;
 
-ITextHost *ME_CreateTextHost(HWND hwnd, CREATESTRUCTW *cs, BOOL bEmulateVersion10)
+static BOOL listbox_registered;
+static BOOL combobox_registered;
+
+static ITextHost *host_create( HWND hwnd, CREATESTRUCTW *cs, BOOL bEmulateVersion10 )
 {
     ITextHostImpl *texthost;
 
@@ -676,3 +681,368 @@ static const ITextHostVtbl textHostVtbl = {
     THISCALL(ITextHostImpl_TxImmReleaseContext),
     THISCALL(ITextHostImpl_TxGetSelectionBarWidth),
 };
+
+static const char * const edit_messages[] =
+{
+    "EM_GETSEL",           "EM_SETSEL",           "EM_GETRECT",             "EM_SETRECT",
+    "EM_SETRECTNP",        "EM_SCROLL",           "EM_LINESCROLL",          "EM_SCROLLCARET",
+    "EM_GETMODIFY",        "EM_SETMODIFY",        "EM_GETLINECOUNT",        "EM_LINEINDEX",
+    "EM_SETHANDLE",        "EM_GETHANDLE",        "EM_GETTHUMB",            "EM_UNKNOWN_BF",
+    "EM_UNKNOWN_C0",       "EM_LINELENGTH",       "EM_REPLACESEL",          "EM_UNKNOWN_C3",
+    "EM_GETLINE",          "EM_LIMITTEXT",        "EM_CANUNDO",             "EM_UNDO",
+    "EM_FMTLINES",         "EM_LINEFROMCHAR",     "EM_UNKNOWN_CA",          "EM_SETTABSTOPS",
+    "EM_SETPASSWORDCHAR",  "EM_EMPTYUNDOBUFFER",  "EM_GETFIRSTVISIBLELINE", "EM_SETREADONLY",
+    "EM_SETWORDBREAKPROC", "EM_GETWORDBREAKPROC", "EM_GETPASSWORDCHAR",     "EM_SETMARGINS",
+    "EM_GETMARGINS",       "EM_GETLIMITTEXT",     "EM_POSFROMCHAR",         "EM_CHARFROMPOS",
+    "EM_SETIMESTATUS",     "EM_GETIMESTATUS"
+};
+
+static const char * const richedit_messages[] =
+{
+    "EM_CANPASTE",         "EM_DISPLAYBAND",      "EM_EXGETSEL",            "EM_EXLIMITTEXT",
+    "EM_EXLINEFROMCHAR",   "EM_EXSETSEL",         "EM_FINDTEXT",            "EM_FORMATRANGE",
+    "EM_GETCHARFORMAT",    "EM_GETEVENTMASK",     "EM_GETOLEINTERFACE",     "EM_GETPARAFORMAT",
+    "EM_GETSELTEXT",       "EM_HIDESELECTION",    "EM_PASTESPECIAL",        "EM_REQUESTRESIZE",
+    "EM_SELECTIONTYPE",    "EM_SETBKGNDCOLOR",    "EM_SETCHARFORMAT",       "EM_SETEVENTMASK",
+    "EM_SETOLECALLBACK",   "EM_SETPARAFORMAT",    "EM_SETTARGETDEVICE",     "EM_STREAMIN",
+    "EM_STREAMOUT",        "EM_GETTEXTRANGE",     "EM_FINDWORDBREAK",       "EM_SETOPTIONS",
+    "EM_GETOPTIONS",       "EM_FINDTEXTEX",       "EM_GETWORDBREAKPROCEX",  "EM_SETWORDBREAKPROCEX",
+    "EM_SETUNDOLIMIT",     "EM_UNKNOWN_USER_83",  "EM_REDO",                "EM_CANREDO",
+    "EM_GETUNDONAME",      "EM_GETREDONAME",      "EM_STOPGROUPTYPING",     "EM_SETTEXTMODE",
+    "EM_GETTEXTMODE",      "EM_AUTOURLDETECT",    "EM_GETAUTOURLDETECT",    "EM_SETPALETTE",
+    "EM_GETTEXTEX",        "EM_GETTEXTLENGTHEX",  "EM_SHOWSCROLLBAR",       "EM_SETTEXTEX",
+    "EM_UNKNOWN_USER_98",  "EM_UNKNOWN_USER_99",  "EM_SETPUNCTUATION",      "EM_GETPUNCTUATION",
+    "EM_SETWORDWRAPMODE",  "EM_GETWORDWRAPMODE",  "EM_SETIMECOLOR",         "EM_GETIMECOLOR",
+    "EM_SETIMEOPTIONS",    "EM_GETIMEOPTIONS",    "EM_CONVPOSITION",        "EM_UNKNOWN_USER_109",
+    "EM_UNKNOWN_USER_110", "EM_UNKNOWN_USER_111", "EM_UNKNOWN_USER_112",    "EM_UNKNOWN_USER_113",
+    "EM_UNKNOWN_USER_114", "EM_UNKNOWN_USER_115", "EM_UNKNOWN_USER_116",    "EM_UNKNOWN_USER_117",
+    "EM_UNKNOWN_USER_118", "EM_UNKNOWN_USER_119", "EM_SETLANGOPTIONS",      "EM_GETLANGOPTIONS",
+    "EM_GETIMECOMPMODE",   "EM_FINDTEXTW",        "EM_FINDTEXTEXW",         "EM_RECONVERSION",
+    "EM_SETIMEMODEBIAS",   "EM_GETIMEMODEBIAS"
+};
+
+static const char *get_msg_name( UINT msg )
+{
+    if (msg >= EM_GETSEL && msg <= EM_CHARFROMPOS)
+        return edit_messages[msg - EM_GETSEL];
+    if (msg >= EM_CANPASTE && msg <= EM_GETIMEMODEBIAS)
+        return richedit_messages[msg - EM_CANPASTE];
+    return "";
+}
+
+static BOOL create_windowed_editor( HWND hwnd, CREATESTRUCTW *create, BOOL emulate_10 )
+{
+    ITextHost *host = host_create( hwnd, create, emulate_10 );
+    ME_TextEditor *editor;
+
+    if (!host) return FALSE;
+
+    editor = ME_MakeEditor( host, emulate_10 );
+    if (!editor)
+    {
+        ITextHost_Release( host );
+        return FALSE;
+    }
+
+    editor->exStyleFlags = GetWindowLongW( hwnd, GWL_EXSTYLE );
+    editor->styleFlags |= GetWindowLongW( hwnd, GWL_STYLE ) & ES_WANTRETURN;
+    editor->hWnd = hwnd; /* FIXME: Remove editor's dependence on hWnd */
+    editor->hwndParent = create->hwndParent;
+
+    SetWindowLongPtrW( hwnd, 0, (LONG_PTR)editor );
+
+    return TRUE;
+}
+
+static LRESULT RichEditWndProc_common( HWND hwnd, UINT msg, WPARAM wparam,
+                                       LPARAM lparam, BOOL unicode )
+{
+    ME_TextEditor *editor;
+    HRESULT hr;
+    LRESULT res = 0;
+
+    TRACE( "enter hwnd %p msg %04x (%s) %lx %lx, unicode %d\n",
+           hwnd, msg, get_msg_name(msg), wparam, lparam, unicode );
+
+    editor = (ME_TextEditor *)GetWindowLongPtrW( hwnd, 0 );
+    if (!editor)
+    {
+        if (msg == WM_NCCREATE)
+        {
+            CREATESTRUCTW *pcs = (CREATESTRUCTW *)lparam;
+
+            TRACE( "WM_NCCREATE: hwnd %p style 0x%08x\n", hwnd, pcs->style );
+            return create_windowed_editor( hwnd, pcs, FALSE );
+        }
+        else return DefWindowProcW( hwnd, msg, wparam, lparam );
+    }
+
+    switch (msg)
+    {
+    case WM_ERASEBKGND:
+    {
+        HDC hdc = (HDC)wparam;
+        RECT rc;
+
+        if (GetUpdateRect( editor->hWnd, &rc, TRUE ))
+            FillRect( hdc, &rc, editor->hbrBackground );
+        return 1;
+    }
+    case WM_PAINT:
+    {
+        HDC hdc;
+        RECT rc;
+        PAINTSTRUCT ps;
+        HBRUSH old_brush;
+
+        update_caret( editor );
+        hdc = BeginPaint( editor->hWnd, &ps );
+        if (!editor->bEmulateVersion10 || (editor->nEventMask & ENM_UPDATE))
+            ME_SendOldNotify( editor, EN_UPDATE );
+        old_brush = SelectObject( hdc, editor->hbrBackground );
+
+        /* Erase area outside of the formatting rectangle */
+        if (ps.rcPaint.top < editor->rcFormat.top)
+        {
+            rc = ps.rcPaint;
+            rc.bottom = editor->rcFormat.top;
+            PatBlt( hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY );
+            ps.rcPaint.top = editor->rcFormat.top;
+        }
+        if (ps.rcPaint.bottom > editor->rcFormat.bottom)
+        {
+            rc = ps.rcPaint;
+            rc.top = editor->rcFormat.bottom;
+            PatBlt( hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY );
+            ps.rcPaint.bottom = editor->rcFormat.bottom;
+        }
+        if (ps.rcPaint.left < editor->rcFormat.left)
+        {
+            rc = ps.rcPaint;
+            rc.right = editor->rcFormat.left;
+            PatBlt( hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY );
+            ps.rcPaint.left = editor->rcFormat.left;
+        }
+        if (ps.rcPaint.right > editor->rcFormat.right)
+        {
+            rc = ps.rcPaint;
+            rc.left = editor->rcFormat.right;
+            PatBlt( hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY );
+            ps.rcPaint.right = editor->rcFormat.right;
+        }
+
+        ME_PaintContent( editor, hdc, &ps.rcPaint );
+        SelectObject( hdc, old_brush );
+        EndPaint( editor->hWnd, &ps );
+        return 0;
+    }
+    case EM_SETOPTIONS:
+    {
+        DWORD style;
+        const DWORD mask = ECO_VERTICAL | ECO_AUTOHSCROLL | ECO_AUTOVSCROLL |
+            ECO_NOHIDESEL | ECO_READONLY | ECO_WANTRETURN |
+            ECO_SELECTIONBAR;
+
+        res = ME_HandleMessage( editor, msg, wparam, lparam, unicode, &hr );
+        style = GetWindowLongW( hwnd, GWL_STYLE );
+        style = (style & ~mask) | (res & mask);
+        SetWindowLongW( hwnd, GWL_STYLE, style );
+        return res;
+    }
+    case EM_SETREADONLY:
+    {
+        DWORD style;
+
+        res = ME_HandleMessage( editor, msg, wparam, lparam, unicode, &hr );
+        style = GetWindowLongW( hwnd, GWL_STYLE );
+        style &= ~ES_READONLY;
+        if (wparam) style |= ES_READONLY;
+        SetWindowLongW( hwnd, GWL_STYLE, style );
+        return res;
+    }
+    default:
+        res = ME_HandleMessage( editor, msg, wparam, lparam, unicode, &hr );
+    }
+
+    if (hr == S_FALSE)
+        res = DefWindowProcW( hwnd, msg, wparam, lparam );
+
+    TRACE( "exit hwnd %p msg %04x (%s) %lx %lx, unicode %d -> %lu\n",
+           hwnd, msg, get_msg_name(msg), wparam, lparam, unicode, res );
+
+    return res;
+}
+
+static LRESULT WINAPI RichEditWndProcW( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
+{
+    BOOL unicode = TRUE;
+
+    /* Under Win9x RichEdit20W returns ANSI strings, see the tests. */
+    if (msg == WM_GETTEXT && (GetVersion() & 0x80000000))
+        unicode = FALSE;
+
+    return RichEditWndProc_common( hwnd, msg, wparam, lparam, unicode );
+}
+
+static LRESULT WINAPI RichEditWndProcA( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
+{
+    return RichEditWndProc_common( hwnd, msg, wparam, lparam, FALSE );
+}
+
+/******************************************************************
+ *        RichEditANSIWndProc (RICHED20.10)
+ */
+LRESULT WINAPI RichEditANSIWndProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
+{
+    return RichEditWndProcA( hwnd, msg, wparam, lparam );
+}
+
+/******************************************************************
+ *        RichEdit10ANSIWndProc (RICHED20.9)
+ */
+LRESULT WINAPI RichEdit10ANSIWndProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
+{
+    if (msg == WM_NCCREATE && !GetWindowLongPtrW( hwnd, 0 ))
+    {
+        CREATESTRUCTW *pcs = (CREATESTRUCTW *)lparam;
+
+        TRACE( "WM_NCCREATE: hwnd %p style 0x%08x\n", hwnd, pcs->style );
+        return create_windowed_editor( hwnd, pcs, TRUE );
+    }
+    return RichEditANSIWndProc( hwnd, msg, wparam, lparam );
+}
+
+static LRESULT WINAPI REComboWndProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
+{
+    /* FIXME: Not implemented */
+    TRACE( "hwnd %p msg %04x (%s) %08lx %08lx\n",
+           hwnd, msg, get_msg_name( msg ), wparam, lparam );
+    return DefWindowProcW( hwnd, msg, wparam, lparam );
+}
+
+static LRESULT WINAPI REListWndProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
+{
+    /* FIXME: Not implemented */
+    TRACE( "hwnd %p msg %04x (%s) %08lx %08lx\n",
+           hwnd, msg, get_msg_name( msg ), wparam, lparam );
+    return DefWindowProcW( hwnd, msg, wparam, lparam );
+}
+
+/******************************************************************
+ *        REExtendedRegisterClass (RICHED20.8)
+ *
+ * FIXME undocumented
+ * Need to check for errors and implement controls and callbacks
+ */
+LRESULT WINAPI REExtendedRegisterClass( void )
+{
+    WNDCLASSW wc;
+    UINT result;
+
+    FIXME( "semi stub\n" );
+    wc.cbClsExtra = 0;
+    wc.cbWndExtra = 4;
+    wc.hInstance = NULL;
+    wc.hIcon = NULL;
+    wc.hCursor = NULL;
+    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
+    wc.lpszMenuName = NULL;
+
+    if (!listbox_registered)
+    {
+        wc.style = CS_PARENTDC | CS_DBLCLKS | CS_GLOBALCLASS;
+        wc.lpfnWndProc = REListWndProc;
+        wc.lpszClassName = L"REListBox20W";
+        if (RegisterClassW( &wc )) listbox_registered = TRUE;
+    }
+
+    if (!combobox_registered)
+    {
+        wc.style = CS_PARENTDC | CS_DBLCLKS | CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW;
+        wc.lpfnWndProc = REComboWndProc;
+        wc.lpszClassName = L"REComboBox20W";
+        if (RegisterClassW( &wc )) combobox_registered = TRUE;
+    }
+
+    result = 0;
+    if (listbox_registered) result += 1;
+    if (combobox_registered) result += 2;
+
+    return result;
+}
+
+static BOOL register_classes( HINSTANCE instance )
+{
+    WNDCLASSW wcW;
+    WNDCLASSA wcA;
+
+    wcW.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
+    wcW.lpfnWndProc = RichEditWndProcW;
+    wcW.cbClsExtra = 0;
+    wcW.cbWndExtra = sizeof(ME_TextEditor *);
+    wcW.hInstance = NULL; /* hInstance would register DLL-local class */
+    wcW.hIcon = NULL;
+    wcW.hCursor = LoadCursorW( NULL, (LPWSTR)IDC_IBEAM );
+    wcW.hbrBackground = GetStockObject( NULL_BRUSH );
+    wcW.lpszMenuName = NULL;
+
+    if (!(GetVersion() & 0x80000000))
+    {
+        wcW.lpszClassName = RICHEDIT_CLASS20W;
+        if (!RegisterClassW( &wcW )) return FALSE;
+        wcW.lpszClassName = MSFTEDIT_CLASS;
+        if (!RegisterClassW( &wcW )) return FALSE;
+    }
+    else
+    {
+        /* WNDCLASSA/W have the same layout */
+        wcW.lpszClassName = (LPCWSTR)"RichEdit20W";
+        if (!RegisterClassA( (WNDCLASSA *)&wcW )) return FALSE;
+        wcW.lpszClassName = (LPCWSTR)"RichEdit50W";
+        if (!RegisterClassA( (WNDCLASSA *)&wcW )) return FALSE;
+    }
+
+    wcA.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
+    wcA.lpfnWndProc = RichEditWndProcA;
+    wcA.cbClsExtra = 0;
+    wcA.cbWndExtra = sizeof(ME_TextEditor *);
+    wcA.hInstance = NULL; /* hInstance would register DLL-local class */
+    wcA.hIcon = NULL;
+    wcA.hCursor = LoadCursorW( NULL, (LPWSTR)IDC_IBEAM );
+    wcA.hbrBackground = GetStockObject(NULL_BRUSH);
+    wcA.lpszMenuName = NULL;
+    wcA.lpszClassName = RICHEDIT_CLASS20A;
+    if (!RegisterClassA( &wcA )) return FALSE;
+    wcA.lpszClassName = "RichEdit50A";
+    if (!RegisterClassA( &wcA )) return FALSE;
+
+    return TRUE;
+}
+
+BOOL WINAPI DllMain( HINSTANCE instance, DWORD reason, void *reserved )
+{
+    switch (reason)
+    {
+    case DLL_PROCESS_ATTACH:
+        DisableThreadLibraryCalls( instance );
+        me_heap = HeapCreate( 0, 0x10000, 0 );
+        if (!register_classes( instance )) return FALSE;
+        cursor_reverse = LoadCursorW( instance, MAKEINTRESOURCEW( OCR_REVERSE ) );
+        LookupInit();
+        break;
+
+    case DLL_PROCESS_DETACH:
+        if (reserved) break;
+        UnregisterClassW( RICHEDIT_CLASS20W, 0 );
+        UnregisterClassW( MSFTEDIT_CLASS, 0 );
+        UnregisterClassA( RICHEDIT_CLASS20A, 0 );
+        UnregisterClassA( "RichEdit50A", 0 );
+        if (listbox_registered) UnregisterClassW( L"REListBox20W", 0 );
+        if (combobox_registered) UnregisterClassW( L"REComboBox20W", 0 );
+        LookupCleanup();
+        HeapDestroy( me_heap );
+        release_typelib();
+        break;
+    }
+    return TRUE;
+}
-- 
2.23.0




More information about the wine-devel mailing list