makefiles: Explicitly create destination dirs when installing symlinks.
[wine/zf.git] / dlls / riched20 / tests / richole.c
bloba5f439aece76345139637f17a851e4b6780fb5a2
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 ok(hwnd != NULL, "class: %s, error: %d\n", lpClassName, (int) GetLastError());
57 return hwnd;
60 static HWND new_richedit(HWND parent)
62 return new_window(RICHEDIT_CLASS20A, ES_MULTILINE, parent);
65 static BOOL touch_file(LPCWSTR filename)
67 HANDLE file;
69 file = CreateFileW(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL,
70 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
72 if(file == INVALID_HANDLE_VALUE)
73 return FALSE;
74 CloseHandle(file);
75 return TRUE;
78 static BOOL is_existing_file(LPCWSTR filename)
80 HANDLE file;
82 file = CreateFileW(filename, GENERIC_READ, 0, NULL,
83 OPEN_EXISTING, 0, NULL);
84 if(file == INVALID_HANDLE_VALUE)
85 return FALSE;
86 CloseHandle(file);
87 return TRUE;
90 static void create_interfaces(HWND *w, IRichEditOle **reOle, ITextDocument **txtDoc,
91 ITextSelection **txtSel)
93 *w = new_richedit(NULL);
94 SendMessageA(*w, EM_GETOLEINTERFACE, 0, (LPARAM)reOle);
95 IRichEditOle_QueryInterface(*reOle, &IID_ITextDocument,
96 (void **) txtDoc);
97 ITextDocument_GetSelection(*txtDoc, txtSel);
100 static void release_interfaces(HWND *w, IRichEditOle **reOle, ITextDocument **txtDoc,
101 ITextSelection **txtSel)
103 if(txtSel)
104 ITextSelection_Release(*txtSel);
105 ITextDocument_Release(*txtDoc);
106 IRichEditOle_Release(*reOle);
107 DestroyWindow(*w);
110 static ULONG get_refcount(IUnknown *iface)
112 IUnknown_AddRef(iface);
113 return IUnknown_Release(iface);
116 #define CHECK_TYPEINFO(disp,expected_riid) _check_typeinfo((IDispatch *)disp, expected_riid, __LINE__)
117 static void _check_typeinfo(IDispatch* disp, REFIID expected_riid, int line)
119 ITypeInfo *typeinfo;
120 TYPEATTR *typeattr;
121 UINT count;
122 HRESULT hr;
124 count = 10;
125 hr = IDispatch_GetTypeInfoCount(disp, &count);
126 ok_(__FILE__,line)(hr == S_OK, "IDispatch_GetTypeInfoCount failed: 0x%08x.\n", hr);
127 ok_(__FILE__,line)(count == 1, "got wrong count: %u.\n", count);
129 hr = IDispatch_GetTypeInfo(disp, 0, LOCALE_SYSTEM_DEFAULT, &typeinfo);
130 ok_(__FILE__,line)(hr == S_OK, "IDispatch_GetTypeInfo failed: 0x%08x.\n", hr);
132 hr = ITypeInfo_GetTypeAttr(typeinfo, &typeattr);
133 ok_(__FILE__,line)(hr == S_OK, "ITypeInfo_GetTypeAttr failed: 0x%08x.\n", hr);
134 ok_(__FILE__,line)(IsEqualGUID(&typeattr->guid, expected_riid),
135 "Unexpected type guid: %s.\n", wine_dbgstr_guid(&typeattr->guid));
137 ITypeInfo_ReleaseTypeAttr(typeinfo, typeattr);
138 ITypeInfo_Release(typeinfo);
141 static void test_Interfaces(void)
143 IRichEditOle *reOle = NULL, *reOle1 = NULL;
144 ITextDocument *txtDoc = NULL;
145 ITextDocument2Old *txtDoc2Old = NULL;
146 ITextSelection *txtSel = NULL, *txtSel2;
147 IUnknown *punk;
148 HRESULT hres;
149 LRESULT res;
150 HWND w;
151 ULONG refcount;
153 w = new_richedit(NULL);
154 if (!w) {
155 skip("Couldn't create window\n");
156 return;
159 res = SendMessageA(w, EM_GETOLEINTERFACE, 0, (LPARAM)&reOle);
160 ok(res, "SendMessage\n");
161 ok(reOle != NULL, "EM_GETOLEINTERFACE\n");
162 EXPECT_REF(reOle, 2);
164 res = SendMessageA(w, EM_GETOLEINTERFACE, 0, (LPARAM)&reOle1);
165 ok(res == 1, "SendMessage\n");
166 ok(reOle1 == reOle, "Should not return a new IRichEditOle interface\n");
167 EXPECT_REF(reOle, 3);
169 hres = IRichEditOle_QueryInterface(reOle, &IID_ITextDocument,
170 (void **) &txtDoc);
171 ok(hres == S_OK, "IRichEditOle_QueryInterface\n");
172 ok(txtDoc != NULL, "IRichEditOle_QueryInterface\n");
173 CHECK_TYPEINFO(txtDoc, &IID_ITextDocument);
175 hres = ITextDocument_GetSelection(txtDoc, NULL);
176 ok(hres == E_INVALIDARG, "ITextDocument_GetSelection: 0x%x\n", hres);
178 EXPECT_REF(txtDoc, 4);
180 hres = ITextDocument_GetSelection(txtDoc, &txtSel);
181 ok(hres == S_OK, "got 0x%08x\n", hres);
183 EXPECT_REF(txtDoc, 4);
184 EXPECT_REF(txtSel, 2);
186 hres = ITextDocument_GetSelection(txtDoc, &txtSel2);
187 ok(hres == S_OK, "got 0x%08x\n", hres);
188 ok(txtSel2 == txtSel, "got %p, %p\n", txtSel, txtSel2);
190 EXPECT_REF(txtDoc, 4);
191 EXPECT_REF(txtSel, 3);
193 ITextSelection_Release(txtSel2);
195 punk = NULL;
196 hres = ITextSelection_QueryInterface(txtSel, &IID_ITextSelection, (void **) &punk);
197 ok(hres == S_OK, "ITextSelection_QueryInterface\n");
198 ok(punk != NULL, "ITextSelection_QueryInterface\n");
199 IUnknown_Release(punk);
201 punk = NULL;
202 hres = ITextSelection_QueryInterface(txtSel, &IID_ITextRange, (void **) &punk);
203 ok(hres == S_OK, "ITextSelection_QueryInterface\n");
204 ok(punk != NULL, "ITextSelection_QueryInterface\n");
205 IUnknown_Release(punk);
207 punk = NULL;
208 hres = ITextSelection_QueryInterface(txtSel, &IID_IDispatch, (void **) &punk);
209 ok(hres == S_OK, "ITextSelection_QueryInterface\n");
210 ok(punk != NULL, "ITextSelection_QueryInterface\n");
211 IUnknown_Release(punk);
213 punk = NULL;
214 hres = IRichEditOle_QueryInterface(reOle, &IID_IOleClientSite, (void **) &punk);
215 ok(hres == E_NOINTERFACE, "IRichEditOle_QueryInterface\n");
217 punk = NULL;
218 hres = IRichEditOle_QueryInterface(reOle, &IID_IOleWindow, (void **) &punk);
219 ok(hres == E_NOINTERFACE, "IRichEditOle_QueryInterface\n");
221 punk = NULL;
222 hres = IRichEditOle_QueryInterface(reOle, &IID_IOleInPlaceSite, (void **) &punk);
223 ok(hres == E_NOINTERFACE, "IRichEditOle_QueryInterface\n");
225 hres = IRichEditOle_QueryInterface(reOle, &IID_ITextDocument2Old, (void **)&txtDoc2Old);
226 ok(hres == S_OK, "IRichEditOle_QueryInterface\n");
227 ok(txtDoc2Old != NULL, "IRichEditOle_QueryInterface\n");
228 ok((ITextDocument *)txtDoc2Old == txtDoc, "interface pointer isn't equal.\n");
229 EXPECT_REF(txtDoc2Old, 5);
230 EXPECT_REF(reOle, 5);
231 CHECK_TYPEINFO(txtDoc2Old, &IID_ITextDocument);
233 ITextDocument2Old_Release(txtDoc2Old);
235 ITextDocument_Release(txtDoc);
236 IRichEditOle_Release(reOle);
237 refcount = IRichEditOle_Release(reOle);
238 ok(refcount == 1, "got wrong ref count: %d\n", refcount);
239 DestroyWindow(w);
241 /* Methods should return CO_E_RELEASED if the backing document has
242 been released. One test should suffice. */
243 hres = ITextSelection_CanEdit(txtSel, NULL);
244 ok(hres == CO_E_RELEASED, "ITextSelection after ITextDocument destroyed\n");
246 ITextSelection_Release(txtSel);
248 w = new_richedit(NULL);
249 res = SendMessageA(w, EM_GETOLEINTERFACE, 0, (LPARAM)&reOle);
250 ok(res, "SendMessage\n");
251 ok(reOle != NULL, "EM_GETOLEINTERFACE\n");
253 hres = IRichEditOle_QueryInterface(reOle, &IID_ITextDocument2Old, (void **)&txtDoc2Old);
254 ok(hres == S_OK, "IRichEditOle_QueryInterface failed: 0x%08x.\n", hres);
255 ok(txtDoc2Old != NULL, "IRichEditOle_QueryInterface\n");
256 CHECK_TYPEINFO(txtDoc2Old, &IID_ITextDocument);
257 ITextDocument2Old_Release(txtDoc2Old);
258 IRichEditOle_Release(reOle);
259 DestroyWindow(w);
262 static void test_ITextDocument_Open(void)
264 IRichEditOle *reOle = NULL;
265 ITextDocument *txtDoc = NULL;
266 ITextSelection *txtSel = NULL;
267 HRESULT hres;
268 HWND w;
269 HANDLE hFile;
270 VARIANT testfile;
271 WCHAR filename[] = {'t', 'e', 's', 't','.','t','x','t', 0};
272 int result;
273 DWORD dw;
274 static const CHAR chACP[] = "TestSomeText";
275 static const CHAR chUTF8[] = "\xef\xbb\xbfTextWithUTF8BOM";
276 static const WCHAR chUTF16[] = {0xfeff, 'T', 'e', 's', 't', 'S', 'o', 'm',
277 'e', 'T', 'e', 'x', 't', 0};
279 #define MAX_BUF_LEN 1024
280 CHAR bufACP[MAX_BUF_LEN];
281 WCHAR bufUnicode[MAX_BUF_LEN];
283 static const int tomConstantsSingle[] =
285 tomReadOnly, tomShareDenyRead, tomShareDenyWrite,
286 tomCreateAlways, tomOpenExisting, tomOpenAlways,
287 tomTruncateExisting, tomRTF, tomText
290 static const int tomConstantsMulti[] =
292 tomReadOnly|tomShareDenyRead|tomPasteFile, tomReadOnly|tomPasteFile,
293 tomReadOnly|tomShareDenyWrite|tomPasteFile,
294 tomReadOnly|tomShareDenyRead|tomShareDenyWrite|tomPasteFile, tomShareDenyWrite|tomPasteFile,
295 tomShareDenyRead|tomShareDenyWrite|tomPasteFile, tomShareDenyRead|tomPasteFile,
296 tomShareDenyRead|tomShareDenyWrite, tomReadOnly|tomShareDenyRead|tomShareDenyWrite,
297 tomReadOnly|tomShareDenyWrite, tomReadOnly|tomShareDenyRead
300 int tomNumSingle = ARRAY_SIZE(tomConstantsSingle);
301 int tomNumMulti = ARRAY_SIZE(tomConstantsMulti);
302 int i;
304 V_VT(&testfile) = VT_BSTR;
305 V_BSTR(&testfile) = SysAllocString(filename);
307 for(i=0; i < tomNumSingle; i++)
309 touch_file(filename);
310 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
311 hres = ITextDocument_Open(txtDoc, &testfile, tomConstantsSingle[i], CP_ACP);
312 todo_wine ok(hres == S_OK, "ITextDocument_Open: Filename:test.txt Flags:0x%x Codepage:CP_ACP hres:0x%x\n",
313 tomConstantsSingle[i], hres);
314 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
315 DeleteFileW(filename);
317 touch_file(filename);
318 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
319 hres = ITextDocument_Open(txtDoc, &testfile, tomConstantsSingle[i], CP_UTF8);
320 todo_wine ok(hres == S_OK, "ITextDocument_Open: Filename:test.txt Flags:0x%x Codepage:CP_UTF8 hres:0x%x\n",
321 tomConstantsSingle[i], hres);
322 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
323 DeleteFileW(filename);
326 for(i=0; i < tomNumMulti; i++)
328 touch_file(filename);
329 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
330 hres = ITextDocument_Open(txtDoc, &testfile, tomConstantsMulti[i], CP_ACP);
331 todo_wine ok(hres == S_OK, "ITextDocument_Open: Filename:test.txt Flags:0x%x Codepage:CP_ACP hres:0x%x\n",
332 tomConstantsMulti[i], hres);
333 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
334 DeleteFileW(filename);
336 touch_file(filename);
337 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
338 hres = ITextDocument_Open(txtDoc, &testfile, tomConstantsMulti[i], CP_UTF8);
339 todo_wine ok(hres == S_OK, "ITextDocument_Open: Filename:test.txt Flags:0x%x Codepage:CP_UTF8 hres:0x%x\n",
340 tomConstantsMulti[i], hres);
341 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
342 DeleteFileW(filename);
345 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
346 hres = ITextDocument_Open(txtDoc, &testfile, tomCreateAlways, CP_ACP);
347 todo_wine ok(hres == S_OK, "ITextDocument_Open should success Codepage:CP_ACP\n");
348 todo_wine ok(is_existing_file(filename), "ITextDocument_Open should create a file\n");
349 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
350 DeleteFileW(filename);
352 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
353 hres = ITextDocument_Open(txtDoc, &testfile, tomCreateAlways, CP_UTF8);
354 todo_wine ok(hres == S_OK, "ITextDocument_Open should success Codepage:CP_UTF8\n");
355 todo_wine ok(is_existing_file(filename), "ITextDocument_Open should create a file\n");
356 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
357 DeleteFileW(filename);
359 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
360 hres = ITextDocument_Open(txtDoc, &testfile, tomOpenAlways, CP_ACP);
361 todo_wine ok(hres == S_OK, "ITextDocument_Open should success Codepage:CP_ACP\n");
362 todo_wine ok(is_existing_file(filename), "ITextDocument_Open should create a file\n");
363 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
364 DeleteFileW(filename);
366 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
367 hres = ITextDocument_Open(txtDoc, &testfile, tomOpenAlways, CP_UTF8);
368 todo_wine ok(hres == S_OK, "ITextDocument_Open should success Codepage:CP_UTF8\n");
369 todo_wine ok(is_existing_file(filename), "ITextDocument_Open should create a file\n");
370 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
371 DeleteFileW(filename);
373 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
374 hres = ITextDocument_Open(txtDoc, &testfile, tomCreateNew, CP_ACP);
375 todo_wine ok(hres == S_OK, "ITextDocument_Open should success Codepage:CP_ACP\n");
376 todo_wine ok(is_existing_file(filename), "ITextDocument_Open should create a file\n");
377 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
378 DeleteFileW(filename);
380 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
381 hres = ITextDocument_Open(txtDoc, &testfile, tomCreateNew, CP_UTF8);
382 todo_wine ok(hres == S_OK, "ITextDocument_Open should success Codepage:CP_UTF8\n");
383 todo_wine ok(is_existing_file(filename), "ITextDocument_Open should create a file\n");
384 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
385 DeleteFileW(filename);
387 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
388 touch_file(filename);
389 hres = ITextDocument_Open(txtDoc, &testfile, tomCreateNew, CP_ACP);
390 todo_wine ok(hres == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "ITextDocument_Open should fail Codepage:CP_ACP\n");
391 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
392 DeleteFileW(filename);
394 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
395 touch_file(filename);
396 hres = ITextDocument_Open(txtDoc, &testfile, tomCreateNew, CP_UTF8);
397 todo_wine ok(hres == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "ITextDocument_Open should fail Codepage:CP_UTF8\n");
398 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
399 DeleteFileW(filename);
401 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
402 hres = ITextDocument_Open(txtDoc, &testfile, tomOpenExisting, CP_ACP);
403 todo_wine ok(hres == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "ITextDocument_Open should fail Codepage:CP_ACP\n");
404 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
406 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
407 hres = ITextDocument_Open(txtDoc, &testfile, tomOpenExisting, CP_UTF8);
408 todo_wine ok(hres == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "ITextDocument_Open should fail Codepage:CP_UTF8\n");
409 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
411 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
412 DeleteFileW(filename);
413 hres = ITextDocument_Open(txtDoc, &testfile, tomText, CP_ACP);
414 todo_wine {
415 ok(hres == S_OK, "got 0x%08x\n", hres);
416 ok(is_existing_file(filename) == TRUE, "a file should be created default\n");
418 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
419 DeleteFileW(filename);
421 /* test of share mode */
422 touch_file(filename);
423 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
424 hres = ITextDocument_Open(txtDoc, &testfile, tomShareDenyRead, CP_ACP);
425 todo_wine
426 ok(hres == S_OK, "got 0x%08x\n", hres);
427 SetLastError(0xdeadbeef);
428 hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
429 FILE_ATTRIBUTE_NORMAL, NULL);
430 todo_wine ok(GetLastError() == ERROR_SHARING_VIOLATION, "ITextDocument_Open should fail\n");
431 CloseHandle(hFile);
432 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
433 DeleteFileW(filename);
435 touch_file(filename);
436 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
437 hres = ITextDocument_Open(txtDoc, &testfile, tomShareDenyWrite, CP_ACP);
438 todo_wine
439 ok(hres == S_OK, "got 0x%08x\n", hres);
440 SetLastError(0xdeadbeef);
441 hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
442 FILE_ATTRIBUTE_NORMAL, NULL);
443 todo_wine ok(GetLastError() == ERROR_SHARING_VIOLATION, "ITextDocument_Open should fail\n");
444 CloseHandle(hFile);
445 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
446 DeleteFileW(filename);
448 touch_file(filename);
449 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
450 SetLastError(0xdeadbeef);
451 hres = ITextDocument_Open(txtDoc, &testfile, tomShareDenyWrite|tomShareDenyRead, CP_ACP);
452 todo_wine
453 ok(hres == S_OK, "got 0x%08x\n", hres);
454 hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
455 FILE_ATTRIBUTE_NORMAL, NULL);
456 todo_wine ok(GetLastError() == ERROR_SHARING_VIOLATION, "ITextDocument_Open should fail\n");
457 CloseHandle(hFile);
458 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
459 DeleteFileW(filename);
461 /* tests to check the content */
462 hFile = CreateFileW(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS,
463 FILE_ATTRIBUTE_NORMAL, NULL);
464 WriteFile(hFile, chACP, sizeof(chACP)-sizeof(CHAR), &dw, NULL);
465 CloseHandle(hFile);
466 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
467 hres = ITextDocument_Open(txtDoc, &testfile, tomReadOnly, CP_ACP);
468 todo_wine
469 ok(hres == S_OK, "got 0x%08x\n", hres);
470 result = SendMessageA(w, WM_GETTEXT, 1024, (LPARAM)bufACP);
471 todo_wine ok(result == 12, "ITextDocument_Open: Test ASCII returned %d, expected 12\n", result);
472 result = strcmp(bufACP, chACP);
473 todo_wine ok(result == 0, "ITextDocument_Open: Test ASCII set wrong text: Result: %s\n", bufACP);
474 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
475 DeleteFileW(filename);
477 hFile = CreateFileW(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS,
478 FILE_ATTRIBUTE_NORMAL, NULL);
479 WriteFile(hFile, chUTF8, sizeof(chUTF8)-sizeof(CHAR), &dw, NULL);
480 CloseHandle(hFile);
481 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
482 hres = ITextDocument_Open(txtDoc, &testfile, tomReadOnly, CP_UTF8);
483 todo_wine
484 ok(hres == S_OK, "got 0x%08x\n", hres);
485 result = SendMessageA(w, WM_GETTEXT, 1024, (LPARAM)bufACP);
486 todo_wine ok(result == 15, "ITextDocument_Open: Test UTF-8 returned %d, expected 15\n", result);
487 result = strcmp(bufACP, &chUTF8[3]);
488 todo_wine ok(result == 0, "ITextDocument_Open: Test UTF-8 set wrong text: Result: %s\n", bufACP);
489 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
490 DeleteFileW(filename);
492 hFile = CreateFileW(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS,
493 FILE_ATTRIBUTE_NORMAL, NULL);
494 WriteFile(hFile, chUTF16, sizeof(chUTF16)-sizeof(WCHAR), &dw, NULL);
495 CloseHandle(hFile);
496 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
497 hres = ITextDocument_Open(txtDoc, &testfile, tomReadOnly, 1200);
498 todo_wine
499 ok(hres == S_OK, "got 0x%08x\n", hres);
500 result = SendMessageW(w, WM_GETTEXT, 1024, (LPARAM)bufUnicode);
501 todo_wine ok(result == 12, "ITextDocument_Open: Test UTF-16 returned %d, expected 12\n", result);
502 result = lstrcmpW(bufUnicode, &chUTF16[1]);
503 todo_wine ok(result == 0, "ITextDocument_Open: Test UTF-16 set wrong text: Result: %s\n", wine_dbgstr_w(bufUnicode));
504 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
505 DeleteFileW(filename);
507 VariantClear(&testfile);
510 static void test_GetText(void)
512 HWND w;
513 IRichEditOle *reOle = NULL;
514 ITextDocument *txtDoc = NULL;
515 ITextSelection *txtSel = NULL;
516 HRESULT hres;
517 BSTR bstr = NULL;
518 int first, lim;
519 static const CHAR test_text1[] = "TestSomeText";
520 static const WCHAR bufW1[] = {'T', 'e', 's', 't', 0};
521 static const WCHAR bufW2[] = {'T', 'e', 'x', 't', '\r', 0};
522 static const WCHAR bufW3[] = {'T', 'e', 'x', 't', 0};
523 static const WCHAR bufW4[] = {'T', 'e', 's', 't', 'S', 'o', 'm',
524 'e', 'T', 'e', 'x', 't', '\r', 0};
525 static const WCHAR bufW5[] = {'\r', 0};
526 static const WCHAR bufW6[] = {'T','e','s','t','S','o','m','e','T',0};
527 BOOL is64bit = sizeof(void *) > sizeof(int);
528 ITextRange *range;
530 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
531 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
533 /* ITextSelection */
534 first = 0; lim = 4;
535 SendMessageA(w, EM_SETSEL, first, lim);
536 hres = ITextSelection_GetText(txtSel, &bstr);
537 ok(hres == S_OK, "ITextSelection_GetText\n");
538 ok(!lstrcmpW(bstr, bufW1), "got wrong text: %s\n", wine_dbgstr_w(bstr));
539 SysFreeString(bstr);
541 first = 4; lim = 0;
542 SendMessageA(w, EM_SETSEL, first, lim);
543 hres = ITextSelection_GetText(txtSel, &bstr);
544 ok(hres == S_OK, "ITextSelection_GetText\n");
545 ok(!lstrcmpW(bstr, bufW1), "got wrong text: %s\n", wine_dbgstr_w(bstr));
546 SysFreeString(bstr);
548 first = 1; lim = 1;
549 SendMessageA(w, EM_SETSEL, first, lim);
550 hres = ITextSelection_GetText(txtSel, &bstr);
551 ok(hres == S_OK, "ITextSelection_GetText\n");
552 ok(!bstr, "got wrong text: %s\n", wine_dbgstr_w(bstr));
554 if (!is64bit)
556 hres = ITextSelection_GetText(txtSel, NULL);
557 ok(hres == E_INVALIDARG, "ITextSelection_GetText\n");
560 first = 8; lim = 12;
561 SendMessageA(w, EM_SETSEL, first, lim);
562 hres = ITextSelection_GetText(txtSel, &bstr);
563 ok(hres == S_OK, "ITextSelection_GetText\n");
564 ok(!lstrcmpW(bstr, bufW3), "got wrong text: %s\n", wine_dbgstr_w(bstr));
565 SysFreeString(bstr);
567 first = 8; lim = 13;
568 SendMessageA(w, EM_SETSEL, first, lim);
569 hres = ITextSelection_GetText(txtSel, &bstr);
570 ok(hres == S_OK, "ITextSelection_GetText\n");
571 ok(!lstrcmpW(bstr, bufW2), "got wrong text: %s\n", wine_dbgstr_w(bstr));
572 SysFreeString(bstr);
574 first = 12; lim = 13;
575 SendMessageA(w, EM_SETSEL, first, lim);
576 hres = ITextSelection_GetText(txtSel, &bstr);
577 ok(hres == S_OK, "ITextSelection_GetText\n");
578 ok(!lstrcmpW(bstr, bufW5), "got wrong text: %s\n", wine_dbgstr_w(bstr));
579 SysFreeString(bstr);
581 first = 0; lim = -1;
582 SendMessageA(w, EM_SETSEL, first, lim);
583 hres = ITextSelection_GetText(txtSel, &bstr);
584 ok(hres == S_OK, "ITextSelection_GetText\n");
585 ok(!lstrcmpW(bstr, bufW4), "got wrong text: %s\n", wine_dbgstr_w(bstr));
586 SysFreeString(bstr);
588 first = -1; lim = 9;
589 SendMessageA(w, EM_SETSEL, first, lim);
590 hres = ITextSelection_GetText(txtSel, &bstr);
591 ok(hres == S_OK, "ITextSelection_GetText\n");
592 ok(!bstr, "got wrong text: %s\n", wine_dbgstr_w(bstr));
594 /* ITextRange */
595 hres = ITextDocument_Range(txtDoc, 0, 4, &range);
596 ok(hres == S_OK, "got 0x%08x\n", hres);
597 hres = ITextRange_GetText(range, &bstr);
598 ok(hres == S_OK, "got 0x%08x\n", hres);
599 ok(!lstrcmpW(bstr, bufW1), "got wrong text: %s\n", wine_dbgstr_w(bstr));
601 SysFreeString(bstr);
602 ITextRange_Release(range);
604 hres = ITextDocument_Range(txtDoc, 4, 0, &range);
605 ok(hres == S_OK, "got 0x%08x\n", hres);
606 hres = ITextRange_GetText(range, &bstr);
607 ok(hres == S_OK, "got 0x%08x\n", hres);
608 ok(!lstrcmpW(bstr, bufW1), "got wrong text: %s\n", wine_dbgstr_w(bstr));
610 SysFreeString(bstr);
611 ITextRange_Release(range);
613 hres = ITextDocument_Range(txtDoc, 1, 1, &range);
614 ok(hres == S_OK, "got 0x%08x\n", hres);
615 hres = ITextRange_GetText(range, &bstr);
616 ok(hres == S_OK, "got 0x%08x\n", hres);
617 ok(!bstr, "got wrong text: %s\n", wine_dbgstr_w(bstr));
618 if (!is64bit)
620 hres = ITextRange_GetText(range, NULL);
621 ok(hres == E_INVALIDARG, "got 0x%08x\n", hres);
623 ITextRange_Release(range);
625 hres = ITextDocument_Range(txtDoc, 8, 12, &range);
626 ok(hres == S_OK, "got 0x%08x\n", hres);
627 hres = ITextRange_GetText(range, &bstr);
628 ok(hres == S_OK, "got 0x%08x\n", hres);
629 ok(!lstrcmpW(bstr, bufW3), "got wrong text: %s\n", wine_dbgstr_w(bstr));
631 SysFreeString(bstr);
632 ITextRange_Release(range);
634 hres = ITextDocument_Range(txtDoc, 8, 13, &range);
635 ok(hres == S_OK, "got 0x%08x\n", hres);
636 hres = ITextRange_GetText(range, &bstr);
637 ok(hres == S_OK, "got 0x%08x\n", hres);
638 ok(!lstrcmpW(bstr, bufW2), "got wrong text: %s\n", wine_dbgstr_w(bstr));
640 SysFreeString(bstr);
641 ITextRange_Release(range);
643 hres = ITextDocument_Range(txtDoc, 12, 13, &range);
644 ok(hres == S_OK, "got 0x%08x\n", hres);
645 hres = ITextRange_GetText(range, &bstr);
646 ok(hres == S_OK, "got 0x%08x\n", hres);
647 ok(!lstrcmpW(bstr, bufW5), "got wrong text: %s\n", wine_dbgstr_w(bstr));
649 SysFreeString(bstr);
650 ITextRange_Release(range);
652 hres = ITextDocument_Range(txtDoc, 0, -1, &range);
653 ok(hres == S_OK, "got 0x%08x\n", hres);
654 hres = ITextRange_GetText(range, &bstr);
655 ok(hres == S_OK, "got 0x%08x\n", hres);
656 ok(!bstr, "got wrong text: %s\n", wine_dbgstr_w(bstr));
657 ITextRange_Release(range);
659 hres = ITextDocument_Range(txtDoc, -1, 9, &range);
660 ok(hres == S_OK, "got 0x%08x\n", hres);
661 hres = ITextRange_GetText(range, &bstr);
662 ok(hres == S_OK, "got 0x%08x\n", hres);
663 ok(!lstrcmpW(bstr, bufW6), "got wrong text: %s\n", wine_dbgstr_w(bstr));
665 SysFreeString(bstr);
667 release_interfaces(&w, &reOle, &txtDoc, NULL);
669 /* detached selection/range */
670 if (is64bit) {
671 bstr = (void*)0xdeadbeef;
672 hres = ITextSelection_GetText(txtSel, &bstr);
673 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
674 todo_wine
675 ok(bstr == NULL, "got %p\n", bstr);
677 bstr = (void*)0xdeadbeef;
678 hres = ITextRange_GetText(range, &bstr);
679 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
680 todo_wine
681 ok(bstr == NULL, "got %p\n", bstr);
683 else {
684 hres = ITextSelection_GetText(txtSel, NULL);
685 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
687 hres = ITextRange_GetText(range, NULL);
688 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
691 ITextRange_Release(range);
692 ITextSelection_Release(txtSel);
695 static void test_ITextDocument_Range(void)
697 static const CHAR test_text1[] = "TestSomeText";
698 HWND w;
699 IRichEditOle *reOle = NULL;
700 ITextDocument *txtDoc = NULL;
701 ITextRange *txtRge, *range2;
702 HRESULT hres;
703 LONG value;
705 create_interfaces(&w, &reOle, &txtDoc, NULL);
706 hres = ITextDocument_Range(txtDoc, 0, 0, &txtRge);
707 ok(hres == S_OK, "ITextDocument_Range fails 0x%x.\n", hres);
708 EXPECT_REF(txtRge, 1);
710 hres = ITextDocument_Range(txtDoc, 0, 0, &range2);
711 ok(hres == S_OK, "ITextDocument_Range fails 0x%x.\n", hres);
712 ok(range2 != txtRge, "A new pointer should be returned\n");
713 ITextRange_Release(range2);
715 hres = ITextDocument_Range(txtDoc, 0, 0, NULL);
716 ok(hres == E_INVALIDARG, "ITextDocument_Range should fail 0x%x.\n", hres);
718 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
720 hres = ITextDocument_Range(txtDoc, 8, 30, &range2);
721 ok(hres == S_OK, "ITextDocument_Range fails 0x%x.\n", hres);
722 hres = ITextRange_GetStart(range2, &value);
723 ok(hres == S_OK, "got 0x%08x\n", hres);
724 ok(value == 8, "got %d\n", value);
726 hres = ITextRange_GetEnd(range2, &value);
727 ok(hres == S_OK, "got 0x%08x\n", hres);
728 ok(value == 13, "got %d\n", value);
729 ITextRange_Release(range2);
731 release_interfaces(&w, &reOle, &txtDoc, NULL);
732 hres = ITextRange_CanEdit(txtRge, NULL);
733 ok(hres == CO_E_RELEASED, "ITextRange after ITextDocument destroyed\n");
734 ITextRange_Release(txtRge);
737 static void test_ITextRange_GetChar(void)
739 HWND w;
740 IRichEditOle *reOle = NULL;
741 ITextDocument *txtDoc = NULL;
742 ITextRange *txtRge = NULL;
743 HRESULT hres;
744 LONG pch;
745 int first, lim;
746 static const CHAR test_text1[] = "TestSomeText";
748 first = 0, lim = 4;
749 create_interfaces(&w, &reOle, &txtDoc, NULL);
750 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
751 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
752 ok(hres == S_OK, "got 0x%08x\n", hres);
753 pch = 0xdeadbeef;
754 hres = ITextRange_GetChar(txtRge, &pch);
755 ok(hres == S_OK, "ITextRange_GetChar\n");
756 ok(pch == 'T', "got wrong char: %c\n", pch);
757 ITextRange_Release(txtRge);
758 release_interfaces(&w, &reOle, &txtDoc, NULL);
760 first = 0; lim = 0;
761 create_interfaces(&w, &reOle, &txtDoc, NULL);
762 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
763 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
764 ok(hres == S_OK, "got 0x%08x\n", hres);
765 pch = 0xdeadbeef;
766 hres = ITextRange_GetChar(txtRge, &pch);
767 ok(hres == S_OK, "ITextRange_GetChar\n");
768 ok(pch == 'T', "got wrong char: %c\n", pch);
769 ITextRange_Release(txtRge);
770 release_interfaces(&w, &reOle, &txtDoc, NULL);
772 first = 12; lim = 12;
773 create_interfaces(&w, &reOle, &txtDoc, NULL);
774 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
775 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
776 ok(hres == S_OK, "got 0x%08x\n", hres);
777 pch = 0xdeadbeef;
778 hres = ITextRange_GetChar(txtRge, &pch);
779 ok(hres == S_OK, "ITextRange_GetChar\n");
780 ok(pch == '\r', "got wrong char: %c\n", pch);
781 ITextRange_Release(txtRge);
782 release_interfaces(&w, &reOle, &txtDoc, NULL);
784 first = 13; lim = 13;
785 create_interfaces(&w, &reOle, &txtDoc, NULL);
786 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
787 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
788 ok(hres == S_OK, "got 0x%08x\n", hres);
789 pch = 0xdeadbeef;
790 hres = ITextRange_GetChar(txtRge, &pch);
791 ok(hres == S_OK, "ITextRange_GetChar\n");
792 ok(pch == '\r', "got wrong char: %c\n", pch);
793 ITextRange_Release(txtRge);
794 release_interfaces(&w, &reOle, &txtDoc, NULL);
796 create_interfaces(&w, &reOle, &txtDoc, NULL);
797 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
798 first = 12; lim = 12;
799 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
800 ok(hres == S_OK, "got 0x%08x\n", hres);
801 hres = ITextRange_GetChar(txtRge, NULL);
802 ok(hres == E_INVALIDARG, "ITextRange_GetChar\n");
804 release_interfaces(&w, &reOle, &txtDoc, NULL);
806 hres = ITextRange_GetChar(txtRge, NULL);
807 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
809 hres = ITextRange_GetChar(txtRge, &pch);
810 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
812 ITextRange_Release(txtRge);
815 /* Helper function for testing ITextRange_ScrollIntoView */
816 static void check_range(HWND w, ITextDocument* doc, int first, int lim,
817 LONG bStart, int expected_nonzero)
819 SCROLLINFO si;
820 ITextRange *txtRge = NULL;
821 HRESULT hres;
823 si.cbSize = sizeof(SCROLLINFO);
824 si.fMask = SIF_POS | SIF_RANGE;
826 hres = ITextDocument_Range(doc, first, lim, &txtRge);
827 ok(hres == S_OK, "got 0x%08x\n", hres);
828 hres = ITextRange_ScrollIntoView(txtRge, bStart);
829 ok(hres == S_OK, "got 0x%08x\n", hres);
830 GetScrollInfo(w, SB_VERT, &si);
831 if (expected_nonzero) {
832 ok(si.nPos != 0,
833 "Scrollbar at 0, should be >0. (TextRange %d-%d, scroll range %d-%d.)\n",
834 first, lim, si.nMin, si.nMax);
835 } else {
836 ok(si.nPos == 0,
837 "Scrollbar at %d, should be 0. (TextRange %d-%d, scroll range %d-%d.)\n",
838 si.nPos, first, lim, si.nMin, si.nMax);
842 static void test_ITextRange_ScrollIntoView(void)
844 HWND w;
845 IRichEditOle *reOle = NULL;
846 ITextDocument *txtDoc = NULL;
847 ITextRange *txtRge = NULL;
848 HRESULT hres;
849 static const CHAR test_text1[] = "1\n2\n3\n4\n5\n6\n7\n8\n9\n10";
851 create_interfaces(&w, &reOle, &txtDoc, NULL);
852 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
854 /* Scroll to the top. */
855 check_range(w, txtDoc, 0, 1, tomStart, 0);
856 check_range(w, txtDoc, 0, 1, tomEnd, 0);
858 /* Scroll to the bottom. */
859 check_range(w, txtDoc, 19, 20, tomStart, 1);
860 check_range(w, txtDoc, 19, 20, tomEnd, 1);
862 /* Back up to the top. */
863 check_range(w, txtDoc, 0, 1, tomStart, 0);
864 check_range(w, txtDoc, 0, 1, tomEnd, 0);
866 /* Large range */
867 check_range(w, txtDoc, 0, 20, tomStart, 0);
868 check_range(w, txtDoc, 0, 20, tomEnd, 1);
870 hres = ITextDocument_Range(txtDoc, 0, 0, &txtRge);
871 ok(hres == S_OK, "got 0x%08x\n", hres);
872 release_interfaces(&w, &reOle, &txtDoc, NULL);
873 hres = ITextRange_ScrollIntoView(txtRge, tomStart);
874 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
875 ITextRange_Release(txtRge);
878 static void test_ITextSelection_GetChar(void)
880 HWND w;
881 IRichEditOle *reOle = NULL;
882 ITextDocument *txtDoc = NULL;
883 ITextSelection *txtSel = NULL;
884 HRESULT hres;
885 LONG pch;
886 int first, lim;
887 static const CHAR test_text1[] = "TestSomeText";
889 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
890 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
892 first = 0; lim = 4;
893 SendMessageA(w, EM_SETSEL, first, lim);
894 pch = 0xdeadbeef;
895 hres = ITextSelection_GetChar(txtSel, &pch);
896 ok(hres == S_OK, "ITextSelection_GetChar\n");
897 ok(pch == 'T', "got wrong char: %c\n", pch);
899 first = 0; lim = 0;
900 SendMessageA(w, EM_SETSEL, first, lim);
901 pch = 0xdeadbeef;
902 hres = ITextSelection_GetChar(txtSel, &pch);
903 ok(hres == S_OK, "ITextSelection_GetChar\n");
904 ok(pch == 'T', "got wrong char: %c\n", pch);
906 first = 12; lim = 12;
907 SendMessageA(w, EM_SETSEL, first, lim);
908 pch = 0xdeadbeef;
909 hres = ITextSelection_GetChar(txtSel, &pch);
910 ok(hres == S_OK, "ITextSelection_GetChar\n");
911 ok(pch == '\r', "got wrong char: %c\n", pch);
913 first = 13; lim = 13;
914 SendMessageA(w, EM_SETSEL, first, lim);
915 pch = 0xdeadbeef;
916 hres = ITextSelection_GetChar(txtSel, &pch);
917 ok(hres == S_OK, "ITextSelection_GetChar\n");
918 ok(pch == '\r', "got wrong char: %c\n", pch);
920 hres = ITextSelection_GetChar(txtSel, NULL);
921 ok(hres == E_INVALIDARG, "ITextSelection_GetChar\n");
923 release_interfaces(&w, &reOle, &txtDoc, NULL);
925 hres = ITextSelection_GetChar(txtSel, NULL);
926 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
928 hres = ITextSelection_GetChar(txtSel, &pch);
929 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
931 ITextSelection_Release(txtSel);
934 static void test_ITextRange_GetStart_GetEnd(void)
936 HWND w;
937 IRichEditOle *reOle = NULL;
938 ITextDocument *txtDoc = NULL;
939 ITextRange *txtRge = NULL;
940 HRESULT hres;
941 int first, lim, start, end;
942 static const CHAR test_text1[] = "TestSomeText";
944 create_interfaces(&w, &reOle, &txtDoc, NULL);
945 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
947 first = 1; lim = 6;
948 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
949 ok(hres == S_OK, "got 0x%08x\n", hres);
950 start = 0xdeadbeef;
951 hres = ITextRange_GetStart(txtRge, &start);
952 ok(hres == S_OK, "ITextRange_GetStart\n");
953 ok(start == 1, "got wrong start value: %d\n", start);
954 end = 0xdeadbeef;
955 hres = ITextRange_GetEnd(txtRge, &end);
956 ok(hres == S_OK, "ITextRange_GetEnd\n");
957 ok(end == 6, "got wrong end value: %d\n", end);
958 ITextRange_Release(txtRge);
960 first = 6; lim = 1;
961 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
962 ok(hres == S_OK, "got 0x%08x\n", hres);
963 start = 0xdeadbeef;
964 hres = ITextRange_GetStart(txtRge, &start);
965 ok(hres == S_OK, "ITextRange_GetStart\n");
966 ok(start == 1, "got wrong start value: %d\n", start);
967 end = 0xdeadbeef;
968 hres = ITextRange_GetEnd(txtRge, &end);
969 ok(hres == S_OK, "ITextRange_GetEnd\n");
970 ok(end == 6, "got wrong end value: %d\n", end);
971 ITextRange_Release(txtRge);
973 first = -1; lim = 13;
974 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
975 ok(hres == S_OK, "got 0x%08x\n", hres);
976 start = 0xdeadbeef;
977 hres = ITextRange_GetStart(txtRge, &start);
978 ok(hres == S_OK, "ITextRange_GetStart\n");
979 ok(start == 0, "got wrong start value: %d\n", start);
980 end = 0xdeadbeef;
981 hres = ITextRange_GetEnd(txtRge, &end);
982 ok(hres == S_OK, "ITextRange_GetEnd\n");
983 ok(end == 13, "got wrong end value: %d\n", end);
984 ITextRange_Release(txtRge);
986 first = 13; lim = 13;
987 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
988 ok(hres == S_OK, "got 0x%08x\n", hres);
989 start = 0xdeadbeef;
990 hres = ITextRange_GetStart(txtRge, &start);
991 ok(hres == S_OK, "ITextRange_GetStart\n");
992 ok(start == 12, "got wrong start value: %d\n", start);
993 end = 0xdeadbeef;
994 hres = ITextRange_GetEnd(txtRge, &end);
995 ok(hres == S_OK, "ITextRange_GetEnd\n");
996 ok(end == 12, "got wrong end value: %d\n", end);
998 /* SetStart */
999 hres = ITextRange_SetStart(txtRge, 0);
1000 ok(hres == S_OK, "got 0x%08x\n", hres);
1002 /* same value */
1003 hres = ITextRange_SetStart(txtRge, 0);
1004 ok(hres == S_FALSE, "got 0x%08x\n", hres);
1006 hres = ITextRange_SetStart(txtRge, 1);
1007 ok(hres == S_OK, "got 0x%08x\n", hres);
1009 /* negative resets to 0, return value is S_FALSE when
1010 position wasn't changed */
1011 hres = ITextRange_SetStart(txtRge, -1);
1012 ok(hres == S_OK, "got 0x%08x\n", hres);
1014 hres = ITextRange_SetStart(txtRge, -1);
1015 ok(hres == S_FALSE, "got 0x%08x\n", hres);
1017 hres = ITextRange_SetStart(txtRge, 0);
1018 ok(hres == S_FALSE, "got 0x%08x\n", hres);
1020 start = -1;
1021 hres = ITextRange_GetStart(txtRge, &start);
1022 ok(hres == S_OK, "got 0x%08x\n", hres);
1023 ok(start == 0, "got %d\n", start);
1025 /* greater than initial end, but less than total char count */
1026 hres = ITextRange_SetStart(txtRge, 1);
1027 ok(hres == S_OK, "got 0x%08x\n", hres);
1029 hres = ITextRange_SetEnd(txtRge, 3);
1030 ok(hres == S_OK, "got 0x%08x\n", hres);
1032 hres = ITextRange_SetStart(txtRge, 10);
1033 ok(hres == S_OK, "got 0x%08x\n", hres);
1035 start = 0;
1036 hres = ITextRange_GetStart(txtRge, &start);
1037 ok(hres == S_OK, "got 0x%08x\n", hres);
1038 ok(start == 10, "got %d\n", start);
1040 end = 0;
1041 hres = ITextRange_GetEnd(txtRge, &end);
1042 ok(hres == S_OK, "got 0x%08x\n", hres);
1043 ok(end == 10, "got %d\n", end);
1045 /* more that total text length */
1046 hres = ITextRange_SetStart(txtRge, 50);
1047 ok(hres == S_OK, "got 0x%08x\n", hres);
1049 start = 0;
1050 hres = ITextRange_GetStart(txtRge, &start);
1051 ok(hres == S_OK, "got 0x%08x\n", hres);
1052 ok(start == 12, "got %d\n", start);
1054 end = 0;
1055 hres = ITextRange_GetEnd(txtRge, &end);
1056 ok(hres == S_OK, "got 0x%08x\n", hres);
1057 ok(end == 12, "got %d\n", end);
1059 /* SetEnd */
1060 hres = ITextRange_SetStart(txtRge, 0);
1061 ok(hres == S_OK, "got 0x%08x\n", hres);
1063 /* same value */
1064 hres = ITextRange_SetEnd(txtRge, 5);
1065 ok(hres == S_OK, "got 0x%08x\n", hres);
1067 hres = ITextRange_SetEnd(txtRge, 5);
1068 ok(hres == S_FALSE, "got 0x%08x\n", hres);
1070 /* negative resets to 0 */
1071 hres = ITextRange_SetEnd(txtRge, -1);
1072 ok(hres == S_OK, "got 0x%08x\n", hres);
1074 end = -1;
1075 hres = ITextRange_GetEnd(txtRge, &end);
1076 ok(hres == S_OK, "got 0x%08x\n", hres);
1077 ok(end == 0, "got %d\n", end);
1079 start = -1;
1080 hres = ITextRange_GetStart(txtRge, &start);
1081 ok(hres == S_OK, "got 0x%08x\n", hres);
1082 ok(start == 0, "got %d\n", start);
1084 /* greater than initial end, but less than total char count */
1085 hres = ITextRange_SetStart(txtRge, 3);
1086 ok(hres == S_OK, "got 0x%08x\n", hres);
1088 hres = ITextRange_SetEnd(txtRge, 1);
1089 ok(hres == S_OK, "got 0x%08x\n", hres);
1091 start = 0;
1092 hres = ITextRange_GetStart(txtRge, &start);
1093 ok(hres == S_OK, "got 0x%08x\n", hres);
1094 ok(start == 1, "got %d\n", start);
1096 end = 0;
1097 hres = ITextRange_GetEnd(txtRge, &end);
1098 ok(hres == S_OK, "got 0x%08x\n", hres);
1099 ok(end == 1, "got %d\n", end);
1101 /* more than total count */
1102 hres = ITextRange_SetEnd(txtRge, 50);
1103 ok(hres == S_OK, "got 0x%08x\n", hres);
1105 start = 0;
1106 hres = ITextRange_GetStart(txtRge, &start);
1107 ok(hres == S_OK, "got 0x%08x\n", hres);
1108 ok(start == 1, "got %d\n", start);
1110 end = 0;
1111 hres = ITextRange_GetEnd(txtRge, &end);
1112 ok(hres == S_OK, "got 0x%08x\n", hres);
1113 ok(end == 13, "got %d\n", end);
1115 /* zero */
1116 hres = ITextRange_SetEnd(txtRge, 0);
1117 ok(hres == S_OK, "got 0x%08x\n", hres);
1119 start = 0;
1120 hres = ITextRange_GetStart(txtRge, &start);
1121 ok(hres == S_OK, "got 0x%08x\n", hres);
1122 ok(start == 0, "got %d\n", start);
1124 end = 0;
1125 hres = ITextRange_GetEnd(txtRge, &end);
1126 ok(hres == S_OK, "got 0x%08x\n", hres);
1127 ok(end == 0, "got %d\n", end);
1129 release_interfaces(&w, &reOle, &txtDoc, NULL);
1131 /* detached range */
1132 hres = ITextRange_SetStart(txtRge, 0);
1133 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1135 hres = ITextRange_SetEnd(txtRge, 3);
1136 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1138 hres = ITextRange_GetStart(txtRge, &start);
1139 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1141 hres = ITextRange_GetStart(txtRge, NULL);
1142 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1144 hres = ITextRange_GetEnd(txtRge, &end);
1145 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1147 hres = ITextRange_GetEnd(txtRge, NULL);
1148 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1150 ITextRange_Release(txtRge);
1153 static void test_ITextSelection_GetStart_GetEnd(void)
1155 HWND w;
1156 IRichEditOle *reOle = NULL;
1157 ITextDocument *txtDoc = NULL;
1158 ITextSelection *txtSel = NULL;
1159 HRESULT hres;
1160 int first, lim, start, end;
1161 static const CHAR test_text1[] = "TestSomeText";
1163 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
1164 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
1166 first = 2; lim = 5;
1167 SendMessageA(w, EM_SETSEL, first, lim);
1168 start = 0xdeadbeef;
1169 hres = ITextSelection_GetStart(txtSel, &start);
1170 ok(hres == S_OK, "ITextSelection_GetStart\n");
1171 ok(start == 2, "got wrong start value: %d\n", start);
1172 end = 0xdeadbeef;
1173 hres = ITextSelection_GetEnd(txtSel, &end);
1174 ok(hres == S_OK, "ITextSelection_GetEnd\n");
1175 ok(end == 5, "got wrong end value: %d\n", end);
1177 first = 5; lim = 2;
1178 SendMessageA(w, EM_SETSEL, first, lim);
1179 start = 0xdeadbeef;
1180 hres = ITextSelection_GetStart(txtSel, &start);
1181 ok(hres == S_OK, "ITextSelection_GetStart\n");
1182 ok(start == 2, "got wrong start value: %d\n", start);
1183 end = 0xdeadbeef;
1184 hres = ITextSelection_GetEnd(txtSel, &end);
1185 ok(hres == S_OK, "ITextSelection_GetEnd\n");
1186 ok(end == 5, "got wrong end value: %d\n", end);
1188 first = 0; lim = -1;
1189 SendMessageA(w, EM_SETSEL, first, lim);
1190 start = 0xdeadbeef;
1191 hres = ITextSelection_GetStart(txtSel, &start);
1192 ok(hres == S_OK, "ITextSelection_GetStart\n");
1193 ok(start == 0, "got wrong start value: %d\n", start);
1194 end = 0xdeadbeef;
1195 hres = ITextSelection_GetEnd(txtSel, &end);
1196 ok(hres == S_OK, "ITextSelection_GetEnd\n");
1197 ok(end == 13, "got wrong end value: %d\n", end);
1199 first = 13; lim = 13;
1200 SendMessageA(w, EM_SETSEL, first, lim);
1201 start = 0xdeadbeef;
1202 hres = ITextSelection_GetStart(txtSel, &start);
1203 ok(hres == S_OK, "ITextSelection_GetStart\n");
1204 ok(start == 12, "got wrong start value: %d\n", start);
1205 end = 0xdeadbeef;
1206 hres = ITextSelection_GetEnd(txtSel, &end);
1207 ok(hres == S_OK, "ITextSelection_GetEnd\n");
1208 ok(end == 12, "got wrong end value: %d\n", end);
1210 /* SetStart/SetEnd */
1211 hres = ITextSelection_SetStart(txtSel, 0);
1212 ok(hres == S_OK, "got 0x%08x\n", hres);
1214 /* same value */
1215 hres = ITextSelection_SetStart(txtSel, 0);
1216 ok(hres == S_FALSE, "got 0x%08x\n", hres);
1218 hres = ITextSelection_SetStart(txtSel, 1);
1219 ok(hres == S_OK, "got 0x%08x\n", hres);
1221 /* negative resets to 0, return value is S_FALSE when
1222 position wasn't changed */
1223 hres = ITextSelection_SetStart(txtSel, -1);
1224 ok(hres == S_OK, "got 0x%08x\n", hres);
1226 hres = ITextSelection_SetStart(txtSel, -1);
1227 ok(hres == S_FALSE, "got 0x%08x\n", hres);
1229 hres = ITextSelection_SetStart(txtSel, 0);
1230 ok(hres == S_FALSE, "got 0x%08x\n", hres);
1232 start = -1;
1233 hres = ITextSelection_GetStart(txtSel, &start);
1234 ok(hres == S_OK, "got 0x%08x\n", hres);
1235 ok(start == 0, "got %d\n", start);
1237 /* greater than initial end, but less than total char count */
1238 hres = ITextSelection_SetStart(txtSel, 1);
1239 ok(hres == S_OK, "got 0x%08x\n", hres);
1241 hres = ITextSelection_SetEnd(txtSel, 3);
1242 ok(hres == S_OK, "got 0x%08x\n", hres);
1244 hres = ITextSelection_SetStart(txtSel, 10);
1245 ok(hres == S_OK, "got 0x%08x\n", hres);
1247 start = 0;
1248 hres = ITextSelection_GetStart(txtSel, &start);
1249 ok(hres == S_OK, "got 0x%08x\n", hres);
1250 ok(start == 10, "got %d\n", start);
1252 end = 0;
1253 hres = ITextSelection_GetEnd(txtSel, &end);
1254 ok(hres == S_OK, "got 0x%08x\n", hres);
1255 ok(end == 10, "got %d\n", end);
1257 /* more that total text length */
1258 hres = ITextSelection_SetStart(txtSel, 50);
1259 ok(hres == S_OK, "got 0x%08x\n", hres);
1261 start = 0;
1262 hres = ITextSelection_GetStart(txtSel, &start);
1263 ok(hres == S_OK, "got 0x%08x\n", hres);
1264 ok(start == 12, "got %d\n", start);
1266 end = 0;
1267 hres = ITextSelection_GetEnd(txtSel, &end);
1268 ok(hres == S_OK, "got 0x%08x\n", hres);
1269 ok(end == 12, "got %d\n", end);
1271 /* SetEnd */
1272 hres = ITextSelection_SetStart(txtSel, 0);
1273 ok(hres == S_OK, "got 0x%08x\n", hres);
1275 /* same value */
1276 hres = ITextSelection_SetEnd(txtSel, 5);
1277 ok(hres == S_OK, "got 0x%08x\n", hres);
1279 hres = ITextSelection_SetEnd(txtSel, 5);
1280 ok(hres == S_FALSE, "got 0x%08x\n", hres);
1282 /* negative resets to 0 */
1283 hres = ITextSelection_SetEnd(txtSel, -1);
1284 ok(hres == S_OK, "got 0x%08x\n", hres);
1286 end = -1;
1287 hres = ITextSelection_GetEnd(txtSel, &end);
1288 ok(hres == S_OK, "got 0x%08x\n", hres);
1289 ok(end == 0, "got %d\n", end);
1291 start = -1;
1292 hres = ITextSelection_GetStart(txtSel, &start);
1293 ok(hres == S_OK, "got 0x%08x\n", hres);
1294 ok(start == 0, "got %d\n", start);
1296 /* greater than initial end, but less than total char count */
1297 hres = ITextSelection_SetStart(txtSel, 3);
1298 ok(hres == S_OK, "got 0x%08x\n", hres);
1300 hres = ITextSelection_SetEnd(txtSel, 1);
1301 ok(hres == S_OK, "got 0x%08x\n", hres);
1303 start = 0;
1304 hres = ITextSelection_GetStart(txtSel, &start);
1305 ok(hres == S_OK, "got 0x%08x\n", hres);
1306 ok(start == 1, "got %d\n", start);
1308 end = 0;
1309 hres = ITextSelection_GetEnd(txtSel, &end);
1310 ok(hres == S_OK, "got 0x%08x\n", hres);
1311 ok(end == 1, "got %d\n", end);
1313 /* more than total count */
1314 hres = ITextSelection_SetEnd(txtSel, 50);
1315 ok(hres == S_OK, "got 0x%08x\n", hres);
1317 start = 0;
1318 hres = ITextSelection_GetStart(txtSel, &start);
1319 ok(hres == S_OK, "got 0x%08x\n", hres);
1320 ok(start == 1, "got %d\n", start);
1322 end = 0;
1323 hres = ITextSelection_GetEnd(txtSel, &end);
1324 ok(hres == S_OK, "got 0x%08x\n", hres);
1325 ok(end == 13, "got %d\n", end);
1327 /* zero */
1328 hres = ITextSelection_SetEnd(txtSel, 0);
1329 ok(hres == S_OK, "got 0x%08x\n", hres);
1331 start = 0;
1332 hres = ITextSelection_GetStart(txtSel, &start);
1333 ok(hres == S_OK, "got 0x%08x\n", hres);
1334 ok(start == 0, "got %d\n", start);
1336 end = 0;
1337 hres = ITextSelection_GetEnd(txtSel, &end);
1338 ok(hres == S_OK, "got 0x%08x\n", hres);
1339 ok(end == 0, "got %d\n", end);
1341 release_interfaces(&w, &reOle, &txtDoc, NULL);
1343 /* detached selection */
1344 hres = ITextSelection_GetStart(txtSel, NULL);
1345 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1347 hres = ITextSelection_GetStart(txtSel, &start);
1348 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1350 hres = ITextSelection_GetEnd(txtSel, NULL);
1351 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1353 hres = ITextSelection_GetEnd(txtSel, &end);
1354 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1356 ITextSelection_Release(txtSel);
1359 static void test_ITextRange_GetDuplicate(void)
1361 HWND w;
1362 IRichEditOle *reOle = NULL;
1363 ITextDocument *txtDoc = NULL;
1364 ITextRange *txtRge = NULL;
1365 ITextRange *txtRgeDup = NULL;
1366 HRESULT hres;
1367 LONG first, lim, start, end;
1368 static const CHAR test_text1[] = "TestSomeText";
1370 create_interfaces(&w, &reOle, &txtDoc, NULL);
1371 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
1372 first = 0; lim = 4;
1373 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
1374 ok(hres == S_OK, "ITextDocument_Range fails 0x%x.\n", hres);
1376 hres = ITextRange_GetDuplicate(txtRge, &txtRgeDup);
1377 ok(hres == S_OK, "ITextRange_GetDuplicate\n");
1378 ok(txtRgeDup != txtRge, "A new pointer should be returned\n");
1379 hres = ITextRange_GetStart(txtRgeDup, &start);
1380 ok(hres == S_OK, "got 0x%08x\n", hres);
1381 ok(start == first, "got wrong value: %d\n", start);
1382 hres = ITextRange_GetEnd(txtRgeDup, &end);
1383 ok(hres == S_OK, "got 0x%08x\n", hres);
1384 ok(end == lim, "got wrong value: %d\n", end);
1386 ITextRange_Release(txtRgeDup);
1388 hres = ITextRange_GetDuplicate(txtRge, NULL);
1389 ok(hres == E_INVALIDARG, "ITextRange_GetDuplicate\n");
1391 release_interfaces(&w, &reOle, &txtDoc, NULL);
1393 hres = ITextRange_GetDuplicate(txtRge, NULL);
1394 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1396 hres = ITextRange_GetDuplicate(txtRge, &txtRgeDup);
1397 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1399 ITextRange_Release(txtRge);
1402 static void test_ITextRange_Collapse(void)
1404 HWND w;
1405 IRichEditOle *reOle = NULL;
1406 ITextDocument *txtDoc = NULL;
1407 ITextRange *txtRge = NULL;
1408 HRESULT hres;
1409 LONG first, lim, start, end;
1410 static const CHAR test_text1[] = "TestSomeText";
1412 create_interfaces(&w, &reOle, &txtDoc, NULL);
1413 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
1415 first = 4; lim = 8;
1416 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
1417 ok(hres == S_OK, "got 0x%08x\n", hres);
1418 hres = ITextRange_Collapse(txtRge, tomTrue);
1419 ok(hres == S_OK, "ITextRange_Collapse\n");
1420 hres = ITextRange_GetStart(txtRge, &start);
1421 ok(hres == S_OK, "got 0x%08x\n", hres);
1422 ok(start == 4, "got wrong start value: %d\n", start);
1423 hres = ITextRange_GetEnd(txtRge, &end);
1424 ok(hres == S_OK, "got 0x%08x\n", hres);
1425 ok(end == 4, "got wrong end value: %d\n", end);
1426 ITextRange_Release(txtRge);
1428 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
1429 ok(hres == S_OK, "got 0x%08x\n", hres);
1430 hres = ITextRange_Collapse(txtRge, tomStart);
1431 ok(hres == S_OK, "ITextRange_Collapse\n");
1432 hres = ITextRange_GetStart(txtRge, &start);
1433 ok(hres == S_OK, "got 0x%08x\n", hres);
1434 ok(start == 4, "got wrong start value: %d\n", start);
1435 hres = ITextRange_GetEnd(txtRge, &end);
1436 ok(hres == S_OK, "got 0x%08x\n", hres);
1437 ok(end == 4, "got wrong end value: %d\n", end);
1438 ITextRange_Release(txtRge);
1440 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
1441 ok(hres == S_OK, "got 0x%08x\n", hres);
1442 hres = ITextRange_Collapse(txtRge, tomFalse);
1443 ok(hres == S_OK, "ITextRange_Collapse\n");
1444 hres = ITextRange_GetStart(txtRge, &start);
1445 ok(hres == S_OK, "got 0x%08x\n", hres);
1446 ok(start == 8, "got wrong start value: %d\n", start);
1447 hres = ITextRange_GetEnd(txtRge, &end);
1448 ok(hres == S_OK, "got 0x%08x\n", hres);
1449 ok(end == 8, "got wrong end value: %d\n", end);
1450 ITextRange_Release(txtRge);
1452 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
1453 ok(hres == S_OK, "got 0x%08x\n", hres);
1454 hres = ITextRange_Collapse(txtRge, tomEnd);
1455 ok(hres == S_OK, "ITextRange_Collapse\n");
1456 hres = ITextRange_GetStart(txtRge, &start);
1457 ok(hres == S_OK, "got 0x%08x\n", hres);
1458 ok(start == 8, "got wrong start value: %d\n", start);
1459 hres = ITextRange_GetEnd(txtRge, &end);
1460 ok(hres == S_OK, "got 0x%08x\n", hres);
1461 ok(end == 8, "got wrong end value: %d\n", end);
1462 ITextRange_Release(txtRge);
1464 /* tomStart is the default */
1465 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
1466 ok(hres == S_OK, "got 0x%08x\n", hres);
1467 hres = ITextRange_Collapse(txtRge, 256);
1468 ok(hres == S_OK, "ITextRange_Collapse\n");
1469 hres = ITextRange_GetStart(txtRge, &start);
1470 ok(hres == S_OK, "got 0x%08x\n", hres);
1471 ok(start == 4, "got wrong start value: %d\n", start);
1472 hres = ITextRange_GetEnd(txtRge, &end);
1473 ok(hres == S_OK, "got 0x%08x\n", hres);
1474 ok(end == 4, "got wrong end value: %d\n", end);
1475 ITextRange_Release(txtRge);
1477 first = 6; lim = 6;
1478 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
1479 ok(hres == S_OK, "got 0x%08x\n", hres);
1480 hres = ITextRange_Collapse(txtRge, tomEnd);
1481 ok(hres == S_FALSE, "ITextRange_Collapse\n");
1482 hres = ITextRange_GetStart(txtRge, &start);
1483 ok(hres == S_OK, "got 0x%08x\n", hres);
1484 ok(start == 6, "got wrong start value: %d\n", start);
1485 hres = ITextRange_GetEnd(txtRge, &end);
1486 ok(hres == S_OK, "got 0x%08x\n", hres);
1487 ok(end == 6, "got wrong end value: %d\n", end);
1488 ITextRange_Release(txtRge);
1490 first = 8; lim = 8;
1491 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
1492 ok(hres == S_OK, "got 0x%08x\n", hres);
1493 hres = ITextRange_Collapse(txtRge, tomStart);
1494 ok(hres == S_FALSE, "ITextRange_Collapse\n");
1495 hres = ITextRange_GetStart(txtRge, &start);
1496 ok(hres == S_OK, "got 0x%08x\n", hres);
1497 ok(start == 8, "got wrong start value: %d\n", start);
1498 hres = ITextRange_GetEnd(txtRge, &end);
1499 ok(hres == S_OK, "got 0x%08x\n", hres);
1500 ok(end == 8, "got wrong end value: %d\n", end);
1502 release_interfaces(&w, &reOle, &txtDoc, NULL);
1504 hres = ITextRange_Collapse(txtRge, tomStart);
1505 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1507 hres = ITextRange_Collapse(txtRge, tomUndefined);
1508 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1510 ITextRange_Release(txtRge);
1513 static void test_ITextSelection_Collapse(void)
1515 HWND w;
1516 IRichEditOle *reOle = NULL;
1517 ITextDocument *txtDoc = NULL;
1518 ITextSelection *txtSel = NULL;
1519 HRESULT hres;
1520 LONG first, lim, start, end;
1521 static const CHAR test_text1[] = "TestSomeText";
1523 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
1524 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
1526 first = 4; lim = 8;
1527 SendMessageA(w, EM_SETSEL, first, lim);
1528 hres = ITextSelection_Collapse(txtSel, tomTrue);
1529 ok(hres == S_OK, "ITextSelection_Collapse\n");
1530 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1531 ok(start == 4, "got wrong start value: %d\n", start);
1532 ok(end == 4, "got wrong end value: %d\n", end);
1534 SendMessageA(w, EM_SETSEL, first, lim);
1535 hres = ITextSelection_Collapse(txtSel, tomStart);
1536 ok(hres == S_OK, "ITextSelection_Collapse\n");
1537 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1538 ok(start == 4, "got wrong start value: %d\n", start);
1539 ok(end == 4, "got wrong end value: %d\n", end);
1541 SendMessageA(w, EM_SETSEL, first, lim);
1542 hres = ITextSelection_Collapse(txtSel, tomFalse);
1543 ok(hres == S_OK, "ITextSelection_Collapse\n");
1544 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1545 ok(start == 8, "got wrong start value: %d\n", start);
1546 ok(end == 8, "got wrong end value: %d\n", end);
1548 SendMessageA(w, EM_SETSEL, first, lim);
1549 hres = ITextSelection_Collapse(txtSel, tomEnd);
1550 ok(hres == S_OK, "ITextSelection_Collapse\n");
1551 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1552 ok(start == 8, "got wrong start value: %d\n", start);
1553 ok(end == 8, "got wrong end value: %d\n", end);
1555 /* tomStart is the default */
1556 SendMessageA(w, EM_SETSEL, first, lim);
1557 hres = ITextSelection_Collapse(txtSel, 256);
1558 ok(hres == S_OK, "ITextSelection_Collapse\n");
1559 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1560 ok(start == 4, "got wrong start value: %d\n", start);
1561 ok(end == 4, "got wrong end value: %d\n", end);
1563 first = 6; lim = 6;
1564 SendMessageA(w, EM_SETSEL, first, lim);
1565 hres = ITextSelection_Collapse(txtSel, tomEnd);
1566 ok(hres == S_FALSE, "ITextSelection_Collapse\n");
1567 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1568 ok(start == 6, "got wrong start value: %d\n", start);
1569 ok(end == 6, "got wrong end value: %d\n", end);
1571 first = 8; lim = 8;
1572 SendMessageA(w, EM_SETSEL, first, lim);
1573 hres = ITextSelection_Collapse(txtSel, tomStart);
1574 ok(hres == S_FALSE, "ITextSelection_Collapse\n");
1575 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1576 ok(start == 8, "got wrong start value: %d\n", start);
1577 ok(end == 8, "got wrong end value: %d\n", end);
1579 release_interfaces(&w, &reOle, &txtDoc, NULL);
1581 hres = ITextSelection_Collapse(txtSel, tomStart);
1582 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1584 hres = ITextSelection_Collapse(txtSel, tomUndefined);
1585 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1587 ITextSelection_Release(txtSel);
1590 static void test_GetClientSite(void)
1592 HWND w;
1593 IRichEditOle *reOle = NULL, *reOle1 = NULL;
1594 ITextDocument *txtDoc = NULL;
1595 IOleClientSite *clientSite = NULL, *clientSite1 = NULL, *clientSite2 = NULL;
1596 IOleWindow *oleWin = NULL, *oleWin1 = NULL;
1597 IOleInPlaceSite *olePlace = NULL, *olePlace1 = NULL;
1598 HRESULT hres;
1599 LONG refcount1, refcount2;
1601 create_interfaces(&w, &reOle, &txtDoc, NULL);
1602 hres = IRichEditOle_GetClientSite(reOle, &clientSite);
1603 ok(hres == S_OK, "IRichEditOle_QueryInterface: 0x%08x\n", hres);
1604 EXPECT_REF(clientSite, 1);
1606 hres = IOleClientSite_QueryInterface(clientSite, &IID_IRichEditOle, (void **)&reOle1);
1607 ok(hres == E_NOINTERFACE, "IOleClientSite_QueryInterface: %x\n", hres);
1609 hres = IRichEditOle_GetClientSite(reOle, &clientSite1);
1610 ok(hres == S_OK, "got 0x%08x\n", hres);
1611 ok(clientSite != clientSite1, "got %p, %p\n", clientSite, clientSite1);
1612 IOleClientSite_Release(clientSite1);
1614 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleClientSite, (void **)&clientSite1);
1615 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1616 ok(clientSite == clientSite1, "Should not return a new pointer.\n");
1617 EXPECT_REF(clientSite, 2);
1619 /* IOleWindow interface */
1620 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleWindow, (void **)&oleWin);
1621 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1622 refcount1 = get_refcount((IUnknown *)clientSite);
1623 refcount2 = get_refcount((IUnknown *)oleWin);
1624 ok(refcount1 == refcount2, "got wrong ref count.\n");
1626 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleWindow, (void **)&oleWin1);
1627 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1628 ok(oleWin == oleWin1, "Should not return a new pointer.\n");
1629 refcount1 = get_refcount((IUnknown *)clientSite);
1630 refcount2 = get_refcount((IUnknown *)oleWin);
1631 ok(refcount1 == refcount2, "got wrong ref count.\n");
1633 hres = IOleWindow_QueryInterface(oleWin, &IID_IOleClientSite, (void **)&clientSite2);
1634 ok(hres == S_OK, "IOleWindow_QueryInterface: 0x%08x\n", hres);
1635 ok(clientSite2 == clientSite1, "got wrong pointer\n");
1637 /* IOleInPlaceSite interface */
1638 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleInPlaceSite, (void **)&olePlace);
1639 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1640 refcount1 = get_refcount((IUnknown *)olePlace);
1641 refcount2 = get_refcount((IUnknown *)clientSite);
1642 ok(refcount1 == refcount2, "got wrong ref count.\n");
1644 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleInPlaceSite, (void **)&olePlace1);
1645 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1646 ok(olePlace == olePlace1, "Should not return a new pointer.\n");
1647 IOleInPlaceSite_Release(olePlace1);
1649 hres = IOleWindow_QueryInterface(oleWin, &IID_IOleInPlaceSite, (void **)&olePlace1);
1650 ok(hres == S_OK, "IOleWindow_QueryInterface: 0x%08x\n", hres);
1651 refcount1 = get_refcount((IUnknown *)olePlace1);
1652 refcount2 = get_refcount((IUnknown *)oleWin);
1653 ok(refcount1 == refcount2, "got wrong ref count.\n");
1655 IOleInPlaceSite_Release(olePlace1);
1656 IOleInPlaceSite_Release(olePlace);
1657 IOleWindow_Release(oleWin1);
1658 IOleWindow_Release(oleWin);
1659 IOleClientSite_Release(clientSite2);
1660 IOleClientSite_Release(clientSite1);
1661 IOleClientSite_Release(clientSite);
1662 release_interfaces(&w, &reOle, &txtDoc, NULL);
1665 static void test_IOleWindow_GetWindow(void)
1667 HWND w;
1668 IRichEditOle *reOle = NULL;
1669 ITextDocument *txtDoc = NULL;
1670 IOleClientSite *clientSite = NULL;
1671 IOleWindow *oleWin = NULL;
1672 HRESULT hres;
1673 HWND hwnd;
1675 create_interfaces(&w, &reOle, &txtDoc, NULL);
1676 hres = IRichEditOle_GetClientSite(reOle, &clientSite);
1677 ok(hres == S_OK, "IRichEditOle_QueryInterface: 0x%08x\n", hres);
1679 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleWindow, (void **)&oleWin);
1680 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1681 hres = IOleWindow_GetWindow(oleWin, &hwnd);
1682 ok(hres == S_OK, "IOleClientSite_GetWindow: 0x%08x\n", hres);
1683 ok(w == hwnd, "got wrong pointer\n");
1685 hres = IOleWindow_GetWindow(oleWin, NULL);
1686 ok(hres == E_INVALIDARG, "IOleClientSite_GetWindow: 0x%08x\n", hres);
1688 IOleWindow_Release(oleWin);
1689 IOleClientSite_Release(clientSite);
1690 release_interfaces(&w, &reOle, &txtDoc, NULL);
1693 static void test_IOleInPlaceSite_GetWindow(void)
1695 HWND w;
1696 IRichEditOle *reOle = NULL;
1697 ITextDocument *txtDoc = NULL;
1698 IOleClientSite *clientSite = NULL;
1699 IOleInPlaceSite *olePlace = NULL;
1700 HRESULT hres;
1701 HWND hwnd;
1703 create_interfaces(&w, &reOle, &txtDoc, NULL);
1704 hres = IRichEditOle_GetClientSite(reOle, &clientSite);
1705 ok(hres == S_OK, "IRichEditOle_QueryInterface: 0x%08x\n", hres);
1707 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleInPlaceSite, (void **)&olePlace);
1708 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1709 hres = IOleInPlaceSite_GetWindow(olePlace, &hwnd);
1710 ok(hres == S_OK, "IOleInPlaceSite_GetWindow: 0x%08x\n", hres);
1711 ok(w == hwnd, "got wrong pointer.\n");
1713 hres = IOleInPlaceSite_GetWindow(olePlace, NULL);
1714 ok(hres == E_INVALIDARG, "IOleInPlaceSite_GetWindow: 0x%08x\n", hres);
1716 IOleInPlaceSite_Release(olePlace);
1717 IOleClientSite_Release(clientSite);
1718 release_interfaces(&w, &reOle, &txtDoc, NULL);
1721 static void test_GetFont(void)
1723 static const CHAR test_text1[] = "TestSomeText";
1724 IRichEditOle *reOle = NULL;
1725 ITextDocument *doc = NULL;
1726 ITextRange *range = NULL;
1727 ITextSelection *selection;
1728 ITextFont *font, *font2;
1729 CHARFORMAT2A cf;
1730 LONG value;
1731 float size;
1732 HRESULT hr;
1733 HWND hwnd;
1734 BOOL ret;
1736 create_interfaces(&hwnd, &reOle, &doc, NULL);
1737 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
1739 hr = ITextDocument_GetSelection(doc, &selection);
1740 ok(hr == S_OK, "got 0x%08x\n", hr);
1741 hr = ITextSelection_GetFont(selection, &font);
1742 ok(hr == S_OK, "got 0x%08x\n", hr);
1743 hr = ITextSelection_GetFont(selection, &font2);
1744 ok(hr == S_OK, "got 0x%08x\n", hr);
1745 ok(font != font2, "got %p, %p\n", font, font2);
1746 ITextFont_Release(font2);
1747 ITextFont_Release(font);
1748 ITextSelection_Release(selection);
1750 EXPECT_REF(reOle, 3);
1751 EXPECT_REF(doc, 3);
1753 hr = ITextDocument_Range(doc, 0, 4, &range);
1754 ok(hr == S_OK, "got 0x%08x\n", hr);
1756 EXPECT_REF(reOle, 3);
1757 EXPECT_REF(doc, 3);
1758 EXPECT_REF(range, 1);
1760 hr = ITextRange_GetFont(range, NULL);
1761 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1763 hr = ITextRange_GetFont(range, &font);
1764 ok(hr == S_OK, "got 0x%08x\n", hr);
1766 EXPECT_REF(reOle, 3);
1767 EXPECT_REF(doc, 3);
1768 EXPECT_REF(range, 2);
1769 EXPECT_REF(font, 1);
1771 hr = ITextRange_GetFont(range, &font2);
1772 ok(hr == S_OK, "got 0x%08x\n", hr);
1773 ok(font != font2, "got %p, %p\n", font, font2);
1775 EXPECT_REF(reOle, 3);
1776 EXPECT_REF(doc, 3);
1777 EXPECT_REF(range, 3);
1778 EXPECT_REF(font, 1);
1779 EXPECT_REF(font2, 1);
1781 ITextFont_Release(font2);
1783 /* set different font style within a range */
1784 hr = ITextFont_GetItalic(font, NULL);
1785 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1787 hr = ITextFont_GetSize(font, NULL);
1788 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1790 size = 0.0;
1791 hr = ITextFont_GetSize(font, &size);
1792 ok(hr == S_OK, "got 0x%08x\n", hr);
1793 ok(size > 0.0, "size %.2f\n", size);
1795 value = 0;
1796 hr = ITextFont_GetLanguageID(font, &value);
1797 ok(hr == S_OK, "got 0x%08x\n", hr);
1798 ok(value == GetSystemDefaultLCID(), "got lcid %x, user lcid %x\n", value,
1799 GetSystemDefaultLCID());
1801 /* range is non-italic */
1802 value = tomTrue;
1803 hr = ITextFont_GetItalic(font, &value);
1804 ok(hr == S_OK, "got 0x%08x\n", hr);
1805 ok(value == tomFalse, "got %d\n", value);
1807 cf.cbSize = sizeof(CHARFORMAT2A);
1808 cf.dwMask = CFM_ITALIC|CFM_SIZE;
1809 cf.dwEffects = CFE_ITALIC;
1810 cf.yHeight = 24.0;
1812 SendMessageA(hwnd, EM_SETSEL, 2, 3);
1813 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
1814 ok(ret, "got %d\n", ret);
1816 /* now range is partially italicized */
1817 value = tomFalse;
1818 hr = ITextFont_GetItalic(font, &value);
1819 ok(hr == S_OK, "got 0x%08x\n", hr);
1820 ok(value == tomUndefined, "got %d\n", value);
1822 size = 0.0;
1823 hr = ITextFont_GetSize(font, &size);
1824 ok(hr == S_OK, "got 0x%08x\n", hr);
1825 ok(size == tomUndefined, "size %.2f\n", size);
1827 ITextFont_Release(font);
1828 release_interfaces(&hwnd, &reOle, &doc, NULL);
1830 hr = ITextRange_GetFont(range, NULL);
1831 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
1833 hr = ITextRange_GetFont(range, &font2);
1834 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
1836 ITextRange_Release(range);
1839 static void test_GetPara(void)
1841 static const CHAR test_text1[] = "TestSomeText";
1842 IRichEditOle *reOle = NULL;
1843 ITextDocument *doc = NULL;
1844 ITextSelection *selection;
1845 ITextRange *range = NULL;
1846 ITextPara *para, *para2;
1847 HRESULT hr;
1848 HWND hwnd;
1850 create_interfaces(&hwnd, &reOle, &doc, &selection);
1851 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
1853 EXPECT_REF(reOle, 3);
1854 EXPECT_REF(doc, 3);
1856 hr = ITextDocument_Range(doc, 0, 4, &range);
1857 ok(hr == S_OK, "got 0x%08x\n", hr);
1859 EXPECT_REF(reOle, 3);
1860 EXPECT_REF(doc, 3);
1861 EXPECT_REF(range, 1);
1863 hr = ITextRange_GetPara(range, NULL);
1864 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1866 hr = ITextRange_GetPara(range, &para);
1867 ok(hr == S_OK, "got 0x%08x\n", hr);
1869 EXPECT_REF(reOle, 3);
1870 EXPECT_REF(doc, 3);
1871 EXPECT_REF(range, 2);
1872 EXPECT_REF(para, 1);
1874 hr = ITextRange_GetPara(range, &para2);
1875 ok(hr == S_OK, "got 0x%08x\n", hr);
1876 ok(para != para2, "got %p, %p\n", para, para2);
1878 EXPECT_REF(reOle, 3);
1879 EXPECT_REF(doc, 3);
1880 EXPECT_REF(range, 3);
1881 EXPECT_REF(para, 1);
1882 EXPECT_REF(para2, 1);
1884 ITextPara_Release(para);
1885 ITextPara_Release(para2);
1887 EXPECT_REF(reOle, 3);
1888 EXPECT_REF(doc, 3);
1889 EXPECT_REF(selection, 2);
1891 hr = ITextSelection_GetPara(selection, &para);
1892 ok(hr == S_OK, "got 0x%08x\n", hr);
1894 EXPECT_REF(reOle, 3);
1895 EXPECT_REF(doc, 3);
1896 EXPECT_REF(selection, 3);
1897 EXPECT_REF(para, 1);
1899 hr = ITextSelection_GetPara(selection, &para2);
1900 ok(hr == S_OK, "got 0x%08x\n", hr);
1901 ok(para != para2, "got %p, %p\n", para, para2);
1903 ITextPara_Release(para);
1904 ITextPara_Release(para2);
1905 release_interfaces(&hwnd, &reOle, &doc, NULL);
1907 hr = ITextRange_GetPara(range, NULL);
1908 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
1910 hr = ITextRange_GetPara(range, &para);
1911 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
1913 hr = ITextSelection_GetPara(selection, NULL);
1914 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
1916 hr = ITextSelection_GetPara(selection, &para);
1917 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
1919 ITextSelection_Release(selection);
1920 ITextRange_Release(range);
1923 static void test_dispatch(void)
1925 static const WCHAR testnameW[] = {'G','e','t','T','e','x','t',0};
1926 static const WCHAR testname2W[] = {'T','e','x','t',0};
1927 IRichEditOle *reOle = NULL;
1928 ITextDocument *doc = NULL;
1929 ITextRange *range = NULL;
1930 WCHAR *nameW;
1931 DISPID dispid;
1932 HRESULT hr;
1933 UINT count;
1934 HWND hwnd;
1936 create_interfaces(&hwnd, &reOle, &doc, NULL);
1938 range = NULL;
1939 hr = ITextDocument_Range(doc, 0, 0, &range);
1940 ok(hr == S_OK, "got 0x%08x\n", hr);
1941 ok(range != NULL, "got %p\n", range);
1943 dispid = 123;
1944 nameW = (WCHAR*)testnameW;
1945 hr = ITextRange_GetIDsOfNames(range, &IID_NULL, &nameW, 1, LOCALE_USER_DEFAULT, &dispid);
1946 ok(hr == DISP_E_UNKNOWNNAME, "got 0x%08x\n", hr);
1947 ok(dispid == DISPID_UNKNOWN, "got %d\n", dispid);
1949 dispid = 123;
1950 nameW = (WCHAR*)testname2W;
1951 hr = ITextRange_GetIDsOfNames(range, &IID_NULL, &nameW, 1, LOCALE_USER_DEFAULT, &dispid);
1952 ok(hr == S_OK, "got 0x%08x\n", hr);
1953 ok(dispid == DISPID_VALUE, "got %d\n", dispid);
1955 release_interfaces(&hwnd, &reOle, &doc, NULL);
1957 /* try dispatch methods on detached range */
1958 hr = ITextRange_GetTypeInfoCount(range, &count);
1959 ok(hr == S_OK, "got 0x%08x\n", hr);
1961 dispid = 123;
1962 nameW = (WCHAR*)testname2W;
1963 hr = ITextRange_GetIDsOfNames(range, &IID_NULL, &nameW, 1, LOCALE_USER_DEFAULT, &dispid);
1964 ok(hr == S_OK, "got 0x%08x\n", hr);
1965 ok(dispid == DISPID_VALUE, "got %d\n", dispid);
1967 ITextRange_Release(range);
1970 static void test_detached_font_getters(ITextFont *font, BOOL duplicate)
1972 HRESULT hr, hrexp = duplicate ? S_OK : CO_E_RELEASED;
1973 LONG value;
1974 float size;
1975 BSTR str;
1977 hr = ITextFont_GetBold(font, NULL);
1978 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1980 hr = ITextFont_GetBold(font, &value);
1981 ok(hr == hrexp, "got 0x%08x\n", hr);
1983 hr = ITextFont_GetForeColor(font, NULL);
1984 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1986 hr = ITextFont_GetForeColor(font, &value);
1987 ok(hr == hrexp, "got 0x%08x\n", hr);
1989 hr = ITextFont_GetItalic(font, NULL);
1990 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1992 hr = ITextFont_GetItalic(font, &value);
1993 ok(hr == hrexp, "got 0x%08x\n", hr);
1995 hr = ITextFont_GetLanguageID(font, NULL);
1996 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1998 hr = ITextFont_GetLanguageID(font, &value);
1999 ok(hr == hrexp, "got 0x%08x\n", hr);
2001 hr = ITextFont_GetName(font, NULL);
2002 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2004 hr = ITextFont_GetName(font, &str);
2005 ok(hr == hrexp, "got 0x%08x\n", hr);
2007 hr = ITextFont_GetSize(font, NULL);
2008 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2010 hr = ITextFont_GetSize(font, &size);
2011 ok(hr == hrexp, "got 0x%08x\n", hr);
2013 hr = ITextFont_GetStrikeThrough(font, NULL);
2014 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2016 hr = ITextFont_GetStrikeThrough(font, &value);
2017 ok(hr == hrexp, "got 0x%08x\n", hr);
2019 hr = ITextFont_GetSubscript(font, NULL);
2020 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2022 hr = ITextFont_GetSubscript(font, &value);
2023 ok(hr == hrexp, "got 0x%08x\n", hr);
2025 hr = ITextFont_GetSuperscript(font, NULL);
2026 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2028 hr = ITextFont_GetSuperscript(font, &value);
2029 ok(hr == hrexp, "got 0x%08x\n", hr);
2031 hr = ITextFont_GetUnderline(font, NULL);
2032 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2034 hr = ITextFont_GetUnderline(font, &value);
2035 ok(hr == hrexp, "got 0x%08x\n", hr);
2038 static void test_textfont_global_defaults(ITextFont *font)
2040 float valuef;
2041 LONG value;
2042 HRESULT hr;
2043 BSTR str;
2045 value = tomUndefined;
2046 hr = ITextFont_GetAllCaps(font, &value);
2047 ok(hr == S_OK, "got 0x%08x\n", hr);
2048 ok(value == tomFalse, "got %d\n", value);
2050 value = tomUndefined;
2051 hr = ITextFont_GetAnimation(font, &value);
2052 ok(hr == S_OK, "got 0x%08x\n", hr);
2053 ok(value == tomFalse, "got %d\n", value);
2055 value = tomUndefined;
2056 hr = ITextFont_GetBackColor(font, &value);
2057 ok(hr == S_OK, "got 0x%08x\n", hr);
2058 ok(value == tomAutoColor, "got %d\n", value);
2060 value = tomUndefined;
2061 hr = ITextFont_GetBold(font, &value);
2062 ok(hr == S_OK, "got 0x%08x\n", hr);
2063 ok(value == tomFalse || value == tomTrue, "got %d\n", value);
2065 value = tomUndefined;
2066 hr = ITextFont_GetEmboss(font, &value);
2067 ok(hr == S_OK, "got 0x%08x\n", hr);
2068 ok(value == tomFalse, "got %d\n", value);
2070 value = tomUndefined;
2071 hr = ITextFont_GetForeColor(font, &value);
2072 ok(hr == S_OK, "got 0x%08x\n", hr);
2073 ok(value == tomAutoColor, "got %d\n", value);
2075 value = tomUndefined;
2076 hr = ITextFont_GetHidden(font, &value);
2077 ok(hr == S_OK, "got 0x%08x\n", hr);
2078 ok(value == tomFalse, "got %d\n", value);
2080 value = tomUndefined;
2081 hr = ITextFont_GetEngrave(font, &value);
2082 ok(hr == S_OK, "got 0x%08x\n", hr);
2083 ok(value == tomFalse, "got %d\n", value);
2085 value = tomUndefined;
2086 hr = ITextFont_GetItalic(font, &value);
2087 ok(hr == S_OK, "got 0x%08x\n", hr);
2088 ok(value == tomFalse, "got %d\n", value);
2090 valuef = 1.0;
2091 hr = ITextFont_GetKerning(font, &valuef);
2092 ok(hr == S_OK, "got 0x%08x\n", hr);
2093 ok(valuef == 0.0, "got %.2f\n", valuef);
2095 value = tomUndefined;
2096 hr = ITextFont_GetLanguageID(font, &value);
2097 ok(hr == S_OK, "got 0x%08x\n", hr);
2098 ok(value == GetSystemDefaultLCID(), "got %d\n", value);
2100 str = NULL;
2101 hr = ITextFont_GetName(font, &str);
2102 ok(hr == S_OK, "got 0x%08x\n", hr);
2103 ok(!lstrcmpW(sysW, str), "%s\n", wine_dbgstr_w(str));
2104 SysFreeString(str);
2106 value = tomUndefined;
2107 hr = ITextFont_GetOutline(font, &value);
2108 ok(hr == S_OK, "got 0x%08x\n", hr);
2109 ok(value == tomFalse, "got %d\n", value);
2111 valuef = 1.0;
2112 hr = ITextFont_GetPosition(font, &valuef);
2113 ok(hr == S_OK, "got 0x%08x\n", hr);
2114 ok(valuef == 0.0, "got %.2f\n", valuef);
2116 value = tomUndefined;
2117 hr = ITextFont_GetProtected(font, &value);
2118 ok(hr == S_OK, "got 0x%08x\n", hr);
2119 ok(value == tomFalse, "got %d\n", value);
2121 value = tomUndefined;
2122 hr = ITextFont_GetShadow(font, &value);
2123 ok(hr == S_OK, "got 0x%08x\n", hr);
2124 ok(value == tomFalse, "got %d\n", value);
2126 valuef = 0.0;
2127 hr = ITextFont_GetSize(font, &valuef);
2128 ok(hr == S_OK, "got 0x%08x\n", hr);
2129 ok(valuef >= 0.0, "got %.2f\n", valuef);
2131 value = tomUndefined;
2132 hr = ITextFont_GetSmallCaps(font, &value);
2133 ok(hr == S_OK, "got 0x%08x\n", hr);
2134 ok(value == tomFalse, "got %d\n", value);
2136 valuef = 1.0;
2137 hr = ITextFont_GetSpacing(font, &valuef);
2138 ok(hr == S_OK, "got 0x%08x\n", hr);
2139 ok(valuef == 0.0, "got %.2f\n", valuef);
2141 value = tomUndefined;
2142 hr = ITextFont_GetStrikeThrough(font, &value);
2143 ok(hr == S_OK, "got 0x%08x\n", hr);
2144 ok(value == tomFalse, "got %d\n", value);
2146 value = tomUndefined;
2147 hr = ITextFont_GetSubscript(font, &value);
2148 ok(hr == S_OK, "got 0x%08x\n", hr);
2149 ok(value == tomFalse, "got %d\n", value);
2151 value = tomUndefined;
2152 hr = ITextFont_GetSuperscript(font, &value);
2153 ok(hr == S_OK, "got 0x%08x\n", hr);
2154 ok(value == tomFalse, "got %d\n", value);
2156 value = tomUndefined;
2157 hr = ITextFont_GetUnderline(font, &value);
2158 ok(hr == S_OK, "got 0x%08x\n", hr);
2159 ok(value == tomFalse, "got %d\n", value);
2161 value = tomUndefined;
2162 hr = ITextFont_GetWeight(font, &value);
2163 ok(hr == S_OK, "got 0x%08x\n", hr);
2164 ok(value == FW_NORMAL || value == FW_BOLD, "got %d\n", value);
2167 static void test_textfont_undefined(ITextFont *font)
2169 float valuef;
2170 LONG value;
2171 HRESULT hr;
2173 value = tomFalse;
2174 hr = ITextFont_GetAllCaps(font, &value);
2175 ok(hr == S_OK, "got 0x%08x\n", hr);
2176 ok(value == tomUndefined, "got %d\n", value);
2178 value = tomFalse;
2179 hr = ITextFont_GetAnimation(font, &value);
2180 ok(hr == S_OK, "got 0x%08x\n", hr);
2181 ok(value == tomUndefined, "got %d\n", value);
2183 value = tomFalse;
2184 hr = ITextFont_GetBackColor(font, &value);
2185 ok(hr == S_OK, "got 0x%08x\n", hr);
2186 ok(value == tomUndefined, "got %d\n", value);
2188 value = tomFalse;
2189 hr = ITextFont_GetBold(font, &value);
2190 ok(hr == S_OK, "got 0x%08x\n", hr);
2191 ok(value == tomUndefined, "got %d\n", value);
2193 value = tomFalse;
2194 hr = ITextFont_GetEmboss(font, &value);
2195 ok(hr == S_OK, "got 0x%08x\n", hr);
2196 ok(value == tomUndefined, "got %d\n", value);
2198 value = tomFalse;
2199 hr = ITextFont_GetForeColor(font, &value);
2200 ok(hr == S_OK, "got 0x%08x\n", hr);
2201 ok(value == tomUndefined, "got %d\n", value);
2203 value = tomFalse;
2204 hr = ITextFont_GetHidden(font, &value);
2205 ok(hr == S_OK, "got 0x%08x\n", hr);
2206 ok(value == tomUndefined, "got %d\n", value);
2208 value = tomFalse;
2209 hr = ITextFont_GetEngrave(font, &value);
2210 ok(hr == S_OK, "got 0x%08x\n", hr);
2211 ok(value == tomUndefined, "got %d\n", value);
2213 value = tomFalse;
2214 hr = ITextFont_GetItalic(font, &value);
2215 ok(hr == S_OK, "got 0x%08x\n", hr);
2216 ok(value == tomUndefined, "got %d\n", value);
2218 valuef = 0.0;
2219 hr = ITextFont_GetKerning(font, &valuef);
2220 ok(hr == S_OK, "got 0x%08x\n", hr);
2221 ok(valuef == tomUndefined, "got %.2f\n", valuef);
2223 value = tomFalse;
2224 hr = ITextFont_GetLanguageID(font, &value);
2225 ok(hr == S_OK, "got 0x%08x\n", hr);
2226 ok(value == tomUndefined, "got %d\n", value);
2228 value = tomFalse;
2229 hr = ITextFont_GetOutline(font, &value);
2230 ok(hr == S_OK, "got 0x%08x\n", hr);
2231 ok(value == tomUndefined, "got %d\n", value);
2233 valuef = 0.0;
2234 hr = ITextFont_GetPosition(font, &valuef);
2235 ok(hr == S_OK, "got 0x%08x\n", hr);
2236 ok(valuef == tomUndefined, "got %.2f\n", valuef);
2238 value = tomFalse;
2239 hr = ITextFont_GetProtected(font, &value);
2240 ok(hr == S_OK, "got 0x%08x\n", hr);
2241 ok(value == tomUndefined, "got %d\n", value);
2243 value = tomFalse;
2244 hr = ITextFont_GetShadow(font, &value);
2245 ok(hr == S_OK, "got 0x%08x\n", hr);
2246 ok(value == tomUndefined, "got %d\n", value);
2248 valuef = 0.0;
2249 hr = ITextFont_GetSize(font, &valuef);
2250 ok(hr == S_OK, "got 0x%08x\n", hr);
2251 ok(valuef == tomUndefined, "got %.2f\n", valuef);
2253 value = tomFalse;
2254 hr = ITextFont_GetSmallCaps(font, &value);
2255 ok(hr == S_OK, "got 0x%08x\n", hr);
2256 ok(value == tomUndefined, "got %d\n", value);
2258 valuef = 0.0;
2259 hr = ITextFont_GetSpacing(font, &valuef);
2260 ok(hr == S_OK, "got 0x%08x\n", hr);
2261 ok(valuef == tomUndefined, "got %.2f\n", valuef);
2263 value = tomFalse;
2264 hr = ITextFont_GetStrikeThrough(font, &value);
2265 ok(hr == S_OK, "got 0x%08x\n", hr);
2266 ok(value == tomUndefined, "got %d\n", value);
2268 value = tomFalse;
2269 hr = ITextFont_GetSubscript(font, &value);
2270 ok(hr == S_OK, "got 0x%08x\n", hr);
2271 ok(value == tomUndefined, "got %d\n", value);
2273 value = tomFalse;
2274 hr = ITextFont_GetSuperscript(font, &value);
2275 ok(hr == S_OK, "got 0x%08x\n", hr);
2276 ok(value == tomUndefined, "got %d\n", value);
2278 value = tomFalse;
2279 hr = ITextFont_GetUnderline(font, &value);
2280 ok(hr == S_OK, "got 0x%08x\n", hr);
2281 ok(value == tomUndefined, "got %d\n", value);
2283 value = tomFalse;
2284 hr = ITextFont_GetWeight(font, &value);
2285 ok(hr == S_OK, "got 0x%08x\n", hr);
2286 ok(value == tomUndefined, "got %d\n", value);
2289 static inline FLOAT twips_to_points(LONG value)
2291 return value * 72.0 / 1440;
2294 static void test_ITextFont(void)
2296 static const WCHAR arialW[] = {'A','r','i','a','l',0};
2297 static const CHAR test_text1[] = "TestSomeText";
2298 ITextFont *font, *font2, *font3;
2299 FLOAT size, position, kerning;
2300 IRichEditOle *reOle = NULL;
2301 ITextDocument *doc = NULL;
2302 ITextRange *range = NULL;
2303 CHARFORMAT2A cf;
2304 LONG value;
2305 HRESULT hr;
2306 HWND hwnd;
2307 BOOL ret;
2308 BSTR str;
2310 create_interfaces(&hwnd, &reOle, &doc, NULL);
2311 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2313 hr = ITextDocument_Range(doc, 0, 10, &range);
2314 ok(hr == S_OK, "got 0x%08x\n", hr);
2316 hr = ITextRange_GetFont(range, &font);
2317 ok(hr == S_OK, "got 0x%08x\n", hr);
2319 hr = ITextFont_Reset(font, tomUseTwips);
2320 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2322 hr = ITextFont_Reset(font, tomUsePoints);
2323 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2325 hr = ITextFont_GetName(font, NULL);
2326 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2328 /* default font size unit is point */
2329 size = 0.0;
2330 hr = ITextFont_GetSize(font, &size);
2331 ok(hr == S_OK, "got 0x%08x\n", hr);
2333 /* set to some non-zero values */
2334 hr = ITextFont_SetPosition(font, 20.0);
2335 ok(hr == S_OK, "got 0x%08x\n", hr);
2337 hr = ITextFont_SetKerning(font, 10.0);
2338 ok(hr == S_OK, "got 0x%08x\n", hr);
2340 position = 0.0;
2341 hr = ITextFont_GetPosition(font, &position);
2342 ok(hr == S_OK, "got 0x%08x\n", hr);
2344 kerning = 0.0;
2345 hr = ITextFont_GetKerning(font, &kerning);
2346 ok(hr == S_OK, "got 0x%08x\n", hr);
2348 memset(&cf, 0, sizeof(cf));
2349 cf.cbSize = sizeof(cf);
2350 cf.dwMask = CFM_SIZE|CFM_OFFSET|CFM_KERNING;
2352 /* CHARFORMAT members are in twips */
2353 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2354 ret = SendMessageA(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2355 ok(ret, "got %d\n", ret);
2356 ok(size == twips_to_points(cf.yHeight), "got yHeight %d, size %.2f\n", cf.yHeight, size);
2357 ok(position == twips_to_points(cf.yOffset), "got yOffset %d, position %.2f\n", cf.yOffset, position);
2358 ok(kerning == twips_to_points(cf.wKerning), "got wKerning %d, kerning %.2f\n", cf.wKerning, kerning);
2360 hr = ITextFont_Reset(font, tomUseTwips);
2361 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2363 hr = ITextFont_Reset(font, tomUsePoints);
2364 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2366 hr = ITextFont_GetDuplicate(font, &font2);
2367 ok(hr == S_OK, "got 0x%08x\n", hr);
2369 hr = ITextFont_Reset(font2, tomUseTwips);
2370 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2372 hr = ITextFont_Reset(font2, tomUsePoints);
2373 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2375 ITextFont_Release(font2);
2377 /* default font name */
2378 str = NULL;
2379 hr = ITextFont_GetName(font, &str);
2380 ok(hr == S_OK, "got 0x%08x\n", hr);
2381 ok(!lstrcmpW(str, sysW), "got %s\n", wine_dbgstr_w(str));
2382 SysFreeString(str);
2384 /* change font name for an inner subrange */
2385 memset(&cf, 0, sizeof(cf));
2386 cf.cbSize = sizeof(cf);
2387 cf.dwMask = CFM_FACE;
2388 strcpy(cf.szFaceName, "Arial");
2390 SendMessageA(hwnd, EM_SETSEL, 3, 4);
2391 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2392 ok(ret, "got %d\n", ret);
2394 /* still original name */
2395 str = NULL;
2396 hr = ITextFont_GetName(font, &str);
2397 ok(hr == S_OK, "got 0x%08x\n", hr);
2398 ok(!lstrcmpW(str, sysW), "got %s\n", wine_dbgstr_w(str));
2399 SysFreeString(str);
2401 SendMessageA(hwnd, EM_SETSEL, 1, 2);
2402 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2403 ok(ret, "got %d\n", ret);
2405 str = NULL;
2406 hr = ITextFont_GetName(font, &str);
2407 ok(hr == S_OK, "got 0x%08x\n", hr);
2408 ok(!lstrcmpW(str, sysW), "got %s\n", wine_dbgstr_w(str));
2409 SysFreeString(str);
2411 /* name is returned for first position within a range */
2412 SendMessageA(hwnd, EM_SETSEL, 0, 1);
2413 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2414 ok(ret, "got %d\n", ret);
2416 str = NULL;
2417 hr = ITextFont_GetName(font, &str);
2418 ok(hr == S_OK, "got 0x%08x\n", hr);
2419 ok(!lstrcmpW(str, arialW), "got %s\n", wine_dbgstr_w(str));
2420 SysFreeString(str);
2422 /* GetDuplicate() */
2423 hr = ITextFont_GetDuplicate(font, NULL);
2424 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2426 EXPECT_REF(range, 2);
2427 font2 = NULL;
2428 hr = ITextFont_GetDuplicate(font, &font2);
2429 ok(hr == S_OK, "got 0x%08x\n", hr);
2430 EXPECT_REF(range, 2);
2432 /* set whole range to italic */
2433 cf.cbSize = sizeof(CHARFORMAT2A);
2434 cf.dwMask = CFM_ITALIC;
2435 cf.dwEffects = CFE_ITALIC;
2437 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2438 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2439 ok(ret, "got %d\n", ret);
2441 value = tomFalse;
2442 hr = ITextFont_GetItalic(font, &value);
2443 ok(hr == S_OK, "got 0x%08x\n", hr);
2444 ok(value == tomTrue, "got %d\n", value);
2446 /* duplicate retains original value */
2447 value = tomTrue;
2448 hr = ITextFont_GetItalic(font2, &value);
2449 ok(hr == S_OK, "got 0x%08x\n", hr);
2450 ok(value == tomFalse, "got %d\n", value);
2452 /* get a duplicate from a cloned font */
2453 hr = ITextFont_GetDuplicate(font2, &font3);
2454 ok(hr == S_OK, "got 0x%08x\n", hr);
2455 ITextFont_Release(font3);
2457 ITextRange_Release(range);
2458 release_interfaces(&hwnd, &reOle, &doc, NULL);
2460 hr = ITextFont_GetDuplicate(font, NULL);
2461 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2463 test_detached_font_getters(font, FALSE);
2464 test_detached_font_getters(font2, TRUE);
2466 /* get a duplicate of detached font */
2467 hr = ITextFont_GetDuplicate(font2, &font3);
2468 ok(hr == S_OK, "got 0x%08x\n", hr);
2469 ITextFont_Release(font3);
2471 /* reset detached font to undefined */
2472 value = tomUndefined;
2473 hr = ITextFont_GetBold(font2, &value);
2474 ok(hr == S_OK, "got 0x%08x\n", hr);
2475 ok(value != tomUndefined, "got %d\n", value);
2477 /* reset to undefined for detached font */
2478 hr = ITextFont_Reset(font2, tomUndefined);
2479 ok(hr == S_OK, "got 0x%08x\n", hr);
2480 test_textfont_undefined(font2);
2482 /* font is detached, default means global TOM defaults */
2483 hr = ITextFont_Reset(font2, tomDefault);
2484 ok(hr == S_OK, "got 0x%08x\n", hr);
2485 test_textfont_global_defaults(font2);
2487 hr = ITextFont_GetDuplicate(font2, &font3);
2488 ok(hr == S_OK, "got 0x%08x\n", hr);
2489 test_textfont_global_defaults(font2);
2491 hr = ITextFont_Reset(font2, tomApplyNow);
2492 ok(hr == S_OK, "got 0x%08x\n", hr);
2493 test_textfont_global_defaults(font2);
2495 hr = ITextFont_Reset(font2, tomApplyLater);
2496 ok(hr == S_OK, "got 0x%08x\n", hr);
2497 test_textfont_global_defaults(font2);
2499 hr = ITextFont_Reset(font2, tomTrackParms);
2500 ok(hr == S_OK, "got 0x%08x\n", hr);
2501 test_textfont_global_defaults(font2);
2503 hr = ITextFont_SetItalic(font2, tomUndefined);
2504 ok(hr == S_OK, "got 0x%08x\n", hr);
2506 hr = ITextFont_GetItalic(font2, &value);
2507 ok(hr == S_OK, "got 0x%08x\n", hr);
2508 ok(value == tomFalse, "got %d\n", value);
2510 hr = ITextFont_Reset(font2, tomCacheParms);
2511 ok(hr == S_OK, "got 0x%08x\n", hr);
2512 test_textfont_global_defaults(font2);
2514 ITextFont_Release(font3);
2515 ITextFont_Release(font2);
2517 font2 = (void*)0xdeadbeef;
2518 hr = ITextFont_GetDuplicate(font, &font2);
2519 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2520 ok(font2 == NULL, "got %p\n", font2);
2522 hr = ITextFont_Reset(font, tomDefault);
2523 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2525 ITextFont_Release(font);
2527 /* Reset() */
2528 create_interfaces(&hwnd, &reOle, &doc, NULL);
2529 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2531 hr = ITextDocument_Range(doc, 0, 10, &range);
2532 ok(hr == S_OK, "got 0x%08x\n", hr);
2534 hr = ITextRange_GetFont(range, &font);
2535 ok(hr == S_OK, "got 0x%08x\n", hr);
2537 value = tomUndefined;
2538 hr = ITextFont_GetBold(font, &value);
2539 ok(hr == S_OK, "got 0x%08x\n", hr);
2540 ok(value != tomUndefined, "got %d\n", value);
2542 /* reset to undefined for attached font */
2543 hr = ITextFont_Reset(font, tomUndefined);
2544 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2546 value = tomUndefined;
2547 hr = ITextFont_GetBold(font, &value);
2548 ok(hr == S_OK, "got 0x%08x\n", hr);
2549 ok(value != tomUndefined, "got %d\n", value);
2551 /* tomCacheParms/tomTrackParms */
2552 hr = ITextFont_Reset(font, tomCacheParms);
2553 ok(hr == S_OK, "got 0x%08x\n", hr);
2555 hr = ITextFont_GetItalic(font, &value);
2556 ok(hr == S_OK, "got 0x%08x\n", hr);
2557 ok(value == tomFalse, "got %d\n", value);
2559 memset(&cf, 0, sizeof(cf));
2560 cf.cbSize = sizeof(CHARFORMAT2A);
2561 cf.dwMask = CFM_ITALIC;
2563 cf.dwEffects = CFE_ITALIC;
2564 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2565 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2566 ok(ret, "got %d\n", ret);
2568 /* still cached value */
2569 hr = ITextFont_GetItalic(font, &value);
2570 ok(hr == S_OK, "got 0x%08x\n", hr);
2571 ok(value == tomFalse, "got %d\n", value);
2573 hr = ITextFont_Reset(font, tomTrackParms);
2574 ok(hr == S_OK, "got 0x%08x\n", hr);
2576 hr = ITextFont_GetItalic(font, &value);
2577 ok(hr == S_OK, "got 0x%08x\n", hr);
2578 ok(value == tomTrue, "got %d\n", value);
2580 /* switch back to cache - value retained */
2581 hr = ITextFont_Reset(font, tomCacheParms);
2582 ok(hr == S_OK, "got 0x%08x\n", hr);
2584 hr = ITextFont_GetItalic(font, &value);
2585 ok(hr == S_OK, "got 0x%08x\n", hr);
2586 ok(value == tomTrue, "got %d\n", value);
2588 /* tomApplyLater */
2589 hr = ITextFont_Reset(font, tomApplyLater);
2590 ok(hr == S_OK, "got 0x%08x\n", hr);
2592 hr = ITextFont_SetItalic(font, tomFalse);
2593 ok(hr == S_OK, "got 0x%08x\n", hr);
2595 hr = ITextFont_GetItalic(font, &value);
2596 ok(hr == S_OK, "got 0x%08x\n", hr);
2597 ok(value == tomFalse, "got %d\n", value);
2599 cf.dwEffects = 0;
2600 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2601 ret = SendMessageA(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2602 ok(ret, "got %d\n", ret);
2603 ok((cf.dwEffects & CFE_ITALIC) == CFE_ITALIC, "got 0x%08x\n", cf.dwEffects);
2605 hr = ITextFont_Reset(font, tomApplyNow);
2606 ok(hr == S_OK, "got 0x%08x\n", hr);
2608 cf.dwEffects = 0;
2609 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2610 ret = SendMessageA(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2611 ok(ret, "got %d\n", ret);
2612 ok((cf.dwEffects & CFE_ITALIC) == 0, "got 0x%08x\n", cf.dwEffects);
2614 hr = ITextFont_SetItalic(font, tomUndefined);
2615 ok(hr == S_OK, "got 0x%08x\n", hr);
2617 hr = ITextFont_GetItalic(font, &value);
2618 ok(hr == S_OK, "got 0x%08x\n", hr);
2619 ok(value == tomFalse, "got %d\n", value);
2621 hr = ITextFont_SetItalic(font, tomAutoColor);
2622 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2624 cf.dwEffects = 0;
2625 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2626 ret = SendMessageA(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2627 ok(ret, "got %d\n", ret);
2628 ok((cf.dwEffects & CFE_ITALIC) == 0, "got 0x%08x\n", cf.dwEffects);
2630 ITextRange_Release(range);
2631 ITextFont_Release(font);
2632 release_interfaces(&hwnd, &reOle, &doc, NULL);
2635 static void test_Delete(void)
2637 static const CHAR test_text1[] = "TestSomeText";
2638 IRichEditOle *reOle = NULL;
2639 ITextDocument *doc = NULL;
2640 ITextRange *range, *range2;
2641 LONG value;
2642 HRESULT hr;
2643 HWND hwnd;
2645 create_interfaces(&hwnd, &reOle, &doc, NULL);
2646 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2648 hr = ITextDocument_Range(doc, 0, 4, &range);
2649 ok(hr == S_OK, "got 0x%08x\n", hr);
2651 hr = ITextDocument_Range(doc, 1, 2, &range2);
2652 ok(hr == S_OK, "got 0x%08x\n", hr);
2654 hr = ITextRange_GetEnd(range, &value);
2655 ok(hr == S_OK, "got 0x%08x\n", hr);
2656 ok(value == 4, "got %d\n", value);
2658 /* unit type doesn't matter is count is 0 */
2659 value = 0;
2660 hr = ITextRange_Delete(range2, tomSentence, 0, &value);
2661 todo_wine {
2662 ok(hr == S_OK, "got 0x%08x\n", hr);
2663 ok(value == 1, "got %d\n", value);
2665 value = 1;
2666 hr = ITextRange_Delete(range2, tomCharacter, 0, &value);
2667 todo_wine {
2668 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2669 ok(value == 0, "got %d\n", value);
2671 hr = ITextRange_GetEnd(range, &value);
2672 ok(hr == S_OK, "got 0x%08x\n", hr);
2673 todo_wine
2674 ok(value == 3, "got %d\n", value);
2676 hr = ITextRange_GetStart(range2, &value);
2677 ok(hr == S_OK, "got 0x%08x\n", hr);
2678 ok(value == 1, "got %d\n", value);
2680 hr = ITextRange_GetEnd(range2, &value);
2681 ok(hr == S_OK, "got 0x%08x\n", hr);
2682 todo_wine
2683 ok(value == 1, "got %d\n", value);
2685 ITextRange_Release(range);
2686 ITextRange_Release(range2);
2687 release_interfaces(&hwnd, &reOle, &doc, NULL);
2690 static void test_SetText(void)
2692 static const CHAR test_text1[] = "TestSomeText";
2693 static const WCHAR textW[] = {'a','b','c','d','e','f','g','h','i',0};
2694 IRichEditOle *reOle = NULL;
2695 ITextDocument *doc = NULL;
2696 ITextRange *range, *range2;
2697 LONG value;
2698 HRESULT hr;
2699 HWND hwnd;
2700 BSTR str;
2702 create_interfaces(&hwnd, &reOle, &doc, NULL);
2703 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2705 hr = ITextDocument_Range(doc, 0, 4, &range);
2706 ok(hr == S_OK, "got 0x%08x\n", hr);
2708 hr = ITextDocument_Range(doc, 0, 4, &range2);
2709 ok(hr == S_OK, "got 0x%08x\n", hr);
2711 value = 1;
2712 hr = ITextRange_GetStart(range2, &value);
2713 ok(hr == S_OK, "got 0x%08x\n", hr);
2714 ok(value == 0, "got %d\n", value);
2716 value = 0;
2717 hr = ITextRange_GetEnd(range2, &value);
2718 ok(hr == S_OK, "got 0x%08x\n", hr);
2719 ok(value == 4, "got %d\n", value);
2721 hr = ITextRange_SetText(range, NULL);
2722 ok(hr == S_OK, "got 0x%08x\n", hr);
2724 value = 1;
2725 hr = ITextRange_GetEnd(range2, &value);
2726 ok(hr == S_OK, "got 0x%08x\n", hr);
2727 ok(value == 0, "got %d\n", value);
2729 str = SysAllocString(textW);
2730 hr = ITextRange_SetText(range, str);
2731 ok(hr == S_OK, "got 0x%08x\n", hr);
2732 SysFreeString(str);
2734 value = 1;
2735 hr = ITextRange_GetStart(range, &value);
2736 ok(hr == S_OK, "got 0x%08x\n", hr);
2737 ok(value == 0, "got %d\n", value);
2739 value = 0;
2740 hr = ITextRange_GetEnd(range, &value);
2741 ok(hr == S_OK, "got 0x%08x\n", hr);
2742 ok(value == 9, "got %d\n", value);
2744 value = 1;
2745 hr = ITextRange_GetStart(range2, &value);
2746 ok(hr == S_OK, "got 0x%08x\n", hr);
2747 ok(value == 0, "got %d\n", value);
2749 value = 0;
2750 hr = ITextRange_GetEnd(range2, &value);
2751 ok(hr == S_OK, "got 0x%08x\n", hr);
2752 ok(value == 0, "got %d\n", value);
2754 str = SysAllocStringLen(NULL, 0);
2755 hr = ITextRange_SetText(range, str);
2756 ok(hr == S_OK, "got 0x%08x\n", hr);
2757 value = 1;
2758 hr = ITextRange_GetEnd(range, &value);
2759 ok(hr == S_OK, "got 0x%08x\n", hr);
2760 ok(value == 0, "got %d\n", value);
2761 SysFreeString(str);
2763 ITextRange_Release(range2);
2764 release_interfaces(&hwnd, &reOle, &doc, NULL);
2766 hr = ITextRange_SetText(range, NULL);
2767 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2769 str = SysAllocStringLen(NULL, 0);
2770 hr = ITextRange_SetText(range, str);
2771 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2772 SysFreeString(str);
2774 ITextRange_Release(range);
2777 static void test_InRange(void)
2779 static const CHAR test_text1[] = "TestSomeText";
2780 ITextRange *range, *range2, *range3;
2781 IRichEditOle *reOle = NULL;
2782 ITextDocument *doc = NULL;
2783 ITextSelection *selection;
2784 LONG value;
2785 HRESULT hr;
2786 HWND hwnd;
2788 create_interfaces(&hwnd, &reOle, &doc, &selection);
2789 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2790 SendMessageA(hwnd, EM_SETSEL, 1, 2);
2792 hr = ITextDocument_Range(doc, 0, 4, &range);
2793 ok(hr == S_OK, "got 0x%08x\n", hr);
2795 hr = ITextDocument_Range(doc, 0, 4, &range2);
2796 ok(hr == S_OK, "got 0x%08x\n", hr);
2798 /* matches selection */
2799 hr = ITextDocument_Range(doc, 1, 2, &range3);
2800 ok(hr == S_OK, "got 0x%08x\n", hr);
2802 hr = ITextRange_InRange(range, NULL, NULL);
2803 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2805 value = tomTrue;
2806 hr = ITextRange_InRange(range, NULL, &value);
2807 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2808 ok(value == tomFalse, "got %d\n", value);
2810 hr = ITextRange_InRange(range, range2, NULL);
2811 ok(hr == S_OK, "got 0x%08x\n", hr);
2813 value = tomFalse;
2814 hr = ITextRange_InRange(range, range2, &value);
2815 ok(hr == S_OK, "got 0x%08x\n", hr);
2816 ok(value == tomTrue, "got %d\n", value);
2818 /* selection */
2819 hr = ITextSelection_InRange(selection, NULL, NULL);
2820 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2822 value = tomTrue;
2823 hr = ITextSelection_InRange(selection, NULL, &value);
2824 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2825 ok(value == tomFalse, "got %d\n", value);
2827 hr = ITextSelection_InRange(selection, range2, NULL);
2828 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2830 value = tomTrue;
2831 hr = ITextSelection_InRange(selection, range2, &value);
2832 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2833 ok(value == tomFalse, "got %d\n", value);
2835 value = tomTrue;
2836 hr = ITextSelection_InRange(selection, range3, &value);
2837 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2838 ok(value == tomFalse, "got %d\n", value);
2840 /* seems to work on ITextSelection ranges only */
2841 value = tomFalse;
2842 hr = ITextSelection_InRange(selection, (ITextRange*)selection, &value);
2843 ok(hr == S_OK, "got 0x%08x\n", hr);
2844 ok(value == tomTrue, "got %d\n", value);
2846 release_interfaces(&hwnd, &reOle, &doc, NULL);
2848 hr = ITextRange_InRange(range, NULL, NULL);
2849 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2851 value = tomTrue;
2852 hr = ITextRange_InRange(range, NULL, &value);
2853 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2854 ok(value == tomFalse, "got %d\n", value);
2856 hr = ITextRange_InRange(range, range2, NULL);
2857 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2859 value = tomTrue;
2860 hr = ITextRange_InRange(range, range2, &value);
2861 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2862 ok(value == tomFalse, "got %d\n", value);
2864 /* selection */
2865 hr = ITextSelection_InRange(selection, NULL, NULL);
2866 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2868 value = tomTrue;
2869 hr = ITextSelection_InRange(selection, NULL, &value);
2870 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2871 ok(value == tomFalse, "got %d\n", value);
2873 hr = ITextSelection_InRange(selection, range2, NULL);
2874 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2876 value = tomTrue;
2877 hr = ITextSelection_InRange(selection, range2, &value);
2878 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2879 ok(value == tomFalse, "got %d\n", value);
2881 ITextRange_Release(range);
2882 ITextRange_Release(range2);
2883 ITextRange_Release(range3);
2884 ITextSelection_Release(selection);
2887 static void test_ITextRange_IsEqual(void)
2889 static const CHAR test_text1[] = "TestSomeText";
2890 ITextRange *range, *range2, *range3;
2891 IRichEditOle *reOle = NULL;
2892 ITextDocument *doc = NULL;
2893 ITextSelection *selection;
2894 LONG value;
2895 HRESULT hr;
2896 HWND hwnd;
2898 create_interfaces(&hwnd, &reOle, &doc, &selection);
2899 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2900 SendMessageA(hwnd, EM_SETSEL, 1, 2);
2902 hr = ITextDocument_Range(doc, 0, 4, &range);
2903 ok(hr == S_OK, "got 0x%08x\n", hr);
2905 hr = ITextDocument_Range(doc, 0, 4, &range2);
2906 ok(hr == S_OK, "got 0x%08x\n", hr);
2908 /* matches selection */
2909 hr = ITextDocument_Range(doc, 1, 2, &range3);
2910 ok(hr == S_OK, "got 0x%08x\n", hr);
2912 hr = ITextRange_IsEqual(range, NULL, NULL);
2913 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2915 value = tomTrue;
2916 hr = ITextRange_IsEqual(range, NULL, &value);
2917 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2918 ok(value == tomFalse, "got %d\n", value);
2920 hr = ITextRange_IsEqual(range, range2, NULL);
2921 ok(hr == S_OK, "got 0x%08x\n", hr);
2923 value = tomFalse;
2924 hr = ITextRange_IsEqual(range, range2, &value);
2925 ok(hr == S_OK, "got 0x%08x\n", hr);
2926 ok(value == tomTrue, "got %d\n", value);
2928 value = tomTrue;
2929 hr = ITextRange_IsEqual(range, range3, &value);
2930 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2931 ok(value == tomFalse, "got %d\n", value);
2933 /* selection */
2934 hr = ITextSelection_IsEqual(selection, NULL, NULL);
2935 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2937 value = tomTrue;
2938 hr = ITextSelection_IsEqual(selection, NULL, &value);
2939 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2940 ok(value == tomFalse, "got %d\n", value);
2942 hr = ITextSelection_IsEqual(selection, range2, NULL);
2943 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2945 value = tomTrue;
2946 hr = ITextSelection_IsEqual(selection, range2, &value);
2947 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2948 ok(value == tomFalse, "got %d\n", value);
2950 value = tomTrue;
2951 hr = ITextSelection_IsEqual(selection, range3, &value);
2952 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2953 ok(value == tomFalse, "got %d\n", value);
2955 /* seems to work on ITextSelection ranges only */
2956 value = tomFalse;
2957 hr = ITextSelection_IsEqual(selection, (ITextRange*)selection, &value);
2958 ok(hr == S_OK, "got 0x%08x\n", hr);
2959 ok(value == tomTrue, "got %d\n", value);
2961 release_interfaces(&hwnd, &reOle, &doc, NULL);
2963 hr = ITextRange_IsEqual(range, NULL, NULL);
2964 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2966 value = tomTrue;
2967 hr = ITextRange_IsEqual(range, NULL, &value);
2968 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2969 ok(value == tomFalse, "got %d\n", value);
2971 hr = ITextRange_IsEqual(range, range2, NULL);
2972 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2974 value = tomTrue;
2975 hr = ITextRange_IsEqual(range, range2, &value);
2976 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2977 ok(value == tomFalse, "got %d\n", value);
2979 /* selection */
2980 hr = ITextSelection_IsEqual(selection, NULL, NULL);
2981 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2983 value = tomTrue;
2984 hr = ITextSelection_IsEqual(selection, NULL, &value);
2985 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2986 ok(value == tomFalse, "got %d\n", value);
2988 hr = ITextSelection_IsEqual(selection, range2, NULL);
2989 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2991 value = tomTrue;
2992 hr = ITextSelection_IsEqual(selection, range2, &value);
2993 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2994 ok(value == tomFalse, "got %d\n", value);
2996 ITextRange_Release(range);
2997 ITextRange_Release(range2);
2998 ITextRange_Release(range3);
2999 ITextSelection_Release(selection);
3002 static void test_Select(void)
3004 static const CHAR test_text1[] = "TestSomeText";
3005 IRichEditOle *reOle = NULL;
3006 ITextDocument *doc = NULL;
3007 ITextSelection *selection;
3008 ITextRange *range;
3009 LONG value;
3010 HRESULT hr;
3011 HWND hwnd;
3013 create_interfaces(&hwnd, &reOle, &doc, &selection);
3014 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
3015 SendMessageA(hwnd, EM_SETSEL, 1, 2);
3017 hr = ITextDocument_Range(doc, 0, 4, &range);
3018 ok(hr == S_OK, "got 0x%08x\n", hr);
3020 hr = ITextRange_Select(range);
3021 ok(hr == S_OK, "got 0x%08x\n", hr);
3023 value = 1;
3024 hr = ITextSelection_GetStart(selection, &value);
3025 ok(hr == S_OK, "got 0x%08x\n", hr);
3026 ok(value == 0, "got %d\n", value);
3028 hr = ITextRange_Select(range);
3029 ok(hr == S_OK, "got 0x%08x\n", hr);
3031 hr = ITextSelection_Select(selection);
3032 ok(hr == S_OK, "got 0x%08x\n", hr);
3034 release_interfaces(&hwnd, &reOle, &doc, NULL);
3036 hr = ITextRange_Select(range);
3037 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3039 hr = ITextSelection_Select(selection);
3040 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3042 ITextRange_Release(range);
3043 ITextSelection_Release(selection);
3046 static void test_GetStoryType(void)
3048 static const CHAR test_text1[] = "TestSomeText";
3049 IRichEditOle *reOle = NULL;
3050 ITextDocument *doc = NULL;
3051 ITextSelection *selection;
3052 ITextRange *range;
3053 LONG value;
3054 HRESULT hr;
3055 HWND hwnd;
3057 create_interfaces(&hwnd, &reOle, &doc, &selection);
3058 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
3059 SendMessageA(hwnd, EM_SETSEL, 1, 2);
3061 hr = ITextDocument_Range(doc, 0, 4, &range);
3062 ok(hr == S_OK, "got 0x%08x\n", hr);
3064 hr = ITextRange_GetStoryType(range, NULL);
3065 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3067 value = tomTextFrameStory;
3068 hr = ITextRange_GetStoryType(range, &value);
3069 ok(hr == S_OK, "got 0x%08x\n", hr);
3070 ok(value == tomUnknownStory, "got %d\n", value);
3072 hr = ITextSelection_GetStoryType(selection, NULL);
3073 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3075 value = tomTextFrameStory;
3076 hr = ITextSelection_GetStoryType(selection, &value);
3077 ok(hr == S_OK, "got 0x%08x\n", hr);
3078 ok(value == tomUnknownStory, "got %d\n", value);
3080 release_interfaces(&hwnd, &reOle, &doc, NULL);
3082 hr = ITextRange_GetStoryType(range, NULL);
3083 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3085 value = 123;
3086 hr = ITextRange_GetStoryType(range, &value);
3087 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3088 ok(value == 123, "got %d\n", value);
3090 hr = ITextSelection_GetStoryType(selection, NULL);
3091 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3093 value = 123;
3094 hr = ITextSelection_GetStoryType(selection, &value);
3095 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3096 ok(value == 123, "got %d\n", value);
3098 ITextRange_Release(range);
3099 ITextSelection_Release(selection);
3102 static void test_SetFont(void)
3104 static const CHAR test_text1[] = "TestSomeText";
3105 IRichEditOle *reOle = NULL;
3106 ITextDocument *doc = NULL;
3107 ITextSelection *selection;
3108 ITextRange *range, *range2;
3109 ITextFont *font, *font2;
3110 LONG value;
3111 HRESULT hr;
3112 HWND hwnd;
3114 create_interfaces(&hwnd, &reOle, &doc, &selection);
3115 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
3116 SendMessageA(hwnd, EM_SETSEL, 1, 2);
3118 hr = ITextDocument_Range(doc, 0, 4, &range);
3119 ok(hr == S_OK, "got 0x%08x\n", hr);
3121 hr = ITextDocument_Range(doc, 5, 2, &range2);
3122 ok(hr == S_OK, "got 0x%08x\n", hr);
3124 EXPECT_REF(range, 1);
3125 hr = ITextRange_GetFont(range, &font);
3126 ok(hr == S_OK, "got 0x%08x\n", hr);
3127 EXPECT_REF(range, 2);
3129 EXPECT_REF(range2, 1);
3130 hr = ITextRange_GetFont(range2, &font2);
3131 ok(hr == S_OK, "got 0x%08x\n", hr);
3132 EXPECT_REF(range2, 2);
3134 hr = ITextRange_SetFont(range, NULL);
3135 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3137 /* setting same font, no-op */
3138 EXPECT_REF(range, 2);
3139 hr = ITextRange_SetFont(range, font);
3140 ok(hr == S_OK, "got 0x%08x\n", hr);
3141 EXPECT_REF(range, 2);
3143 EXPECT_REF(range2, 2);
3144 EXPECT_REF(range, 2);
3145 hr = ITextRange_SetFont(range, font2);
3146 ok(hr == S_OK, "got 0x%08x\n", hr);
3147 EXPECT_REF(range2, 2);
3148 EXPECT_REF(range, 2);
3150 /* originally range 0-4 is non-italic */
3151 value = tomTrue;
3152 hr = ITextFont_GetItalic(font, &value);
3153 ok(hr == S_OK, "got 0x%08x\n", hr);
3154 ok(value == tomFalse, "got %d\n", value);
3156 /* set range 5-2 to italic, then set this font to range 0-4 */
3157 hr = ITextFont_SetItalic(font2, tomTrue);
3158 ok(hr == S_OK, "got 0x%08x\n", hr);
3160 hr = ITextRange_SetFont(range, font2);
3161 ok(hr == S_OK, "got 0x%08x\n", hr);
3163 value = tomFalse;
3164 hr = ITextFont_GetItalic(font, &value);
3165 ok(hr == S_OK, "got 0x%08x\n", hr);
3166 ok(value == tomTrue, "got %d\n", value);
3168 release_interfaces(&hwnd, &reOle, &doc, NULL);
3170 hr = ITextRange_SetFont(range, NULL);
3171 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3173 hr = ITextRange_SetFont(range, font);
3174 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3176 hr = ITextSelection_SetFont(selection, NULL);
3177 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3179 hr = ITextSelection_SetFont(selection, font);
3180 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3182 ITextFont_Release(font);
3183 ITextFont_Release(font2);
3184 ITextRange_Release(range);
3185 ITextRange_Release(range2);
3186 ITextSelection_Release(selection);
3189 static void fill_reobject_struct(REOBJECT *reobj, LONG cp, LPOLEOBJECT poleobj,
3190 LPSTORAGE pstg, LPOLECLIENTSITE polesite, LONG sizel_cx,
3191 LONG sizel_cy, DWORD aspect, DWORD flags, DWORD user)
3193 reobj->cbStruct = sizeof(*reobj);
3194 reobj->clsid = CLSID_NULL;
3195 reobj->cp = cp;
3196 reobj->poleobj = poleobj;
3197 reobj->pstg = pstg;
3198 reobj->polesite = polesite;
3199 reobj->sizel.cx = sizel_cx;
3200 reobj->sizel.cy = sizel_cy;
3201 reobj->dvaspect = aspect;
3202 reobj->dwFlags = flags;
3203 reobj->dwUser = user;
3206 #define CHECK_REOBJECT_STRUCT(reobj,poleobj,pstg,polesite,user) \
3207 _check_reobject_struct(reobj, poleobj, pstg, polesite, user, __LINE__)
3208 static void _check_reobject_struct(REOBJECT reobj, LPOLEOBJECT poleobj, LPSTORAGE pstg,
3209 LPOLECLIENTSITE polesite, DWORD user, int line)
3211 ok_(__FILE__,line)(reobj.poleobj == poleobj, "got wrong object interface.\n");
3212 ok_(__FILE__,line)(reobj.pstg == pstg, "got wrong storage interface.\n");
3213 ok_(__FILE__,line)(reobj.polesite == polesite, "got wrong site interface.\n");
3214 ok_(__FILE__,line)(reobj.dwUser == user, "got wrong user-defined value.\n");
3217 static void test_InsertObject(void)
3219 static CHAR test_text1[] = "abcdefg";
3220 IRichEditOle *reole = NULL;
3221 ITextDocument *doc = NULL;
3222 IOleClientSite *clientsite;
3223 REOBJECT reo1, reo2, reo3, received_reo1, received_reo2, received_reo3, received_reo4;
3224 HRESULT hr;
3225 HWND hwnd;
3226 LONG count;
3228 create_interfaces(&hwnd, &reole, &doc, NULL);
3229 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
3231 hr = IRichEditOle_InsertObject(reole, NULL);
3232 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3234 /* insert object1 in (0, 1)*/
3235 SendMessageA(hwnd, EM_SETSEL, 0, 1);
3236 hr = IRichEditOle_GetClientSite(reole, &clientsite);
3237 ok(hr == S_OK, "IRichEditOle_GetClientSite failed: 0x%08x\n", hr);
3238 fill_reobject_struct(&reo1, REO_CP_SELECTION, NULL, NULL, clientsite, 10, 10, DVASPECT_CONTENT, 0, 1);
3239 hr = IRichEditOle_InsertObject(reole, &reo1);
3240 ok(hr == S_OK, "IRichEditOle_InsertObject failed: 0x%08x\n", hr);
3241 count = IRichEditOle_GetObjectCount(reole);
3242 ok(count == 1, "got wrong object count: %d\n", count);
3243 IOleClientSite_Release(clientsite);
3245 /* insert object2 in (2, 3)*/
3246 SendMessageA(hwnd, EM_SETSEL, 2, 3);
3247 hr = IRichEditOle_GetClientSite(reole, &clientsite);
3248 ok(hr == S_OK, "IRichEditOle_GetClientSite failed: 0x%08x\n", hr);
3249 fill_reobject_struct(&reo2, REO_CP_SELECTION, NULL, NULL, clientsite, 10, 10, DVASPECT_CONTENT, 0, 2);
3250 hr = IRichEditOle_InsertObject(reole, &reo2);
3251 ok(hr == S_OK, "IRichEditOle_InsertObject failed: 0x%08x\n", hr);
3252 count = IRichEditOle_GetObjectCount(reole);
3253 ok(count == 2, "got wrong object count: %d\n", count);
3254 IOleClientSite_Release(clientsite);
3256 /* insert object3 in (1, 2)*/
3257 SendMessageA(hwnd, EM_SETSEL, 1, 2);
3258 hr = IRichEditOle_GetClientSite(reole, &clientsite);
3259 ok(hr == S_OK, "IRichEditOle_GetClientSite failed: 0x%08x\n", hr);
3260 fill_reobject_struct(&reo3, REO_CP_SELECTION, NULL, NULL, clientsite, 10, 10, DVASPECT_CONTENT, 0, 3);
3261 hr = IRichEditOle_InsertObject(reole, &reo3);
3262 ok(hr == S_OK, "IRichEditOle_InsertObject failed: 0x%08x\n", hr);
3263 count = IRichEditOle_GetObjectCount(reole);
3264 ok(count == 3, "got wrong object count: %d\n", count);
3265 IOleClientSite_Release(clientsite);
3267 /* tests below show that order of rebject (from 0 to 2) is: reo1,reo3,reo2 */
3268 received_reo1.cbStruct = sizeof(received_reo1);
3269 hr = IRichEditOle_GetObject(reole, 0, &received_reo1, REO_GETOBJ_ALL_INTERFACES);
3270 ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
3271 CHECK_REOBJECT_STRUCT(received_reo1, NULL, NULL, reo1.polesite, 1);
3273 received_reo2.cbStruct = sizeof(received_reo2);
3274 hr = IRichEditOle_GetObject(reole, 1, &received_reo2, REO_GETOBJ_ALL_INTERFACES);
3275 ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
3276 CHECK_REOBJECT_STRUCT(received_reo2, NULL, NULL, reo3.polesite, 3);
3278 received_reo3.cbStruct = sizeof(received_reo3);
3279 hr = IRichEditOle_GetObject(reole, 2, &received_reo3, REO_GETOBJ_ALL_INTERFACES);
3280 ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
3281 CHECK_REOBJECT_STRUCT(received_reo3, NULL, NULL, reo2.polesite, 2);
3283 hr = IRichEditOle_GetObject(reole, 2, NULL, REO_GETOBJ_ALL_INTERFACES);
3284 ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr);
3286 received_reo4.cbStruct = 0;
3287 hr = IRichEditOle_GetObject(reole, 2, &received_reo4, REO_GETOBJ_ALL_INTERFACES);
3288 ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr);
3290 received_reo4.cbStruct = sizeof(received_reo4);
3291 hr = IRichEditOle_GetObject(reole, 2, &received_reo4, REO_GETOBJ_PSTG);
3292 ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
3293 CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, NULL, 2);
3295 hr = IRichEditOle_GetObject(reole, 2, &received_reo4, REO_GETOBJ_POLESITE);
3296 ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
3297 CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo2.polesite, 2);
3299 hr = IRichEditOle_GetObject(reole, 4, &received_reo4, REO_GETOBJ_POLESITE);
3300 ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr);
3302 hr = IRichEditOle_GetObject(reole, 1024, &received_reo4, REO_GETOBJ_POLESITE);
3303 ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr);
3305 /* received_reo4 will be zeroed before be used */
3306 hr = IRichEditOle_GetObject(reole, 2, &received_reo4, REO_GETOBJ_NO_INTERFACES);
3307 ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
3308 CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, NULL, 2);
3310 received_reo4.cbStruct = sizeof(received_reo4);
3311 received_reo4.cp = 0;
3312 hr = IRichEditOle_GetObject(reole, REO_IOB_USE_CP, &received_reo4, REO_GETOBJ_ALL_INTERFACES);
3313 ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
3314 CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo1.polesite, 1);
3316 received_reo4.cbStruct = sizeof(received_reo4);
3317 received_reo4.cp = 1;
3318 hr = IRichEditOle_GetObject(reole, REO_IOB_USE_CP, &received_reo4, REO_GETOBJ_ALL_INTERFACES);
3319 ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
3320 CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo3.polesite, 3);
3322 received_reo4.cbStruct = sizeof(received_reo4);
3323 received_reo4.cp = 2;
3324 hr = IRichEditOle_GetObject(reole, REO_IOB_USE_CP, &received_reo4, REO_GETOBJ_ALL_INTERFACES);
3325 ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
3326 CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo2.polesite, 2);
3328 received_reo4.cbStruct = sizeof(received_reo4);
3329 received_reo4.cp = 4;
3330 hr = IRichEditOle_GetObject(reole, REO_IOB_USE_CP, &received_reo4, REO_GETOBJ_ALL_INTERFACES);
3331 ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr);
3332 /* received_reo4 didn't be zeroed in E_INVALIDARG case */
3333 CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo2.polesite, 2);
3335 SendMessageA(hwnd, EM_SETSEL, 0, 1);
3336 received_reo4.cbStruct = sizeof(received_reo4);
3337 received_reo4.cp = 1;
3338 hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo4, REO_GETOBJ_ALL_INTERFACES);
3339 ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
3340 CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo1.polesite, 1);
3342 SendMessageA(hwnd, EM_SETSEL, 1, 2);
3343 received_reo4.cbStruct = sizeof(received_reo4);
3344 received_reo4.cp = 0;
3345 hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo4, REO_GETOBJ_ALL_INTERFACES);
3346 ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
3347 CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo3.polesite, 3);
3349 SendMessageA(hwnd, EM_SETSEL, 2, 3);
3350 received_reo4.cbStruct = sizeof(received_reo4);
3351 received_reo4.cp = 0;
3352 hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo4, REO_GETOBJ_ALL_INTERFACES);
3353 ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
3354 CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo2.polesite, 2);
3356 SendMessageA(hwnd, EM_SETSEL, 0, 2);
3357 received_reo4.cbStruct = sizeof(received_reo4);
3358 received_reo4.cp = 0;
3359 hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo4, REO_GETOBJ_ALL_INTERFACES);
3360 ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
3361 CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo1.polesite, 1);
3363 SendMessageA(hwnd, EM_SETSEL, 1, 3);
3364 received_reo4.cbStruct = sizeof(received_reo4);
3365 received_reo4.cp = 0;
3366 hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo4, REO_GETOBJ_ALL_INTERFACES);
3367 ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
3368 CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo3.polesite, 3);
3370 SendMessageA(hwnd, EM_SETSEL, 2, 0);
3371 received_reo4.cbStruct = sizeof(received_reo4);
3372 received_reo4.cp = 0;
3373 hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo4, REO_GETOBJ_ALL_INTERFACES);
3374 ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
3375 CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo1.polesite, 1);
3377 SendMessageA(hwnd, EM_SETSEL, 0, 6);
3378 received_reo4.cbStruct = sizeof(received_reo4);
3379 received_reo4.cp = 0;
3380 hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo4, REO_GETOBJ_ALL_INTERFACES);
3381 ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
3382 CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo1.polesite, 1);
3384 SendMessageA(hwnd, EM_SETSEL, 4, 5);
3385 received_reo4.cbStruct = sizeof(received_reo4);
3386 received_reo4.cp = 0;
3387 hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo4, REO_GETOBJ_ALL_INTERFACES);
3388 ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr);
3390 release_interfaces(&hwnd, &reole, &doc, NULL);
3393 static void test_GetStoryLength(void)
3395 static const CHAR test_text1[] = "TestSomeText";
3396 IRichEditOle *reOle = NULL;
3397 ITextDocument *doc = NULL;
3398 ITextSelection *selection;
3399 ITextRange *range;
3400 LONG value;
3401 HRESULT hr;
3402 HWND hwnd;
3404 create_interfaces(&hwnd, &reOle, &doc, &selection);
3405 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
3406 SendMessageA(hwnd, EM_SETSEL, 1, 2);
3408 hr = ITextDocument_Range(doc, 0, 4, &range);
3409 ok(hr == S_OK, "got 0x%08x\n", hr);
3411 hr = ITextRange_GetStoryLength(range, NULL);
3412 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3414 value = 0;
3415 hr = ITextRange_GetStoryLength(range, &value);
3416 ok(hr == S_OK, "got 0x%08x\n", hr);
3417 ok(value == 13, "got %d\n", value);
3419 hr = ITextSelection_GetStoryLength(selection, NULL);
3420 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3422 value = 0;
3423 hr = ITextSelection_GetStoryLength(selection, &value);
3424 ok(hr == S_OK, "got 0x%08x\n", hr);
3425 ok(value == 13, "got %d\n", value);
3427 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)"");
3429 value = 0;
3430 hr = ITextRange_GetStoryLength(range, &value);
3431 ok(hr == S_OK, "got 0x%08x\n", hr);
3432 ok(value == 1, "got %d\n", value);
3434 value = 0;
3435 hr = ITextSelection_GetStoryLength(selection, &value);
3436 ok(hr == S_OK, "got 0x%08x\n", hr);
3437 ok(value == 1, "got %d\n", value);
3439 release_interfaces(&hwnd, &reOle, &doc, NULL);
3441 hr = ITextRange_GetStoryLength(range, NULL);
3442 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3444 value = 100;
3445 hr = ITextRange_GetStoryLength(range, &value);
3446 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3447 ok(value == 100, "got %d\n", value);
3449 hr = ITextSelection_GetStoryLength(selection, NULL);
3450 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3452 value = 100;
3453 hr = ITextSelection_GetStoryLength(selection, &value);
3454 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3455 ok(value == 100, "got %d\n", value);
3457 ITextSelection_Release(selection);
3458 ITextRange_Release(range);
3461 static void test_ITextSelection_GetDuplicate(void)
3463 static const CHAR test_text1[] = "TestSomeText";
3464 IRichEditOle *reOle = NULL;
3465 ITextDocument *doc = NULL;
3466 ITextSelection *selection, *sel2;
3467 ITextRange *range, *range2;
3468 ITextFont *font;
3469 LONG value;
3470 HRESULT hr;
3471 HWND hwnd;
3473 create_interfaces(&hwnd, &reOle, &doc, &selection);
3474 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
3475 SendMessageA(hwnd, EM_SETSEL, 1, 2);
3477 hr = ITextSelection_GetDuplicate(selection, NULL);
3478 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3480 EXPECT_REF(selection, 2);
3482 hr = ITextSelection_GetDuplicate(selection, &range);
3483 ok(hr == S_OK, "got 0x%08x\n", hr);
3485 hr = ITextSelection_GetDuplicate(selection, &range2);
3486 ok(hr == S_OK, "got 0x%08x\n", hr);
3487 ok(range != range2, "got %p, %p\n", range, range2);
3489 EXPECT_REF(selection, 2);
3490 EXPECT_REF(range, 1);
3491 EXPECT_REF(range2, 1);
3493 ITextRange_Release(range2);
3495 value = 0;
3496 hr = ITextRange_GetStart(range, &value);
3497 ok(hr == S_OK, "got 0x%08x\n", hr);
3498 ok(value == 1, "got %d\n", value);
3500 value = 0;
3501 hr = ITextRange_GetEnd(range, &value);
3502 ok(hr == S_OK, "got 0x%08x\n", hr);
3503 ok(value == 2, "got %d\n", value);
3505 SendMessageA(hwnd, EM_SETSEL, 2, 3);
3507 value = 0;
3508 hr = ITextRange_GetStart(range, &value);
3509 ok(hr == S_OK, "got 0x%08x\n", hr);
3510 ok(value == 1, "got %d\n", value);
3512 value = 0;
3513 hr = ITextRange_GetEnd(range, &value);
3514 ok(hr == S_OK, "got 0x%08x\n", hr);
3515 ok(value == 2, "got %d\n", value);
3517 hr = ITextRange_QueryInterface(range, &IID_ITextSelection, (void**)&sel2);
3518 ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);
3520 release_interfaces(&hwnd, &reOle, &doc, NULL);
3522 hr = ITextSelection_GetDuplicate(selection, NULL);
3523 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3525 hr = ITextSelection_GetDuplicate(selection, &range);
3526 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3528 hr = ITextRange_GetFont(range, &font);
3529 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3531 ITextSelection_Release(selection);
3532 ITextRange_Release(range);
3535 #define RESET_RANGE(range,start,end) \
3536 _reset_range(range, start, end, __LINE__)
3537 static void _reset_range(ITextRange *range, LONG start, LONG end, int line)
3539 HRESULT hr;
3541 hr = ITextRange_SetStart(range, start);
3542 ok_(__FILE__,line)(hr == S_OK, "SetStart failed: 0x%08x\n", hr);
3543 hr = ITextRange_SetEnd(range, end);
3544 ok_(__FILE__,line)(hr == S_OK, "SetEnd failed: 0x%08x\n", hr);
3547 #define CHECK_RANGE(range,expected_start,expected_end) \
3548 _check_range(range, expected_start, expected_end, __LINE__)
3549 static void _check_range(ITextRange* range, LONG expected_start, LONG expected_end, int line)
3551 HRESULT hr;
3552 LONG value;
3554 hr = ITextRange_GetStart(range, &value);
3555 ok_(__FILE__,line)(hr == S_OK, "GetStart failed: 0x%08x\n", hr);
3556 ok_(__FILE__,line)(value == expected_start, "Expected start %d got %d\n",
3557 expected_start, value);
3558 hr = ITextRange_GetEnd(range, &value);
3559 ok_(__FILE__,line)(hr == S_OK, "GetEnd failed: 0x%08x\n", hr);
3560 ok_(__FILE__,line)(value == expected_end, "Expected end %d got %d\n",
3561 expected_end, value);
3564 #define RESET_SELECTION(selection,start,end) \
3565 _reset_selection(selection, start, end, __LINE__)
3566 static void _reset_selection(ITextSelection *selection, LONG start, LONG end, int line)
3568 HRESULT hr;
3570 hr = ITextSelection_SetStart(selection, start);
3571 ok_(__FILE__,line)(hr == S_OK, "SetStart failed: 0x%08x\n", hr);
3572 hr = ITextSelection_SetEnd(selection, end);
3573 ok_(__FILE__,line)(hr == S_OK, "SetEnd failed: 0x%08x\n", hr);
3576 #define CHECK_SELECTION(selection,expected_start,expected_end) \
3577 _check_selection(selection, expected_start, expected_end, __LINE__)
3578 static void _check_selection(ITextSelection *selection, LONG expected_start, LONG expected_end, int line)
3580 HRESULT hr;
3581 LONG value;
3583 hr = ITextSelection_GetStart(selection, &value);
3584 ok_(__FILE__,line)(hr == S_OK, "GetStart failed: 0x%08x\n", hr);
3585 ok_(__FILE__,line)(value == expected_start, "Expected start %d got %d\n",
3586 expected_start, value);
3587 hr = ITextSelection_GetEnd(selection, &value);
3588 ok_(__FILE__,line)(hr == S_OK, "GetEnd failed: 0x%08x\n", hr);
3589 ok_(__FILE__,line)(value == expected_end, "Expected end %d got %d\n",
3590 expected_end, value);
3593 static void test_ITextRange_SetRange(void)
3595 static const CHAR test_text1[] = "TestSomeText";
3596 ITextDocument *txtDoc = NULL;
3597 IRichEditOle *reOle = NULL;
3598 ITextRange *txtRge = NULL;
3599 HRESULT hr;
3600 HWND w;
3602 create_interfaces(&w, &reOle, &txtDoc, NULL);
3603 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
3604 ITextDocument_Range(txtDoc, 0, 0, &txtRge);
3606 hr = ITextRange_SetRange(txtRge, 2, 4);
3607 ok(hr == S_OK, "got 0x%08x.\n", hr);
3608 CHECK_RANGE(txtRge, 2, 4);
3610 hr = ITextRange_SetRange(txtRge, 2, 4);
3611 ok(hr == S_FALSE, "got 0x%08x.\n", hr);
3612 CHECK_RANGE(txtRge, 2, 4);
3614 hr = ITextRange_SetRange(txtRge, 4, 2);
3615 ok(hr == S_FALSE, "got 0x%08x.\n", hr);
3616 CHECK_RANGE(txtRge, 2, 4);
3618 hr = ITextRange_SetRange(txtRge, 14, 14);
3619 ok(hr == S_OK, "got 0x%08x.\n", hr);
3620 CHECK_RANGE(txtRge, 12, 12);
3622 hr = ITextRange_SetRange(txtRge, 15, 15);
3623 ok(hr == S_FALSE, "got 0x%08x.\n", hr);
3624 CHECK_RANGE(txtRge, 12, 12);
3626 hr = ITextRange_SetRange(txtRge, 14, 1);
3627 ok(hr == S_OK, "got 0x%08x.\n", hr);
3628 CHECK_RANGE(txtRge, 1, 13);
3630 hr = ITextRange_SetRange(txtRge, -1, 4);
3631 ok(hr == S_OK, "got 0x%08x.\n", hr);
3632 CHECK_RANGE(txtRge, 0, 4);
3634 ITextRange_Release(txtRge);
3635 release_interfaces(&w, &reOle, &txtDoc, NULL);
3638 static void test_Expand(void)
3640 static const char test_text1[] = "TestSomeText";
3641 IRichEditOle *reole = NULL;
3642 ITextDocument *doc = NULL;
3643 ITextSelection *selection;
3644 ITextRange *range;
3645 LONG value;
3646 HRESULT hr;
3647 HWND hwnd;
3649 create_interfaces(&hwnd, &reole, &doc, &selection);
3650 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
3651 SendMessageA(hwnd, EM_SETSEL, 1, 2);
3653 hr = ITextDocument_Range(doc, 0, 4, &range);
3654 ok(hr == S_OK, "got 0x%08x\n", hr);
3656 hr = ITextRange_Expand(range, tomStory, NULL);
3657 ok(hr == S_OK, "got 0x%08x\n", hr);
3658 CHECK_RANGE(range, 0, 13);
3660 hr = ITextSelection_Expand(selection, tomStory, NULL);
3661 ok(hr == S_OK, "got 0x%08x\n", hr);
3662 CHECK_SELECTION(selection, 0, 13);
3664 RESET_RANGE(range, 1, 2);
3665 RESET_SELECTION(selection, 1, 2);
3667 value = 0;
3668 hr = ITextRange_Expand(range, tomStory, &value);
3669 ok(hr == S_OK, "got 0x%08x\n", hr);
3670 ok(value == 12, "got %d\n", value);
3671 CHECK_RANGE(range, 0, 13);
3673 value = 0;
3674 hr = ITextSelection_Expand(selection, tomStory, &value);
3675 ok(hr == S_OK, "got 0x%08x\n", hr);
3676 ok(value == 12, "got %d\n", value);
3677 CHECK_SELECTION(selection, 0, 13);
3679 release_interfaces(&hwnd, &reole, &doc, NULL);
3681 hr = ITextRange_Expand(range, tomStory, NULL);
3682 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3684 hr = ITextRange_Expand(range, tomStory, &value);
3685 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3687 hr = ITextSelection_Expand(selection, tomStory, NULL);
3688 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3690 hr = ITextSelection_Expand(selection, tomStory, &value);
3691 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3693 ITextSelection_Release(selection);
3694 ITextRange_Release(range);
3697 static void test_MoveEnd_story(void)
3699 static const char test_text1[] = "Word1 Word2";
3700 IRichEditOle *reole = NULL;
3701 ITextDocument *doc = NULL;
3702 ITextSelection *selection;
3703 ITextRange *range;
3704 LONG delta;
3705 HRESULT hr;
3706 HWND hwnd;
3708 create_interfaces(&hwnd, &reole, &doc, &selection);
3709 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
3710 SendMessageA(hwnd, EM_SETSEL, 1, 2);
3712 hr = ITextDocument_Range(doc, 1, 2, &range);
3713 ok(hr == S_OK, "got 0x%08x\n", hr);
3715 hr = ITextRange_MoveEnd(range, tomStory, 0, &delta);
3716 ok(hr == S_FALSE, "got 0x%08x\n", hr);
3717 ok(delta == 0, "got %d\n", delta);
3718 CHECK_RANGE(range, 1, 2);
3720 hr = ITextRange_MoveEnd(range, tomStory, -1, &delta);
3721 ok(hr == S_OK, "got 0x%08x\n", hr);
3722 ok(delta == -1, "got %d\n", delta);
3723 CHECK_RANGE(range, 0, 0);
3725 hr = ITextRange_MoveEnd(range, tomStory, 1, &delta);
3726 ok(hr == S_OK, "got 0x%08x\n", hr);
3727 ok(delta == 1, "got %d\n", delta);
3728 CHECK_RANGE(range, 0, 12);
3730 hr = ITextRange_MoveEnd(range, tomStory, 1, &delta);
3731 ok(hr == S_FALSE, "got 0x%08x\n", hr);
3732 ok(delta == 0, "got %d\n", delta);
3733 CHECK_RANGE(range, 0, 12);
3735 RESET_RANGE(range, 1, 2);
3737 hr = ITextRange_MoveEnd(range, tomStory, 3, &delta);
3738 ok(hr == S_OK, "got 0x%08x\n", hr);
3739 ok(delta == 1, "got %d\n", delta);
3740 CHECK_RANGE(range, 1, 12);
3742 RESET_RANGE(range, 2, 3);
3744 hr = ITextRange_MoveEnd(range, tomStory, -3, &delta);
3745 ok(hr == S_OK, "got 0x%08x\n", hr);
3746 ok(delta == -1, "got %d\n", delta);
3747 CHECK_RANGE(range, 0, 0);
3749 hr = ITextRange_MoveEnd(range, tomStory, -1, &delta);
3750 ok(hr == S_FALSE, "got 0x%08x\n", hr);
3751 ok(delta == 0, "got %d\n", delta);
3752 CHECK_RANGE(range, 0, 0);
3754 hr = ITextSelection_MoveEnd(selection, tomStory, 0, &delta);
3755 ok(hr == S_FALSE, "got 0x%08x\n", hr);
3756 ok(delta == 0, "got %d\n", delta);
3757 CHECK_SELECTION(selection, 1, 2);
3759 hr = ITextSelection_MoveEnd(selection, tomStory, -1, &delta);
3760 ok(hr == S_OK, "got 0x%08x\n", hr);
3761 ok(delta == -1, "got %d\n", delta);
3762 CHECK_SELECTION(selection, 0, 0);
3764 hr = ITextSelection_MoveEnd(selection, tomStory, 1, &delta);
3765 ok(hr == S_OK, "got 0x%08x\n", hr);
3766 ok(delta == 1, "got %d\n", delta);
3767 CHECK_SELECTION(selection, 0, 12);
3769 hr = ITextSelection_MoveEnd(selection, tomStory, 1, &delta);
3770 ok(hr == S_FALSE, "got 0x%08x\n", hr);
3771 ok(delta == 0, "got %d\n", delta);
3772 CHECK_SELECTION(selection, 0, 12);
3774 RESET_SELECTION(selection, 1, 2);
3776 hr = ITextSelection_MoveEnd(selection, tomStory, 3, &delta);
3777 ok(hr == S_OK, "got 0x%08x\n", hr);
3778 ok(delta == 1, "got %d\n", delta);
3779 CHECK_SELECTION(selection, 1, 12);
3781 RESET_SELECTION(selection, 2, 3);
3783 hr = ITextSelection_MoveEnd(selection, tomStory, -3, &delta);
3784 ok(hr == S_OK, "got 0x%08x\n", hr);
3785 ok(delta == -1, "got %d\n", delta);
3786 CHECK_SELECTION(selection, 0, 0);
3788 hr = ITextSelection_MoveEnd(selection, tomStory, -1, &delta);
3789 ok(hr == S_FALSE, "got 0x%08x\n", hr);
3790 ok(delta == 0, "got %d\n", delta);
3791 CHECK_SELECTION(selection, 0, 0);
3793 release_interfaces(&hwnd, &reole, &doc, NULL);
3795 hr = ITextRange_MoveEnd(range, tomStory, 1, NULL);
3796 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3798 hr = ITextRange_MoveEnd(range, tomStory, 1, &delta);
3799 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3801 hr = ITextSelection_MoveEnd(selection, tomStory, 1, NULL);
3802 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3804 hr = ITextSelection_MoveEnd(selection, tomStory, 1, &delta);
3805 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3807 ITextSelection_Release(selection);
3808 ITextRange_Release(range);
3811 static void test_character_movestart(ITextRange *range, int textlen, int i, int j, LONG target)
3813 HRESULT hr;
3814 LONG delta = 0;
3815 LONG expected_delta;
3816 LONG expected_start = target;
3818 if (expected_start < 0)
3819 expected_start = 0;
3820 else if (expected_start > textlen)
3821 expected_start = textlen;
3822 expected_delta = expected_start - i;
3823 hr = ITextRange_SetRange(range, i, j);
3824 ok(SUCCEEDED(hr), "got 0x%08x\n", hr);
3825 hr = ITextRange_MoveStart(range, tomCharacter, target - i, &delta);
3826 if (expected_start == i) {
3827 ok(hr == S_FALSE, "(%d,%d) move by %d got hr=0x%08x\n", i, j, target - i, hr);
3828 ok(delta == 0, "(%d,%d) move by %d got delta %d\n", i, j, target - i, delta);
3829 CHECK_RANGE(range, i, j);
3830 } else {
3831 ok(hr == S_OK, "(%d,%d) move by %d got hr=0x%08x\n", i, j, target - i, hr);
3832 ok(delta == expected_delta, "(%d,%d) move by %d got delta %d\n", i, j, target - i, delta);
3833 if (expected_start <= j)
3834 CHECK_RANGE(range, expected_start, j);
3835 else
3836 CHECK_RANGE(range, expected_start, expected_start);
3840 static void test_character_moveend(ITextRange *range, int textlen, int i, int j, LONG target)
3842 HRESULT hr;
3843 LONG delta;
3844 LONG expected_delta;
3845 LONG expected_end = target;
3847 if (expected_end < 0)
3848 expected_end = 0;
3849 else if (expected_end > textlen + 1)
3850 expected_end = textlen + 1;
3851 expected_delta = expected_end - j;
3852 hr = ITextRange_SetRange(range, i, j);
3853 ok(SUCCEEDED(hr), "got 0x%08x\n", hr);
3854 hr = ITextRange_MoveEnd(range, tomCharacter, target - j, &delta);
3855 if (expected_end == j) {
3856 ok(hr == S_FALSE, "(%d,%d) move by %d got hr=0x%08x\n", i, j, target - j, hr);
3857 ok(delta == 0, "(%d,%d) move by %d got delta %d\n", i, j, target - j, delta);
3858 CHECK_RANGE(range, i, j);
3859 } else {
3860 ok(hr == S_OK, "(%d,%d) move by %d got hr=0x%08x\n", i, j, target - j, hr);
3861 ok(delta == expected_delta, "(%d,%d) move by %d got delta %d\n", i, j, target - j, delta);
3862 if (i <= expected_end)
3863 CHECK_RANGE(range, i, expected_end);
3864 else
3865 CHECK_RANGE(range, expected_end, expected_end);
3869 static void test_character_move(ITextRange *range, int textlen, int i, int j, LONG target)
3871 HRESULT hr;
3872 LONG move_by;
3873 LONG delta = 0;
3874 LONG expected_delta;
3875 LONG expected_location = target;
3877 if (expected_location < 0)
3878 expected_location = 0;
3879 else if (expected_location > textlen)
3880 expected_location = textlen;
3882 if (target <= i) {
3883 move_by = target - i;
3884 expected_delta = expected_location - i;
3885 if (i != j) {
3886 --move_by;
3887 --expected_delta;
3889 } else if (j <= target) {
3890 move_by = target - j;
3891 expected_delta = expected_location - j;
3892 if (i != j) {
3893 ++move_by;
3894 ++expected_delta;
3896 } else {
3897 /* There's no way to move to a point between start and end: */
3898 return;
3901 hr = ITextRange_SetRange(range, i, j);
3902 ok(SUCCEEDED(hr), "got 0x%08x\n", hr);
3903 hr = ITextRange_Move(range, tomCharacter, move_by, &delta);
3904 if (expected_delta == 0) {
3905 ok(hr == S_FALSE, "(%d,%d) move by %d got hr=0x%08x\n", i, j, move_by, hr);
3906 ok(delta == 0, "(%d,%d) move by %d got delta %d\n", i, j, move_by, delta);
3907 CHECK_RANGE(range, expected_location, expected_location);
3908 } else {
3909 ok(hr == S_OK, "(%d,%d) move by %d got hr=0x%08x\n", i, j, move_by, hr);
3910 ok(delta == expected_delta, "(%d,%d) move by %d got delta %d\n", i, j, move_by, delta);
3911 CHECK_RANGE(range, expected_location, expected_location);
3915 static void test_character_startof(ITextRange *range, int textlen, int i, int j)
3917 HRESULT hr;
3918 LONG delta;
3920 hr = ITextRange_SetRange(range, i, j);
3921 ok(SUCCEEDED(hr), "got 0x%08x\n", hr);
3922 hr = ITextRange_StartOf(range, tomCharacter, tomMove, &delta);
3923 if (i == j) {
3924 ok(hr == S_FALSE, "(%d,%d) tomMove got hr=0x%08x\n", i, j, hr);
3925 ok(delta == 0, "(%d,%d) tomMove got delta %d\n", i, j, delta);
3926 } else {
3927 ok(hr == S_OK, "(%d,%d) tomMove got hr=0x%08x\n", i, j, hr);
3928 ok(delta == -1, "(%d,%d) tomMove got delta %d\n", i, j, delta);
3930 CHECK_RANGE(range, i, i);
3932 hr = ITextRange_SetRange(range, i, j);
3933 ok(SUCCEEDED(hr), "got 0x%08x\n", hr);
3934 hr = ITextRange_StartOf(range, tomCharacter, tomExtend, &delta);
3935 ok(hr == S_FALSE, "(%d,%d) tomExtend got hr=0x%08x\n", i, j, hr);
3936 ok(delta == 0, "(%d,%d) tomExtend got delta %d\n", i, j, delta);
3937 CHECK_RANGE(range, i, j);
3940 static void test_character_endof(ITextRange *range, int textlen, int i, int j)
3942 HRESULT hr;
3943 LONG end;
3944 LONG delta;
3946 hr = ITextRange_SetRange(range, i, j);
3947 ok(SUCCEEDED(hr), "got 0x%08x\n", hr);
3948 hr = ITextRange_EndOf(range, tomCharacter, tomMove, &delta);
3950 /* A character "end", apparently cannot be before the very first character */
3951 end = j;
3952 if (j == 0)
3953 ++end;
3955 if (i == end) {
3956 ok(hr == S_FALSE, "(%d,%d) tomMove got hr=0x%08x\n", i, j, hr);
3957 ok(delta == 0, "(%d,%d) tomMove got delta %d\n", i, j, delta);
3958 } else {
3959 ok(hr == S_OK, "(%d,%d) tomMove got hr=0x%08x\n", i, j, hr);
3960 ok(delta == 1, "(%d,%d) tomMove got delta %d\n", i, j, delta);
3962 CHECK_RANGE(range, end, end);
3964 hr = ITextRange_SetRange(range, i, j);
3965 ok(SUCCEEDED(hr), "got 0x%08x\n", hr);
3966 hr = ITextRange_EndOf(range, tomCharacter, tomExtend, &delta);
3967 if (0 < j) {
3968 ok(hr == S_FALSE, "(%d,%d) tomExtend got hr=0x%08x\n", i, j, hr);
3969 ok(delta == 0, "(%d,%d) tomExtend got delta %d\n", i, j, delta);
3970 } else {
3971 ok(hr == S_OK, "(%d,%d) tomExtend got hr=0x%08x\n", i, j, hr);
3972 ok(delta == 1, "(%d,%d) tomExtend got delta %d\n", i, j, delta);
3974 CHECK_RANGE(range, i, end);
3977 static void test_character_movement(void)
3979 static const char test_text1[] = "ab\n c";
3980 IRichEditOle *reole = NULL;
3981 ITextDocument *doc = NULL;
3982 ITextRange *range;
3983 ITextSelection *selection;
3984 HRESULT hr;
3985 HWND hwnd;
3986 int i, j;
3987 const int textlen = strlen(test_text1);
3989 create_interfaces(&hwnd, &reole, &doc, &selection);
3990 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
3992 hr = ITextDocument_Range(doc, 0, 0, &range);
3993 ok(hr == S_OK, "got 0x%08x\n", hr);
3995 /* Exhaustive test of every possible combination of (start,end) locations,
3996 * against every possible target location to move to. */
3997 for (i = 0; i <= textlen; i++) {
3998 for (j = i; j <= textlen; j++) {
3999 LONG target;
4000 for (target = -2; target <= textlen + 3; target++) {
4001 test_character_moveend(range, textlen, i, j, target);
4002 test_character_movestart(range, textlen, i, j, target);
4003 test_character_move(range, textlen, i, j, target);
4005 test_character_startof(range, textlen, i, j);
4006 test_character_endof(range, textlen, i, j);
4010 release_interfaces(&hwnd, &reole, &doc, NULL);
4011 ITextSelection_Release(selection);
4012 ITextRange_Release(range);
4015 #define CLIPBOARD_RANGE_CONTAINS(range, start, end, expected) _clipboard_range_contains(range, start, end, expected, __LINE__, 0);
4016 #define TODO_CLIPBOARD_RANGE_CONTAINS(range, start, end, expected) _clipboard_range_contains(range, start, end, expected, __LINE__, 1);
4017 static void _clipboard_range_contains(ITextRange *range, LONG start, LONG end, const char *expected, int line, int todo)
4019 HRESULT hr;
4020 BOOL clipboard_open;
4021 HGLOBAL global;
4022 const char *clipboard_text;
4024 hr = ITextRange_SetRange(range, start, end);
4025 ok_(__FILE__,line)(SUCCEEDED(hr), "SetRange failed: 0x%08x\n", hr);
4026 hr = ITextRange_Copy(range, NULL);
4027 ok_(__FILE__,line)(hr == S_OK, "Copy failed: 0x%08x\n", hr);
4029 clipboard_open = OpenClipboard(NULL);
4030 ok_(__FILE__,line)(clipboard_open, "OpenClipboard failed: %d\n", GetLastError());
4031 global = GetClipboardData(CF_TEXT);
4032 ok_(__FILE__,line)(global != NULL, "GetClipboardData failed: %p\n", global);
4033 clipboard_text = GlobalLock(global);
4034 ok_(__FILE__,line)(clipboard_text != NULL, "GlobalLock failed: %p\n", clipboard_text);
4035 todo_wine_if(todo) ok_(__FILE__,line)(!strcmp(expected, clipboard_text), "unexpected contents: %s\n", wine_dbgstr_a(clipboard_text));
4036 GlobalUnlock(global);
4037 CloseClipboard();
4040 static void test_clipboard(void)
4042 static const char text_in[] = "ab\n c";
4043 IRichEditOle *reole = NULL;
4044 ITextDocument *doc = NULL;
4045 ITextRange *range;
4046 ITextSelection *selection;
4047 HRESULT hr;
4048 HWND hwnd;
4050 create_interfaces(&hwnd, &reole, &doc, &selection);
4051 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)text_in);
4053 hr = ITextDocument_Range(doc, 0, 0, &range);
4054 ok(hr == S_OK, "got 0x%08x\n", hr);
4056 CLIPBOARD_RANGE_CONTAINS(range, 0, 5, "ab\r\n c")
4057 CLIPBOARD_RANGE_CONTAINS(range, 0, 0, "ab\r\n c")
4058 CLIPBOARD_RANGE_CONTAINS(range, 1, 1, "ab\r\n c")
4059 CLIPBOARD_RANGE_CONTAINS(range, 0, 1, "a")
4060 CLIPBOARD_RANGE_CONTAINS(range, 5, 6, "")
4062 /* Setting password char does not stop Copy */
4063 SendMessageA(hwnd, EM_SETPASSWORDCHAR, '*', 0);
4064 CLIPBOARD_RANGE_CONTAINS(range, 0, 1, "a")
4066 /* Cut can be undone */
4067 hr = ITextRange_SetRange(range, 0, 1);
4068 ok(SUCCEEDED(hr), "SetRange failed: 0x%08x\n", hr);
4069 hr = ITextRange_Cut(range, NULL);
4070 ok(hr == S_OK, "Cut failed: 0x%08x\n", hr);
4071 CLIPBOARD_RANGE_CONTAINS(range, 0, 4, "b\r\n c");
4072 hr = ITextDocument_Undo(doc, 1, NULL);
4073 todo_wine ok(hr == S_OK, "Undo failed: 0x%08x\n", hr);
4074 TODO_CLIPBOARD_RANGE_CONTAINS(range, 0, 5, "ab\r\n c");
4076 /* Cannot cut when read-only */
4077 SendMessageA(hwnd, EM_SETREADONLY, TRUE, 0);
4078 hr = ITextRange_SetRange(range, 0, 1);
4079 ok(SUCCEEDED(hr), "SetRange failed: 0x%08x\n", hr);
4080 hr = ITextRange_Cut(range, NULL);
4081 ok(hr == E_ACCESSDENIED, "got 0x%08x\n", hr);
4083 release_interfaces(&hwnd, &reole, &doc, NULL);
4084 ITextSelection_Release(selection);
4085 ITextRange_Release(range);
4088 START_TEST(richole)
4090 /* Must explicitly LoadLibrary(). The test has no references to functions in
4091 * RICHED20.DLL, so the linker doesn't actually link to it. */
4092 hmoduleRichEdit = LoadLibraryA("riched20.dll");
4093 ok(hmoduleRichEdit != NULL, "error: %d\n", (int) GetLastError());
4095 test_Interfaces();
4096 test_ITextDocument_Open();
4097 test_GetText();
4098 test_ITextSelection_GetChar();
4099 test_ITextSelection_GetStart_GetEnd();
4100 test_ITextSelection_Collapse();
4101 test_ITextDocument_Range();
4102 test_ITextRange_GetChar();
4103 test_ITextRange_ScrollIntoView();
4104 test_ITextRange_GetStart_GetEnd();
4105 test_ITextRange_SetRange();
4106 test_ITextRange_GetDuplicate();
4107 test_ITextRange_Collapse();
4108 test_GetClientSite();
4109 test_IOleWindow_GetWindow();
4110 test_IOleInPlaceSite_GetWindow();
4111 test_GetFont();
4112 test_GetPara();
4113 test_dispatch();
4114 test_ITextFont();
4115 test_Delete();
4116 test_SetText();
4117 test_InRange();
4118 test_ITextRange_IsEqual();
4119 test_Select();
4120 test_GetStoryType();
4121 test_SetFont();
4122 test_InsertObject();
4123 test_GetStoryLength();
4124 test_ITextSelection_GetDuplicate();
4125 test_Expand();
4126 test_MoveEnd_story();
4127 test_character_movement();
4128 test_clipboard();