riched20/tests: Test more return values and released cases.
[wine/multimedia.git] / dlls / riched20 / tests / richole.c
blob02aaefb919195f4c564fe366a60a298ab3de5931
1 /*
2 * Tests for IRichEditOle and friends.
4 * Copyright 2008 Google (Dan Hipschman)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define COBJMACROS
23 #include <stdarg.h>
25 #include <windef.h>
26 #include <winbase.h>
27 #include <wingdi.h>
28 #include <winuser.h>
29 #include <initguid.h>
30 #include <ole2.h>
31 #include <richedit.h>
32 #include <richole.h>
33 #include <tom.h>
34 #include <wine/test.h>
36 static HMODULE hmoduleRichEdit;
38 DEFINE_GUID(GUID_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
40 static const WCHAR sysW[] = {'S','y','s','t','e','m',0};
42 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
43 static void _expect_ref(IUnknown* obj, ULONG ref, int line)
45 ULONG rc;
46 IUnknown_AddRef(obj);
47 rc = IUnknown_Release(obj);
48 ok_(__FILE__,line)(rc == ref, "expected refcount %d, got %d\n", ref, rc);
51 static HWND new_window(LPCSTR lpClassName, DWORD dwStyle, HWND parent)
53 HWND hwnd = CreateWindowA(lpClassName, NULL,
54 dwStyle | WS_POPUP | WS_HSCROLL | WS_VSCROLL | WS_VISIBLE,
55 0, 0, 200, 60, parent, NULL, hmoduleRichEdit, NULL);
56 return hwnd;
59 static HWND new_richedit(HWND parent)
61 return new_window(RICHEDIT_CLASS20A, ES_MULTILINE, parent);
64 static BOOL touch_file(LPCWSTR filename)
66 HANDLE file;
68 file = CreateFileW(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL,
69 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
71 if(file == INVALID_HANDLE_VALUE)
72 return FALSE;
73 CloseHandle(file);
74 return TRUE;
77 static BOOL is_existing_file(LPCWSTR filename)
79 HANDLE file;
81 file = CreateFileW(filename, GENERIC_READ, 0, NULL,
82 OPEN_EXISTING, 0, NULL);
83 if(file == INVALID_HANDLE_VALUE)
84 return FALSE;
85 CloseHandle(file);
86 return TRUE;
89 static void create_interfaces(HWND *w, IRichEditOle **reOle, ITextDocument **txtDoc,
90 ITextSelection **txtSel)
92 *w = new_richedit(NULL);
93 SendMessageA(*w, EM_GETOLEINTERFACE, 0, (LPARAM)reOle);
94 IRichEditOle_QueryInterface(*reOle, &IID_ITextDocument,
95 (void **) txtDoc);
96 ITextDocument_GetSelection(*txtDoc, txtSel);
99 static void release_interfaces(HWND *w, IRichEditOle **reOle, ITextDocument **txtDoc,
100 ITextSelection **txtSel)
102 if(txtSel)
103 ITextSelection_Release(*txtSel);
104 ITextDocument_Release(*txtDoc);
105 IRichEditOle_Release(*reOle);
106 DestroyWindow(*w);
109 static ULONG get_refcount(IUnknown *iface)
111 IUnknown_AddRef(iface);
112 return IUnknown_Release(iface);
115 static void test_Interfaces(void)
117 IRichEditOle *reOle = NULL, *reOle1 = NULL;
118 ITextDocument *txtDoc = NULL;
119 ITextSelection *txtSel = NULL, *txtSel2;
120 IUnknown *punk;
121 HRESULT hres;
122 LRESULT res;
123 HWND w;
124 ULONG refcount;
126 w = new_richedit(NULL);
127 if (!w) {
128 skip("Couldn't create window\n");
129 return;
132 res = SendMessageA(w, EM_GETOLEINTERFACE, 0, (LPARAM)&reOle);
133 ok(res, "SendMessage\n");
134 ok(reOle != NULL, "EM_GETOLEINTERFACE\n");
135 EXPECT_REF(reOle, 2);
137 res = SendMessageA(w, EM_GETOLEINTERFACE, 0, (LPARAM)&reOle1);
138 ok(res == 1, "SendMessage\n");
139 ok(reOle1 == reOle, "Should not return a new IRichEditOle interface\n");
140 EXPECT_REF(reOle, 3);
142 hres = IRichEditOle_QueryInterface(reOle, &IID_ITextDocument,
143 (void **) &txtDoc);
144 ok(hres == S_OK, "IRichEditOle_QueryInterface\n");
145 ok(txtDoc != NULL, "IRichEditOle_QueryInterface\n");
147 hres = ITextDocument_GetSelection(txtDoc, NULL);
148 ok(hres == E_INVALIDARG, "ITextDocument_GetSelection: 0x%x\n", hres);
150 EXPECT_REF(txtDoc, 4);
152 hres = ITextDocument_GetSelection(txtDoc, &txtSel);
153 ok(hres == S_OK, "got 0x%08x\n", hres);
155 EXPECT_REF(txtDoc, 4);
156 EXPECT_REF(txtSel, 2);
158 hres = ITextDocument_GetSelection(txtDoc, &txtSel2);
159 ok(hres == S_OK, "got 0x%08x\n", hres);
160 ok(txtSel2 == txtSel, "got %p, %p\n", txtSel, txtSel2);
162 EXPECT_REF(txtDoc, 4);
163 EXPECT_REF(txtSel, 3);
165 ITextSelection_Release(txtSel2);
167 punk = NULL;
168 hres = ITextSelection_QueryInterface(txtSel, &IID_ITextSelection, (void **) &punk);
169 ok(hres == S_OK, "ITextSelection_QueryInterface\n");
170 ok(punk != NULL, "ITextSelection_QueryInterface\n");
171 IUnknown_Release(punk);
173 punk = NULL;
174 hres = ITextSelection_QueryInterface(txtSel, &IID_ITextRange, (void **) &punk);
175 ok(hres == S_OK, "ITextSelection_QueryInterface\n");
176 ok(punk != NULL, "ITextSelection_QueryInterface\n");
177 IUnknown_Release(punk);
179 punk = NULL;
180 hres = ITextSelection_QueryInterface(txtSel, &IID_IDispatch, (void **) &punk);
181 ok(hres == S_OK, "ITextSelection_QueryInterface\n");
182 ok(punk != NULL, "ITextSelection_QueryInterface\n");
183 IUnknown_Release(punk);
185 punk = NULL;
186 hres = IRichEditOle_QueryInterface(reOle, &IID_IOleClientSite, (void **) &punk);
187 ok(hres == E_NOINTERFACE, "IRichEditOle_QueryInterface\n");
189 punk = NULL;
190 hres = IRichEditOle_QueryInterface(reOle, &IID_IOleWindow, (void **) &punk);
191 ok(hres == E_NOINTERFACE, "IRichEditOle_QueryInterface\n");
193 punk = NULL;
194 hres = IRichEditOle_QueryInterface(reOle, &IID_IOleInPlaceSite, (void **) &punk);
195 ok(hres == E_NOINTERFACE, "IRichEditOle_QueryInterface\n");
197 ITextDocument_Release(txtDoc);
198 IRichEditOle_Release(reOle);
199 refcount = IRichEditOle_Release(reOle);
200 ok(refcount == 1, "got wrong ref count: %d\n", refcount);
201 DestroyWindow(w);
203 /* Methods should return CO_E_RELEASED if the backing document has
204 been released. One test should suffice. */
205 hres = ITextSelection_CanEdit(txtSel, NULL);
206 ok(hres == CO_E_RELEASED, "ITextSelection after ITextDocument destroyed\n");
208 ITextSelection_Release(txtSel);
211 static void test_ITextDocument_Open(void)
213 IRichEditOle *reOle = NULL;
214 ITextDocument *txtDoc = NULL;
215 ITextSelection *txtSel = NULL;
216 HRESULT hres;
217 HWND w;
218 HANDLE hFile;
219 VARIANT testfile;
220 WCHAR filename[] = {'t', 'e', 's', 't','.','t','x','t', 0};
221 int result;
222 DWORD dw;
223 static const CHAR chACP[] = "TestSomeText";
224 static const CHAR chUTF8[] = "\xef\xbb\xbfTextWithUTF8BOM";
225 static const WCHAR chUTF16[] = {0xfeff, 'T', 'e', 's', 't', 'S', 'o', 'm',
226 'e', 'T', 'e', 'x', 't', 0};
228 #define MAX_BUF_LEN 1024
229 CHAR bufACP[MAX_BUF_LEN];
230 WCHAR bufUnicode[MAX_BUF_LEN];
232 static const int tomConstantsSingle[] =
234 tomReadOnly, tomShareDenyRead, tomShareDenyWrite,
235 tomCreateAlways, tomOpenExisting, tomOpenAlways,
236 tomTruncateExisting, tomRTF, tomText
239 static const int tomConstantsMulti[] =
241 tomReadOnly|tomShareDenyRead|tomPasteFile, tomReadOnly|tomPasteFile,
242 tomReadOnly|tomShareDenyWrite|tomPasteFile,
243 tomReadOnly|tomShareDenyRead|tomShareDenyWrite|tomPasteFile, tomShareDenyWrite|tomPasteFile,
244 tomShareDenyRead|tomShareDenyWrite|tomPasteFile, tomShareDenyRead|tomPasteFile,
245 tomShareDenyRead|tomShareDenyWrite, tomReadOnly|tomShareDenyRead|tomShareDenyWrite,
246 tomReadOnly|tomShareDenyWrite, tomReadOnly|tomShareDenyRead
249 int tomNumSingle = sizeof(tomConstantsSingle)/sizeof(tomConstantsSingle[0]);
250 int tomNumMulti = sizeof(tomConstantsMulti)/sizeof(tomConstantsMulti[0]);
251 int i;
253 V_VT(&testfile) = VT_BSTR;
254 V_BSTR(&testfile) = SysAllocString(filename);
256 for(i=0; i < tomNumSingle; i++)
258 touch_file(filename);
259 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
260 hres = ITextDocument_Open(txtDoc, &testfile, tomConstantsSingle[i], CP_ACP);
261 todo_wine ok(hres == S_OK, "ITextDocument_Open: Filename:test.txt Flags:0x%x Codepage:CP_ACP hres:0x%x\n",
262 tomConstantsSingle[i], hres);
263 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
264 DeleteFileW(filename);
266 touch_file(filename);
267 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
268 hres = ITextDocument_Open(txtDoc, &testfile, tomConstantsSingle[i], CP_UTF8);
269 todo_wine ok(hres == S_OK, "ITextDocument_Open: Filename:test.txt Flags:0x%x Codepage:CP_UTF8 hres:0x%x\n",
270 tomConstantsSingle[i], hres);
271 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
272 DeleteFileW(filename);
275 for(i=0; i < tomNumMulti; i++)
277 touch_file(filename);
278 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
279 hres = ITextDocument_Open(txtDoc, &testfile, tomConstantsMulti[i], CP_ACP);
280 todo_wine ok(hres == S_OK, "ITextDocument_Open: Filename:test.txt Flags:0x%x Codepage:CP_ACP hres:0x%x\n",
281 tomConstantsMulti[i], hres);
282 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
283 DeleteFileW(filename);
285 touch_file(filename);
286 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
287 hres = ITextDocument_Open(txtDoc, &testfile, tomConstantsMulti[i], CP_UTF8);
288 todo_wine ok(hres == S_OK, "ITextDocument_Open: Filename:test.txt Flags:0x%x Codepage:CP_UTF8 hres:0x%x\n",
289 tomConstantsMulti[i], hres);
290 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
291 DeleteFileW(filename);
294 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
295 hres = ITextDocument_Open(txtDoc, &testfile, tomCreateAlways, CP_ACP);
296 todo_wine ok(hres == S_OK, "ITextDocument_Open should success Codepage:CP_ACP\n");
297 todo_wine ok(is_existing_file(filename), "ITextDocument_Open should create a file\n");
298 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
299 DeleteFileW(filename);
301 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
302 hres = ITextDocument_Open(txtDoc, &testfile, tomCreateAlways, CP_UTF8);
303 todo_wine ok(hres == S_OK, "ITextDocument_Open should success Codepage:CP_UTF8\n");
304 todo_wine ok(is_existing_file(filename), "ITextDocument_Open should create a file\n");
305 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
306 DeleteFileW(filename);
308 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
309 hres = ITextDocument_Open(txtDoc, &testfile, tomOpenAlways, CP_ACP);
310 todo_wine ok(hres == S_OK, "ITextDocument_Open should success Codepage:CP_ACP\n");
311 todo_wine ok(is_existing_file(filename), "ITextDocument_Open should create a file\n");
312 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
313 DeleteFileW(filename);
315 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
316 hres = ITextDocument_Open(txtDoc, &testfile, tomOpenAlways, CP_UTF8);
317 todo_wine ok(hres == S_OK, "ITextDocument_Open should success Codepage:CP_UTF8\n");
318 todo_wine ok(is_existing_file(filename), "ITextDocument_Open should create a file\n");
319 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
320 DeleteFileW(filename);
322 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
323 hres = ITextDocument_Open(txtDoc, &testfile, tomCreateNew, CP_ACP);
324 todo_wine ok(hres == S_OK, "ITextDocument_Open should success Codepage:CP_ACP\n");
325 todo_wine ok(is_existing_file(filename), "ITextDocument_Open should create a file\n");
326 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
327 DeleteFileW(filename);
329 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
330 hres = ITextDocument_Open(txtDoc, &testfile, tomCreateNew, CP_UTF8);
331 todo_wine ok(hres == S_OK, "ITextDocument_Open should success Codepage:CP_UTF8\n");
332 todo_wine ok(is_existing_file(filename), "ITextDocument_Open should create a file\n");
333 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
334 DeleteFileW(filename);
336 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
337 touch_file(filename);
338 hres = ITextDocument_Open(txtDoc, &testfile, tomCreateNew, CP_ACP);
339 todo_wine ok(hres == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "ITextDocument_Open should fail Codepage:CP_ACP\n");
340 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
341 DeleteFileW(filename);
343 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
344 touch_file(filename);
345 hres = ITextDocument_Open(txtDoc, &testfile, tomCreateNew, CP_UTF8);
346 todo_wine ok(hres == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "ITextDocument_Open should fail Codepage:CP_UTF8\n");
347 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
348 DeleteFileW(filename);
350 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
351 hres = ITextDocument_Open(txtDoc, &testfile, tomOpenExisting, CP_ACP);
352 todo_wine ok(hres == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "ITextDocument_Open should fail Codepage:CP_ACP\n");
353 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
355 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
356 hres = ITextDocument_Open(txtDoc, &testfile, tomOpenExisting, CP_UTF8);
357 todo_wine ok(hres == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "ITextDocument_Open should fail Codepage:CP_UTF8\n");
358 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
360 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
361 DeleteFileW(filename);
362 hres = ITextDocument_Open(txtDoc, &testfile, tomText, CP_ACP);
363 todo_wine {
364 ok(hres == S_OK, "got 0x%08x\n", hres);
365 ok(is_existing_file(filename) == TRUE, "a file should be created default\n");
367 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
368 DeleteFileW(filename);
370 /* test of share mode */
371 touch_file(filename);
372 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
373 hres = ITextDocument_Open(txtDoc, &testfile, tomShareDenyRead, CP_ACP);
374 todo_wine
375 ok(hres == S_OK, "got 0x%08x\n", hres);
376 SetLastError(0xdeadbeef);
377 hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
378 FILE_ATTRIBUTE_NORMAL, NULL);
379 todo_wine ok(GetLastError() == ERROR_SHARING_VIOLATION, "ITextDocument_Open should fail\n");
380 CloseHandle(hFile);
381 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
382 DeleteFileW(filename);
384 touch_file(filename);
385 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
386 hres = ITextDocument_Open(txtDoc, &testfile, tomShareDenyWrite, CP_ACP);
387 todo_wine
388 ok(hres == S_OK, "got 0x%08x\n", hres);
389 SetLastError(0xdeadbeef);
390 hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
391 FILE_ATTRIBUTE_NORMAL, NULL);
392 todo_wine ok(GetLastError() == ERROR_SHARING_VIOLATION, "ITextDocument_Open should fail\n");
393 CloseHandle(hFile);
394 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
395 DeleteFileW(filename);
397 touch_file(filename);
398 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
399 SetLastError(0xdeadbeef);
400 hres = ITextDocument_Open(txtDoc, &testfile, tomShareDenyWrite|tomShareDenyRead, CP_ACP);
401 todo_wine
402 ok(hres == S_OK, "got 0x%08x\n", hres);
403 hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
404 FILE_ATTRIBUTE_NORMAL, NULL);
405 todo_wine ok(GetLastError() == ERROR_SHARING_VIOLATION, "ITextDocument_Open should fail\n");
406 CloseHandle(hFile);
407 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
408 DeleteFileW(filename);
410 /* tests to check the content */
411 hFile = CreateFileW(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS,
412 FILE_ATTRIBUTE_NORMAL, NULL);
413 WriteFile(hFile, chACP, sizeof(chACP)-sizeof(CHAR), &dw, NULL);
414 CloseHandle(hFile);
415 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
416 hres = ITextDocument_Open(txtDoc, &testfile, tomReadOnly, CP_ACP);
417 todo_wine
418 ok(hres == S_OK, "got 0x%08x\n", hres);
419 result = SendMessageA(w, WM_GETTEXT, 1024, (LPARAM)bufACP);
420 todo_wine ok(result == 12, "ITextDocument_Open: Test ASCII returned %d, expected 12\n", result);
421 result = strcmp(bufACP, chACP);
422 todo_wine ok(result == 0, "ITextDocument_Open: Test ASCII set wrong text: Result: %s\n", bufACP);
423 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
424 DeleteFileW(filename);
426 hFile = CreateFileW(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS,
427 FILE_ATTRIBUTE_NORMAL, NULL);
428 WriteFile(hFile, chUTF8, sizeof(chUTF8)-sizeof(CHAR), &dw, NULL);
429 CloseHandle(hFile);
430 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
431 hres = ITextDocument_Open(txtDoc, &testfile, tomReadOnly, CP_UTF8);
432 todo_wine
433 ok(hres == S_OK, "got 0x%08x\n", hres);
434 result = SendMessageA(w, WM_GETTEXT, 1024, (LPARAM)bufACP);
435 todo_wine ok(result == 15, "ITextDocument_Open: Test UTF-8 returned %d, expected 15\n", result);
436 result = strcmp(bufACP, &chUTF8[3]);
437 todo_wine ok(result == 0, "ITextDocument_Open: Test UTF-8 set wrong text: Result: %s\n", bufACP);
438 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
439 DeleteFileW(filename);
441 hFile = CreateFileW(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS,
442 FILE_ATTRIBUTE_NORMAL, NULL);
443 WriteFile(hFile, chUTF16, sizeof(chUTF16)-sizeof(WCHAR), &dw, NULL);
444 CloseHandle(hFile);
445 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
446 hres = ITextDocument_Open(txtDoc, &testfile, tomReadOnly, 1200);
447 todo_wine
448 ok(hres == S_OK, "got 0x%08x\n", hres);
449 result = SendMessageW(w, WM_GETTEXT, 1024, (LPARAM)bufUnicode);
450 todo_wine ok(result == 12, "ITextDocument_Open: Test UTF-16 returned %d, expected 12\n", result);
451 result = lstrcmpW(bufUnicode, &chUTF16[1]);
452 todo_wine ok(result == 0, "ITextDocument_Open: Test UTF-16 set wrong text: Result: %s\n", wine_dbgstr_w(bufUnicode));
453 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
454 DeleteFileW(filename);
456 VariantClear(&testfile);
459 static void test_GetText(void)
461 HWND w;
462 IRichEditOle *reOle = NULL;
463 ITextDocument *txtDoc = NULL;
464 ITextSelection *txtSel = NULL;
465 HRESULT hres;
466 BSTR bstr = NULL;
467 int first, lim;
468 static const CHAR test_text1[] = "TestSomeText";
469 static const WCHAR bufW1[] = {'T', 'e', 's', 't', 0};
470 static const WCHAR bufW2[] = {'T', 'e', 'x', 't', '\r', 0};
471 static const WCHAR bufW3[] = {'T', 'e', 'x', 't', 0};
472 static const WCHAR bufW4[] = {'T', 'e', 's', 't', 'S', 'o', 'm',
473 'e', 'T', 'e', 'x', 't', '\r', 0};
474 static const WCHAR bufW5[] = {'\r', 0};
475 static const WCHAR bufW6[] = {'T','e','s','t','S','o','m','e','T',0};
476 BOOL is64bit = sizeof(void *) > sizeof(int);
477 ITextRange *range;
479 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
480 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
482 /* ITextSelection */
483 first = 0, lim = 4;
484 SendMessageA(w, EM_SETSEL, first, lim);
485 hres = ITextSelection_GetText(txtSel, &bstr);
486 ok(hres == S_OK, "ITextSelection_GetText\n");
487 ok(!lstrcmpW(bstr, bufW1), "got wrong text: %s\n", wine_dbgstr_w(bstr));
488 SysFreeString(bstr);
490 first = 4, lim = 0;
491 SendMessageA(w, EM_SETSEL, first, lim);
492 hres = ITextSelection_GetText(txtSel, &bstr);
493 ok(hres == S_OK, "ITextSelection_GetText\n");
494 ok(!lstrcmpW(bstr, bufW1), "got wrong text: %s\n", wine_dbgstr_w(bstr));
495 SysFreeString(bstr);
497 first = 1, lim = 1;
498 SendMessageA(w, EM_SETSEL, first, lim);
499 hres = ITextSelection_GetText(txtSel, &bstr);
500 ok(hres == S_OK, "ITextSelection_GetText\n");
501 ok(!bstr, "got wrong text: %s\n", wine_dbgstr_w(bstr));
503 if (!is64bit)
505 hres = ITextSelection_GetText(txtSel, NULL);
506 ok(hres == E_INVALIDARG, "ITextSelection_GetText\n");
509 first = 8, lim = 12;
510 SendMessageA(w, EM_SETSEL, first, lim);
511 hres = ITextSelection_GetText(txtSel, &bstr);
512 ok(hres == S_OK, "ITextSelection_GetText\n");
513 ok(!lstrcmpW(bstr, bufW3), "got wrong text: %s\n", wine_dbgstr_w(bstr));
514 SysFreeString(bstr);
516 first = 8, lim = 13;
517 SendMessageA(w, EM_SETSEL, first, lim);
518 hres = ITextSelection_GetText(txtSel, &bstr);
519 ok(hres == S_OK, "ITextSelection_GetText\n");
520 ok(!lstrcmpW(bstr, bufW2), "got wrong text: %s\n", wine_dbgstr_w(bstr));
521 SysFreeString(bstr);
523 first = 12, lim = 13;
524 SendMessageA(w, EM_SETSEL, first, lim);
525 hres = ITextSelection_GetText(txtSel, &bstr);
526 ok(hres == S_OK, "ITextSelection_GetText\n");
527 ok(!lstrcmpW(bstr, bufW5), "got wrong text: %s\n", wine_dbgstr_w(bstr));
528 SysFreeString(bstr);
530 first = 0, lim = -1;
531 SendMessageA(w, EM_SETSEL, first, lim);
532 hres = ITextSelection_GetText(txtSel, &bstr);
533 ok(hres == S_OK, "ITextSelection_GetText\n");
534 ok(!lstrcmpW(bstr, bufW4), "got wrong text: %s\n", wine_dbgstr_w(bstr));
535 SysFreeString(bstr);
537 first = -1, lim = 9;
538 SendMessageA(w, EM_SETSEL, first, lim);
539 hres = ITextSelection_GetText(txtSel, &bstr);
540 ok(hres == S_OK, "ITextSelection_GetText\n");
541 ok(!bstr, "got wrong text: %s\n", wine_dbgstr_w(bstr));
543 /* ITextRange */
544 hres = ITextDocument_Range(txtDoc, 0, 4, &range);
545 ok(hres == S_OK, "got 0x%08x\n", hres);
546 hres = ITextRange_GetText(range, &bstr);
547 todo_wine {
548 ok(hres == S_OK, "got 0x%08x\n", hres);
549 ok(!lstrcmpW(bstr, bufW1), "got wrong text: %s\n", wine_dbgstr_w(bstr));
551 SysFreeString(bstr);
552 ITextRange_Release(range);
554 hres = ITextDocument_Range(txtDoc, 4, 0, &range);
555 ok(hres == S_OK, "got 0x%08x\n", hres);
556 hres = ITextRange_GetText(range, &bstr);
557 todo_wine {
558 ok(hres == S_OK, "got 0x%08x\n", hres);
559 ok(!lstrcmpW(bstr, bufW1), "got wrong text: %s\n", wine_dbgstr_w(bstr));
561 SysFreeString(bstr);
562 ITextRange_Release(range);
564 hres = ITextDocument_Range(txtDoc, 1, 1, &range);
565 ok(hres == S_OK, "got 0x%08x\n", hres);
566 hres = ITextRange_GetText(range, &bstr);
567 todo_wine
568 ok(hres == S_OK, "got 0x%08x\n", hres);
569 ok(!bstr, "got wrong text: %s\n", wine_dbgstr_w(bstr));
570 if (!is64bit)
572 hres = ITextRange_GetText(range, NULL);
573 ok(hres == E_INVALIDARG, "got 0x%08x\n", hres);
575 ITextRange_Release(range);
577 hres = ITextDocument_Range(txtDoc, 8, 12, &range);
578 ok(hres == S_OK, "got 0x%08x\n", hres);
579 hres = ITextRange_GetText(range, &bstr);
580 todo_wine {
581 ok(hres == S_OK, "got 0x%08x\n", hres);
582 ok(!lstrcmpW(bstr, bufW3), "got wrong text: %s\n", wine_dbgstr_w(bstr));
584 SysFreeString(bstr);
585 ITextRange_Release(range);
587 hres = ITextDocument_Range(txtDoc, 8, 13, &range);
588 ok(hres == S_OK, "got 0x%08x\n", hres);
589 hres = ITextRange_GetText(range, &bstr);
590 todo_wine {
591 ok(hres == S_OK, "got 0x%08x\n", hres);
592 ok(!lstrcmpW(bstr, bufW2), "got wrong text: %s\n", wine_dbgstr_w(bstr));
594 SysFreeString(bstr);
595 ITextRange_Release(range);
597 hres = ITextDocument_Range(txtDoc, 12, 13, &range);
598 ok(hres == S_OK, "got 0x%08x\n", hres);
599 hres = ITextRange_GetText(range, &bstr);
600 todo_wine {
601 ok(hres == S_OK, "got 0x%08x\n", hres);
602 ok(!lstrcmpW(bstr, bufW5), "got wrong text: %s\n", wine_dbgstr_w(bstr));
604 SysFreeString(bstr);
605 ITextRange_Release(range);
607 hres = ITextDocument_Range(txtDoc, 0, -1, &range);
608 ok(hres == S_OK, "got 0x%08x\n", hres);
609 hres = ITextRange_GetText(range, &bstr);
610 todo_wine
611 ok(hres == S_OK, "got 0x%08x\n", hres);
612 ok(!bstr, "got wrong text: %s\n", wine_dbgstr_w(bstr));
613 ITextRange_Release(range);
615 hres = ITextDocument_Range(txtDoc, -1, 9, &range);
616 ok(hres == S_OK, "got 0x%08x\n", hres);
617 hres = ITextRange_GetText(range, &bstr);
618 todo_wine {
619 ok(hres == S_OK, "got 0x%08x\n", hres);
620 ok(!lstrcmpW(bstr, bufW6), "got wrong text: %s\n", wine_dbgstr_w(bstr));
622 SysFreeString(bstr);
624 release_interfaces(&w, &reOle, &txtDoc, NULL);
626 /* detached selection/range */
627 if (is64bit) {
628 bstr = (void*)0xdeadbeef;
629 hres = ITextSelection_GetText(txtSel, &bstr);
630 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
631 todo_wine
632 ok(bstr == NULL, "got %p\n", bstr);
634 bstr = (void*)0xdeadbeef;
635 hres = ITextRange_GetText(range, &bstr);
636 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
637 todo_wine
638 ok(bstr == NULL, "got %p\n", bstr);
640 else {
641 hres = ITextSelection_GetText(txtSel, NULL);
642 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
644 hres = ITextRange_GetText(range, NULL);
645 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
648 ITextRange_Release(range);
649 ITextSelection_Release(txtSel);
652 static void test_ITextDocument_Range(void)
654 static const CHAR test_text1[] = "TestSomeText";
655 HWND w;
656 IRichEditOle *reOle = NULL;
657 ITextDocument *txtDoc = NULL;
658 ITextRange *txtRge, *range2;
659 HRESULT hres;
660 LONG value;
662 create_interfaces(&w, &reOle, &txtDoc, NULL);
663 hres = ITextDocument_Range(txtDoc, 0, 0, &txtRge);
664 ok(hres == S_OK, "ITextDocument_Range fails 0x%x.\n", hres);
665 EXPECT_REF(txtRge, 1);
667 hres = ITextDocument_Range(txtDoc, 0, 0, &range2);
668 ok(hres == S_OK, "ITextDocument_Range fails 0x%x.\n", hres);
669 ok(range2 != txtRge, "A new pointer should be returned\n");
670 ITextRange_Release(range2);
672 hres = ITextDocument_Range(txtDoc, 0, 0, NULL);
673 ok(hres == E_INVALIDARG, "ITextDocument_Range should fail 0x%x.\n", hres);
675 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
677 hres = ITextDocument_Range(txtDoc, 8, 30, &range2);
678 ok(hres == S_OK, "ITextDocument_Range fails 0x%x.\n", hres);
679 hres = ITextRange_GetStart(range2, &value);
680 ok(hres == S_OK, "got 0x%08x\n", hres);
681 ok(value == 8, "got %d\n", value);
683 hres = ITextRange_GetEnd(range2, &value);
684 ok(hres == S_OK, "got 0x%08x\n", hres);
685 ok(value == 13, "got %d\n", value);
686 ITextRange_Release(range2);
688 release_interfaces(&w, &reOle, &txtDoc, NULL);
689 hres = ITextRange_CanEdit(txtRge, NULL);
690 ok(hres == CO_E_RELEASED, "ITextRange after ITextDocument destroyed\n");
691 ITextRange_Release(txtRge);
694 static void test_ITextRange_GetChar(void)
696 HWND w;
697 IRichEditOle *reOle = NULL;
698 ITextDocument *txtDoc = NULL;
699 ITextRange *txtRge = NULL;
700 HRESULT hres;
701 LONG pch;
702 int first, lim;
703 static const CHAR test_text1[] = "TestSomeText";
705 first = 0, lim = 4;
706 create_interfaces(&w, &reOle, &txtDoc, NULL);
707 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
708 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
709 ok(hres == S_OK, "got 0x%08x\n", hres);
710 pch = 0xdeadbeef;
711 hres = ITextRange_GetChar(txtRge, &pch);
712 ok(hres == S_OK, "ITextRange_GetChar\n");
713 ok(pch == 'T', "got wrong char: %c\n", pch);
714 ITextRange_Release(txtRge);
715 release_interfaces(&w, &reOle, &txtDoc, NULL);
717 first = 0, lim = 0;
718 create_interfaces(&w, &reOle, &txtDoc, NULL);
719 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
720 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
721 ok(hres == S_OK, "got 0x%08x\n", hres);
722 pch = 0xdeadbeef;
723 hres = ITextRange_GetChar(txtRge, &pch);
724 ok(hres == S_OK, "ITextRange_GetChar\n");
725 ok(pch == 'T', "got wrong char: %c\n", pch);
726 ITextRange_Release(txtRge);
727 release_interfaces(&w, &reOle, &txtDoc, NULL);
729 first = 12, lim = 12;
730 create_interfaces(&w, &reOle, &txtDoc, NULL);
731 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
732 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
733 ok(hres == S_OK, "got 0x%08x\n", hres);
734 pch = 0xdeadbeef;
735 hres = ITextRange_GetChar(txtRge, &pch);
736 ok(hres == S_OK, "ITextRange_GetChar\n");
737 ok(pch == '\r', "got wrong char: %c\n", pch);
738 ITextRange_Release(txtRge);
739 release_interfaces(&w, &reOle, &txtDoc, NULL);
741 first = 13, lim = 13;
742 create_interfaces(&w, &reOle, &txtDoc, NULL);
743 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
744 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
745 ok(hres == S_OK, "got 0x%08x\n", hres);
746 pch = 0xdeadbeef;
747 hres = ITextRange_GetChar(txtRge, &pch);
748 ok(hres == S_OK, "ITextRange_GetChar\n");
749 ok(pch == '\r', "got wrong char: %c\n", pch);
750 ITextRange_Release(txtRge);
751 release_interfaces(&w, &reOle, &txtDoc, NULL);
753 create_interfaces(&w, &reOle, &txtDoc, NULL);
754 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
755 first = 12, lim = 12;
756 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
757 ok(hres == S_OK, "got 0x%08x\n", hres);
758 hres = ITextRange_GetChar(txtRge, NULL);
759 ok(hres == E_INVALIDARG, "ITextRange_GetChar\n");
761 release_interfaces(&w, &reOle, &txtDoc, NULL);
763 hres = ITextRange_GetChar(txtRge, NULL);
764 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
766 hres = ITextRange_GetChar(txtRge, &pch);
767 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
769 ITextRange_Release(txtRge);
772 static void test_ITextSelection_GetChar(void)
774 HWND w;
775 IRichEditOle *reOle = NULL;
776 ITextDocument *txtDoc = NULL;
777 ITextSelection *txtSel = NULL;
778 HRESULT hres;
779 LONG pch;
780 int first, lim;
781 static const CHAR test_text1[] = "TestSomeText";
783 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
784 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
786 first = 0, lim = 4;
787 SendMessageA(w, EM_SETSEL, first, lim);
788 pch = 0xdeadbeef;
789 hres = ITextSelection_GetChar(txtSel, &pch);
790 ok(hres == S_OK, "ITextSelection_GetChar\n");
791 ok(pch == 'T', "got wrong char: %c\n", pch);
793 first = 0, lim = 0;
794 SendMessageA(w, EM_SETSEL, first, lim);
795 pch = 0xdeadbeef;
796 hres = ITextSelection_GetChar(txtSel, &pch);
797 ok(hres == S_OK, "ITextSelection_GetChar\n");
798 ok(pch == 'T', "got wrong char: %c\n", pch);
800 first = 12, lim = 12;
801 SendMessageA(w, EM_SETSEL, first, lim);
802 pch = 0xdeadbeef;
803 hres = ITextSelection_GetChar(txtSel, &pch);
804 ok(hres == S_OK, "ITextSelection_GetChar\n");
805 ok(pch == '\r', "got wrong char: %c\n", pch);
807 first = 13, lim = 13;
808 SendMessageA(w, EM_SETSEL, first, lim);
809 pch = 0xdeadbeef;
810 hres = ITextSelection_GetChar(txtSel, &pch);
811 ok(hres == S_OK, "ITextSelection_GetChar\n");
812 ok(pch == '\r', "got wrong char: %c\n", pch);
814 hres = ITextSelection_GetChar(txtSel, NULL);
815 ok(hres == E_INVALIDARG, "ITextSelection_GetChar\n");
817 release_interfaces(&w, &reOle, &txtDoc, NULL);
819 hres = ITextSelection_GetChar(txtSel, NULL);
820 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
822 hres = ITextSelection_GetChar(txtSel, &pch);
823 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
825 ITextSelection_Release(txtSel);
828 static void test_ITextRange_GetStart_GetEnd(void)
830 HWND w;
831 IRichEditOle *reOle = NULL;
832 ITextDocument *txtDoc = NULL;
833 ITextRange *txtRge = NULL;
834 HRESULT hres;
835 int first, lim, start, end;
836 static const CHAR test_text1[] = "TestSomeText";
838 create_interfaces(&w, &reOle, &txtDoc, NULL);
839 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
841 first = 1, lim = 6;
842 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
843 ok(hres == S_OK, "got 0x%08x\n", hres);
844 start = 0xdeadbeef;
845 hres = ITextRange_GetStart(txtRge, &start);
846 ok(hres == S_OK, "ITextRange_GetStart\n");
847 ok(start == 1, "got wrong start value: %d\n", start);
848 end = 0xdeadbeef;
849 hres = ITextRange_GetEnd(txtRge, &end);
850 ok(hres == S_OK, "ITextRange_GetEnd\n");
851 ok(end == 6, "got wrong end value: %d\n", end);
852 ITextRange_Release(txtRge);
854 first = 6, lim = 1;
855 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
856 ok(hres == S_OK, "got 0x%08x\n", hres);
857 start = 0xdeadbeef;
858 hres = ITextRange_GetStart(txtRge, &start);
859 ok(hres == S_OK, "ITextRange_GetStart\n");
860 ok(start == 1, "got wrong start value: %d\n", start);
861 end = 0xdeadbeef;
862 hres = ITextRange_GetEnd(txtRge, &end);
863 ok(hres == S_OK, "ITextRange_GetEnd\n");
864 ok(end == 6, "got wrong end value: %d\n", end);
865 ITextRange_Release(txtRge);
867 first = -1, lim = 13;
868 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
869 ok(hres == S_OK, "got 0x%08x\n", hres);
870 start = 0xdeadbeef;
871 hres = ITextRange_GetStart(txtRge, &start);
872 ok(hres == S_OK, "ITextRange_GetStart\n");
873 ok(start == 0, "got wrong start value: %d\n", start);
874 end = 0xdeadbeef;
875 hres = ITextRange_GetEnd(txtRge, &end);
876 ok(hres == S_OK, "ITextRange_GetEnd\n");
877 ok(end == 13, "got wrong end value: %d\n", end);
878 ITextRange_Release(txtRge);
880 first = 13, lim = 13;
881 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
882 ok(hres == S_OK, "got 0x%08x\n", hres);
883 start = 0xdeadbeef;
884 hres = ITextRange_GetStart(txtRge, &start);
885 ok(hres == S_OK, "ITextRange_GetStart\n");
886 ok(start == 12, "got wrong start value: %d\n", start);
887 end = 0xdeadbeef;
888 hres = ITextRange_GetEnd(txtRge, &end);
889 ok(hres == S_OK, "ITextRange_GetEnd\n");
890 ok(end == 12, "got wrong end value: %d\n", end);
892 /* SetStart */
893 hres = ITextRange_SetStart(txtRge, 0);
894 ok(hres == S_OK, "got 0x%08x\n", hres);
896 /* same value */
897 hres = ITextRange_SetStart(txtRge, 0);
898 ok(hres == S_FALSE, "got 0x%08x\n", hres);
900 hres = ITextRange_SetStart(txtRge, 1);
901 ok(hres == S_OK, "got 0x%08x\n", hres);
903 /* negative resets to 0, return value is S_FALSE when
904 position wasn't changed */
905 hres = ITextRange_SetStart(txtRge, -1);
906 ok(hres == S_OK, "got 0x%08x\n", hres);
908 hres = ITextRange_SetStart(txtRge, -1);
909 ok(hres == S_FALSE, "got 0x%08x\n", hres);
911 hres = ITextRange_SetStart(txtRge, 0);
912 ok(hres == S_FALSE, "got 0x%08x\n", hres);
914 start = -1;
915 hres = ITextRange_GetStart(txtRge, &start);
916 ok(hres == S_OK, "got 0x%08x\n", hres);
917 ok(start == 0, "got %d\n", start);
919 /* greater than initial end, but less than total char count */
920 hres = ITextRange_SetStart(txtRge, 1);
921 ok(hres == S_OK, "got 0x%08x\n", hres);
923 hres = ITextRange_SetEnd(txtRge, 3);
924 ok(hres == S_OK, "got 0x%08x\n", hres);
926 hres = ITextRange_SetStart(txtRge, 10);
927 ok(hres == S_OK, "got 0x%08x\n", hres);
929 start = 0;
930 hres = ITextRange_GetStart(txtRge, &start);
931 ok(hres == S_OK, "got 0x%08x\n", hres);
932 ok(start == 10, "got %d\n", start);
934 end = 0;
935 hres = ITextRange_GetEnd(txtRge, &end);
936 ok(hres == S_OK, "got 0x%08x\n", hres);
937 ok(end == 10, "got %d\n", end);
939 /* more that total text length */
940 hres = ITextRange_SetStart(txtRge, 50);
941 ok(hres == S_OK, "got 0x%08x\n", hres);
943 start = 0;
944 hres = ITextRange_GetStart(txtRge, &start);
945 ok(hres == S_OK, "got 0x%08x\n", hres);
946 ok(start == 12, "got %d\n", start);
948 end = 0;
949 hres = ITextRange_GetEnd(txtRge, &end);
950 ok(hres == S_OK, "got 0x%08x\n", hres);
951 ok(end == 12, "got %d\n", end);
953 /* SetEnd */
954 hres = ITextRange_SetStart(txtRge, 0);
955 ok(hres == S_OK, "got 0x%08x\n", hres);
957 /* same value */
958 hres = ITextRange_SetEnd(txtRge, 5);
959 ok(hres == S_OK, "got 0x%08x\n", hres);
961 hres = ITextRange_SetEnd(txtRge, 5);
962 ok(hres == S_FALSE, "got 0x%08x\n", hres);
964 /* negative resets to 0 */
965 hres = ITextRange_SetEnd(txtRge, -1);
966 ok(hres == S_OK, "got 0x%08x\n", hres);
968 end = -1;
969 hres = ITextRange_GetEnd(txtRge, &end);
970 ok(hres == S_OK, "got 0x%08x\n", hres);
971 ok(end == 0, "got %d\n", end);
973 start = -1;
974 hres = ITextRange_GetStart(txtRge, &start);
975 ok(hres == S_OK, "got 0x%08x\n", hres);
976 ok(start == 0, "got %d\n", start);
978 /* greater than initial end, but less than total char count */
979 hres = ITextRange_SetStart(txtRge, 3);
980 ok(hres == S_OK, "got 0x%08x\n", hres);
982 hres = ITextRange_SetEnd(txtRge, 1);
983 ok(hres == S_OK, "got 0x%08x\n", hres);
985 start = 0;
986 hres = ITextRange_GetStart(txtRge, &start);
987 ok(hres == S_OK, "got 0x%08x\n", hres);
988 ok(start == 1, "got %d\n", start);
990 end = 0;
991 hres = ITextRange_GetEnd(txtRge, &end);
992 ok(hres == S_OK, "got 0x%08x\n", hres);
993 ok(end == 1, "got %d\n", end);
995 /* more than total count */
996 hres = ITextRange_SetEnd(txtRge, 50);
997 ok(hres == S_OK, "got 0x%08x\n", hres);
999 start = 0;
1000 hres = ITextRange_GetStart(txtRge, &start);
1001 ok(hres == S_OK, "got 0x%08x\n", hres);
1002 ok(start == 1, "got %d\n", start);
1004 end = 0;
1005 hres = ITextRange_GetEnd(txtRge, &end);
1006 ok(hres == S_OK, "got 0x%08x\n", hres);
1007 ok(end == 13, "got %d\n", end);
1009 /* zero */
1010 hres = ITextRange_SetEnd(txtRge, 0);
1011 ok(hres == S_OK, "got 0x%08x\n", hres);
1013 start = 0;
1014 hres = ITextRange_GetStart(txtRge, &start);
1015 ok(hres == S_OK, "got 0x%08x\n", hres);
1016 ok(start == 0, "got %d\n", start);
1018 end = 0;
1019 hres = ITextRange_GetEnd(txtRge, &end);
1020 ok(hres == S_OK, "got 0x%08x\n", hres);
1021 ok(end == 0, "got %d\n", end);
1023 release_interfaces(&w, &reOle, &txtDoc, NULL);
1025 /* detached range */
1026 hres = ITextRange_SetStart(txtRge, 0);
1027 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1029 hres = ITextRange_SetEnd(txtRge, 3);
1030 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1032 hres = ITextRange_GetStart(txtRge, &start);
1033 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1035 hres = ITextRange_GetStart(txtRge, NULL);
1036 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1038 hres = ITextRange_GetEnd(txtRge, &end);
1039 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1041 hres = ITextRange_GetEnd(txtRge, NULL);
1042 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1044 ITextRange_Release(txtRge);
1047 static void test_ITextSelection_GetStart_GetEnd(void)
1049 HWND w;
1050 IRichEditOle *reOle = NULL;
1051 ITextDocument *txtDoc = NULL;
1052 ITextSelection *txtSel = NULL;
1053 HRESULT hres;
1054 int first, lim, start, end;
1055 static const CHAR test_text1[] = "TestSomeText";
1057 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
1058 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
1060 first = 2, lim = 5;
1061 SendMessageA(w, EM_SETSEL, first, lim);
1062 start = 0xdeadbeef;
1063 hres = ITextSelection_GetStart(txtSel, &start);
1064 ok(hres == S_OK, "ITextSelection_GetStart\n");
1065 ok(start == 2, "got wrong start value: %d\n", start);
1066 end = 0xdeadbeef;
1067 hres = ITextSelection_GetEnd(txtSel, &end);
1068 ok(hres == S_OK, "ITextSelection_GetEnd\n");
1069 ok(end == 5, "got wrong end value: %d\n", end);
1071 first = 5, lim = 2;
1072 SendMessageA(w, EM_SETSEL, first, lim);
1073 start = 0xdeadbeef;
1074 hres = ITextSelection_GetStart(txtSel, &start);
1075 ok(hres == S_OK, "ITextSelection_GetStart\n");
1076 ok(start == 2, "got wrong start value: %d\n", start);
1077 end = 0xdeadbeef;
1078 hres = ITextSelection_GetEnd(txtSel, &end);
1079 ok(hres == S_OK, "ITextSelection_GetEnd\n");
1080 ok(end == 5, "got wrong end value: %d\n", end);
1082 first = 0, lim = -1;
1083 SendMessageA(w, EM_SETSEL, first, lim);
1084 start = 0xdeadbeef;
1085 hres = ITextSelection_GetStart(txtSel, &start);
1086 ok(hres == S_OK, "ITextSelection_GetStart\n");
1087 ok(start == 0, "got wrong start value: %d\n", start);
1088 end = 0xdeadbeef;
1089 hres = ITextSelection_GetEnd(txtSel, &end);
1090 ok(hres == S_OK, "ITextSelection_GetEnd\n");
1091 ok(end == 13, "got wrong end value: %d\n", end);
1093 first = 13, lim = 13;
1094 SendMessageA(w, EM_SETSEL, first, lim);
1095 start = 0xdeadbeef;
1096 hres = ITextSelection_GetStart(txtSel, &start);
1097 ok(hres == S_OK, "ITextSelection_GetStart\n");
1098 ok(start == 12, "got wrong start value: %d\n", start);
1099 end = 0xdeadbeef;
1100 hres = ITextSelection_GetEnd(txtSel, &end);
1101 ok(hres == S_OK, "ITextSelection_GetEnd\n");
1102 ok(end == 12, "got wrong end value: %d\n", end);
1104 /* SetStart/SetEnd */
1105 hres = ITextSelection_SetStart(txtSel, 0);
1106 ok(hres == S_OK, "got 0x%08x\n", hres);
1108 /* same value */
1109 hres = ITextSelection_SetStart(txtSel, 0);
1110 ok(hres == S_FALSE, "got 0x%08x\n", hres);
1112 hres = ITextSelection_SetStart(txtSel, 1);
1113 ok(hres == S_OK, "got 0x%08x\n", hres);
1115 /* negative resets to 0, return value is S_FALSE when
1116 position wasn't changed */
1117 hres = ITextSelection_SetStart(txtSel, -1);
1118 ok(hres == S_OK, "got 0x%08x\n", hres);
1120 hres = ITextSelection_SetStart(txtSel, -1);
1121 ok(hres == S_FALSE, "got 0x%08x\n", hres);
1123 hres = ITextSelection_SetStart(txtSel, 0);
1124 ok(hres == S_FALSE, "got 0x%08x\n", hres);
1126 start = -1;
1127 hres = ITextSelection_GetStart(txtSel, &start);
1128 ok(hres == S_OK, "got 0x%08x\n", hres);
1129 ok(start == 0, "got %d\n", start);
1131 /* greater than initial end, but less than total char count */
1132 hres = ITextSelection_SetStart(txtSel, 1);
1133 ok(hres == S_OK, "got 0x%08x\n", hres);
1135 hres = ITextSelection_SetEnd(txtSel, 3);
1136 ok(hres == S_OK, "got 0x%08x\n", hres);
1138 hres = ITextSelection_SetStart(txtSel, 10);
1139 ok(hres == S_OK, "got 0x%08x\n", hres);
1141 start = 0;
1142 hres = ITextSelection_GetStart(txtSel, &start);
1143 ok(hres == S_OK, "got 0x%08x\n", hres);
1144 ok(start == 10, "got %d\n", start);
1146 end = 0;
1147 hres = ITextSelection_GetEnd(txtSel, &end);
1148 ok(hres == S_OK, "got 0x%08x\n", hres);
1149 ok(end == 10, "got %d\n", end);
1151 /* more that total text length */
1152 hres = ITextSelection_SetStart(txtSel, 50);
1153 ok(hres == S_OK, "got 0x%08x\n", hres);
1155 start = 0;
1156 hres = ITextSelection_GetStart(txtSel, &start);
1157 ok(hres == S_OK, "got 0x%08x\n", hres);
1158 ok(start == 12, "got %d\n", start);
1160 end = 0;
1161 hres = ITextSelection_GetEnd(txtSel, &end);
1162 ok(hres == S_OK, "got 0x%08x\n", hres);
1163 ok(end == 12, "got %d\n", end);
1165 /* SetEnd */
1166 hres = ITextSelection_SetStart(txtSel, 0);
1167 ok(hres == S_OK, "got 0x%08x\n", hres);
1169 /* same value */
1170 hres = ITextSelection_SetEnd(txtSel, 5);
1171 ok(hres == S_OK, "got 0x%08x\n", hres);
1173 hres = ITextSelection_SetEnd(txtSel, 5);
1174 ok(hres == S_FALSE, "got 0x%08x\n", hres);
1176 /* negative resets to 0 */
1177 hres = ITextSelection_SetEnd(txtSel, -1);
1178 ok(hres == S_OK, "got 0x%08x\n", hres);
1180 end = -1;
1181 hres = ITextSelection_GetEnd(txtSel, &end);
1182 ok(hres == S_OK, "got 0x%08x\n", hres);
1183 ok(end == 0, "got %d\n", end);
1185 start = -1;
1186 hres = ITextSelection_GetStart(txtSel, &start);
1187 ok(hres == S_OK, "got 0x%08x\n", hres);
1188 ok(start == 0, "got %d\n", start);
1190 /* greater than initial end, but less than total char count */
1191 hres = ITextSelection_SetStart(txtSel, 3);
1192 ok(hres == S_OK, "got 0x%08x\n", hres);
1194 hres = ITextSelection_SetEnd(txtSel, 1);
1195 ok(hres == S_OK, "got 0x%08x\n", hres);
1197 start = 0;
1198 hres = ITextSelection_GetStart(txtSel, &start);
1199 ok(hres == S_OK, "got 0x%08x\n", hres);
1200 ok(start == 1, "got %d\n", start);
1202 end = 0;
1203 hres = ITextSelection_GetEnd(txtSel, &end);
1204 ok(hres == S_OK, "got 0x%08x\n", hres);
1205 ok(end == 1, "got %d\n", end);
1207 /* more than total count */
1208 hres = ITextSelection_SetEnd(txtSel, 50);
1209 ok(hres == S_OK, "got 0x%08x\n", hres);
1211 start = 0;
1212 hres = ITextSelection_GetStart(txtSel, &start);
1213 ok(hres == S_OK, "got 0x%08x\n", hres);
1214 ok(start == 1, "got %d\n", start);
1216 end = 0;
1217 hres = ITextSelection_GetEnd(txtSel, &end);
1218 ok(hres == S_OK, "got 0x%08x\n", hres);
1219 ok(end == 13, "got %d\n", end);
1221 /* zero */
1222 hres = ITextSelection_SetEnd(txtSel, 0);
1223 ok(hres == S_OK, "got 0x%08x\n", hres);
1225 start = 0;
1226 hres = ITextSelection_GetStart(txtSel, &start);
1227 ok(hres == S_OK, "got 0x%08x\n", hres);
1228 ok(start == 0, "got %d\n", start);
1230 end = 0;
1231 hres = ITextSelection_GetEnd(txtSel, &end);
1232 ok(hres == S_OK, "got 0x%08x\n", hres);
1233 ok(end == 0, "got %d\n", end);
1235 release_interfaces(&w, &reOle, &txtDoc, NULL);
1237 /* detached selection */
1238 hres = ITextSelection_GetStart(txtSel, NULL);
1239 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1241 hres = ITextSelection_GetStart(txtSel, &start);
1242 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1244 hres = ITextSelection_GetEnd(txtSel, NULL);
1245 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1247 hres = ITextSelection_GetEnd(txtSel, &end);
1248 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1250 ITextSelection_Release(txtSel);
1253 static void test_ITextRange_GetDuplicate(void)
1255 HWND w;
1256 IRichEditOle *reOle = NULL;
1257 ITextDocument *txtDoc = NULL;
1258 ITextRange *txtRge = NULL;
1259 ITextRange *txtRgeDup = NULL;
1260 HRESULT hres;
1261 LONG first, lim, start, end;
1262 static const CHAR test_text1[] = "TestSomeText";
1264 create_interfaces(&w, &reOle, &txtDoc, NULL);
1265 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
1266 first = 0, lim = 4;
1267 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
1268 ok(hres == S_OK, "ITextDocument_Range fails 0x%x.\n", hres);
1270 hres = ITextRange_GetDuplicate(txtRge, &txtRgeDup);
1271 ok(hres == S_OK, "ITextRange_GetDuplicate\n");
1272 ok(txtRgeDup != txtRge, "A new pointer should be returned\n");
1273 hres = ITextRange_GetStart(txtRgeDup, &start);
1274 ok(hres == S_OK, "got 0x%08x\n", hres);
1275 ok(start == first, "got wrong value: %d\n", start);
1276 hres = ITextRange_GetEnd(txtRgeDup, &end);
1277 ok(hres == S_OK, "got 0x%08x\n", hres);
1278 ok(end == lim, "got wrong value: %d\n", end);
1280 ITextRange_Release(txtRgeDup);
1282 hres = ITextRange_GetDuplicate(txtRge, NULL);
1283 ok(hres == E_INVALIDARG, "ITextRange_GetDuplicate\n");
1285 release_interfaces(&w, &reOle, &txtDoc, NULL);
1287 hres = ITextRange_GetDuplicate(txtRge, NULL);
1288 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1290 hres = ITextRange_GetDuplicate(txtRge, &txtRgeDup);
1291 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1293 ITextRange_Release(txtRge);
1296 static void test_ITextRange_Collapse(void)
1298 HWND w;
1299 IRichEditOle *reOle = NULL;
1300 ITextDocument *txtDoc = NULL;
1301 ITextRange *txtRge = NULL;
1302 HRESULT hres;
1303 LONG first, lim, start, end;
1304 static const CHAR test_text1[] = "TestSomeText";
1306 create_interfaces(&w, &reOle, &txtDoc, NULL);
1307 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
1309 first = 4, lim = 8;
1310 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
1311 ok(hres == S_OK, "got 0x%08x\n", hres);
1312 hres = ITextRange_Collapse(txtRge, tomTrue);
1313 ok(hres == S_OK, "ITextRange_Collapse\n");
1314 hres = ITextRange_GetStart(txtRge, &start);
1315 ok(hres == S_OK, "got 0x%08x\n", hres);
1316 ok(start == 4, "got wrong start value: %d\n", start);
1317 hres = ITextRange_GetEnd(txtRge, &end);
1318 ok(hres == S_OK, "got 0x%08x\n", hres);
1319 ok(end == 4, "got wrong end value: %d\n", end);
1320 ITextRange_Release(txtRge);
1322 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
1323 ok(hres == S_OK, "got 0x%08x\n", hres);
1324 hres = ITextRange_Collapse(txtRge, tomStart);
1325 ok(hres == S_OK, "ITextRange_Collapse\n");
1326 hres = ITextRange_GetStart(txtRge, &start);
1327 ok(hres == S_OK, "got 0x%08x\n", hres);
1328 ok(start == 4, "got wrong start value: %d\n", start);
1329 hres = ITextRange_GetEnd(txtRge, &end);
1330 ok(hres == S_OK, "got 0x%08x\n", hres);
1331 ok(end == 4, "got wrong end value: %d\n", end);
1332 ITextRange_Release(txtRge);
1334 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
1335 ok(hres == S_OK, "got 0x%08x\n", hres);
1336 hres = ITextRange_Collapse(txtRge, tomFalse);
1337 ok(hres == S_OK, "ITextRange_Collapse\n");
1338 hres = ITextRange_GetStart(txtRge, &start);
1339 ok(hres == S_OK, "got 0x%08x\n", hres);
1340 ok(start == 8, "got wrong start value: %d\n", start);
1341 hres = ITextRange_GetEnd(txtRge, &end);
1342 ok(hres == S_OK, "got 0x%08x\n", hres);
1343 ok(end == 8, "got wrong end value: %d\n", end);
1344 ITextRange_Release(txtRge);
1346 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
1347 ok(hres == S_OK, "got 0x%08x\n", hres);
1348 hres = ITextRange_Collapse(txtRge, tomEnd);
1349 ok(hres == S_OK, "ITextRange_Collapse\n");
1350 hres = ITextRange_GetStart(txtRge, &start);
1351 ok(hres == S_OK, "got 0x%08x\n", hres);
1352 ok(start == 8, "got wrong start value: %d\n", start);
1353 hres = ITextRange_GetEnd(txtRge, &end);
1354 ok(hres == S_OK, "got 0x%08x\n", hres);
1355 ok(end == 8, "got wrong end value: %d\n", end);
1356 ITextRange_Release(txtRge);
1358 /* tomStart is the default */
1359 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
1360 ok(hres == S_OK, "got 0x%08x\n", hres);
1361 hres = ITextRange_Collapse(txtRge, 256);
1362 ok(hres == S_OK, "ITextRange_Collapse\n");
1363 hres = ITextRange_GetStart(txtRge, &start);
1364 ok(hres == S_OK, "got 0x%08x\n", hres);
1365 ok(start == 4, "got wrong start value: %d\n", start);
1366 hres = ITextRange_GetEnd(txtRge, &end);
1367 ok(hres == S_OK, "got 0x%08x\n", hres);
1368 ok(end == 4, "got wrong end value: %d\n", end);
1369 ITextRange_Release(txtRge);
1371 first = 6, lim = 6;
1372 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
1373 ok(hres == S_OK, "got 0x%08x\n", hres);
1374 hres = ITextRange_Collapse(txtRge, tomEnd);
1375 ok(hres == S_FALSE, "ITextRange_Collapse\n");
1376 hres = ITextRange_GetStart(txtRge, &start);
1377 ok(hres == S_OK, "got 0x%08x\n", hres);
1378 ok(start == 6, "got wrong start value: %d\n", start);
1379 hres = ITextRange_GetEnd(txtRge, &end);
1380 ok(hres == S_OK, "got 0x%08x\n", hres);
1381 ok(end == 6, "got wrong end value: %d\n", end);
1382 ITextRange_Release(txtRge);
1384 first = 8, lim = 8;
1385 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
1386 ok(hres == S_OK, "got 0x%08x\n", hres);
1387 hres = ITextRange_Collapse(txtRge, tomStart);
1388 ok(hres == S_FALSE, "ITextRange_Collapse\n");
1389 hres = ITextRange_GetStart(txtRge, &start);
1390 ok(hres == S_OK, "got 0x%08x\n", hres);
1391 ok(start == 8, "got wrong start value: %d\n", start);
1392 hres = ITextRange_GetEnd(txtRge, &end);
1393 ok(hres == S_OK, "got 0x%08x\n", hres);
1394 ok(end == 8, "got wrong end value: %d\n", end);
1396 release_interfaces(&w, &reOle, &txtDoc, NULL);
1398 hres = ITextRange_Collapse(txtRge, tomStart);
1399 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1401 hres = ITextRange_Collapse(txtRge, tomUndefined);
1402 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1404 ITextRange_Release(txtRge);
1407 static void test_ITextSelection_Collapse(void)
1409 HWND w;
1410 IRichEditOle *reOle = NULL;
1411 ITextDocument *txtDoc = NULL;
1412 ITextSelection *txtSel = NULL;
1413 HRESULT hres;
1414 LONG first, lim, start, end;
1415 static const CHAR test_text1[] = "TestSomeText";
1417 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
1418 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
1420 first = 4, lim = 8;
1421 SendMessageA(w, EM_SETSEL, first, lim);
1422 hres = ITextSelection_Collapse(txtSel, tomTrue);
1423 ok(hres == S_OK, "ITextSelection_Collapse\n");
1424 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1425 ok(start == 4, "got wrong start value: %d\n", start);
1426 ok(end == 4, "got wrong end value: %d\n", end);
1428 SendMessageA(w, EM_SETSEL, first, lim);
1429 hres = ITextSelection_Collapse(txtSel, tomStart);
1430 ok(hres == S_OK, "ITextSelection_Collapse\n");
1431 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1432 ok(start == 4, "got wrong start value: %d\n", start);
1433 ok(end == 4, "got wrong end value: %d\n", end);
1435 SendMessageA(w, EM_SETSEL, first, lim);
1436 hres = ITextSelection_Collapse(txtSel, tomFalse);
1437 ok(hres == S_OK, "ITextSelection_Collapse\n");
1438 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1439 ok(start == 8, "got wrong start value: %d\n", start);
1440 ok(end == 8, "got wrong end value: %d\n", end);
1442 SendMessageA(w, EM_SETSEL, first, lim);
1443 hres = ITextSelection_Collapse(txtSel, tomEnd);
1444 ok(hres == S_OK, "ITextSelection_Collapse\n");
1445 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1446 ok(start == 8, "got wrong start value: %d\n", start);
1447 ok(end == 8, "got wrong end value: %d\n", end);
1449 /* tomStart is the default */
1450 SendMessageA(w, EM_SETSEL, first, lim);
1451 hres = ITextSelection_Collapse(txtSel, 256);
1452 ok(hres == S_OK, "ITextSelection_Collapse\n");
1453 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1454 ok(start == 4, "got wrong start value: %d\n", start);
1455 ok(end == 4, "got wrong end value: %d\n", end);
1457 first = 6, lim = 6;
1458 SendMessageA(w, EM_SETSEL, first, lim);
1459 hres = ITextSelection_Collapse(txtSel, tomEnd);
1460 ok(hres == S_FALSE, "ITextSelection_Collapse\n");
1461 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1462 ok(start == 6, "got wrong start value: %d\n", start);
1463 ok(end == 6, "got wrong end value: %d\n", end);
1465 first = 8, lim = 8;
1466 SendMessageA(w, EM_SETSEL, first, lim);
1467 hres = ITextSelection_Collapse(txtSel, tomStart);
1468 ok(hres == S_FALSE, "ITextSelection_Collapse\n");
1469 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1470 ok(start == 8, "got wrong start value: %d\n", start);
1471 ok(end == 8, "got wrong end value: %d\n", end);
1473 release_interfaces(&w, &reOle, &txtDoc, NULL);
1475 hres = ITextSelection_Collapse(txtSel, tomStart);
1476 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1478 hres = ITextSelection_Collapse(txtSel, tomUndefined);
1479 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1481 ITextSelection_Release(txtSel);
1484 static void test_IOleClientSite_QueryInterface(void)
1486 HWND w;
1487 IRichEditOle *reOle = NULL, *reOle1 = NULL;
1488 ITextDocument *txtDoc = NULL;
1489 IOleClientSite *clientSite = NULL, *clientSite1 = NULL, *clientSite2 = NULL;
1490 IOleWindow *oleWin = NULL, *oleWin1 = NULL;
1491 IOleInPlaceSite *olePlace = NULL, *olePlace1 = NULL;
1492 HRESULT hres;
1493 LONG refcount1, refcount2;
1495 create_interfaces(&w, &reOle, &txtDoc, NULL);
1496 hres = IRichEditOle_GetClientSite(reOle, &clientSite);
1497 ok(hres == S_OK, "IRichEditOle_QueryInterface: 0x%08x\n", hres);
1498 refcount1 = get_refcount((IUnknown *)clientSite);
1499 todo_wine ok(refcount1 == 1, "got wrong ref count: %d\n", refcount1);
1501 hres = IOleClientSite_QueryInterface(clientSite, &IID_IRichEditOle, (void **)&reOle1);
1502 ok(hres == E_NOINTERFACE, "IOleClientSite_QueryInterface: %x\n", hres);
1504 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleClientSite, (void **)&clientSite1);
1505 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1506 ok(clientSite == clientSite1, "Should not return a new pointer.\n");
1507 refcount1 = get_refcount((IUnknown *)clientSite);
1508 todo_wine ok(refcount1 == 2, "got wrong ref count: %d\n", refcount1);
1510 /* IOleWindow interface */
1511 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleWindow, (void **)&oleWin);
1512 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1513 refcount1 = get_refcount((IUnknown *)clientSite);
1514 refcount2 = get_refcount((IUnknown *)oleWin);
1515 ok(refcount1 == refcount2, "got wrong ref count.\n");
1517 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleWindow, (void **)&oleWin1);
1518 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1519 ok(oleWin == oleWin1, "Should not return a new pointer.\n");
1520 refcount1 = get_refcount((IUnknown *)clientSite);
1521 refcount2 = get_refcount((IUnknown *)oleWin);
1522 ok(refcount1 == refcount2, "got wrong ref count.\n");
1524 hres = IOleWindow_QueryInterface(oleWin, &IID_IOleClientSite, (void **)&clientSite2);
1525 ok(hres == S_OK, "IOleWindow_QueryInterface: 0x%08x\n", hres);
1526 ok(clientSite2 == clientSite1, "got wrong pointer\n");
1528 /* IOleInPlaceSite interface */
1529 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleInPlaceSite, (void **)&olePlace);
1530 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1531 refcount1 = get_refcount((IUnknown *)olePlace);
1532 refcount2 = get_refcount((IUnknown *)clientSite);
1533 ok(refcount1 == refcount2, "got wrong ref count.\n");
1535 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleInPlaceSite, (void **)&olePlace1);
1536 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1537 ok(olePlace == olePlace1, "Should not return a new pointer.\n");
1538 IOleInPlaceSite_Release(olePlace1);
1540 hres = IOleWindow_QueryInterface(oleWin, &IID_IOleInPlaceSite, (void **)&olePlace1);
1541 ok(hres == S_OK, "IOleWindow_QueryInterface: 0x%08x\n", hres);
1542 refcount1 = get_refcount((IUnknown *)olePlace1);
1543 refcount2 = get_refcount((IUnknown *)oleWin);
1544 ok(refcount1 == refcount2, "got wrong ref count.\n");
1546 IOleInPlaceSite_Release(olePlace1);
1547 IOleInPlaceSite_Release(olePlace);
1548 IOleWindow_Release(oleWin1);
1549 IOleWindow_Release(oleWin);
1550 IOleClientSite_Release(clientSite2);
1551 IOleClientSite_Release(clientSite1);
1552 IOleClientSite_Release(clientSite);
1553 release_interfaces(&w, &reOle, &txtDoc, NULL);
1556 static void test_IOleWindow_GetWindow(void)
1558 HWND w;
1559 IRichEditOle *reOle = NULL;
1560 ITextDocument *txtDoc = NULL;
1561 IOleClientSite *clientSite = NULL;
1562 IOleWindow *oleWin = NULL;
1563 HRESULT hres;
1564 HWND hwnd;
1566 create_interfaces(&w, &reOle, &txtDoc, NULL);
1567 hres = IRichEditOle_GetClientSite(reOle, &clientSite);
1568 ok(hres == S_OK, "IRichEditOle_QueryInterface: 0x%08x\n", hres);
1570 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleWindow, (void **)&oleWin);
1571 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1572 hres = IOleWindow_GetWindow(oleWin, &hwnd);
1573 ok(hres == S_OK, "IOleClientSite_GetWindow: 0x%08x\n", hres);
1574 ok(w == hwnd, "got wrong pointer\n");
1576 hres = IOleWindow_GetWindow(oleWin, NULL);
1577 ok(hres == E_INVALIDARG, "IOleClientSite_GetWindow: 0x%08x\n", hres);
1579 IOleWindow_Release(oleWin);
1580 IOleClientSite_Release(clientSite);
1581 release_interfaces(&w, &reOle, &txtDoc, NULL);
1584 static void test_IOleInPlaceSite_GetWindow(void)
1586 HWND w;
1587 IRichEditOle *reOle = NULL;
1588 ITextDocument *txtDoc = NULL;
1589 IOleClientSite *clientSite = NULL;
1590 IOleInPlaceSite *olePlace = NULL;
1591 HRESULT hres;
1592 HWND hwnd;
1594 create_interfaces(&w, &reOle, &txtDoc, NULL);
1595 hres = IRichEditOle_GetClientSite(reOle, &clientSite);
1596 ok(hres == S_OK, "IRichEditOle_QueryInterface: 0x%08x\n", hres);
1598 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleInPlaceSite, (void **)&olePlace);
1599 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1600 hres = IOleInPlaceSite_GetWindow(olePlace, &hwnd);
1601 ok(hres == S_OK, "IOleInPlaceSite_GetWindow: 0x%08x\n", hres);
1602 ok(w == hwnd, "got wrong pointer.\n");
1604 hres = IOleInPlaceSite_GetWindow(olePlace, NULL);
1605 ok(hres == E_INVALIDARG, "IOleInPlaceSite_GetWindow: 0x%08x\n", hres);
1607 IOleInPlaceSite_Release(olePlace);
1608 IOleClientSite_Release(clientSite);
1609 release_interfaces(&w, &reOle, &txtDoc, NULL);
1612 static void test_GetFont(void)
1614 static const CHAR test_text1[] = "TestSomeText";
1615 IRichEditOle *reOle = NULL;
1616 ITextDocument *doc = NULL;
1617 ITextRange *range = NULL;
1618 ITextSelection *selection;
1619 ITextFont *font, *font2;
1620 CHARFORMAT2A cf;
1621 LONG value;
1622 float size;
1623 HRESULT hr;
1624 HWND hwnd;
1625 BOOL ret;
1627 create_interfaces(&hwnd, &reOle, &doc, NULL);
1628 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
1630 hr = ITextDocument_GetSelection(doc, &selection);
1631 ok(hr == S_OK, "got 0x%08x\n", hr);
1632 hr = ITextSelection_GetFont(selection, &font);
1633 ok(hr == S_OK, "got 0x%08x\n", hr);
1634 hr = ITextSelection_GetFont(selection, &font2);
1635 ok(hr == S_OK, "got 0x%08x\n", hr);
1636 ok(font != font2, "got %p, %p\n", font, font2);
1637 ITextFont_Release(font2);
1638 ITextFont_Release(font);
1639 ITextSelection_Release(selection);
1641 EXPECT_REF(reOle, 3);
1642 EXPECT_REF(doc, 3);
1644 hr = ITextDocument_Range(doc, 0, 4, &range);
1645 ok(hr == S_OK, "got 0x%08x\n", hr);
1647 EXPECT_REF(reOle, 3);
1648 EXPECT_REF(doc, 3);
1649 EXPECT_REF(range, 1);
1651 hr = ITextRange_GetFont(range, NULL);
1652 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1654 hr = ITextRange_GetFont(range, &font);
1655 ok(hr == S_OK, "got 0x%08x\n", hr);
1657 EXPECT_REF(reOle, 3);
1658 EXPECT_REF(doc, 3);
1659 EXPECT_REF(range, 2);
1660 EXPECT_REF(font, 1);
1662 hr = ITextRange_GetFont(range, &font2);
1663 ok(hr == S_OK, "got 0x%08x\n", hr);
1664 ok(font != font2, "got %p, %p\n", font, font2);
1666 EXPECT_REF(reOle, 3);
1667 EXPECT_REF(doc, 3);
1668 EXPECT_REF(range, 3);
1669 EXPECT_REF(font, 1);
1670 EXPECT_REF(font2, 1);
1672 ITextFont_Release(font2);
1674 /* set different font style within a range */
1675 hr = ITextFont_GetItalic(font, NULL);
1676 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1678 hr = ITextFont_GetSize(font, NULL);
1679 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1681 size = 0.0;
1682 hr = ITextFont_GetSize(font, &size);
1683 ok(hr == S_OK, "got 0x%08x\n", hr);
1684 ok(size > 0.0, "size %.2f\n", size);
1686 value = 0;
1687 hr = ITextFont_GetLanguageID(font, &value);
1688 ok(hr == S_OK, "got 0x%08x\n", hr);
1689 todo_wine
1690 ok(value == GetSystemDefaultLCID(), "got lcid %x, user lcid %x\n", value,
1691 GetSystemDefaultLCID());
1693 /* range is non-italic */
1694 value = tomTrue;
1695 hr = ITextFont_GetItalic(font, &value);
1696 ok(hr == S_OK, "got 0x%08x\n", hr);
1697 ok(value == tomFalse, "got %d\n", value);
1699 cf.cbSize = sizeof(CHARFORMAT2A);
1700 cf.dwMask = CFM_ITALIC|CFM_SIZE;
1701 cf.dwEffects = CFE_ITALIC;
1702 cf.yHeight = 24.0;
1704 SendMessageA(hwnd, EM_SETSEL, 2, 3);
1705 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
1706 ok(ret, "got %d\n", ret);
1708 /* now range is partially italicized */
1709 value = tomFalse;
1710 hr = ITextFont_GetItalic(font, &value);
1711 ok(hr == S_OK, "got 0x%08x\n", hr);
1712 ok(value == tomUndefined, "got %d\n", value);
1714 size = 0.0;
1715 hr = ITextFont_GetSize(font, &size);
1716 ok(hr == S_OK, "got 0x%08x\n", hr);
1717 ok(size == tomUndefined, "size %.2f\n", size);
1719 ITextFont_Release(font);
1720 release_interfaces(&hwnd, &reOle, &doc, NULL);
1722 hr = ITextRange_GetFont(range, NULL);
1723 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
1725 hr = ITextRange_GetFont(range, &font2);
1726 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
1728 ITextRange_Release(range);
1731 static void test_GetPara(void)
1733 static const CHAR test_text1[] = "TestSomeText";
1734 IRichEditOle *reOle = NULL;
1735 ITextDocument *doc = NULL;
1736 ITextSelection *selection;
1737 ITextRange *range = NULL;
1738 ITextPara *para, *para2;
1739 HRESULT hr;
1740 HWND hwnd;
1742 create_interfaces(&hwnd, &reOle, &doc, &selection);
1743 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
1745 EXPECT_REF(reOle, 3);
1746 EXPECT_REF(doc, 3);
1748 hr = ITextDocument_Range(doc, 0, 4, &range);
1749 ok(hr == S_OK, "got 0x%08x\n", hr);
1751 EXPECT_REF(reOle, 3);
1752 EXPECT_REF(doc, 3);
1753 EXPECT_REF(range, 1);
1755 hr = ITextRange_GetPara(range, NULL);
1756 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1758 hr = ITextRange_GetPara(range, &para);
1759 ok(hr == S_OK, "got 0x%08x\n", hr);
1761 EXPECT_REF(reOle, 3);
1762 EXPECT_REF(doc, 3);
1763 EXPECT_REF(range, 2);
1764 EXPECT_REF(para, 1);
1766 hr = ITextRange_GetPara(range, &para2);
1767 ok(hr == S_OK, "got 0x%08x\n", hr);
1768 ok(para != para2, "got %p, %p\n", para, para2);
1770 EXPECT_REF(reOle, 3);
1771 EXPECT_REF(doc, 3);
1772 EXPECT_REF(range, 3);
1773 EXPECT_REF(para, 1);
1774 EXPECT_REF(para2, 1);
1776 ITextPara_Release(para);
1777 ITextPara_Release(para2);
1779 EXPECT_REF(reOle, 3);
1780 EXPECT_REF(doc, 3);
1781 EXPECT_REF(selection, 2);
1783 hr = ITextSelection_GetPara(selection, &para);
1784 ok(hr == S_OK, "got 0x%08x\n", hr);
1786 EXPECT_REF(reOle, 3);
1787 EXPECT_REF(doc, 3);
1788 EXPECT_REF(selection, 3);
1789 EXPECT_REF(para, 1);
1791 hr = ITextSelection_GetPara(selection, &para2);
1792 ok(hr == S_OK, "got 0x%08x\n", hr);
1793 ok(para != para2, "got %p, %p\n", para, para2);
1795 ITextPara_Release(para);
1796 ITextPara_Release(para2);
1797 release_interfaces(&hwnd, &reOle, &doc, NULL);
1799 hr = ITextRange_GetPara(range, NULL);
1800 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
1802 hr = ITextRange_GetPara(range, &para);
1803 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
1805 hr = ITextSelection_GetPara(selection, NULL);
1806 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
1808 hr = ITextSelection_GetPara(selection, &para);
1809 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
1811 ITextSelection_Release(selection);
1812 ITextRange_Release(range);
1815 static void test_dispatch(void)
1817 static const WCHAR testnameW[] = {'G','e','t','T','e','x','t',0};
1818 static const WCHAR testname2W[] = {'T','e','x','t',0};
1819 IRichEditOle *reOle = NULL;
1820 ITextDocument *doc = NULL;
1821 ITextRange *range = NULL;
1822 WCHAR *nameW;
1823 DISPID dispid;
1824 HRESULT hr;
1825 UINT count;
1826 HWND hwnd;
1828 create_interfaces(&hwnd, &reOle, &doc, NULL);
1830 range = NULL;
1831 hr = ITextDocument_Range(doc, 0, 0, &range);
1832 ok(hr == S_OK, "got 0x%08x\n", hr);
1833 ok(range != NULL, "got %p\n", range);
1835 dispid = 123;
1836 nameW = (WCHAR*)testnameW;
1837 hr = ITextRange_GetIDsOfNames(range, &IID_NULL, &nameW, 1, LOCALE_USER_DEFAULT, &dispid);
1838 ok(hr == DISP_E_UNKNOWNNAME, "got 0x%08x\n", hr);
1839 ok(dispid == DISPID_UNKNOWN, "got %d\n", dispid);
1841 dispid = 123;
1842 nameW = (WCHAR*)testname2W;
1843 hr = ITextRange_GetIDsOfNames(range, &IID_NULL, &nameW, 1, LOCALE_USER_DEFAULT, &dispid);
1844 ok(hr == S_OK, "got 0x%08x\n", hr);
1845 ok(dispid == DISPID_VALUE, "got %d\n", dispid);
1847 release_interfaces(&hwnd, &reOle, &doc, NULL);
1849 /* try dispatch methods on detached range */
1850 hr = ITextRange_GetTypeInfoCount(range, &count);
1851 ok(hr == S_OK, "got 0x%08x\n", hr);
1853 dispid = 123;
1854 nameW = (WCHAR*)testname2W;
1855 hr = ITextRange_GetIDsOfNames(range, &IID_NULL, &nameW, 1, LOCALE_USER_DEFAULT, &dispid);
1856 ok(hr == S_OK, "got 0x%08x\n", hr);
1857 ok(dispid == DISPID_VALUE, "got %d\n", dispid);
1859 ITextRange_Release(range);
1862 static void test_detached_font_getters(ITextFont *font, BOOL duplicate)
1864 HRESULT hr, hrexp = duplicate ? S_OK : CO_E_RELEASED;
1865 LONG value;
1866 float size;
1867 BSTR str;
1869 hr = ITextFont_GetBold(font, NULL);
1870 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1872 hr = ITextFont_GetBold(font, &value);
1873 ok(hr == hrexp, "got 0x%08x\n", hr);
1875 hr = ITextFont_GetForeColor(font, NULL);
1876 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1878 hr = ITextFont_GetForeColor(font, &value);
1879 ok(hr == hrexp, "got 0x%08x\n", hr);
1881 hr = ITextFont_GetItalic(font, NULL);
1882 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1884 hr = ITextFont_GetItalic(font, &value);
1885 ok(hr == hrexp, "got 0x%08x\n", hr);
1887 hr = ITextFont_GetLanguageID(font, NULL);
1888 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1890 hr = ITextFont_GetLanguageID(font, &value);
1891 ok(hr == hrexp, "got 0x%08x\n", hr);
1893 hr = ITextFont_GetName(font, NULL);
1894 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1896 hr = ITextFont_GetName(font, &str);
1897 ok(hr == hrexp, "got 0x%08x\n", hr);
1899 hr = ITextFont_GetSize(font, NULL);
1900 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1902 hr = ITextFont_GetSize(font, &size);
1903 ok(hr == hrexp, "got 0x%08x\n", hr);
1905 hr = ITextFont_GetStrikeThrough(font, NULL);
1906 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1908 hr = ITextFont_GetStrikeThrough(font, &value);
1909 ok(hr == hrexp, "got 0x%08x\n", hr);
1911 hr = ITextFont_GetSubscript(font, NULL);
1912 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1914 hr = ITextFont_GetSubscript(font, &value);
1915 ok(hr == hrexp, "got 0x%08x\n", hr);
1917 hr = ITextFont_GetSuperscript(font, NULL);
1918 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1920 hr = ITextFont_GetSuperscript(font, &value);
1921 ok(hr == hrexp, "got 0x%08x\n", hr);
1923 hr = ITextFont_GetUnderline(font, NULL);
1924 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1926 hr = ITextFont_GetUnderline(font, &value);
1927 ok(hr == hrexp, "got 0x%08x\n", hr);
1930 static void test_textfont_global_defaults(ITextFont *font)
1932 float valuef;
1933 LONG value;
1934 HRESULT hr;
1935 BSTR str;
1937 value = tomUndefined;
1938 hr = ITextFont_GetAllCaps(font, &value);
1939 ok(hr == S_OK, "got 0x%08x\n", hr);
1940 ok(value == tomFalse, "got %d\n", value);
1942 value = tomUndefined;
1943 hr = ITextFont_GetAnimation(font, &value);
1944 ok(hr == S_OK, "got 0x%08x\n", hr);
1945 ok(value == tomFalse, "got %d\n", value);
1947 value = tomUndefined;
1948 hr = ITextFont_GetBackColor(font, &value);
1949 ok(hr == S_OK, "got 0x%08x\n", hr);
1950 ok(value == tomAutoColor, "got %d\n", value);
1952 value = tomUndefined;
1953 hr = ITextFont_GetBold(font, &value);
1954 ok(hr == S_OK, "got 0x%08x\n", hr);
1955 ok(value == tomFalse || value == tomTrue, "got %d\n", value);
1957 value = tomUndefined;
1958 hr = ITextFont_GetEmboss(font, &value);
1959 ok(hr == S_OK, "got 0x%08x\n", hr);
1960 ok(value == tomFalse, "got %d\n", value);
1962 value = tomUndefined;
1963 hr = ITextFont_GetForeColor(font, &value);
1964 ok(hr == S_OK, "got 0x%08x\n", hr);
1965 ok(value == tomAutoColor, "got %d\n", value);
1967 value = tomUndefined;
1968 hr = ITextFont_GetHidden(font, &value);
1969 ok(hr == S_OK, "got 0x%08x\n", hr);
1970 ok(value == tomFalse, "got %d\n", value);
1972 value = tomUndefined;
1973 hr = ITextFont_GetEngrave(font, &value);
1974 ok(hr == S_OK, "got 0x%08x\n", hr);
1975 ok(value == tomFalse, "got %d\n", value);
1977 value = tomUndefined;
1978 hr = ITextFont_GetItalic(font, &value);
1979 ok(hr == S_OK, "got 0x%08x\n", hr);
1980 ok(value == tomFalse, "got %d\n", value);
1982 valuef = 1.0;
1983 hr = ITextFont_GetKerning(font, &valuef);
1984 ok(hr == S_OK, "got 0x%08x\n", hr);
1985 ok(valuef == 0.0, "got %.2f\n", valuef);
1987 value = tomUndefined;
1988 hr = ITextFont_GetLanguageID(font, &value);
1989 ok(hr == S_OK, "got 0x%08x\n", hr);
1990 ok(value == GetSystemDefaultLCID(), "got %d\n", value);
1992 str = NULL;
1993 hr = ITextFont_GetName(font, &str);
1994 ok(hr == S_OK, "got 0x%08x\n", hr);
1995 ok(!lstrcmpW(sysW, str), "%s\n", wine_dbgstr_w(str));
1996 SysFreeString(str);
1998 value = tomUndefined;
1999 hr = ITextFont_GetOutline(font, &value);
2000 ok(hr == S_OK, "got 0x%08x\n", hr);
2001 ok(value == tomFalse, "got %d\n", value);
2003 valuef = 1.0;
2004 hr = ITextFont_GetPosition(font, &valuef);
2005 ok(hr == S_OK, "got 0x%08x\n", hr);
2006 ok(valuef == 0.0, "got %.2f\n", valuef);
2008 value = tomUndefined;
2009 hr = ITextFont_GetProtected(font, &value);
2010 ok(hr == S_OK, "got 0x%08x\n", hr);
2011 ok(value == tomFalse, "got %d\n", value);
2013 value = tomUndefined;
2014 hr = ITextFont_GetShadow(font, &value);
2015 ok(hr == S_OK, "got 0x%08x\n", hr);
2016 ok(value == tomFalse, "got %d\n", value);
2018 valuef = 0.0;
2019 hr = ITextFont_GetSize(font, &valuef);
2020 ok(hr == S_OK, "got 0x%08x\n", hr);
2021 ok(valuef >= 0.0, "got %.2f\n", valuef);
2023 value = tomUndefined;
2024 hr = ITextFont_GetSmallCaps(font, &value);
2025 ok(hr == S_OK, "got 0x%08x\n", hr);
2026 ok(value == tomFalse, "got %d\n", value);
2028 valuef = 1.0;
2029 hr = ITextFont_GetSpacing(font, &valuef);
2030 ok(hr == S_OK, "got 0x%08x\n", hr);
2031 ok(valuef == 0.0, "got %.2f\n", valuef);
2033 value = tomUndefined;
2034 hr = ITextFont_GetStrikeThrough(font, &value);
2035 ok(hr == S_OK, "got 0x%08x\n", hr);
2036 ok(value == tomFalse, "got %d\n", value);
2038 value = tomUndefined;
2039 hr = ITextFont_GetSubscript(font, &value);
2040 ok(hr == S_OK, "got 0x%08x\n", hr);
2041 ok(value == tomFalse, "got %d\n", value);
2043 value = tomUndefined;
2044 hr = ITextFont_GetSuperscript(font, &value);
2045 ok(hr == S_OK, "got 0x%08x\n", hr);
2046 ok(value == tomFalse, "got %d\n", value);
2048 value = tomUndefined;
2049 hr = ITextFont_GetUnderline(font, &value);
2050 ok(hr == S_OK, "got 0x%08x\n", hr);
2051 ok(value == tomFalse, "got %d\n", value);
2053 value = tomUndefined;
2054 hr = ITextFont_GetWeight(font, &value);
2055 ok(hr == S_OK, "got 0x%08x\n", hr);
2056 ok(value == FW_NORMAL || value == FW_BOLD, "got %d\n", value);
2059 static void test_textfont_undefined(ITextFont *font)
2061 float valuef;
2062 LONG value;
2063 HRESULT hr;
2065 value = tomFalse;
2066 hr = ITextFont_GetAllCaps(font, &value);
2067 ok(hr == S_OK, "got 0x%08x\n", hr);
2068 ok(value == tomUndefined, "got %d\n", value);
2070 value = tomFalse;
2071 hr = ITextFont_GetAnimation(font, &value);
2072 ok(hr == S_OK, "got 0x%08x\n", hr);
2073 ok(value == tomUndefined, "got %d\n", value);
2075 value = tomFalse;
2076 hr = ITextFont_GetBackColor(font, &value);
2077 ok(hr == S_OK, "got 0x%08x\n", hr);
2078 ok(value == tomUndefined, "got %d\n", value);
2080 value = tomFalse;
2081 hr = ITextFont_GetBold(font, &value);
2082 ok(hr == S_OK, "got 0x%08x\n", hr);
2083 ok(value == tomUndefined, "got %d\n", value);
2085 value = tomFalse;
2086 hr = ITextFont_GetEmboss(font, &value);
2087 ok(hr == S_OK, "got 0x%08x\n", hr);
2088 ok(value == tomUndefined, "got %d\n", value);
2090 value = tomFalse;
2091 hr = ITextFont_GetForeColor(font, &value);
2092 ok(hr == S_OK, "got 0x%08x\n", hr);
2093 ok(value == tomUndefined, "got %d\n", value);
2095 value = tomFalse;
2096 hr = ITextFont_GetHidden(font, &value);
2097 ok(hr == S_OK, "got 0x%08x\n", hr);
2098 ok(value == tomUndefined, "got %d\n", value);
2100 value = tomFalse;
2101 hr = ITextFont_GetEngrave(font, &value);
2102 ok(hr == S_OK, "got 0x%08x\n", hr);
2103 ok(value == tomUndefined, "got %d\n", value);
2105 value = tomFalse;
2106 hr = ITextFont_GetItalic(font, &value);
2107 ok(hr == S_OK, "got 0x%08x\n", hr);
2108 ok(value == tomUndefined, "got %d\n", value);
2110 valuef = 0.0;
2111 hr = ITextFont_GetKerning(font, &valuef);
2112 ok(hr == S_OK, "got 0x%08x\n", hr);
2113 ok(valuef == tomUndefined, "got %.2f\n", valuef);
2115 value = tomFalse;
2116 hr = ITextFont_GetLanguageID(font, &value);
2117 ok(hr == S_OK, "got 0x%08x\n", hr);
2118 ok(value == tomUndefined, "got %d\n", value);
2120 value = tomFalse;
2121 hr = ITextFont_GetOutline(font, &value);
2122 ok(hr == S_OK, "got 0x%08x\n", hr);
2123 ok(value == tomUndefined, "got %d\n", value);
2125 valuef = 0.0;
2126 hr = ITextFont_GetPosition(font, &valuef);
2127 ok(hr == S_OK, "got 0x%08x\n", hr);
2128 ok(valuef == tomUndefined, "got %.2f\n", valuef);
2130 value = tomFalse;
2131 hr = ITextFont_GetProtected(font, &value);
2132 ok(hr == S_OK, "got 0x%08x\n", hr);
2133 ok(value == tomUndefined, "got %d\n", value);
2135 value = tomFalse;
2136 hr = ITextFont_GetShadow(font, &value);
2137 ok(hr == S_OK, "got 0x%08x\n", hr);
2138 ok(value == tomUndefined, "got %d\n", value);
2140 valuef = 0.0;
2141 hr = ITextFont_GetSize(font, &valuef);
2142 ok(hr == S_OK, "got 0x%08x\n", hr);
2143 ok(valuef == tomUndefined, "got %.2f\n", valuef);
2145 value = tomFalse;
2146 hr = ITextFont_GetSmallCaps(font, &value);
2147 ok(hr == S_OK, "got 0x%08x\n", hr);
2148 ok(value == tomUndefined, "got %d\n", value);
2150 valuef = 0.0;
2151 hr = ITextFont_GetSpacing(font, &valuef);
2152 ok(hr == S_OK, "got 0x%08x\n", hr);
2153 ok(valuef == tomUndefined, "got %.2f\n", valuef);
2155 value = tomFalse;
2156 hr = ITextFont_GetStrikeThrough(font, &value);
2157 ok(hr == S_OK, "got 0x%08x\n", hr);
2158 ok(value == tomUndefined, "got %d\n", value);
2160 value = tomFalse;
2161 hr = ITextFont_GetSubscript(font, &value);
2162 ok(hr == S_OK, "got 0x%08x\n", hr);
2163 ok(value == tomUndefined, "got %d\n", value);
2165 value = tomFalse;
2166 hr = ITextFont_GetSuperscript(font, &value);
2167 ok(hr == S_OK, "got 0x%08x\n", hr);
2168 ok(value == tomUndefined, "got %d\n", value);
2170 value = tomFalse;
2171 hr = ITextFont_GetUnderline(font, &value);
2172 ok(hr == S_OK, "got 0x%08x\n", hr);
2173 ok(value == tomUndefined, "got %d\n", value);
2175 value = tomFalse;
2176 hr = ITextFont_GetWeight(font, &value);
2177 ok(hr == S_OK, "got 0x%08x\n", hr);
2178 ok(value == tomUndefined, "got %d\n", value);
2181 static inline FLOAT twips_to_points(LONG value)
2183 return value * 72.0 / 1440;
2186 static void test_ITextFont(void)
2188 static const WCHAR arialW[] = {'A','r','i','a','l',0};
2189 static const CHAR test_text1[] = "TestSomeText";
2190 ITextFont *font, *font2, *font3;
2191 FLOAT size, position, kerning;
2192 IRichEditOle *reOle = NULL;
2193 ITextDocument *doc = NULL;
2194 ITextRange *range = NULL;
2195 CHARFORMAT2A cf;
2196 LONG value;
2197 HRESULT hr;
2198 HWND hwnd;
2199 BOOL ret;
2200 BSTR str;
2202 create_interfaces(&hwnd, &reOle, &doc, NULL);
2203 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2205 hr = ITextDocument_Range(doc, 0, 10, &range);
2206 ok(hr == S_OK, "got 0x%08x\n", hr);
2208 hr = ITextRange_GetFont(range, &font);
2209 ok(hr == S_OK, "got 0x%08x\n", hr);
2211 hr = ITextFont_Reset(font, tomUseTwips);
2212 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2214 hr = ITextFont_Reset(font, tomUsePoints);
2215 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2217 hr = ITextFont_GetName(font, NULL);
2218 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2220 /* default font size unit is point */
2221 size = 0.0;
2222 hr = ITextFont_GetSize(font, &size);
2223 ok(hr == S_OK, "got 0x%08x\n", hr);
2225 /* set to some non-zero values */
2226 hr = ITextFont_SetPosition(font, 20.0);
2227 ok(hr == S_OK, "got 0x%08x\n", hr);
2229 hr = ITextFont_SetKerning(font, 10.0);
2230 ok(hr == S_OK, "got 0x%08x\n", hr);
2232 position = 0.0;
2233 hr = ITextFont_GetPosition(font, &position);
2234 ok(hr == S_OK, "got 0x%08x\n", hr);
2236 kerning = 0.0;
2237 hr = ITextFont_GetKerning(font, &kerning);
2238 ok(hr == S_OK, "got 0x%08x\n", hr);
2240 memset(&cf, 0, sizeof(cf));
2241 cf.cbSize = sizeof(cf);
2242 cf.dwMask = CFM_SIZE|CFM_OFFSET|CFM_KERNING;
2244 /* CHARFORMAT members are in twips */
2245 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2246 ret = SendMessageA(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2247 ok(ret, "got %d\n", ret);
2248 ok(size == twips_to_points(cf.yHeight), "got yHeight %d, size %.2f\n", cf.yHeight, size);
2249 ok(position == twips_to_points(cf.yOffset), "got yOffset %d, position %.2f\n", cf.yOffset, position);
2250 ok(kerning == twips_to_points(cf.wKerning), "got wKerning %d, kerning %.2f\n", cf.wKerning, kerning);
2252 hr = ITextFont_Reset(font, tomUseTwips);
2253 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2255 hr = ITextFont_Reset(font, tomUsePoints);
2256 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2258 hr = ITextFont_GetDuplicate(font, &font2);
2259 ok(hr == S_OK, "got 0x%08x\n", hr);
2261 hr = ITextFont_Reset(font2, tomUseTwips);
2262 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2264 hr = ITextFont_Reset(font2, tomUsePoints);
2265 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2267 ITextFont_Release(font2);
2269 /* default font name */
2270 str = NULL;
2271 hr = ITextFont_GetName(font, &str);
2272 ok(hr == S_OK, "got 0x%08x\n", hr);
2273 ok(!lstrcmpW(str, sysW), "got %s\n", wine_dbgstr_w(str));
2274 SysFreeString(str);
2276 /* change font name for an inner subrange */
2277 memset(&cf, 0, sizeof(cf));
2278 cf.cbSize = sizeof(cf);
2279 cf.dwMask = CFM_FACE;
2280 strcpy(cf.szFaceName, "Arial");
2282 SendMessageA(hwnd, EM_SETSEL, 3, 4);
2283 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2284 ok(ret, "got %d\n", ret);
2286 /* still original name */
2287 str = NULL;
2288 hr = ITextFont_GetName(font, &str);
2289 ok(hr == S_OK, "got 0x%08x\n", hr);
2290 ok(!lstrcmpW(str, sysW), "got %s\n", wine_dbgstr_w(str));
2291 SysFreeString(str);
2293 SendMessageA(hwnd, EM_SETSEL, 1, 2);
2294 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2295 ok(ret, "got %d\n", ret);
2297 str = NULL;
2298 hr = ITextFont_GetName(font, &str);
2299 ok(hr == S_OK, "got 0x%08x\n", hr);
2300 ok(!lstrcmpW(str, sysW), "got %s\n", wine_dbgstr_w(str));
2301 SysFreeString(str);
2303 /* name is returned for first position within a range */
2304 SendMessageA(hwnd, EM_SETSEL, 0, 1);
2305 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2306 ok(ret, "got %d\n", ret);
2308 str = NULL;
2309 hr = ITextFont_GetName(font, &str);
2310 ok(hr == S_OK, "got 0x%08x\n", hr);
2311 ok(!lstrcmpW(str, arialW), "got %s\n", wine_dbgstr_w(str));
2312 SysFreeString(str);
2314 /* GetDuplicate() */
2315 hr = ITextFont_GetDuplicate(font, NULL);
2316 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2318 EXPECT_REF(range, 2);
2319 font2 = NULL;
2320 hr = ITextFont_GetDuplicate(font, &font2);
2321 ok(hr == S_OK, "got 0x%08x\n", hr);
2322 EXPECT_REF(range, 2);
2324 /* set whole range to italic */
2325 cf.cbSize = sizeof(CHARFORMAT2A);
2326 cf.dwMask = CFM_ITALIC;
2327 cf.dwEffects = CFE_ITALIC;
2329 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2330 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2331 ok(ret, "got %d\n", ret);
2333 value = tomFalse;
2334 hr = ITextFont_GetItalic(font, &value);
2335 ok(hr == S_OK, "got 0x%08x\n", hr);
2336 ok(value == tomTrue, "got %d\n", value);
2338 /* duplicate retains original value */
2339 value = tomTrue;
2340 hr = ITextFont_GetItalic(font2, &value);
2341 ok(hr == S_OK, "got 0x%08x\n", hr);
2342 ok(value == tomFalse, "got %d\n", value);
2344 /* get a duplicate from a cloned font */
2345 hr = ITextFont_GetDuplicate(font2, &font3);
2346 ok(hr == S_OK, "got 0x%08x\n", hr);
2347 ITextFont_Release(font3);
2349 ITextRange_Release(range);
2350 release_interfaces(&hwnd, &reOle, &doc, NULL);
2352 hr = ITextFont_GetDuplicate(font, NULL);
2353 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2355 test_detached_font_getters(font, FALSE);
2356 test_detached_font_getters(font2, TRUE);
2358 /* get a duplicate of detached font */
2359 hr = ITextFont_GetDuplicate(font2, &font3);
2360 ok(hr == S_OK, "got 0x%08x\n", hr);
2361 ITextFont_Release(font3);
2363 /* reset detached font to undefined */
2364 value = tomUndefined;
2365 hr = ITextFont_GetBold(font2, &value);
2366 ok(hr == S_OK, "got 0x%08x\n", hr);
2367 ok(value != tomUndefined, "got %d\n", value);
2369 /* reset to undefined for deatached font */
2370 hr = ITextFont_Reset(font2, tomUndefined);
2371 ok(hr == S_OK, "got 0x%08x\n", hr);
2372 test_textfont_undefined(font2);
2374 /* font is detached, default means global TOM defaults */
2375 hr = ITextFont_Reset(font2, tomDefault);
2376 ok(hr == S_OK, "got 0x%08x\n", hr);
2377 test_textfont_global_defaults(font2);
2379 hr = ITextFont_GetDuplicate(font2, &font3);
2380 ok(hr == S_OK, "got 0x%08x\n", hr);
2381 test_textfont_global_defaults(font2);
2383 hr = ITextFont_Reset(font2, tomApplyNow);
2384 ok(hr == S_OK, "got 0x%08x\n", hr);
2385 test_textfont_global_defaults(font2);
2387 hr = ITextFont_Reset(font2, tomApplyLater);
2388 ok(hr == S_OK, "got 0x%08x\n", hr);
2389 test_textfont_global_defaults(font2);
2391 hr = ITextFont_Reset(font2, tomTrackParms);
2392 ok(hr == S_OK, "got 0x%08x\n", hr);
2393 test_textfont_global_defaults(font2);
2395 hr = ITextFont_SetItalic(font2, tomUndefined);
2396 ok(hr == S_OK, "got 0x%08x\n", hr);
2398 hr = ITextFont_GetItalic(font2, &value);
2399 ok(hr == S_OK, "got 0x%08x\n", hr);
2400 ok(value == tomFalse, "got %d\n", value);
2402 hr = ITextFont_Reset(font2, tomCacheParms);
2403 ok(hr == S_OK, "got 0x%08x\n", hr);
2404 test_textfont_global_defaults(font2);
2406 ITextFont_Release(font3);
2407 ITextFont_Release(font2);
2409 font2 = (void*)0xdeadbeef;
2410 hr = ITextFont_GetDuplicate(font, &font2);
2411 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2412 ok(font2 == NULL, "got %p\n", font2);
2414 hr = ITextFont_Reset(font, tomDefault);
2415 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2417 ITextFont_Release(font);
2419 /* Reset() */
2420 create_interfaces(&hwnd, &reOle, &doc, NULL);
2421 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2423 hr = ITextDocument_Range(doc, 0, 10, &range);
2424 ok(hr == S_OK, "got 0x%08x\n", hr);
2426 hr = ITextRange_GetFont(range, &font);
2427 ok(hr == S_OK, "got 0x%08x\n", hr);
2429 value = tomUndefined;
2430 hr = ITextFont_GetBold(font, &value);
2431 ok(hr == S_OK, "got 0x%08x\n", hr);
2432 ok(value != tomUndefined, "got %d\n", value);
2434 /* reset to undefined for attached font */
2435 hr = ITextFont_Reset(font, tomUndefined);
2436 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2438 value = tomUndefined;
2439 hr = ITextFont_GetBold(font, &value);
2440 ok(hr == S_OK, "got 0x%08x\n", hr);
2441 ok(value != tomUndefined, "got %d\n", value);
2443 /* tomCacheParms/tomTrackParms */
2444 hr = ITextFont_Reset(font, tomCacheParms);
2445 ok(hr == S_OK, "got 0x%08x\n", hr);
2447 hr = ITextFont_GetItalic(font, &value);
2448 ok(hr == S_OK, "got 0x%08x\n", hr);
2449 ok(value == tomFalse, "got %d\n", value);
2451 memset(&cf, 0, sizeof(cf));
2452 cf.cbSize = sizeof(CHARFORMAT2A);
2453 cf.dwMask = CFM_ITALIC;
2455 cf.dwEffects = CFE_ITALIC;
2456 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2457 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2458 ok(ret, "got %d\n", ret);
2460 /* still cached value */
2461 hr = ITextFont_GetItalic(font, &value);
2462 ok(hr == S_OK, "got 0x%08x\n", hr);
2463 ok(value == tomFalse, "got %d\n", value);
2465 hr = ITextFont_Reset(font, tomTrackParms);
2466 ok(hr == S_OK, "got 0x%08x\n", hr);
2468 hr = ITextFont_GetItalic(font, &value);
2469 ok(hr == S_OK, "got 0x%08x\n", hr);
2470 ok(value == tomTrue, "got %d\n", value);
2472 /* switch back to cache - value retained */
2473 hr = ITextFont_Reset(font, tomCacheParms);
2474 ok(hr == S_OK, "got 0x%08x\n", hr);
2476 hr = ITextFont_GetItalic(font, &value);
2477 ok(hr == S_OK, "got 0x%08x\n", hr);
2478 ok(value == tomTrue, "got %d\n", value);
2480 /* tomApplyLater */
2481 hr = ITextFont_Reset(font, tomApplyLater);
2482 ok(hr == S_OK, "got 0x%08x\n", hr);
2484 hr = ITextFont_SetItalic(font, tomFalse);
2485 ok(hr == S_OK, "got 0x%08x\n", hr);
2487 hr = ITextFont_GetItalic(font, &value);
2488 ok(hr == S_OK, "got 0x%08x\n", hr);
2489 ok(value == tomFalse, "got %d\n", value);
2491 cf.dwEffects = 0;
2492 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2493 ret = SendMessageA(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2494 ok(ret, "got %d\n", ret);
2495 ok((cf.dwEffects & CFE_ITALIC) == CFE_ITALIC, "got 0x%08x\n", cf.dwEffects);
2497 hr = ITextFont_Reset(font, tomApplyNow);
2498 ok(hr == S_OK, "got 0x%08x\n", hr);
2500 cf.dwEffects = 0;
2501 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2502 ret = SendMessageA(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2503 ok(ret, "got %d\n", ret);
2504 ok((cf.dwEffects & CFE_ITALIC) == 0, "got 0x%08x\n", cf.dwEffects);
2506 hr = ITextFont_SetItalic(font, tomUndefined);
2507 ok(hr == S_OK, "got 0x%08x\n", hr);
2509 hr = ITextFont_GetItalic(font, &value);
2510 ok(hr == S_OK, "got 0x%08x\n", hr);
2511 ok(value == tomFalse, "got %d\n", value);
2513 hr = ITextFont_SetItalic(font, tomAutoColor);
2514 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2516 cf.dwEffects = 0;
2517 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2518 ret = SendMessageA(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2519 ok(ret, "got %d\n", ret);
2520 ok((cf.dwEffects & CFE_ITALIC) == 0, "got 0x%08x\n", cf.dwEffects);
2522 ITextRange_Release(range);
2523 ITextFont_Release(font);
2524 release_interfaces(&hwnd, &reOle, &doc, NULL);
2527 static void test_Delete(void)
2529 static const CHAR test_text1[] = "TestSomeText";
2530 IRichEditOle *reOle = NULL;
2531 ITextDocument *doc = NULL;
2532 ITextRange *range, *range2;
2533 LONG value;
2534 HRESULT hr;
2535 HWND hwnd;
2537 create_interfaces(&hwnd, &reOle, &doc, NULL);
2538 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2540 hr = ITextDocument_Range(doc, 0, 4, &range);
2541 ok(hr == S_OK, "got 0x%08x\n", hr);
2543 hr = ITextDocument_Range(doc, 1, 2, &range2);
2544 ok(hr == S_OK, "got 0x%08x\n", hr);
2546 hr = ITextRange_GetEnd(range, &value);
2547 ok(hr == S_OK, "got 0x%08x\n", hr);
2548 ok(value == 4, "got %d\n", value);
2550 /* unit type doesn't matter is count is 0 */
2551 value = 0;
2552 hr = ITextRange_Delete(range2, tomSentence, 0, &value);
2553 todo_wine {
2554 ok(hr == S_OK, "got 0x%08x\n", hr);
2555 ok(value == 1, "got %d\n", value);
2557 value = 1;
2558 hr = ITextRange_Delete(range2, tomCharacter, 0, &value);
2559 todo_wine {
2560 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2561 ok(value == 0, "got %d\n", value);
2563 hr = ITextRange_GetEnd(range, &value);
2564 ok(hr == S_OK, "got 0x%08x\n", hr);
2565 todo_wine
2566 ok(value == 3, "got %d\n", value);
2568 hr = ITextRange_GetStart(range2, &value);
2569 ok(hr == S_OK, "got 0x%08x\n", hr);
2570 ok(value == 1, "got %d\n", value);
2572 hr = ITextRange_GetEnd(range2, &value);
2573 ok(hr == S_OK, "got 0x%08x\n", hr);
2574 todo_wine
2575 ok(value == 1, "got %d\n", value);
2577 ITextRange_Release(range);
2578 ITextRange_Release(range2);
2579 release_interfaces(&hwnd, &reOle, &doc, NULL);
2582 static void test_SetText(void)
2584 static const CHAR test_text1[] = "TestSomeText";
2585 static const WCHAR textW[] = {'a','b','c','d','e','f','g','h','i',0};
2586 IRichEditOle *reOle = NULL;
2587 ITextDocument *doc = NULL;
2588 ITextRange *range, *range2;
2589 LONG value;
2590 HRESULT hr;
2591 HWND hwnd;
2592 BSTR str;
2594 create_interfaces(&hwnd, &reOle, &doc, NULL);
2595 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2597 hr = ITextDocument_Range(doc, 0, 4, &range);
2598 ok(hr == S_OK, "got 0x%08x\n", hr);
2600 hr = ITextDocument_Range(doc, 0, 4, &range2);
2601 ok(hr == S_OK, "got 0x%08x\n", hr);
2603 value = 1;
2604 hr = ITextRange_GetStart(range2, &value);
2605 ok(hr == S_OK, "got 0x%08x\n", hr);
2606 ok(value == 0, "got %d\n", value);
2608 value = 0;
2609 hr = ITextRange_GetEnd(range2, &value);
2610 ok(hr == S_OK, "got 0x%08x\n", hr);
2611 ok(value == 4, "got %d\n", value);
2613 hr = ITextRange_SetText(range, NULL);
2614 ok(hr == S_OK, "got 0x%08x\n", hr);
2616 value = 1;
2617 hr = ITextRange_GetEnd(range2, &value);
2618 ok(hr == S_OK, "got 0x%08x\n", hr);
2619 ok(value == 0, "got %d\n", value);
2621 str = SysAllocString(textW);
2622 hr = ITextRange_SetText(range, str);
2623 ok(hr == S_OK, "got 0x%08x\n", hr);
2625 value = 1;
2626 hr = ITextRange_GetStart(range, &value);
2627 ok(hr == S_OK, "got 0x%08x\n", hr);
2628 ok(value == 0, "got %d\n", value);
2630 value = 0;
2631 hr = ITextRange_GetEnd(range, &value);
2632 ok(hr == S_OK, "got 0x%08x\n", hr);
2633 ok(value == 9, "got %d\n", value);
2635 value = 1;
2636 hr = ITextRange_GetStart(range2, &value);
2637 ok(hr == S_OK, "got 0x%08x\n", hr);
2638 ok(value == 0, "got %d\n", value);
2640 value = 0;
2641 hr = ITextRange_GetEnd(range2, &value);
2642 ok(hr == S_OK, "got 0x%08x\n", hr);
2643 ok(value == 0, "got %d\n", value);
2645 str = SysAllocStringLen(NULL, 0);
2646 hr = ITextRange_SetText(range, str);
2647 ok(hr == S_OK, "got 0x%08x\n", hr);
2648 value = 1;
2649 hr = ITextRange_GetEnd(range, &value);
2650 ok(hr == S_OK, "got 0x%08x\n", hr);
2651 ok(value == 0, "got %d\n", value);
2652 SysFreeString(str);
2654 ITextRange_Release(range2);
2655 release_interfaces(&hwnd, &reOle, &doc, NULL);
2657 hr = ITextRange_SetText(range, NULL);
2658 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2660 str = SysAllocStringLen(NULL, 0);
2661 hr = ITextRange_SetText(range, str);
2662 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2663 SysFreeString(str);
2665 ITextRange_Release(range);
2668 static void test_InRange(void)
2670 static const CHAR test_text1[] = "TestSomeText";
2671 ITextRange *range, *range2, *range3;
2672 IRichEditOle *reOle = NULL;
2673 ITextDocument *doc = NULL;
2674 ITextSelection *selection;
2675 LONG value;
2676 HRESULT hr;
2677 HWND hwnd;
2679 create_interfaces(&hwnd, &reOle, &doc, &selection);
2680 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2681 SendMessageA(hwnd, EM_SETSEL, 1, 2);
2683 hr = ITextDocument_Range(doc, 0, 4, &range);
2684 ok(hr == S_OK, "got 0x%08x\n", hr);
2686 hr = ITextDocument_Range(doc, 0, 4, &range2);
2687 ok(hr == S_OK, "got 0x%08x\n", hr);
2689 /* matches selection */
2690 hr = ITextDocument_Range(doc, 1, 2, &range3);
2691 ok(hr == S_OK, "got 0x%08x\n", hr);
2693 hr = ITextRange_InRange(range, NULL, NULL);
2694 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2696 value = tomTrue;
2697 hr = ITextRange_InRange(range, NULL, &value);
2698 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2699 ok(value == tomFalse, "got %d\n", value);
2701 hr = ITextRange_InRange(range, range2, NULL);
2702 ok(hr == S_OK, "got 0x%08x\n", hr);
2704 value = tomFalse;
2705 hr = ITextRange_InRange(range, range2, &value);
2706 ok(hr == S_OK, "got 0x%08x\n", hr);
2707 ok(value == tomTrue, "got %d\n", value);
2709 /* selection */
2710 hr = ITextSelection_InRange(selection, NULL, NULL);
2711 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2713 value = tomTrue;
2714 hr = ITextSelection_InRange(selection, NULL, &value);
2715 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2716 ok(value == tomFalse, "got %d\n", value);
2718 hr = ITextSelection_InRange(selection, range2, NULL);
2719 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2721 value = tomTrue;
2722 hr = ITextSelection_InRange(selection, range2, &value);
2723 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2724 ok(value == tomFalse, "got %d\n", value);
2726 value = tomTrue;
2727 hr = ITextSelection_InRange(selection, range3, &value);
2728 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2729 ok(value == tomFalse, "got %d\n", value);
2731 /* seems to work on ITextSelection ranges only */
2732 value = tomFalse;
2733 hr = ITextSelection_InRange(selection, (ITextRange*)selection, &value);
2734 ok(hr == S_OK, "got 0x%08x\n", hr);
2735 ok(value == tomTrue, "got %d\n", value);
2737 release_interfaces(&hwnd, &reOle, &doc, NULL);
2739 hr = ITextRange_InRange(range, NULL, NULL);
2740 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2742 value = tomTrue;
2743 hr = ITextRange_InRange(range, NULL, &value);
2744 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2745 ok(value == tomFalse, "got %d\n", value);
2747 hr = ITextRange_InRange(range, range2, NULL);
2748 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2750 value = tomTrue;
2751 hr = ITextRange_InRange(range, range2, &value);
2752 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2753 ok(value == tomFalse, "got %d\n", value);
2755 /* selection */
2756 hr = ITextSelection_InRange(selection, NULL, NULL);
2757 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2759 value = tomTrue;
2760 hr = ITextSelection_InRange(selection, NULL, &value);
2761 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2762 ok(value == tomFalse, "got %d\n", value);
2764 hr = ITextSelection_InRange(selection, range2, NULL);
2765 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2767 value = tomTrue;
2768 hr = ITextSelection_InRange(selection, range2, &value);
2769 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2770 ok(value == tomFalse, "got %d\n", value);
2772 ITextRange_Release(range);
2773 ITextRange_Release(range2);
2774 ITextRange_Release(range3);
2775 ITextSelection_Release(selection);
2778 static void test_ITextRange_IsEqual(void)
2780 static const CHAR test_text1[] = "TestSomeText";
2781 ITextRange *range, *range2, *range3;
2782 IRichEditOle *reOle = NULL;
2783 ITextDocument *doc = NULL;
2784 ITextSelection *selection;
2785 LONG value;
2786 HRESULT hr;
2787 HWND hwnd;
2789 create_interfaces(&hwnd, &reOle, &doc, &selection);
2790 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2791 SendMessageA(hwnd, EM_SETSEL, 1, 2);
2793 hr = ITextDocument_Range(doc, 0, 4, &range);
2794 ok(hr == S_OK, "got 0x%08x\n", hr);
2796 hr = ITextDocument_Range(doc, 0, 4, &range2);
2797 ok(hr == S_OK, "got 0x%08x\n", hr);
2799 /* matches selection */
2800 hr = ITextDocument_Range(doc, 1, 2, &range3);
2801 ok(hr == S_OK, "got 0x%08x\n", hr);
2803 hr = ITextRange_IsEqual(range, NULL, NULL);
2804 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2806 value = tomTrue;
2807 hr = ITextRange_IsEqual(range, NULL, &value);
2808 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2809 ok(value == tomFalse, "got %d\n", value);
2811 hr = ITextRange_IsEqual(range, range2, NULL);
2812 ok(hr == S_OK, "got 0x%08x\n", hr);
2814 value = tomFalse;
2815 hr = ITextRange_IsEqual(range, range2, &value);
2816 ok(hr == S_OK, "got 0x%08x\n", hr);
2817 ok(value == tomTrue, "got %d\n", value);
2819 value = tomTrue;
2820 hr = ITextRange_IsEqual(range, range3, &value);
2821 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2822 ok(value == tomFalse, "got %d\n", value);
2824 /* selection */
2825 hr = ITextSelection_IsEqual(selection, NULL, NULL);
2826 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2828 value = tomTrue;
2829 hr = ITextSelection_IsEqual(selection, NULL, &value);
2830 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2831 ok(value == tomFalse, "got %d\n", value);
2833 hr = ITextSelection_IsEqual(selection, range2, NULL);
2834 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2836 value = tomTrue;
2837 hr = ITextSelection_IsEqual(selection, range2, &value);
2838 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2839 ok(value == tomFalse, "got %d\n", value);
2841 value = tomTrue;
2842 hr = ITextSelection_IsEqual(selection, range3, &value);
2843 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2844 ok(value == tomFalse, "got %d\n", value);
2846 /* seems to work on ITextSelection ranges only */
2847 value = tomFalse;
2848 hr = ITextSelection_IsEqual(selection, (ITextRange*)selection, &value);
2849 ok(hr == S_OK, "got 0x%08x\n", hr);
2850 ok(value == tomTrue, "got %d\n", value);
2852 release_interfaces(&hwnd, &reOle, &doc, NULL);
2854 hr = ITextRange_IsEqual(range, NULL, NULL);
2855 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2857 value = tomTrue;
2858 hr = ITextRange_IsEqual(range, NULL, &value);
2859 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2860 ok(value == tomFalse, "got %d\n", value);
2862 hr = ITextRange_IsEqual(range, range2, NULL);
2863 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2865 value = tomTrue;
2866 hr = ITextRange_IsEqual(range, range2, &value);
2867 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2868 ok(value == tomFalse, "got %d\n", value);
2870 /* selection */
2871 hr = ITextSelection_IsEqual(selection, NULL, NULL);
2872 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2874 value = tomTrue;
2875 hr = ITextSelection_IsEqual(selection, NULL, &value);
2876 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2877 ok(value == tomFalse, "got %d\n", value);
2879 hr = ITextSelection_IsEqual(selection, range2, NULL);
2880 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2882 value = tomTrue;
2883 hr = ITextSelection_IsEqual(selection, range2, &value);
2884 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2885 ok(value == tomFalse, "got %d\n", value);
2887 ITextRange_Release(range);
2888 ITextRange_Release(range2);
2889 ITextRange_Release(range3);
2890 ITextSelection_Release(selection);
2893 static void test_Select(void)
2895 static const CHAR test_text1[] = "TestSomeText";
2896 IRichEditOle *reOle = NULL;
2897 ITextDocument *doc = NULL;
2898 ITextSelection *selection;
2899 ITextRange *range;
2900 LONG value;
2901 HRESULT hr;
2902 HWND hwnd;
2904 create_interfaces(&hwnd, &reOle, &doc, &selection);
2905 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2906 SendMessageA(hwnd, EM_SETSEL, 1, 2);
2908 hr = ITextDocument_Range(doc, 0, 4, &range);
2909 ok(hr == S_OK, "got 0x%08x\n", hr);
2911 hr = ITextRange_Select(range);
2912 ok(hr == S_OK, "got 0x%08x\n", hr);
2914 value = 1;
2915 hr = ITextSelection_GetStart(selection, &value);
2916 ok(hr == S_OK, "got 0x%08x\n", hr);
2917 ok(value == 0, "got %d\n", value);
2919 hr = ITextRange_Select(range);
2920 ok(hr == S_OK, "got 0x%08x\n", hr);
2922 hr = ITextSelection_Select(selection);
2923 ok(hr == S_OK, "got 0x%08x\n", hr);
2925 release_interfaces(&hwnd, &reOle, &doc, NULL);
2927 hr = ITextRange_Select(range);
2928 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2930 hr = ITextSelection_Select(selection);
2931 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2933 ITextRange_Release(range);
2934 ITextSelection_Release(selection);
2937 static void test_GetStoryType(void)
2939 static const CHAR test_text1[] = "TestSomeText";
2940 IRichEditOle *reOle = NULL;
2941 ITextDocument *doc = NULL;
2942 ITextSelection *selection;
2943 ITextRange *range;
2944 LONG value;
2945 HRESULT hr;
2946 HWND hwnd;
2948 create_interfaces(&hwnd, &reOle, &doc, &selection);
2949 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2950 SendMessageA(hwnd, EM_SETSEL, 1, 2);
2952 hr = ITextDocument_Range(doc, 0, 4, &range);
2953 ok(hr == S_OK, "got 0x%08x\n", hr);
2955 hr = ITextRange_GetStoryType(range, NULL);
2956 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2958 value = tomTextFrameStory;
2959 hr = ITextRange_GetStoryType(range, &value);
2960 ok(hr == S_OK, "got 0x%08x\n", hr);
2961 ok(value == tomUnknownStory, "got %d\n", value);
2963 hr = ITextSelection_GetStoryType(selection, NULL);
2964 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2966 value = tomTextFrameStory;
2967 hr = ITextSelection_GetStoryType(selection, &value);
2968 ok(hr == S_OK, "got 0x%08x\n", hr);
2969 ok(value == tomUnknownStory, "got %d\n", value);
2971 release_interfaces(&hwnd, &reOle, &doc, NULL);
2973 hr = ITextRange_GetStoryType(range, NULL);
2974 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2976 value = 123;
2977 hr = ITextRange_GetStoryType(range, &value);
2978 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2979 ok(value == 123, "got %d\n", value);
2981 hr = ITextSelection_GetStoryType(selection, NULL);
2982 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2984 value = 123;
2985 hr = ITextSelection_GetStoryType(selection, &value);
2986 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2987 ok(value == 123, "got %d\n", value);
2989 ITextRange_Release(range);
2990 ITextSelection_Release(selection);
2993 static void test_SetFont(void)
2995 static const CHAR test_text1[] = "TestSomeText";
2996 IRichEditOle *reOle = NULL;
2997 ITextDocument *doc = NULL;
2998 ITextSelection *selection;
2999 ITextRange *range, *range2;
3000 ITextFont *font, *font2;
3001 LONG value;
3002 HRESULT hr;
3003 HWND hwnd;
3005 create_interfaces(&hwnd, &reOle, &doc, &selection);
3006 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
3007 SendMessageA(hwnd, EM_SETSEL, 1, 2);
3009 hr = ITextDocument_Range(doc, 0, 4, &range);
3010 ok(hr == S_OK, "got 0x%08x\n", hr);
3012 hr = ITextDocument_Range(doc, 5, 2, &range2);
3013 ok(hr == S_OK, "got 0x%08x\n", hr);
3015 EXPECT_REF(range, 1);
3016 hr = ITextRange_GetFont(range, &font);
3017 ok(hr == S_OK, "got 0x%08x\n", hr);
3018 EXPECT_REF(range, 2);
3020 EXPECT_REF(range2, 1);
3021 hr = ITextRange_GetFont(range2, &font2);
3022 ok(hr == S_OK, "got 0x%08x\n", hr);
3023 EXPECT_REF(range2, 2);
3025 hr = ITextRange_SetFont(range, NULL);
3026 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3028 /* setting same font, no-op */
3029 EXPECT_REF(range, 2);
3030 hr = ITextRange_SetFont(range, font);
3031 ok(hr == S_OK, "got 0x%08x\n", hr);
3032 EXPECT_REF(range, 2);
3034 EXPECT_REF(range2, 2);
3035 EXPECT_REF(range, 2);
3036 hr = ITextRange_SetFont(range, font2);
3037 ok(hr == S_OK, "got 0x%08x\n", hr);
3038 EXPECT_REF(range2, 2);
3039 EXPECT_REF(range, 2);
3041 /* originaly range 0-4 is non-italic */
3042 value = tomTrue;
3043 hr = ITextFont_GetItalic(font, &value);
3044 ok(hr == S_OK, "got 0x%08x\n", hr);
3045 ok(value == tomFalse, "got %d\n", value);
3047 /* set range 5-2 to italic, then set this font to range 0-4 */
3048 hr = ITextFont_SetItalic(font2, tomTrue);
3049 ok(hr == S_OK, "got 0x%08x\n", hr);
3051 hr = ITextRange_SetFont(range, font2);
3052 ok(hr == S_OK, "got 0x%08x\n", hr);
3054 value = tomFalse;
3055 hr = ITextFont_GetItalic(font, &value);
3056 ok(hr == S_OK, "got 0x%08x\n", hr);
3057 ok(value == tomTrue, "got %d\n", value);
3059 release_interfaces(&hwnd, &reOle, &doc, NULL);
3061 hr = ITextRange_SetFont(range, NULL);
3062 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3064 hr = ITextRange_SetFont(range, font);
3065 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3067 hr = ITextSelection_SetFont(selection, NULL);
3068 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3070 hr = ITextSelection_SetFont(selection, font);
3071 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3073 ITextFont_Release(font);
3074 ITextFont_Release(font2);
3075 ITextRange_Release(range);
3076 ITextRange_Release(range2);
3077 ITextSelection_Release(selection);
3080 START_TEST(richole)
3082 /* Must explicitly LoadLibrary(). The test has no references to functions in
3083 * RICHED20.DLL, so the linker doesn't actually link to it. */
3084 hmoduleRichEdit = LoadLibraryA("riched20.dll");
3085 ok(hmoduleRichEdit != NULL, "error: %d\n", (int) GetLastError());
3087 test_Interfaces();
3088 test_ITextDocument_Open();
3089 test_GetText();
3090 test_ITextSelection_GetChar();
3091 test_ITextSelection_GetStart_GetEnd();
3092 test_ITextSelection_Collapse();
3093 test_ITextDocument_Range();
3094 test_ITextRange_GetChar();
3095 test_ITextRange_GetStart_GetEnd();
3096 test_ITextRange_GetDuplicate();
3097 test_ITextRange_Collapse();
3098 test_IOleClientSite_QueryInterface();
3099 test_IOleWindow_GetWindow();
3100 test_IOleInPlaceSite_GetWindow();
3101 test_GetFont();
3102 test_GetPara();
3103 test_dispatch();
3104 test_ITextFont();
3105 test_Delete();
3106 test_SetText();
3107 test_InRange();
3108 test_ITextRange_IsEqual();
3109 test_Select();
3110 test_GetStoryType();
3111 test_SetFont();