Author: akhaldi
Date: Mon Oct  6 18:42:09 2014
New Revision: 64572

URL: http://svn.reactos.org/svn/reactos?rev=64572&view=rev
Log:
[RICHED20_WINETEST]
* Sync with Wine 1.7.27.
CORE-8540

Modified:
    trunk/rostests/winetests/riched20/editor.c
    trunk/rostests/winetests/riched20/richole.c

Modified: trunk/rostests/winetests/riched20/editor.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/riched20/editor.c?rev=64572&r1=64571&r2=64572&view=diff
==============================================================================
--- trunk/rostests/winetests/riched20/editor.c  [iso-8859-1] (original)
+++ trunk/rostests/winetests/riched20/editor.c  [iso-8859-1] Mon Oct  6 
18:42:09 2014
@@ -4362,7 +4362,9 @@
   {5, 10, 10, 5, 10, 0},
   {15, 17, 17, 15, 17, 0},
   /* test cpMax > strlen() */
-  {0, 100, 18, 0, 18, 1},
+  {0, 100, 18, 0, 18, 0},
+  /* test cpMin < 0 && cpMax >= 0 after cpMax > strlen() */
+  {-1, 1, 17, 17, 17, 0},
   /* test cpMin == cpMax */
   {5, 5, 5, 5, 5, 0},
   /* test cpMin < 0 && cpMax >= 0 (bug 4462) */
@@ -4372,13 +4374,13 @@
   /* test cpMin < 0 && cpMax < 0 */
   {-1, -1, 17, 17, 17, 0},
   {-4, -5, 17, 17, 17, 0},
-  /* test cMin >=0 && cpMax < 0 (bug 6814) */
-  {0, -1, 18, 0, 18, 1},
-  {17, -5, 18, 17, 18, 1},
+  /* test cpMin >=0 && cpMax < 0 (bug 6814) */
+  {0, -1, 18, 0, 18, 0},
+  {17, -5, 18, 17, 18, 0},
   {18, -3, 17, 17, 17, 0},
   /* test if cpMin > cpMax */
-  {15, 19, 18, 15, 18, 1},
-  {19, 15, 18, 15, 18, 1}
+  {15, 19, 18, 15, 18, 0},
+  {19, 15, 18, 15, 18, 0},
 };
 
 static void check_EM_EXSETSEL(HWND hwnd, const struct exsetsel_s *setsel, int 
id) {
@@ -5070,11 +5072,13 @@
   DWORD phase;
   LRESULT result;
   EDITSTREAM es;
-  char buffer[1024] = {0};
+  char buffer[1024] = {0}, tmp[16];
+  CHARRANGE range;
 
   const char * streamText0 = "{\\rtf1 TestSomeText}";
   const char * streamText0a = "{\\rtf1 TestSomeText\\par}";
   const char * streamText0b = "{\\rtf1 TestSomeText\\par\\par}";
+  const char * ptr;
 
   const char * streamText1 =
   
"{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang12298{\\fonttbl{\\f0\\fswiss\\fprq2\\fcharset0
 System;}}\r\n"
@@ -5099,6 +5103,9 @@
       "This text just needs to be long enough to cause run to be split onto "
       "two separate lines and make sure the null terminating character is "
       "handled properly.\0";
+
+  const WCHAR UTF8Split_exp[4] = {0xd6, 0xcf, 0xcb, 0};
+
   int length4 = strlen(streamText4) + 1;
   struct StringWithLength cookieForStream4 = {
       length4,
@@ -5128,7 +5135,8 @@
   ok(es.dwError == 0, "EM_STREAMIN: Test 0 set error %d, expected %d\n", 
es.dwError, 0);
 
   /* Native richedit 2.0 ignores last \par */
-  es.dwCookie = (DWORD_PTR)&streamText0a;
+  ptr = streamText0a;
+  es.dwCookie = (DWORD_PTR)&ptr;
   es.dwError = 0;
   es.pfnCallback = test_EM_STREAMIN_esCallback;
   result = SendMessageA(hwndRichEdit, EM_STREAMIN, SF_RTF, (LPARAM)&es);
@@ -5157,6 +5165,43 @@
       "EM_STREAMIN: Test 0-b set wrong text: Result: %s\n",buffer);
   ok(es.dwError == 0, "EM_STREAMIN: Test 0-b set error %d, expected %d\n", 
es.dwError, 0);
 
+  /* Show that when using SFF_SELECTION the last \par is not ignored. */
+  ptr = streamText0a;
+  es.dwCookie = (DWORD_PTR)&ptr;
+  es.dwError = 0;
+  es.pfnCallback = test_EM_STREAMIN_esCallback;
+  result = SendMessageA(hwndRichEdit, EM_STREAMIN, SF_RTF, (LPARAM)&es);
+  ok(result == 12, "got %ld, expected %d\n", result, 12);
+
+  result = SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)buffer);
+  ok (result  == 12,
+      "EM_STREAMIN: Test 0-a returned %ld, expected 12\n", result);
+  result = strcmp (buffer,"TestSomeText");
+  ok (result  == 0,
+      "EM_STREAMIN: Test 0-a set wrong text: Result: %s\n",buffer);
+  ok(es.dwError == 0, "EM_STREAMIN: Test 0-a set error %d, expected %d\n", 
es.dwError, 0);
+
+  range.cpMin = 0;
+  range.cpMax = -1;
+  result = SendMessageA(hwndRichEdit, EM_EXSETSEL, 0, (LPARAM)&range);
+  ok (result == 13, "got %ld\n", result);
+
+  ptr = streamText0a;
+  es.dwCookie = (DWORD_PTR)&ptr;
+  es.dwError = 0;
+  es.pfnCallback = test_EM_STREAMIN_esCallback;
+
+  result = SendMessageA(hwndRichEdit, EM_STREAMIN, SFF_SELECTION | SF_RTF, 
(LPARAM)&es);
+  ok(result == 13, "got %ld, expected 13\n", result);
+
+  result = SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)buffer);
+  ok (result  == 14,
+      "EM_STREAMIN: Test SFF_SELECTION 0-a returned %ld, expected 14\n", 
result);
+  result = strcmp (buffer,"TestSomeText\r\n");
+  ok (result  == 0,
+      "EM_STREAMIN: Test SFF_SELECTION 0-a set wrong text: Result: 
%s\n",buffer);
+  ok(es.dwError == 0, "EM_STREAMIN: Test SFF_SELECTION 0-a set error %d, 
expected %d\n", es.dwError, 0);
+
   es.dwCookie = (DWORD_PTR)&streamText1;
   es.dwError = 0;
   es.pfnCallback = test_EM_STREAMIN_esCallback;
@@ -5216,10 +5261,12 @@
   result = SendMessageA(hwndRichEdit, EM_STREAMIN, SF_TEXT, (LPARAM)&es);
   ok(result == 8, "got %ld\n", result);
 
+  WideCharToMultiByte(CP_ACP, 0, UTF8Split_exp, -1, tmp, sizeof(tmp), NULL, 
NULL);
+
   result = SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)buffer);
   ok(result  == 3,
       "EM_STREAMIN: Test UTF8Split returned %ld\n", result);
-  result = memcmp (buffer,"\xd6\xcf\xcb", 3);
+  result = memcmp (buffer, tmp, 3);
   ok(result  == 0,
       "EM_STREAMIN: Test UTF8Split set wrong text: Result: %s\n",buffer);
   ok(es.dwError == 0, "EM_STREAMIN: Test UTF8Split set error %d, expected 
%d\n", es.dwError, 0);
@@ -5888,6 +5935,62 @@
        "selections is incorrectly at (%d,%d)\n", sel_start, sel_end);
 
     DestroyWindow(hwndRichedit_WM_NOTIFY);
+    DestroyWindow(parent);
+}
+
+static int cpMin_EN_LINK = -1;
+static int cpMax_EN_LINK = -1;
+
+static LRESULT WINAPI EN_LINK_ParentMsgCheckProcA(HWND hwnd, UINT message, 
WPARAM wParam, LPARAM lParam)
+{
+    ENLINK* enlink = (ENLINK*)lParam;
+    if(message == WM_NOTIFY && enlink->nmhdr.code == EN_LINK)
+    {
+        cpMin_EN_LINK = enlink->chrg.cpMin;
+        cpMax_EN_LINK = enlink->chrg.cpMax;
+    }
+    return DefWindowProcA(hwnd, message, wParam, lParam);
+}
+
+static void test_EN_LINK(void)
+{
+    HWND parent;
+    WNDCLASSA cls;
+    HWND hwndRichedit_EN_LINK;
+    CHARFORMAT2A cf2;
+
+    /* register class to capture WM_NOTIFY */
+    cls.style = 0;
+    cls.lpfnWndProc = EN_LINK_ParentMsgCheckProcA;
+    cls.cbClsExtra = 0;
+    cls.cbWndExtra = 0;
+    cls.hInstance = GetModuleHandleA(0);
+    cls.hIcon = 0;
+    cls.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW);
+    cls.hbrBackground = GetStockObject(WHITE_BRUSH);
+    cls.lpszMenuName = NULL;
+    cls.lpszClassName = "EN_LINK_ParentClass";
+    if(!RegisterClassA(&cls)) assert(0);
+
+    parent = CreateWindowA(cls.lpszClassName, NULL, WS_POPUP|WS_VISIBLE,
+                           0, 0, 200, 60, NULL, NULL, NULL, NULL);
+    ok(parent != 0, "Failed to create parent window\n");
+
+    hwndRichedit_EN_LINK = new_richedit(parent);
+    ok(hwndRichedit_EN_LINK != 0, "Failed to create edit window\n");
+
+    SendMessageA(hwndRichedit_EN_LINK, EM_SETEVENTMASK, 0, ENM_LINK);
+
+    cf2.cbSize = sizeof(CHARFORMAT2A);
+    cf2.dwMask = CFM_LINK;
+    cf2.dwEffects = CFE_LINK;
+    SendMessageA(hwndRichedit_EN_LINK, EM_SETCHARFORMAT, 0, (LPARAM)&cf2);
+    /* mixing letters and numbers causes runs to be split */
+    SendMessageA(hwndRichedit_EN_LINK, WM_SETTEXT, 0, (LPARAM)"link text with 
at least 2 runs");
+    SendMessageA(hwndRichedit_EN_LINK, WM_LBUTTONDOWN, 0, MAKELPARAM(5, 5));
+    ok(cpMin_EN_LINK == 0 && cpMax_EN_LINK == 31, "Expected link range [0,31) 
got [%i,%i)\n", cpMin_EN_LINK, cpMax_EN_LINK);
+
+    DestroyWindow(hwndRichedit_EN_LINK);
     DestroyWindow(parent);
 }
 
@@ -7472,6 +7575,25 @@
     ok( fmt.wAlignment == def_align, "got %d exppect %d\n", fmt.wAlignment, 
def_align );
 
     DestroyWindow( richedit );
+}
+
+static void test_EM_SETREADONLY(void)
+{
+    HWND richedit = new_richeditW(NULL);
+    DWORD dwStyle;
+    LRESULT res;
+
+    res = SendMessageA(richedit, EM_SETREADONLY, TRUE, 0);
+    ok(res == 1, "EM_SETREADONLY\n");
+    dwStyle = GetWindowLongA(richedit, GWL_STYLE);
+    ok(dwStyle & ES_READONLY, "got wrong value: 0x%x\n", dwStyle & 
ES_READONLY);
+
+    res = SendMessageA(richedit, EM_SETREADONLY, FALSE, 0);
+    ok(res == 1, "EM_SETREADONLY\n");
+    dwStyle = GetWindowLongA(richedit, GWL_STYLE);
+    ok(!(dwStyle & ES_READONLY), "got wrong value: 0x%x\n", dwStyle & 
ES_READONLY);
+
+    DestroyWindow(richedit);
 }
 
 START_TEST( editor )
@@ -7519,6 +7641,7 @@
   test_EM_REPLACESEL(1);
   test_EM_REPLACESEL(0);
   test_WM_NOTIFY();
+  test_EN_LINK();
   test_EM_AUTOURLDETECT();
   test_eventMask();
   test_undo_coalescing();
@@ -7536,6 +7659,7 @@
   test_enter();
   test_WM_CREATE();
   test_reset_default_para_fmt();
+  test_EM_SETREADONLY();
 
   /* Set the environment variable WINETEST_RICHED20 to keep windows
    * responsive and open for 30 seconds. This is useful for debugging.

Modified: trunk/rostests/winetests/riched20/richole.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/riched20/richole.c?rev=64572&r1=64571&r2=64572&view=diff
==============================================================================
--- trunk/rostests/winetests/riched20/richole.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/riched20/richole.c [iso-8859-1] Mon Oct  6 
18:42:09 2014
@@ -86,21 +86,29 @@
 static void release_interfaces(HWND *w, IRichEditOle **reOle, ITextDocument 
**txtDoc,
                                ITextSelection **txtSel)
 {
+  if(txtSel)
+    ITextSelection_Release(*txtSel);
   ITextDocument_Release(*txtDoc);
   IRichEditOle_Release(*reOle);
   DestroyWindow(*w);
-  ITextSelection_Release(*txtSel);
+}
+
+static ULONG get_refcount(IUnknown *iface)
+{
+  IUnknown_AddRef(iface);
+  return IUnknown_Release(iface);
 }
 
 static void test_Interfaces(void)
 {
-  IRichEditOle *reOle = NULL;
+  IRichEditOle *reOle = NULL, *reOle1 = NULL;
   ITextDocument *txtDoc = NULL;
   ITextSelection *txtSel = NULL;
   IUnknown *punk;
   HRESULT hres;
   LRESULT res;
   HWND w;
+  ULONG refcount;
 
   w = new_richedit(NULL);
   if (!w) {
@@ -111,6 +119,14 @@
   res = SendMessageA(w, EM_GETOLEINTERFACE, 0, (LPARAM)&reOle);
   ok(res, "SendMessage\n");
   ok(reOle != NULL, "EM_GETOLEINTERFACE\n");
+  refcount = get_refcount((IUnknown *)reOle);
+  ok(refcount == 2, "got wrong ref count: %d\n", refcount);
+
+  res = SendMessageA(w, EM_GETOLEINTERFACE, 0, (LPARAM)&reOle1);
+  ok(res == 1, "SendMessage\n");
+  ok(reOle1 == reOle, "Should not return a new IRichEditOle interface\n");
+  refcount = get_refcount((IUnknown *)reOle);
+  ok(refcount == 3, "got wrong ref count: %d\n", refcount);
 
   hres = IRichEditOle_QueryInterface(reOle, &IID_ITextDocument,
                                  (void **) &txtDoc);
@@ -142,6 +158,8 @@
 
   ITextDocument_Release(txtDoc);
   IRichEditOle_Release(reOle);
+  refcount = IRichEditOle_Release(reOle);
+  ok(refcount == 1, "got wrong ref count: %d\n", refcount);
   DestroyWindow(w);
 
   /* Methods should return CO_E_RELEASED if the backing document has
@@ -385,6 +403,544 @@
   VariantClear(&testfile);
 }
 
+static void test_ITextSelection_GetText(void)
+{
+  HWND w;
+  IRichEditOle *reOle = NULL;
+  ITextDocument *txtDoc = NULL;
+  ITextSelection *txtSel = NULL;
+  HRESULT hres;
+  BSTR bstr = NULL;
+  int first, lim;
+  static const CHAR test_text1[] = "TestSomeText";
+  static const WCHAR bufW1[] = {'T', 'e', 's', 't', 0};
+  static const WCHAR bufW2[] = {'T', 'e', 'x', 't', '\r', 0};
+  static const WCHAR bufW3[] = {'T', 'e', 'x', 't', 0};
+  static const WCHAR bufW4[] = {'T', 'e', 's', 't', 'S', 'o', 'm',
+                                'e', 'T', 'e', 'x', 't', '\r', 0};
+  static const WCHAR bufW5[] = {'\r', 0};
+  BOOL is64bit = sizeof(void *) > sizeof(int);
+
+  create_interfaces(&w, &reOle, &txtDoc, &txtSel);
+  SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
+
+  first = 0, lim = 4;
+  SendMessageA(w, EM_SETSEL, first, lim);
+  hres = ITextSelection_GetText(txtSel, &bstr);
+  ok(hres == S_OK, "ITextSelection_GetText\n");
+  ok(!lstrcmpW(bstr, bufW1), "got wrong text: %s\n", wine_dbgstr_w(bstr));
+  SysFreeString(bstr);
+
+  first = 4, lim = 0;
+  SendMessageA(w, EM_SETSEL, first, lim);
+  hres = ITextSelection_GetText(txtSel, &bstr);
+  ok(hres == S_OK, "ITextSelection_GetText\n");
+  ok(!lstrcmpW(bstr, bufW1), "got wrong text: %s\n", wine_dbgstr_w(bstr));
+  SysFreeString(bstr);
+
+  first = 1, lim = 1;
+  SendMessageA(w, EM_SETSEL, first, lim);
+  hres = ITextSelection_GetText(txtSel, &bstr);
+  ok(hres == S_OK, "ITextSelection_GetText\n");
+  ok(!bstr, "got wrong text: %s\n", wine_dbgstr_w(bstr));
+
+  if (!is64bit)
+    {
+      hres = ITextSelection_GetText(txtSel, NULL);
+      ok(hres == E_INVALIDARG, "ITextSelection_GetText\n");
+    }
+
+  first = 8, lim = 12;
+  SendMessageA(w, EM_SETSEL, first, lim);
+  hres = ITextSelection_GetText(txtSel, &bstr);
+  ok(hres == S_OK, "ITextSelection_GetText\n");
+  ok(!lstrcmpW(bstr, bufW3), "got wrong text: %s\n", wine_dbgstr_w(bstr));
+  SysFreeString(bstr);
+
+  first = 8, lim = 13;
+  SendMessageA(w, EM_SETSEL, first, lim);
+  hres = ITextSelection_GetText(txtSel, &bstr);
+  ok(hres == S_OK, "ITextSelection_GetText\n");
+  ok(!lstrcmpW(bstr, bufW2), "got wrong text: %s\n", wine_dbgstr_w(bstr));
+  SysFreeString(bstr);
+
+  first = 12, lim = 13;
+  SendMessageA(w, EM_SETSEL, first, lim);
+  hres = ITextSelection_GetText(txtSel, &bstr);
+  ok(hres == S_OK, "ITextSelection_GetText\n");
+  ok(!lstrcmpW(bstr, bufW5), "got wrong text: %s\n", wine_dbgstr_w(bstr));
+  SysFreeString(bstr);
+
+  first = 0, lim = -1;
+  SendMessageA(w, EM_SETSEL, first, lim);
+  hres = ITextSelection_GetText(txtSel, &bstr);
+  ok(hres == S_OK, "ITextSelection_GetText\n");
+  ok(!lstrcmpW(bstr, bufW4), "got wrong text: %s\n", wine_dbgstr_w(bstr));
+  SysFreeString(bstr);
+
+  first = -1, lim = 9;
+  SendMessageA(w, EM_SETSEL, first, lim);
+  hres = ITextSelection_GetText(txtSel, &bstr);
+  ok(hres == S_OK, "ITextSelection_GetText\n");
+  ok(!bstr, "got wrong text: %s\n", wine_dbgstr_w(bstr));
+
+  release_interfaces(&w, &reOle, &txtDoc, &txtSel);
+}
+
+static void test_ITextDocument_Range(void)
+{
+  HWND w;
+  IRichEditOle *reOle = NULL;
+  ITextDocument *txtDoc = NULL;
+  ITextRange *txtRge = NULL;
+  ITextRange *pointer = NULL;
+  HRESULT hres;
+  ULONG refcount;
+
+  create_interfaces(&w, &reOle, &txtDoc, NULL);
+  hres = ITextDocument_Range(txtDoc, 0, 0, &txtRge);
+  ok(hres == S_OK, "ITextDocument_Range fails 0x%x.\n", hres);
+  refcount = get_refcount((IUnknown *)txtRge);
+  ok(refcount == 1, "get wrong refcount: returned %d expected 1\n", refcount);
+
+  pointer = txtRge;
+  hres = ITextDocument_Range(txtDoc, 0, 0, &txtRge);
+  ok(hres == S_OK, "ITextDocument_Range fails 0x%x.\n", hres);
+  ok(pointer != txtRge, "A new pointer should be returned\n");
+  ITextRange_Release(pointer);
+
+  hres = ITextDocument_Range(txtDoc, 0, 0, NULL);
+  ok(hres == E_INVALIDARG, "ITextDocument_Range should fail 0x%x.\n", hres);
+
+  release_interfaces(&w, &reOle, &txtDoc, NULL);
+  hres = ITextRange_CanEdit(txtRge, NULL);
+  ok(hres == CO_E_RELEASED, "ITextRange after ITextDocument destroyed\n");
+  ITextRange_Release(txtRge);
+}
+
+static void test_ITextRange_GetChar(void)
+{
+  HWND w;
+  IRichEditOle *reOle = NULL;
+  ITextDocument *txtDoc = NULL;
+  ITextRange *txtRge = NULL;
+  HRESULT hres;
+  LONG pch = 0xdeadbeef;
+  int first, lim;
+  static const CHAR test_text1[] = "TestSomeText";
+
+  first = 0, lim = 4;
+  create_interfaces(&w, &reOle, &txtDoc, NULL);
+  SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
+  ITextDocument_Range(txtDoc, first, lim, &txtRge);
+  pch = 0xdeadbeef;
+  hres = ITextRange_GetChar(txtRge, &pch);
+  ok(hres == S_OK, "ITextRange_GetChar\n");
+  ok(pch == 'T', "got wrong char: %c\n", pch);
+  ITextRange_Release(txtRge);
+  release_interfaces(&w, &reOle, &txtDoc, NULL);
+
+  first = 0, lim = 0;
+  create_interfaces(&w, &reOle, &txtDoc, NULL);
+  SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
+  ITextDocument_Range(txtDoc, first, lim, &txtRge);
+  pch = 0xdeadbeef;
+  hres = ITextRange_GetChar(txtRge, &pch);
+  ok(hres == S_OK, "ITextRange_GetChar\n");
+  ok(pch == 'T', "got wrong char: %c\n", pch);
+  ITextRange_Release(txtRge);
+  release_interfaces(&w, &reOle, &txtDoc, NULL);
+
+  first = 12, lim = 12;
+  create_interfaces(&w, &reOle, &txtDoc, NULL);
+  SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
+  ITextDocument_Range(txtDoc, first, lim, &txtRge);
+  pch = 0xdeadbeef;
+  hres = ITextRange_GetChar(txtRge, &pch);
+  ok(hres == S_OK, "ITextRange_GetChar\n");
+  ok(pch == '\r', "got wrong char: %c\n", pch);
+  ITextRange_Release(txtRge);
+  release_interfaces(&w, &reOle, &txtDoc, NULL);
+
+  first = 13, lim = 13;
+  create_interfaces(&w, &reOle, &txtDoc, NULL);
+  SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
+  ITextDocument_Range(txtDoc, first, lim, &txtRge);
+  pch = 0xdeadbeef;
+  hres = ITextRange_GetChar(txtRge, &pch);
+  ok(hres == S_OK, "ITextRange_GetChar\n");
+  ok(pch == '\r', "got wrong char: %c\n", pch);
+  ITextRange_Release(txtRge);
+  release_interfaces(&w, &reOle, &txtDoc, NULL);
+
+  create_interfaces(&w, &reOle, &txtDoc, NULL);
+  SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
+  first = 12, lim = 12;
+  ITextDocument_Range(txtDoc, first, lim, &txtRge);
+  hres = ITextRange_GetChar(txtRge, NULL);
+  ok(hres == E_INVALIDARG, "ITextRange_GetChar\n");
+  ITextRange_Release(txtRge);
+  release_interfaces(&w, &reOle, &txtDoc, NULL);
+}
+
+static void test_ITextSelection_GetChar(void)
+{
+  HWND w;
+  IRichEditOle *reOle = NULL;
+  ITextDocument *txtDoc = NULL;
+  ITextSelection *txtSel = NULL;
+  HRESULT hres;
+  LONG pch = 0xdeadbeef;
+  int first, lim;
+  static const CHAR test_text1[] = "TestSomeText";
+
+  create_interfaces(&w, &reOle, &txtDoc, &txtSel);
+  SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
+
+  first = 0, lim = 4;
+  SendMessageA(w, EM_SETSEL, first, lim);
+  pch = 0xdeadbeef;
+  hres = ITextSelection_GetChar(txtSel, &pch);
+  ok(hres == S_OK, "ITextSelection_GetChar\n");
+  ok(pch == 'T', "got wrong char: %c\n", pch);
+
+  first = 0, lim = 0;
+  SendMessageA(w, EM_SETSEL, first, lim);
+  pch = 0xdeadbeef;
+  hres = ITextSelection_GetChar(txtSel, &pch);
+  ok(hres == S_OK, "ITextSelection_GetChar\n");
+  ok(pch == 'T', "got wrong char: %c\n", pch);
+
+  first = 12, lim = 12;
+  SendMessageA(w, EM_SETSEL, first, lim);
+  pch = 0xdeadbeef;
+  hres = ITextSelection_GetChar(txtSel, &pch);
+  ok(hres == S_OK, "ITextSelection_GetChar\n");
+  ok(pch == '\r', "got wrong char: %c\n", pch);
+
+  first = 13, lim = 13;
+  SendMessageA(w, EM_SETSEL, first, lim);
+  pch = 0xdeadbeef;
+  hres = ITextSelection_GetChar(txtSel, &pch);
+  ok(hres == S_OK, "ITextSelection_GetChar\n");
+  ok(pch == '\r', "got wrong char: %c\n", pch);
+
+  hres = ITextSelection_GetChar(txtSel, NULL);
+  ok(hres == E_INVALIDARG, "ITextSelection_GetChar\n");
+
+  release_interfaces(&w, &reOle, &txtDoc, &txtSel);
+}
+
+static void test_ITextRange_GetStart_GetEnd(void)
+{
+  HWND w;
+  IRichEditOle *reOle = NULL;
+  ITextDocument *txtDoc = NULL;
+  ITextRange *txtRge = NULL;
+  HRESULT hres;
+  int first, lim, start, end;
+  static const CHAR test_text1[] = "TestSomeText";
+
+  create_interfaces(&w, &reOle, &txtDoc, NULL);
+  SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
+
+  first = 1, lim = 6;
+  ITextDocument_Range(txtDoc, first, lim, &txtRge);
+  start = 0xdeadbeef;
+  hres = ITextRange_GetStart(txtRge, &start);
+  ok(hres == S_OK, "ITextRange_GetStart\n");
+  ok(start == 1, "got wrong start value: %d\n", start);
+  end = 0xdeadbeef;
+  hres = ITextRange_GetEnd(txtRge, &end);
+  ok(hres == S_OK, "ITextRange_GetEnd\n");
+  ok(end == 6, "got wrong end value: %d\n", end);
+  ITextRange_Release(txtRge);
+
+  first = 6, lim = 1;
+  ITextDocument_Range(txtDoc, first, lim, &txtRge);
+  start = 0xdeadbeef;
+  hres = ITextRange_GetStart(txtRge, &start);
+  ok(hres == S_OK, "ITextRange_GetStart\n");
+  ok(start == 1, "got wrong start value: %d\n", start);
+  end = 0xdeadbeef;
+  hres = ITextRange_GetEnd(txtRge, &end);
+  ok(hres == S_OK, "ITextRange_GetEnd\n");
+  ok(end == 6, "got wrong end value: %d\n", end);
+  ITextRange_Release(txtRge);
+
+  first = -1, lim = 13;
+  ITextDocument_Range(txtDoc, first, lim, &txtRge);
+  start = 0xdeadbeef;
+  hres = ITextRange_GetStart(txtRge, &start);
+  ok(hres == S_OK, "ITextRange_GetStart\n");
+  ok(start == 0, "got wrong start value: %d\n", start);
+  end = 0xdeadbeef;
+  hres = ITextRange_GetEnd(txtRge, &end);
+  ok(hres == S_OK, "ITextRange_GetEnd\n");
+  ok(end == 13, "got wrong end value: %d\n", end);
+  ITextRange_Release(txtRge);
+
+  first = 13, lim = 13;
+  ITextDocument_Range(txtDoc, first, lim, &txtRge);
+  start = 0xdeadbeef;
+  hres = ITextRange_GetStart(txtRge, &start);
+  ok(hres == S_OK, "ITextRange_GetStart\n");
+  ok(start == 12, "got wrong start value: %d\n", start);
+  end = 0xdeadbeef;
+  hres = ITextRange_GetEnd(txtRge, &end);
+  ok(hres == S_OK, "ITextRange_GetEnd\n");
+  ok(end == 12, "got wrong end value: %d\n", end);
+  ITextRange_Release(txtRge);
+
+  release_interfaces(&w, &reOle, &txtDoc, NULL);
+}
+
+static void test_ITextSelection_GetStart_GetEnd(void)
+{
+  HWND w;
+  IRichEditOle *reOle = NULL;
+  ITextDocument *txtDoc = NULL;
+  ITextSelection *txtSel = NULL;
+  HRESULT hres;
+  int first, lim, start, end;
+  static const CHAR test_text1[] = "TestSomeText";
+
+  create_interfaces(&w, &reOle, &txtDoc, &txtSel);
+  SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
+
+  first = 2, lim = 5;
+  SendMessageA(w, EM_SETSEL, first, lim);
+  start = 0xdeadbeef;
+  hres = ITextSelection_GetStart(txtSel, &start);
+  ok(hres == S_OK, "ITextSelection_GetStart\n");
+  ok(start == 2, "got wrong start value: %d\n", start);
+  end = 0xdeadbeef;
+  hres = ITextSelection_GetEnd(txtSel, &end);
+  ok(hres == S_OK, "ITextSelection_GetEnd\n");
+  ok(end == 5, "got wrong end value: %d\n", end);
+
+  first = 5, lim = 2;
+  SendMessageA(w, EM_SETSEL, first, lim);
+  start = 0xdeadbeef;
+  hres = ITextSelection_GetStart(txtSel, &start);
+  ok(hres == S_OK, "ITextSelection_GetStart\n");
+  ok(start == 2, "got wrong start value: %d\n", start);
+  end = 0xdeadbeef;
+  hres = ITextSelection_GetEnd(txtSel, &end);
+  ok(hres == S_OK, "ITextSelection_GetEnd\n");
+  ok(end == 5, "got wrong end value: %d\n", end);
+
+  first = 0, lim = -1;
+  SendMessageA(w, EM_SETSEL, first, lim);
+  start = 0xdeadbeef;
+  hres = ITextSelection_GetStart(txtSel, &start);
+  ok(hres == S_OK, "ITextSelection_GetStart\n");
+  ok(start == 0, "got wrong start value: %d\n", start);
+  end = 0xdeadbeef;
+  hres = ITextSelection_GetEnd(txtSel, &end);
+  ok(hres == S_OK, "ITextSelection_GetEnd\n");
+  ok(end == 13, "got wrong end value: %d\n", end);
+
+  first = 13, lim = 13;
+  SendMessageA(w, EM_SETSEL, first, lim);
+  start = 0xdeadbeef;
+  hres = ITextSelection_GetStart(txtSel, &start);
+  ok(hres == S_OK, "ITextSelection_GetStart\n");
+  ok(start == 12, "got wrong start value: %d\n", start);
+  end = 0xdeadbeef;
+  hres = ITextSelection_GetEnd(txtSel, &end);
+  ok(hres == S_OK, "ITextSelection_GetEnd\n");
+  ok(end == 12, "got wrong end value: %d\n", end);
+
+  release_interfaces(&w, &reOle, &txtDoc, &txtSel);
+}
+
+static void test_ITextRange_GetDuplicate(void)
+{
+  HWND w;
+  IRichEditOle *reOle = NULL;
+  ITextDocument *txtDoc = NULL;
+  ITextRange *txtRge = NULL;
+  ITextRange *txtRgeDup = NULL;
+  HRESULT hres;
+  LONG first, lim, start, end;
+  static const CHAR test_text1[] = "TestSomeText";
+
+  create_interfaces(&w, &reOle, &txtDoc, NULL);
+  SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
+  first = 0, lim = 4;
+  hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
+  ok(hres == S_OK, "ITextDocument_Range fails 0x%x.\n", hres);
+
+  hres = ITextRange_GetDuplicate(txtRge, &txtRgeDup);
+  ok(hres == S_OK, "ITextRange_GetDuplicate\n");
+  ok(txtRgeDup != txtRge, "A new pointer should be returned\n");
+  ITextRange_GetStart(txtRgeDup, &start);
+  ok(start == first, "got wrong value: %d\n", start);
+  ITextRange_GetEnd(txtRgeDup, &end);
+  ok(end == lim, "got wrong value: %d\n", end);
+
+  ITextRange_Release(txtRgeDup);
+
+  hres = ITextRange_GetDuplicate(txtRge, NULL);
+  ok(hres == E_INVALIDARG, "ITextRange_GetDuplicate\n");
+
+  ITextRange_Release(txtRge);
+  release_interfaces(&w, &reOle, &txtDoc, NULL);
+}
+
+static void test_ITextRange_Collapse(void)
+{
+  HWND w;
+  IRichEditOle *reOle = NULL;
+  ITextDocument *txtDoc = NULL;
+  ITextRange *txtRge = NULL;
+  HRESULT hres;
+  LONG first, lim, start, end;
+  static const CHAR test_text1[] = "TestSomeText";
+
+  create_interfaces(&w, &reOle, &txtDoc, NULL);
+  SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
+
+  first = 4, lim = 8;
+  ITextDocument_Range(txtDoc, first, lim, &txtRge);
+  hres = ITextRange_Collapse(txtRge, tomTrue);
+  ok(hres == S_OK, "ITextRange_Collapse\n");
+  ITextRange_GetStart(txtRge, &start);
+  ok(start == 4, "got wrong start value: %d\n", start);
+  ITextRange_GetEnd(txtRge, &end);
+  ok(end == 4, "got wrong end value: %d\n", end);
+  ITextRange_Release(txtRge);
+
+  ITextDocument_Range(txtDoc, first, lim, &txtRge);
+  hres = ITextRange_Collapse(txtRge, tomStart);
+  ok(hres == S_OK, "ITextRange_Collapse\n");
+  ITextRange_GetStart(txtRge, &start);
+  ok(start == 4, "got wrong start value: %d\n", start);
+  ITextRange_GetEnd(txtRge, &end);
+  ok(end == 4, "got wrong end value: %d\n", end);
+  ITextRange_Release(txtRge);
+
+  ITextDocument_Range(txtDoc, first, lim, &txtRge);
+  hres = ITextRange_Collapse(txtRge, tomFalse);
+  ok(hres == S_OK, "ITextRange_Collapse\n");
+  ITextRange_GetStart(txtRge, &start);
+  ok(start == 8, "got wrong start value: %d\n", start);
+  ITextRange_GetEnd(txtRge, &end);
+  ok(end == 8, "got wrong end value: %d\n", end);
+  ITextRange_Release(txtRge);
+
+  ITextDocument_Range(txtDoc, first, lim, &txtRge);
+  hres = ITextRange_Collapse(txtRge, tomEnd);
+  ok(hres == S_OK, "ITextRange_Collapse\n");
+  ITextRange_GetStart(txtRge, &start);
+  ok(start == 8, "got wrong start value: %d\n", start);
+  ITextRange_GetEnd(txtRge, &end);
+  ok(end == 8, "got wrong end value: %d\n", end);
+  ITextRange_Release(txtRge);
+
+  /* tomStart is the default */
+  ITextDocument_Range(txtDoc, first, lim, &txtRge);
+  hres = ITextRange_Collapse(txtRge, 256);
+  ok(hres == S_OK, "ITextRange_Collapse\n");
+  ITextRange_GetStart(txtRge, &start);
+  ok(start == 4, "got wrong start value: %d\n", start);
+  ITextRange_GetEnd(txtRge, &end);
+  ok(end == 4, "got wrong end value: %d\n", end);
+  ITextRange_Release(txtRge);
+
+  first = 6, lim = 6;
+  ITextDocument_Range(txtDoc, first, lim, &txtRge);
+  hres = ITextRange_Collapse(txtRge, tomEnd);
+  ok(hres == S_FALSE, "ITextRange_Collapse\n");
+  ITextRange_GetStart(txtRge, &start);
+  ok(start == 6, "got wrong start value: %d\n", start);
+  ITextRange_GetEnd(txtRge, &end);
+  ok(end == 6, "got wrong end value: %d\n", end);
+  ITextRange_Release(txtRge);
+
+  first = 8, lim = 8;
+  ITextDocument_Range(txtDoc, first, lim, &txtRge);
+  hres = ITextRange_Collapse(txtRge, tomStart);
+  ok(hres == S_FALSE, "ITextRange_Collapse\n");
+  ITextRange_GetStart(txtRge, &start);
+  ok(start == 8, "got wrong start value: %d\n", start);
+  ITextRange_GetEnd(txtRge, &end);
+  ok(end == 8, "got wrong end value: %d\n", end);
+  ITextRange_Release(txtRge);
+
+  release_interfaces(&w, &reOle, &txtDoc, NULL);
+}
+
+static void test_ITextSelection_Collapse(void)
+{
+  HWND w;
+  IRichEditOle *reOle = NULL;
+  ITextDocument *txtDoc = NULL;
+  ITextSelection *txtSel = NULL;
+  HRESULT hres;
+  LONG first, lim, start, end;
+  static const CHAR test_text1[] = "TestSomeText";
+
+  create_interfaces(&w, &reOle, &txtDoc, &txtSel);
+  SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
+
+  first = 4, lim = 8;
+  SendMessageA(w, EM_SETSEL, first, lim);
+  hres = ITextSelection_Collapse(txtSel, tomTrue);
+  ok(hres == S_OK, "ITextSelection_Collapse\n");
+  SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
+  ok(start == 4, "got wrong start value: %d\n", start);
+  ok(end == 4, "got wrong end value: %d\n", end);
+
+  SendMessageA(w, EM_SETSEL, first, lim);
+  hres = ITextSelection_Collapse(txtSel, tomStart);
+  ok(hres == S_OK, "ITextSelection_Collapse\n");
+  SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
+  ok(start == 4, "got wrong start value: %d\n", start);
+  ok(end == 4, "got wrong end value: %d\n", end);
+
+  SendMessageA(w, EM_SETSEL, first, lim);
+  hres = ITextSelection_Collapse(txtSel, tomFalse);
+  ok(hres == S_OK, "ITextSelection_Collapse\n");
+  SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
+  ok(start == 8, "got wrong start value: %d\n", start);
+  ok(end == 8, "got wrong end value: %d\n", end);
+
+  SendMessageA(w, EM_SETSEL, first, lim);
+  hres = ITextSelection_Collapse(txtSel, tomEnd);
+  ok(hres == S_OK, "ITextSelection_Collapse\n");
+  SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
+  ok(start == 8, "got wrong start value: %d\n", start);
+  ok(end == 8, "got wrong end value: %d\n", end);
+
+  /* tomStart is the default */
+  SendMessageA(w, EM_SETSEL, first, lim);
+  hres = ITextSelection_Collapse(txtSel, 256);
+  ok(hres == S_OK, "ITextSelection_Collapse\n");
+  SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
+  ok(start == 4, "got wrong start value: %d\n", start);
+  ok(end == 4, "got wrong end value: %d\n", end);
+
+  first = 6, lim = 6;
+  SendMessageA(w, EM_SETSEL, first, lim);
+  hres = ITextSelection_Collapse(txtSel, tomEnd);
+  ok(hres == S_FALSE, "ITextSelection_Collapse\n");
+  SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
+  ok(start == 6, "got wrong start value: %d\n", start);
+  ok(end == 6, "got wrong end value: %d\n", end);
+
+  first = 8, lim = 8;
+  SendMessageA(w, EM_SETSEL, first, lim);
+  hres = ITextSelection_Collapse(txtSel, tomStart);
+  ok(hres == S_FALSE, "ITextSelection_Collapse\n");
+  SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
+  ok(start == 8, "got wrong start value: %d\n", start);
+  ok(end == 8, "got wrong end value: %d\n", end);
+
+  release_interfaces(&w, &reOle, &txtDoc, &txtSel);
+}
+
 START_TEST(richole)
 {
   /* Must explicitly LoadLibrary(). The test has no references to functions in
@@ -394,4 +950,13 @@
 
   test_Interfaces();
   test_ITextDocument_Open();
-}
+  test_ITextSelection_GetText();
+  test_ITextSelection_GetChar();
+  test_ITextSelection_GetStart_GetEnd();
+  test_ITextSelection_Collapse();
+  test_ITextDocument_Range();
+  test_ITextRange_GetChar();
+  test_ITextRange_GetStart_GetEnd();
+  test_ITextRange_GetDuplicate();
+  test_ITextRange_Collapse();
+}


Reply via email to