[RICHED20_WINETEST] Sync with Wine Staging 1.7.55. CORE-10536
[reactos.git] / rostests / winetests / riched20 / richole.c
1 /*
2 * Tests for IRichEditOle and friends.
3 *
4 * Copyright 2008 Google (Dan Hipschman)
5 *
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.
10 *
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.
15 *
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
19 */
20
21 #define COBJMACROS
22
23 #include <stdarg.h>
24
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>
35
36 static HMODULE hmoduleRichEdit;
37
38 DEFINE_GUID(GUID_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
39
40 static const WCHAR sysW[] = {'S','y','s','t','e','m',0};
41
42 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
43 static void _expect_ref(IUnknown* obj, ULONG ref, int line)
44 {
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);
49 }
50
51 static HWND new_window(LPCSTR lpClassName, DWORD dwStyle, HWND parent)
52 {
53 HWND hwnd = CreateWindowA(lpClassName, NULL,
54 dwStyle | WS_POPUP | WS_HSCROLL | WS_VSCROLL | WS_VISIBLE,
55 0, 0, 200, 60, parent, NULL, hmoduleRichEdit, NULL);
56 return hwnd;
57 }
58
59 static HWND new_richedit(HWND parent)
60 {
61 return new_window(RICHEDIT_CLASS20A, ES_MULTILINE, parent);
62 }
63
64 static BOOL touch_file(LPCWSTR filename)
65 {
66 HANDLE file;
67
68 file = CreateFileW(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL,
69 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
70
71 if(file == INVALID_HANDLE_VALUE)
72 return FALSE;
73 CloseHandle(file);
74 return TRUE;
75 }
76
77 static BOOL is_existing_file(LPCWSTR filename)
78 {
79 HANDLE file;
80
81 file = CreateFileW(filename, GENERIC_READ, 0, NULL,
82 OPEN_EXISTING, 0, NULL);
83 if(file == INVALID_HANDLE_VALUE)
84 return FALSE;
85 CloseHandle(file);
86 return TRUE;
87 }
88
89 static void create_interfaces(HWND *w, IRichEditOle **reOle, ITextDocument **txtDoc,
90 ITextSelection **txtSel)
91 {
92 *w = new_richedit(NULL);
93 SendMessageA(*w, EM_GETOLEINTERFACE, 0, (LPARAM)reOle);
94 IRichEditOle_QueryInterface(*reOle, &IID_ITextDocument,
95 (void **) txtDoc);
96 ITextDocument_GetSelection(*txtDoc, txtSel);
97 }
98
99 static void release_interfaces(HWND *w, IRichEditOle **reOle, ITextDocument **txtDoc,
100 ITextSelection **txtSel)
101 {
102 if(txtSel)
103 ITextSelection_Release(*txtSel);
104 ITextDocument_Release(*txtDoc);
105 IRichEditOle_Release(*reOle);
106 DestroyWindow(*w);
107 }
108
109 static ULONG get_refcount(IUnknown *iface)
110 {
111 IUnknown_AddRef(iface);
112 return IUnknown_Release(iface);
113 }
114
115 static void test_Interfaces(void)
116 {
117 IRichEditOle *reOle = NULL, *reOle1 = NULL;
118 ITextDocument *txtDoc = NULL;
119 ITextSelection *txtSel = NULL, *txtSel2;
120 IUnknown *punk;
121 HRESULT hres;
122 LRESULT res;
123 HWND w;
124 ULONG refcount;
125
126 w = new_richedit(NULL);
127 if (!w) {
128 skip("Couldn't create window\n");
129 return;
130 }
131
132 res = SendMessageA(w, EM_GETOLEINTERFACE, 0, (LPARAM)&reOle);
133 ok(res, "SendMessage\n");
134 ok(reOle != NULL, "EM_GETOLEINTERFACE\n");
135 EXPECT_REF(reOle, 2);
136
137 res = SendMessageA(w, EM_GETOLEINTERFACE, 0, (LPARAM)&reOle1);
138 ok(res == 1, "SendMessage\n");
139 ok(reOle1 == reOle, "Should not return a new IRichEditOle interface\n");
140 EXPECT_REF(reOle, 3);
141
142 hres = IRichEditOle_QueryInterface(reOle, &IID_ITextDocument,
143 (void **) &txtDoc);
144 ok(hres == S_OK, "IRichEditOle_QueryInterface\n");
145 ok(txtDoc != NULL, "IRichEditOle_QueryInterface\n");
146
147 hres = ITextDocument_GetSelection(txtDoc, NULL);
148 ok(hres == E_INVALIDARG, "ITextDocument_GetSelection: 0x%x\n", hres);
149
150 EXPECT_REF(txtDoc, 4);
151
152 hres = ITextDocument_GetSelection(txtDoc, &txtSel);
153 ok(hres == S_OK, "got 0x%08x\n", hres);
154
155 EXPECT_REF(txtDoc, 4);
156 EXPECT_REF(txtSel, 2);
157
158 hres = ITextDocument_GetSelection(txtDoc, &txtSel2);
159 ok(hres == S_OK, "got 0x%08x\n", hres);
160 ok(txtSel2 == txtSel, "got %p, %p\n", txtSel, txtSel2);
161
162 EXPECT_REF(txtDoc, 4);
163 EXPECT_REF(txtSel, 3);
164
165 ITextSelection_Release(txtSel2);
166
167 punk = NULL;
168 hres = ITextSelection_QueryInterface(txtSel, &IID_ITextSelection, (void **) &punk);
169 ok(hres == S_OK, "ITextSelection_QueryInterface\n");
170 ok(punk != NULL, "ITextSelection_QueryInterface\n");
171 IUnknown_Release(punk);
172
173 punk = NULL;
174 hres = ITextSelection_QueryInterface(txtSel, &IID_ITextRange, (void **) &punk);
175 ok(hres == S_OK, "ITextSelection_QueryInterface\n");
176 ok(punk != NULL, "ITextSelection_QueryInterface\n");
177 IUnknown_Release(punk);
178
179 punk = NULL;
180 hres = ITextSelection_QueryInterface(txtSel, &IID_IDispatch, (void **) &punk);
181 ok(hres == S_OK, "ITextSelection_QueryInterface\n");
182 ok(punk != NULL, "ITextSelection_QueryInterface\n");
183 IUnknown_Release(punk);
184
185 punk = NULL;
186 hres = IRichEditOle_QueryInterface(reOle, &IID_IOleClientSite, (void **) &punk);
187 ok(hres == E_NOINTERFACE, "IRichEditOle_QueryInterface\n");
188
189 punk = NULL;
190 hres = IRichEditOle_QueryInterface(reOle, &IID_IOleWindow, (void **) &punk);
191 ok(hres == E_NOINTERFACE, "IRichEditOle_QueryInterface\n");
192
193 punk = NULL;
194 hres = IRichEditOle_QueryInterface(reOle, &IID_IOleInPlaceSite, (void **) &punk);
195 ok(hres == E_NOINTERFACE, "IRichEditOle_QueryInterface\n");
196
197 ITextDocument_Release(txtDoc);
198 IRichEditOle_Release(reOle);
199 refcount = IRichEditOle_Release(reOle);
200 ok(refcount == 1, "got wrong ref count: %d\n", refcount);
201 DestroyWindow(w);
202
203 /* Methods should return CO_E_RELEASED if the backing document has
204 been released. One test should suffice. */
205 hres = ITextSelection_CanEdit(txtSel, NULL);
206 ok(hres == CO_E_RELEASED, "ITextSelection after ITextDocument destroyed\n");
207
208 ITextSelection_Release(txtSel);
209 }
210
211 static void test_ITextDocument_Open(void)
212 {
213 IRichEditOle *reOle = NULL;
214 ITextDocument *txtDoc = NULL;
215 ITextSelection *txtSel = NULL;
216 HRESULT hres;
217 HWND w;
218 HANDLE hFile;
219 VARIANT testfile;
220 WCHAR filename[] = {'t', 'e', 's', 't','.','t','x','t', 0};
221 int result;
222 DWORD dw;
223 static const CHAR chACP[] = "TestSomeText";
224 static const CHAR chUTF8[] = "\xef\xbb\xbfTextWithUTF8BOM";
225 static const WCHAR chUTF16[] = {0xfeff, 'T', 'e', 's', 't', 'S', 'o', 'm',
226 'e', 'T', 'e', 'x', 't', 0};
227
228 #define MAX_BUF_LEN 1024
229 CHAR bufACP[MAX_BUF_LEN];
230 WCHAR bufUnicode[MAX_BUF_LEN];
231
232 static const int tomConstantsSingle[] =
233 {
234 tomReadOnly, tomShareDenyRead, tomShareDenyWrite,
235 tomCreateAlways, tomOpenExisting, tomOpenAlways,
236 tomTruncateExisting, tomRTF, tomText
237 };
238
239 static const int tomConstantsMulti[] =
240 {
241 tomReadOnly|tomShareDenyRead|tomPasteFile, tomReadOnly|tomPasteFile,
242 tomReadOnly|tomShareDenyWrite|tomPasteFile,
243 tomReadOnly|tomShareDenyRead|tomShareDenyWrite|tomPasteFile, tomShareDenyWrite|tomPasteFile,
244 tomShareDenyRead|tomShareDenyWrite|tomPasteFile, tomShareDenyRead|tomPasteFile,
245 tomShareDenyRead|tomShareDenyWrite, tomReadOnly|tomShareDenyRead|tomShareDenyWrite,
246 tomReadOnly|tomShareDenyWrite, tomReadOnly|tomShareDenyRead
247 };
248
249 int tomNumSingle = sizeof(tomConstantsSingle)/sizeof(tomConstantsSingle[0]);
250 int tomNumMulti = sizeof(tomConstantsMulti)/sizeof(tomConstantsMulti[0]);
251 int i;
252
253 V_VT(&testfile) = VT_BSTR;
254 V_BSTR(&testfile) = SysAllocString(filename);
255
256 for(i=0; i < tomNumSingle; i++)
257 {
258 touch_file(filename);
259 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
260 hres = ITextDocument_Open(txtDoc, &testfile, tomConstantsSingle[i], CP_ACP);
261 todo_wine ok(hres == S_OK, "ITextDocument_Open: Filename:test.txt Flags:0x%x Codepage:CP_ACP hres:0x%x\n",
262 tomConstantsSingle[i], hres);
263 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
264 DeleteFileW(filename);
265
266 touch_file(filename);
267 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
268 hres = ITextDocument_Open(txtDoc, &testfile, tomConstantsSingle[i], CP_UTF8);
269 todo_wine ok(hres == S_OK, "ITextDocument_Open: Filename:test.txt Flags:0x%x Codepage:CP_UTF8 hres:0x%x\n",
270 tomConstantsSingle[i], hres);
271 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
272 DeleteFileW(filename);
273 }
274
275 for(i=0; i < tomNumMulti; i++)
276 {
277 touch_file(filename);
278 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
279 hres = ITextDocument_Open(txtDoc, &testfile, tomConstantsMulti[i], CP_ACP);
280 todo_wine ok(hres == S_OK, "ITextDocument_Open: Filename:test.txt Flags:0x%x Codepage:CP_ACP hres:0x%x\n",
281 tomConstantsMulti[i], hres);
282 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
283 DeleteFileW(filename);
284
285 touch_file(filename);
286 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
287 hres = ITextDocument_Open(txtDoc, &testfile, tomConstantsMulti[i], CP_UTF8);
288 todo_wine ok(hres == S_OK, "ITextDocument_Open: Filename:test.txt Flags:0x%x Codepage:CP_UTF8 hres:0x%x\n",
289 tomConstantsMulti[i], hres);
290 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
291 DeleteFileW(filename);
292 }
293
294 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
295 hres = ITextDocument_Open(txtDoc, &testfile, tomCreateAlways, CP_ACP);
296 todo_wine ok(hres == S_OK, "ITextDocument_Open should success Codepage:CP_ACP\n");
297 todo_wine ok(is_existing_file(filename), "ITextDocument_Open should create a file\n");
298 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
299 DeleteFileW(filename);
300
301 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
302 hres = ITextDocument_Open(txtDoc, &testfile, tomCreateAlways, CP_UTF8);
303 todo_wine ok(hres == S_OK, "ITextDocument_Open should success Codepage:CP_UTF8\n");
304 todo_wine ok(is_existing_file(filename), "ITextDocument_Open should create a file\n");
305 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
306 DeleteFileW(filename);
307
308 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
309 hres = ITextDocument_Open(txtDoc, &testfile, tomOpenAlways, CP_ACP);
310 todo_wine ok(hres == S_OK, "ITextDocument_Open should success Codepage:CP_ACP\n");
311 todo_wine ok(is_existing_file(filename), "ITextDocument_Open should create a file\n");
312 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
313 DeleteFileW(filename);
314
315 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
316 hres = ITextDocument_Open(txtDoc, &testfile, tomOpenAlways, CP_UTF8);
317 todo_wine ok(hres == S_OK, "ITextDocument_Open should success Codepage:CP_UTF8\n");
318 todo_wine ok(is_existing_file(filename), "ITextDocument_Open should create a file\n");
319 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
320 DeleteFileW(filename);
321
322 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
323 hres = ITextDocument_Open(txtDoc, &testfile, tomCreateNew, CP_ACP);
324 todo_wine ok(hres == S_OK, "ITextDocument_Open should success Codepage:CP_ACP\n");
325 todo_wine ok(is_existing_file(filename), "ITextDocument_Open should create a file\n");
326 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
327 DeleteFileW(filename);
328
329 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
330 hres = ITextDocument_Open(txtDoc, &testfile, tomCreateNew, CP_UTF8);
331 todo_wine ok(hres == S_OK, "ITextDocument_Open should success Codepage:CP_UTF8\n");
332 todo_wine ok(is_existing_file(filename), "ITextDocument_Open should create a file\n");
333 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
334 DeleteFileW(filename);
335
336 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
337 touch_file(filename);
338 hres = ITextDocument_Open(txtDoc, &testfile, tomCreateNew, CP_ACP);
339 todo_wine ok(hres == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "ITextDocument_Open should fail Codepage:CP_ACP\n");
340 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
341 DeleteFileW(filename);
342
343 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
344 touch_file(filename);
345 hres = ITextDocument_Open(txtDoc, &testfile, tomCreateNew, CP_UTF8);
346 todo_wine ok(hres == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "ITextDocument_Open should fail Codepage:CP_UTF8\n");
347 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
348 DeleteFileW(filename);
349
350 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
351 hres = ITextDocument_Open(txtDoc, &testfile, tomOpenExisting, CP_ACP);
352 todo_wine ok(hres == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "ITextDocument_Open should fail Codepage:CP_ACP\n");
353 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
354
355 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
356 hres = ITextDocument_Open(txtDoc, &testfile, tomOpenExisting, CP_UTF8);
357 todo_wine ok(hres == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "ITextDocument_Open should fail Codepage:CP_UTF8\n");
358 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
359
360 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
361 DeleteFileW(filename);
362 hres = ITextDocument_Open(txtDoc, &testfile, tomText, CP_ACP);
363 todo_wine {
364 ok(hres == S_OK, "got 0x%08x\n", hres);
365 ok(is_existing_file(filename) == TRUE, "a file should be created default\n");
366 }
367 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
368 DeleteFileW(filename);
369
370 /* test of share mode */
371 touch_file(filename);
372 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
373 hres = ITextDocument_Open(txtDoc, &testfile, tomShareDenyRead, CP_ACP);
374 todo_wine
375 ok(hres == S_OK, "got 0x%08x\n", hres);
376 SetLastError(0xdeadbeef);
377 hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
378 FILE_ATTRIBUTE_NORMAL, NULL);
379 todo_wine ok(GetLastError() == ERROR_SHARING_VIOLATION, "ITextDocument_Open should fail\n");
380 CloseHandle(hFile);
381 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
382 DeleteFileW(filename);
383
384 touch_file(filename);
385 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
386 hres = ITextDocument_Open(txtDoc, &testfile, tomShareDenyWrite, CP_ACP);
387 todo_wine
388 ok(hres == S_OK, "got 0x%08x\n", hres);
389 SetLastError(0xdeadbeef);
390 hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
391 FILE_ATTRIBUTE_NORMAL, NULL);
392 todo_wine ok(GetLastError() == ERROR_SHARING_VIOLATION, "ITextDocument_Open should fail\n");
393 CloseHandle(hFile);
394 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
395 DeleteFileW(filename);
396
397 touch_file(filename);
398 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
399 SetLastError(0xdeadbeef);
400 hres = ITextDocument_Open(txtDoc, &testfile, tomShareDenyWrite|tomShareDenyRead, CP_ACP);
401 todo_wine
402 ok(hres == S_OK, "got 0x%08x\n", hres);
403 hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
404 FILE_ATTRIBUTE_NORMAL, NULL);
405 todo_wine ok(GetLastError() == ERROR_SHARING_VIOLATION, "ITextDocument_Open should fail\n");
406 CloseHandle(hFile);
407 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
408 DeleteFileW(filename);
409
410 /* tests to check the content */
411 hFile = CreateFileW(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS,
412 FILE_ATTRIBUTE_NORMAL, NULL);
413 WriteFile(hFile, chACP, sizeof(chACP)-sizeof(CHAR), &dw, NULL);
414 CloseHandle(hFile);
415 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
416 hres = ITextDocument_Open(txtDoc, &testfile, tomReadOnly, CP_ACP);
417 todo_wine
418 ok(hres == S_OK, "got 0x%08x\n", hres);
419 result = SendMessageA(w, WM_GETTEXT, 1024, (LPARAM)bufACP);
420 todo_wine ok(result == 12, "ITextDocument_Open: Test ASCII returned %d, expected 12\n", result);
421 result = strcmp(bufACP, chACP);
422 todo_wine ok(result == 0, "ITextDocument_Open: Test ASCII set wrong text: Result: %s\n", bufACP);
423 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
424 DeleteFileW(filename);
425
426 hFile = CreateFileW(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS,
427 FILE_ATTRIBUTE_NORMAL, NULL);
428 WriteFile(hFile, chUTF8, sizeof(chUTF8)-sizeof(CHAR), &dw, NULL);
429 CloseHandle(hFile);
430 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
431 hres = ITextDocument_Open(txtDoc, &testfile, tomReadOnly, CP_UTF8);
432 todo_wine
433 ok(hres == S_OK, "got 0x%08x\n", hres);
434 result = SendMessageA(w, WM_GETTEXT, 1024, (LPARAM)bufACP);
435 todo_wine ok(result == 15, "ITextDocument_Open: Test UTF-8 returned %d, expected 15\n", result);
436 result = strcmp(bufACP, &chUTF8[3]);
437 todo_wine ok(result == 0, "ITextDocument_Open: Test UTF-8 set wrong text: Result: %s\n", bufACP);
438 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
439 DeleteFileW(filename);
440
441 hFile = CreateFileW(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS,
442 FILE_ATTRIBUTE_NORMAL, NULL);
443 WriteFile(hFile, chUTF16, sizeof(chUTF16)-sizeof(WCHAR), &dw, NULL);
444 CloseHandle(hFile);
445 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
446 hres = ITextDocument_Open(txtDoc, &testfile, tomReadOnly, 1200);
447 todo_wine
448 ok(hres == S_OK, "got 0x%08x\n", hres);
449 result = SendMessageW(w, WM_GETTEXT, 1024, (LPARAM)bufUnicode);
450 todo_wine ok(result == 12, "ITextDocument_Open: Test UTF-16 returned %d, expected 12\n", result);
451 result = lstrcmpW(bufUnicode, &chUTF16[1]);
452 todo_wine ok(result == 0, "ITextDocument_Open: Test UTF-16 set wrong text: Result: %s\n", wine_dbgstr_w(bufUnicode));
453 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
454 DeleteFileW(filename);
455
456 VariantClear(&testfile);
457 }
458
459 static void test_GetText(void)
460 {
461 HWND w;
462 IRichEditOle *reOle = NULL;
463 ITextDocument *txtDoc = NULL;
464 ITextSelection *txtSel = NULL;
465 HRESULT hres;
466 BSTR bstr = NULL;
467 int first, lim;
468 static const CHAR test_text1[] = "TestSomeText";
469 static const WCHAR bufW1[] = {'T', 'e', 's', 't', 0};
470 static const WCHAR bufW2[] = {'T', 'e', 'x', 't', '\r', 0};
471 static const WCHAR bufW3[] = {'T', 'e', 'x', 't', 0};
472 static const WCHAR bufW4[] = {'T', 'e', 's', 't', 'S', 'o', 'm',
473 'e', 'T', 'e', 'x', 't', '\r', 0};
474 static const WCHAR bufW5[] = {'\r', 0};
475 static const WCHAR bufW6[] = {'T','e','s','t','S','o','m','e','T',0};
476 BOOL is64bit = sizeof(void *) > sizeof(int);
477 ITextRange *range;
478
479 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
480 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
481
482 /* ITextSelection */
483 first = 0, lim = 4;
484 SendMessageA(w, EM_SETSEL, first, lim);
485 hres = ITextSelection_GetText(txtSel, &bstr);
486 ok(hres == S_OK, "ITextSelection_GetText\n");
487 ok(!lstrcmpW(bstr, bufW1), "got wrong text: %s\n", wine_dbgstr_w(bstr));
488 SysFreeString(bstr);
489
490 first = 4, lim = 0;
491 SendMessageA(w, EM_SETSEL, first, lim);
492 hres = ITextSelection_GetText(txtSel, &bstr);
493 ok(hres == S_OK, "ITextSelection_GetText\n");
494 ok(!lstrcmpW(bstr, bufW1), "got wrong text: %s\n", wine_dbgstr_w(bstr));
495 SysFreeString(bstr);
496
497 first = 1, lim = 1;
498 SendMessageA(w, EM_SETSEL, first, lim);
499 hres = ITextSelection_GetText(txtSel, &bstr);
500 ok(hres == S_OK, "ITextSelection_GetText\n");
501 ok(!bstr, "got wrong text: %s\n", wine_dbgstr_w(bstr));
502
503 if (!is64bit)
504 {
505 hres = ITextSelection_GetText(txtSel, NULL);
506 ok(hres == E_INVALIDARG, "ITextSelection_GetText\n");
507 }
508
509 first = 8, lim = 12;
510 SendMessageA(w, EM_SETSEL, first, lim);
511 hres = ITextSelection_GetText(txtSel, &bstr);
512 ok(hres == S_OK, "ITextSelection_GetText\n");
513 ok(!lstrcmpW(bstr, bufW3), "got wrong text: %s\n", wine_dbgstr_w(bstr));
514 SysFreeString(bstr);
515
516 first = 8, lim = 13;
517 SendMessageA(w, EM_SETSEL, first, lim);
518 hres = ITextSelection_GetText(txtSel, &bstr);
519 ok(hres == S_OK, "ITextSelection_GetText\n");
520 ok(!lstrcmpW(bstr, bufW2), "got wrong text: %s\n", wine_dbgstr_w(bstr));
521 SysFreeString(bstr);
522
523 first = 12, lim = 13;
524 SendMessageA(w, EM_SETSEL, first, lim);
525 hres = ITextSelection_GetText(txtSel, &bstr);
526 ok(hres == S_OK, "ITextSelection_GetText\n");
527 ok(!lstrcmpW(bstr, bufW5), "got wrong text: %s\n", wine_dbgstr_w(bstr));
528 SysFreeString(bstr);
529
530 first = 0, lim = -1;
531 SendMessageA(w, EM_SETSEL, first, lim);
532 hres = ITextSelection_GetText(txtSel, &bstr);
533 ok(hres == S_OK, "ITextSelection_GetText\n");
534 ok(!lstrcmpW(bstr, bufW4), "got wrong text: %s\n", wine_dbgstr_w(bstr));
535 SysFreeString(bstr);
536
537 first = -1, lim = 9;
538 SendMessageA(w, EM_SETSEL, first, lim);
539 hres = ITextSelection_GetText(txtSel, &bstr);
540 ok(hres == S_OK, "ITextSelection_GetText\n");
541 ok(!bstr, "got wrong text: %s\n", wine_dbgstr_w(bstr));
542
543 /* ITextRange */
544 hres = ITextDocument_Range(txtDoc, 0, 4, &range);
545 ok(hres == S_OK, "got 0x%08x\n", hres);
546 hres = ITextRange_GetText(range, &bstr);
547 ok(hres == S_OK, "got 0x%08x\n", hres);
548 ok(!lstrcmpW(bstr, bufW1), "got wrong text: %s\n", wine_dbgstr_w(bstr));
549
550 SysFreeString(bstr);
551 ITextRange_Release(range);
552
553 hres = ITextDocument_Range(txtDoc, 4, 0, &range);
554 ok(hres == S_OK, "got 0x%08x\n", hres);
555 hres = ITextRange_GetText(range, &bstr);
556 ok(hres == S_OK, "got 0x%08x\n", hres);
557 ok(!lstrcmpW(bstr, bufW1), "got wrong text: %s\n", wine_dbgstr_w(bstr));
558
559 SysFreeString(bstr);
560 ITextRange_Release(range);
561
562 hres = ITextDocument_Range(txtDoc, 1, 1, &range);
563 ok(hres == S_OK, "got 0x%08x\n", hres);
564 hres = ITextRange_GetText(range, &bstr);
565 ok(hres == S_OK, "got 0x%08x\n", hres);
566 ok(!bstr, "got wrong text: %s\n", wine_dbgstr_w(bstr));
567 if (!is64bit)
568 {
569 hres = ITextRange_GetText(range, NULL);
570 ok(hres == E_INVALIDARG, "got 0x%08x\n", hres);
571 }
572 ITextRange_Release(range);
573
574 hres = ITextDocument_Range(txtDoc, 8, 12, &range);
575 ok(hres == S_OK, "got 0x%08x\n", hres);
576 hres = ITextRange_GetText(range, &bstr);
577 ok(hres == S_OK, "got 0x%08x\n", hres);
578 ok(!lstrcmpW(bstr, bufW3), "got wrong text: %s\n", wine_dbgstr_w(bstr));
579
580 SysFreeString(bstr);
581 ITextRange_Release(range);
582
583 hres = ITextDocument_Range(txtDoc, 8, 13, &range);
584 ok(hres == S_OK, "got 0x%08x\n", hres);
585 hres = ITextRange_GetText(range, &bstr);
586 ok(hres == S_OK, "got 0x%08x\n", hres);
587 ok(!lstrcmpW(bstr, bufW2), "got wrong text: %s\n", wine_dbgstr_w(bstr));
588
589 SysFreeString(bstr);
590 ITextRange_Release(range);
591
592 hres = ITextDocument_Range(txtDoc, 12, 13, &range);
593 ok(hres == S_OK, "got 0x%08x\n", hres);
594 hres = ITextRange_GetText(range, &bstr);
595 ok(hres == S_OK, "got 0x%08x\n", hres);
596 ok(!lstrcmpW(bstr, bufW5), "got wrong text: %s\n", wine_dbgstr_w(bstr));
597
598 SysFreeString(bstr);
599 ITextRange_Release(range);
600
601 hres = ITextDocument_Range(txtDoc, 0, -1, &range);
602 ok(hres == S_OK, "got 0x%08x\n", hres);
603 hres = ITextRange_GetText(range, &bstr);
604 ok(hres == S_OK, "got 0x%08x\n", hres);
605 ok(!bstr, "got wrong text: %s\n", wine_dbgstr_w(bstr));
606 ITextRange_Release(range);
607
608 hres = ITextDocument_Range(txtDoc, -1, 9, &range);
609 ok(hres == S_OK, "got 0x%08x\n", hres);
610 hres = ITextRange_GetText(range, &bstr);
611 ok(hres == S_OK, "got 0x%08x\n", hres);
612 ok(!lstrcmpW(bstr, bufW6), "got wrong text: %s\n", wine_dbgstr_w(bstr));
613
614 SysFreeString(bstr);
615
616 release_interfaces(&w, &reOle, &txtDoc, NULL);
617
618 /* detached selection/range */
619 if (is64bit) {
620 bstr = (void*)0xdeadbeef;
621 hres = ITextSelection_GetText(txtSel, &bstr);
622 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
623 todo_wine
624 ok(bstr == NULL, "got %p\n", bstr);
625
626 bstr = (void*)0xdeadbeef;
627 hres = ITextRange_GetText(range, &bstr);
628 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
629 todo_wine
630 ok(bstr == NULL, "got %p\n", bstr);
631 }
632 else {
633 hres = ITextSelection_GetText(txtSel, NULL);
634 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
635
636 hres = ITextRange_GetText(range, NULL);
637 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
638 }
639
640 ITextRange_Release(range);
641 ITextSelection_Release(txtSel);
642 }
643
644 static void test_ITextDocument_Range(void)
645 {
646 static const CHAR test_text1[] = "TestSomeText";
647 HWND w;
648 IRichEditOle *reOle = NULL;
649 ITextDocument *txtDoc = NULL;
650 ITextRange *txtRge, *range2;
651 HRESULT hres;
652 LONG value;
653
654 create_interfaces(&w, &reOle, &txtDoc, NULL);
655 hres = ITextDocument_Range(txtDoc, 0, 0, &txtRge);
656 ok(hres == S_OK, "ITextDocument_Range fails 0x%x.\n", hres);
657 EXPECT_REF(txtRge, 1);
658
659 hres = ITextDocument_Range(txtDoc, 0, 0, &range2);
660 ok(hres == S_OK, "ITextDocument_Range fails 0x%x.\n", hres);
661 ok(range2 != txtRge, "A new pointer should be returned\n");
662 ITextRange_Release(range2);
663
664 hres = ITextDocument_Range(txtDoc, 0, 0, NULL);
665 ok(hres == E_INVALIDARG, "ITextDocument_Range should fail 0x%x.\n", hres);
666
667 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
668
669 hres = ITextDocument_Range(txtDoc, 8, 30, &range2);
670 ok(hres == S_OK, "ITextDocument_Range fails 0x%x.\n", hres);
671 hres = ITextRange_GetStart(range2, &value);
672 ok(hres == S_OK, "got 0x%08x\n", hres);
673 ok(value == 8, "got %d\n", value);
674
675 hres = ITextRange_GetEnd(range2, &value);
676 ok(hres == S_OK, "got 0x%08x\n", hres);
677 ok(value == 13, "got %d\n", value);
678 ITextRange_Release(range2);
679
680 release_interfaces(&w, &reOle, &txtDoc, NULL);
681 hres = ITextRange_CanEdit(txtRge, NULL);
682 ok(hres == CO_E_RELEASED, "ITextRange after ITextDocument destroyed\n");
683 ITextRange_Release(txtRge);
684 }
685
686 static void test_ITextRange_GetChar(void)
687 {
688 HWND w;
689 IRichEditOle *reOle = NULL;
690 ITextDocument *txtDoc = NULL;
691 ITextRange *txtRge = NULL;
692 HRESULT hres;
693 LONG pch;
694 int first, lim;
695 static const CHAR test_text1[] = "TestSomeText";
696
697 first = 0, lim = 4;
698 create_interfaces(&w, &reOle, &txtDoc, NULL);
699 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
700 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
701 ok(hres == S_OK, "got 0x%08x\n", hres);
702 pch = 0xdeadbeef;
703 hres = ITextRange_GetChar(txtRge, &pch);
704 ok(hres == S_OK, "ITextRange_GetChar\n");
705 ok(pch == 'T', "got wrong char: %c\n", pch);
706 ITextRange_Release(txtRge);
707 release_interfaces(&w, &reOle, &txtDoc, NULL);
708
709 first = 0, lim = 0;
710 create_interfaces(&w, &reOle, &txtDoc, NULL);
711 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
712 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
713 ok(hres == S_OK, "got 0x%08x\n", hres);
714 pch = 0xdeadbeef;
715 hres = ITextRange_GetChar(txtRge, &pch);
716 ok(hres == S_OK, "ITextRange_GetChar\n");
717 ok(pch == 'T', "got wrong char: %c\n", pch);
718 ITextRange_Release(txtRge);
719 release_interfaces(&w, &reOle, &txtDoc, NULL);
720
721 first = 12, lim = 12;
722 create_interfaces(&w, &reOle, &txtDoc, NULL);
723 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
724 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
725 ok(hres == S_OK, "got 0x%08x\n", hres);
726 pch = 0xdeadbeef;
727 hres = ITextRange_GetChar(txtRge, &pch);
728 ok(hres == S_OK, "ITextRange_GetChar\n");
729 ok(pch == '\r', "got wrong char: %c\n", pch);
730 ITextRange_Release(txtRge);
731 release_interfaces(&w, &reOle, &txtDoc, NULL);
732
733 first = 13, lim = 13;
734 create_interfaces(&w, &reOle, &txtDoc, NULL);
735 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
736 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
737 ok(hres == S_OK, "got 0x%08x\n", hres);
738 pch = 0xdeadbeef;
739 hres = ITextRange_GetChar(txtRge, &pch);
740 ok(hres == S_OK, "ITextRange_GetChar\n");
741 ok(pch == '\r', "got wrong char: %c\n", pch);
742 ITextRange_Release(txtRge);
743 release_interfaces(&w, &reOle, &txtDoc, NULL);
744
745 create_interfaces(&w, &reOle, &txtDoc, NULL);
746 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
747 first = 12, lim = 12;
748 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
749 ok(hres == S_OK, "got 0x%08x\n", hres);
750 hres = ITextRange_GetChar(txtRge, NULL);
751 ok(hres == E_INVALIDARG, "ITextRange_GetChar\n");
752
753 release_interfaces(&w, &reOle, &txtDoc, NULL);
754
755 hres = ITextRange_GetChar(txtRge, NULL);
756 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
757
758 hres = ITextRange_GetChar(txtRge, &pch);
759 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
760
761 ITextRange_Release(txtRge);
762 }
763
764 static void test_ITextSelection_GetChar(void)
765 {
766 HWND w;
767 IRichEditOle *reOle = NULL;
768 ITextDocument *txtDoc = NULL;
769 ITextSelection *txtSel = NULL;
770 HRESULT hres;
771 LONG pch;
772 int first, lim;
773 static const CHAR test_text1[] = "TestSomeText";
774
775 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
776 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
777
778 first = 0, lim = 4;
779 SendMessageA(w, EM_SETSEL, first, lim);
780 pch = 0xdeadbeef;
781 hres = ITextSelection_GetChar(txtSel, &pch);
782 ok(hres == S_OK, "ITextSelection_GetChar\n");
783 ok(pch == 'T', "got wrong char: %c\n", pch);
784
785 first = 0, lim = 0;
786 SendMessageA(w, EM_SETSEL, first, lim);
787 pch = 0xdeadbeef;
788 hres = ITextSelection_GetChar(txtSel, &pch);
789 ok(hres == S_OK, "ITextSelection_GetChar\n");
790 ok(pch == 'T', "got wrong char: %c\n", pch);
791
792 first = 12, lim = 12;
793 SendMessageA(w, EM_SETSEL, first, lim);
794 pch = 0xdeadbeef;
795 hres = ITextSelection_GetChar(txtSel, &pch);
796 ok(hres == S_OK, "ITextSelection_GetChar\n");
797 ok(pch == '\r', "got wrong char: %c\n", pch);
798
799 first = 13, lim = 13;
800 SendMessageA(w, EM_SETSEL, first, lim);
801 pch = 0xdeadbeef;
802 hres = ITextSelection_GetChar(txtSel, &pch);
803 ok(hres == S_OK, "ITextSelection_GetChar\n");
804 ok(pch == '\r', "got wrong char: %c\n", pch);
805
806 hres = ITextSelection_GetChar(txtSel, NULL);
807 ok(hres == E_INVALIDARG, "ITextSelection_GetChar\n");
808
809 release_interfaces(&w, &reOle, &txtDoc, NULL);
810
811 hres = ITextSelection_GetChar(txtSel, NULL);
812 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
813
814 hres = ITextSelection_GetChar(txtSel, &pch);
815 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
816
817 ITextSelection_Release(txtSel);
818 }
819
820 static void test_ITextRange_GetStart_GetEnd(void)
821 {
822 HWND w;
823 IRichEditOle *reOle = NULL;
824 ITextDocument *txtDoc = NULL;
825 ITextRange *txtRge = NULL;
826 HRESULT hres;
827 int first, lim, start, end;
828 static const CHAR test_text1[] = "TestSomeText";
829
830 create_interfaces(&w, &reOle, &txtDoc, NULL);
831 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
832
833 first = 1, lim = 6;
834 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
835 ok(hres == S_OK, "got 0x%08x\n", hres);
836 start = 0xdeadbeef;
837 hres = ITextRange_GetStart(txtRge, &start);
838 ok(hres == S_OK, "ITextRange_GetStart\n");
839 ok(start == 1, "got wrong start value: %d\n", start);
840 end = 0xdeadbeef;
841 hres = ITextRange_GetEnd(txtRge, &end);
842 ok(hres == S_OK, "ITextRange_GetEnd\n");
843 ok(end == 6, "got wrong end value: %d\n", end);
844 ITextRange_Release(txtRge);
845
846 first = 6, lim = 1;
847 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
848 ok(hres == S_OK, "got 0x%08x\n", hres);
849 start = 0xdeadbeef;
850 hres = ITextRange_GetStart(txtRge, &start);
851 ok(hres == S_OK, "ITextRange_GetStart\n");
852 ok(start == 1, "got wrong start value: %d\n", start);
853 end = 0xdeadbeef;
854 hres = ITextRange_GetEnd(txtRge, &end);
855 ok(hres == S_OK, "ITextRange_GetEnd\n");
856 ok(end == 6, "got wrong end value: %d\n", end);
857 ITextRange_Release(txtRge);
858
859 first = -1, lim = 13;
860 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
861 ok(hres == S_OK, "got 0x%08x\n", hres);
862 start = 0xdeadbeef;
863 hres = ITextRange_GetStart(txtRge, &start);
864 ok(hres == S_OK, "ITextRange_GetStart\n");
865 ok(start == 0, "got wrong start value: %d\n", start);
866 end = 0xdeadbeef;
867 hres = ITextRange_GetEnd(txtRge, &end);
868 ok(hres == S_OK, "ITextRange_GetEnd\n");
869 ok(end == 13, "got wrong end value: %d\n", end);
870 ITextRange_Release(txtRge);
871
872 first = 13, lim = 13;
873 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
874 ok(hres == S_OK, "got 0x%08x\n", hres);
875 start = 0xdeadbeef;
876 hres = ITextRange_GetStart(txtRge, &start);
877 ok(hres == S_OK, "ITextRange_GetStart\n");
878 ok(start == 12, "got wrong start value: %d\n", start);
879 end = 0xdeadbeef;
880 hres = ITextRange_GetEnd(txtRge, &end);
881 ok(hres == S_OK, "ITextRange_GetEnd\n");
882 ok(end == 12, "got wrong end value: %d\n", end);
883
884 /* SetStart */
885 hres = ITextRange_SetStart(txtRge, 0);
886 ok(hres == S_OK, "got 0x%08x\n", hres);
887
888 /* same value */
889 hres = ITextRange_SetStart(txtRge, 0);
890 ok(hres == S_FALSE, "got 0x%08x\n", hres);
891
892 hres = ITextRange_SetStart(txtRge, 1);
893 ok(hres == S_OK, "got 0x%08x\n", hres);
894
895 /* negative resets to 0, return value is S_FALSE when
896 position wasn't changed */
897 hres = ITextRange_SetStart(txtRge, -1);
898 ok(hres == S_OK, "got 0x%08x\n", hres);
899
900 hres = ITextRange_SetStart(txtRge, -1);
901 ok(hres == S_FALSE, "got 0x%08x\n", hres);
902
903 hres = ITextRange_SetStart(txtRge, 0);
904 ok(hres == S_FALSE, "got 0x%08x\n", hres);
905
906 start = -1;
907 hres = ITextRange_GetStart(txtRge, &start);
908 ok(hres == S_OK, "got 0x%08x\n", hres);
909 ok(start == 0, "got %d\n", start);
910
911 /* greater than initial end, but less than total char count */
912 hres = ITextRange_SetStart(txtRge, 1);
913 ok(hres == S_OK, "got 0x%08x\n", hres);
914
915 hres = ITextRange_SetEnd(txtRge, 3);
916 ok(hres == S_OK, "got 0x%08x\n", hres);
917
918 hres = ITextRange_SetStart(txtRge, 10);
919 ok(hres == S_OK, "got 0x%08x\n", hres);
920
921 start = 0;
922 hres = ITextRange_GetStart(txtRge, &start);
923 ok(hres == S_OK, "got 0x%08x\n", hres);
924 ok(start == 10, "got %d\n", start);
925
926 end = 0;
927 hres = ITextRange_GetEnd(txtRge, &end);
928 ok(hres == S_OK, "got 0x%08x\n", hres);
929 ok(end == 10, "got %d\n", end);
930
931 /* more that total text length */
932 hres = ITextRange_SetStart(txtRge, 50);
933 ok(hres == S_OK, "got 0x%08x\n", hres);
934
935 start = 0;
936 hres = ITextRange_GetStart(txtRge, &start);
937 ok(hres == S_OK, "got 0x%08x\n", hres);
938 ok(start == 12, "got %d\n", start);
939
940 end = 0;
941 hres = ITextRange_GetEnd(txtRge, &end);
942 ok(hres == S_OK, "got 0x%08x\n", hres);
943 ok(end == 12, "got %d\n", end);
944
945 /* SetEnd */
946 hres = ITextRange_SetStart(txtRge, 0);
947 ok(hres == S_OK, "got 0x%08x\n", hres);
948
949 /* same value */
950 hres = ITextRange_SetEnd(txtRge, 5);
951 ok(hres == S_OK, "got 0x%08x\n", hres);
952
953 hres = ITextRange_SetEnd(txtRge, 5);
954 ok(hres == S_FALSE, "got 0x%08x\n", hres);
955
956 /* negative resets to 0 */
957 hres = ITextRange_SetEnd(txtRge, -1);
958 ok(hres == S_OK, "got 0x%08x\n", hres);
959
960 end = -1;
961 hres = ITextRange_GetEnd(txtRge, &end);
962 ok(hres == S_OK, "got 0x%08x\n", hres);
963 ok(end == 0, "got %d\n", end);
964
965 start = -1;
966 hres = ITextRange_GetStart(txtRge, &start);
967 ok(hres == S_OK, "got 0x%08x\n", hres);
968 ok(start == 0, "got %d\n", start);
969
970 /* greater than initial end, but less than total char count */
971 hres = ITextRange_SetStart(txtRge, 3);
972 ok(hres == S_OK, "got 0x%08x\n", hres);
973
974 hres = ITextRange_SetEnd(txtRge, 1);
975 ok(hres == S_OK, "got 0x%08x\n", hres);
976
977 start = 0;
978 hres = ITextRange_GetStart(txtRge, &start);
979 ok(hres == S_OK, "got 0x%08x\n", hres);
980 ok(start == 1, "got %d\n", start);
981
982 end = 0;
983 hres = ITextRange_GetEnd(txtRge, &end);
984 ok(hres == S_OK, "got 0x%08x\n", hres);
985 ok(end == 1, "got %d\n", end);
986
987 /* more than total count */
988 hres = ITextRange_SetEnd(txtRge, 50);
989 ok(hres == S_OK, "got 0x%08x\n", hres);
990
991 start = 0;
992 hres = ITextRange_GetStart(txtRge, &start);
993 ok(hres == S_OK, "got 0x%08x\n", hres);
994 ok(start == 1, "got %d\n", start);
995
996 end = 0;
997 hres = ITextRange_GetEnd(txtRge, &end);
998 ok(hres == S_OK, "got 0x%08x\n", hres);
999 ok(end == 13, "got %d\n", end);
1000
1001 /* zero */
1002 hres = ITextRange_SetEnd(txtRge, 0);
1003 ok(hres == S_OK, "got 0x%08x\n", hres);
1004
1005 start = 0;
1006 hres = ITextRange_GetStart(txtRge, &start);
1007 ok(hres == S_OK, "got 0x%08x\n", hres);
1008 ok(start == 0, "got %d\n", start);
1009
1010 end = 0;
1011 hres = ITextRange_GetEnd(txtRge, &end);
1012 ok(hres == S_OK, "got 0x%08x\n", hres);
1013 ok(end == 0, "got %d\n", end);
1014
1015 release_interfaces(&w, &reOle, &txtDoc, NULL);
1016
1017 /* detached range */
1018 hres = ITextRange_SetStart(txtRge, 0);
1019 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1020
1021 hres = ITextRange_SetEnd(txtRge, 3);
1022 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1023
1024 hres = ITextRange_GetStart(txtRge, &start);
1025 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1026
1027 hres = ITextRange_GetStart(txtRge, NULL);
1028 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1029
1030 hres = ITextRange_GetEnd(txtRge, &end);
1031 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1032
1033 hres = ITextRange_GetEnd(txtRge, NULL);
1034 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1035
1036 ITextRange_Release(txtRge);
1037 }
1038
1039 static void test_ITextSelection_GetStart_GetEnd(void)
1040 {
1041 HWND w;
1042 IRichEditOle *reOle = NULL;
1043 ITextDocument *txtDoc = NULL;
1044 ITextSelection *txtSel = NULL;
1045 HRESULT hres;
1046 int first, lim, start, end;
1047 static const CHAR test_text1[] = "TestSomeText";
1048
1049 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
1050 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
1051
1052 first = 2, lim = 5;
1053 SendMessageA(w, EM_SETSEL, first, lim);
1054 start = 0xdeadbeef;
1055 hres = ITextSelection_GetStart(txtSel, &start);
1056 ok(hres == S_OK, "ITextSelection_GetStart\n");
1057 ok(start == 2, "got wrong start value: %d\n", start);
1058 end = 0xdeadbeef;
1059 hres = ITextSelection_GetEnd(txtSel, &end);
1060 ok(hres == S_OK, "ITextSelection_GetEnd\n");
1061 ok(end == 5, "got wrong end value: %d\n", end);
1062
1063 first = 5, lim = 2;
1064 SendMessageA(w, EM_SETSEL, first, lim);
1065 start = 0xdeadbeef;
1066 hres = ITextSelection_GetStart(txtSel, &start);
1067 ok(hres == S_OK, "ITextSelection_GetStart\n");
1068 ok(start == 2, "got wrong start value: %d\n", start);
1069 end = 0xdeadbeef;
1070 hres = ITextSelection_GetEnd(txtSel, &end);
1071 ok(hres == S_OK, "ITextSelection_GetEnd\n");
1072 ok(end == 5, "got wrong end value: %d\n", end);
1073
1074 first = 0, lim = -1;
1075 SendMessageA(w, EM_SETSEL, first, lim);
1076 start = 0xdeadbeef;
1077 hres = ITextSelection_GetStart(txtSel, &start);
1078 ok(hres == S_OK, "ITextSelection_GetStart\n");
1079 ok(start == 0, "got wrong start value: %d\n", start);
1080 end = 0xdeadbeef;
1081 hres = ITextSelection_GetEnd(txtSel, &end);
1082 ok(hres == S_OK, "ITextSelection_GetEnd\n");
1083 ok(end == 13, "got wrong end value: %d\n", end);
1084
1085 first = 13, lim = 13;
1086 SendMessageA(w, EM_SETSEL, first, lim);
1087 start = 0xdeadbeef;
1088 hres = ITextSelection_GetStart(txtSel, &start);
1089 ok(hres == S_OK, "ITextSelection_GetStart\n");
1090 ok(start == 12, "got wrong start value: %d\n", start);
1091 end = 0xdeadbeef;
1092 hres = ITextSelection_GetEnd(txtSel, &end);
1093 ok(hres == S_OK, "ITextSelection_GetEnd\n");
1094 ok(end == 12, "got wrong end value: %d\n", end);
1095
1096 /* SetStart/SetEnd */
1097 hres = ITextSelection_SetStart(txtSel, 0);
1098 ok(hres == S_OK, "got 0x%08x\n", hres);
1099
1100 /* same value */
1101 hres = ITextSelection_SetStart(txtSel, 0);
1102 ok(hres == S_FALSE, "got 0x%08x\n", hres);
1103
1104 hres = ITextSelection_SetStart(txtSel, 1);
1105 ok(hres == S_OK, "got 0x%08x\n", hres);
1106
1107 /* negative resets to 0, return value is S_FALSE when
1108 position wasn't changed */
1109 hres = ITextSelection_SetStart(txtSel, -1);
1110 ok(hres == S_OK, "got 0x%08x\n", hres);
1111
1112 hres = ITextSelection_SetStart(txtSel, -1);
1113 ok(hres == S_FALSE, "got 0x%08x\n", hres);
1114
1115 hres = ITextSelection_SetStart(txtSel, 0);
1116 ok(hres == S_FALSE, "got 0x%08x\n", hres);
1117
1118 start = -1;
1119 hres = ITextSelection_GetStart(txtSel, &start);
1120 ok(hres == S_OK, "got 0x%08x\n", hres);
1121 ok(start == 0, "got %d\n", start);
1122
1123 /* greater than initial end, but less than total char count */
1124 hres = ITextSelection_SetStart(txtSel, 1);
1125 ok(hres == S_OK, "got 0x%08x\n", hres);
1126
1127 hres = ITextSelection_SetEnd(txtSel, 3);
1128 ok(hres == S_OK, "got 0x%08x\n", hres);
1129
1130 hres = ITextSelection_SetStart(txtSel, 10);
1131 ok(hres == S_OK, "got 0x%08x\n", hres);
1132
1133 start = 0;
1134 hres = ITextSelection_GetStart(txtSel, &start);
1135 ok(hres == S_OK, "got 0x%08x\n", hres);
1136 ok(start == 10, "got %d\n", start);
1137
1138 end = 0;
1139 hres = ITextSelection_GetEnd(txtSel, &end);
1140 ok(hres == S_OK, "got 0x%08x\n", hres);
1141 ok(end == 10, "got %d\n", end);
1142
1143 /* more that total text length */
1144 hres = ITextSelection_SetStart(txtSel, 50);
1145 ok(hres == S_OK, "got 0x%08x\n", hres);
1146
1147 start = 0;
1148 hres = ITextSelection_GetStart(txtSel, &start);
1149 ok(hres == S_OK, "got 0x%08x\n", hres);
1150 ok(start == 12, "got %d\n", start);
1151
1152 end = 0;
1153 hres = ITextSelection_GetEnd(txtSel, &end);
1154 ok(hres == S_OK, "got 0x%08x\n", hres);
1155 ok(end == 12, "got %d\n", end);
1156
1157 /* SetEnd */
1158 hres = ITextSelection_SetStart(txtSel, 0);
1159 ok(hres == S_OK, "got 0x%08x\n", hres);
1160
1161 /* same value */
1162 hres = ITextSelection_SetEnd(txtSel, 5);
1163 ok(hres == S_OK, "got 0x%08x\n", hres);
1164
1165 hres = ITextSelection_SetEnd(txtSel, 5);
1166 ok(hres == S_FALSE, "got 0x%08x\n", hres);
1167
1168 /* negative resets to 0 */
1169 hres = ITextSelection_SetEnd(txtSel, -1);
1170 ok(hres == S_OK, "got 0x%08x\n", hres);
1171
1172 end = -1;
1173 hres = ITextSelection_GetEnd(txtSel, &end);
1174 ok(hres == S_OK, "got 0x%08x\n", hres);
1175 ok(end == 0, "got %d\n", end);
1176
1177 start = -1;
1178 hres = ITextSelection_GetStart(txtSel, &start);
1179 ok(hres == S_OK, "got 0x%08x\n", hres);
1180 ok(start == 0, "got %d\n", start);
1181
1182 /* greater than initial end, but less than total char count */
1183 hres = ITextSelection_SetStart(txtSel, 3);
1184 ok(hres == S_OK, "got 0x%08x\n", hres);
1185
1186 hres = ITextSelection_SetEnd(txtSel, 1);
1187 ok(hres == S_OK, "got 0x%08x\n", hres);
1188
1189 start = 0;
1190 hres = ITextSelection_GetStart(txtSel, &start);
1191 ok(hres == S_OK, "got 0x%08x\n", hres);
1192 ok(start == 1, "got %d\n", start);
1193
1194 end = 0;
1195 hres = ITextSelection_GetEnd(txtSel, &end);
1196 ok(hres == S_OK, "got 0x%08x\n", hres);
1197 ok(end == 1, "got %d\n", end);
1198
1199 /* more than total count */
1200 hres = ITextSelection_SetEnd(txtSel, 50);
1201 ok(hres == S_OK, "got 0x%08x\n", hres);
1202
1203 start = 0;
1204 hres = ITextSelection_GetStart(txtSel, &start);
1205 ok(hres == S_OK, "got 0x%08x\n", hres);
1206 ok(start == 1, "got %d\n", start);
1207
1208 end = 0;
1209 hres = ITextSelection_GetEnd(txtSel, &end);
1210 ok(hres == S_OK, "got 0x%08x\n", hres);
1211 ok(end == 13, "got %d\n", end);
1212
1213 /* zero */
1214 hres = ITextSelection_SetEnd(txtSel, 0);
1215 ok(hres == S_OK, "got 0x%08x\n", hres);
1216
1217 start = 0;
1218 hres = ITextSelection_GetStart(txtSel, &start);
1219 ok(hres == S_OK, "got 0x%08x\n", hres);
1220 ok(start == 0, "got %d\n", start);
1221
1222 end = 0;
1223 hres = ITextSelection_GetEnd(txtSel, &end);
1224 ok(hres == S_OK, "got 0x%08x\n", hres);
1225 ok(end == 0, "got %d\n", end);
1226
1227 release_interfaces(&w, &reOle, &txtDoc, NULL);
1228
1229 /* detached selection */
1230 hres = ITextSelection_GetStart(txtSel, NULL);
1231 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1232
1233 hres = ITextSelection_GetStart(txtSel, &start);
1234 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1235
1236 hres = ITextSelection_GetEnd(txtSel, NULL);
1237 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1238
1239 hres = ITextSelection_GetEnd(txtSel, &end);
1240 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1241
1242 ITextSelection_Release(txtSel);
1243 }
1244
1245 static void test_ITextRange_GetDuplicate(void)
1246 {
1247 HWND w;
1248 IRichEditOle *reOle = NULL;
1249 ITextDocument *txtDoc = NULL;
1250 ITextRange *txtRge = NULL;
1251 ITextRange *txtRgeDup = NULL;
1252 HRESULT hres;
1253 LONG first, lim, start, end;
1254 static const CHAR test_text1[] = "TestSomeText";
1255
1256 create_interfaces(&w, &reOle, &txtDoc, NULL);
1257 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
1258 first = 0, lim = 4;
1259 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
1260 ok(hres == S_OK, "ITextDocument_Range fails 0x%x.\n", hres);
1261
1262 hres = ITextRange_GetDuplicate(txtRge, &txtRgeDup);
1263 ok(hres == S_OK, "ITextRange_GetDuplicate\n");
1264 ok(txtRgeDup != txtRge, "A new pointer should be returned\n");
1265 hres = ITextRange_GetStart(txtRgeDup, &start);
1266 ok(hres == S_OK, "got 0x%08x\n", hres);
1267 ok(start == first, "got wrong value: %d\n", start);
1268 hres = ITextRange_GetEnd(txtRgeDup, &end);
1269 ok(hres == S_OK, "got 0x%08x\n", hres);
1270 ok(end == lim, "got wrong value: %d\n", end);
1271
1272 ITextRange_Release(txtRgeDup);
1273
1274 hres = ITextRange_GetDuplicate(txtRge, NULL);
1275 ok(hres == E_INVALIDARG, "ITextRange_GetDuplicate\n");
1276
1277 release_interfaces(&w, &reOle, &txtDoc, NULL);
1278
1279 hres = ITextRange_GetDuplicate(txtRge, NULL);
1280 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1281
1282 hres = ITextRange_GetDuplicate(txtRge, &txtRgeDup);
1283 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1284
1285 ITextRange_Release(txtRge);
1286 }
1287
1288 static void test_ITextRange_Collapse(void)
1289 {
1290 HWND w;
1291 IRichEditOle *reOle = NULL;
1292 ITextDocument *txtDoc = NULL;
1293 ITextRange *txtRge = NULL;
1294 HRESULT hres;
1295 LONG first, lim, start, end;
1296 static const CHAR test_text1[] = "TestSomeText";
1297
1298 create_interfaces(&w, &reOle, &txtDoc, NULL);
1299 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
1300
1301 first = 4, lim = 8;
1302 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
1303 ok(hres == S_OK, "got 0x%08x\n", hres);
1304 hres = ITextRange_Collapse(txtRge, tomTrue);
1305 ok(hres == S_OK, "ITextRange_Collapse\n");
1306 hres = ITextRange_GetStart(txtRge, &start);
1307 ok(hres == S_OK, "got 0x%08x\n", hres);
1308 ok(start == 4, "got wrong start value: %d\n", start);
1309 hres = ITextRange_GetEnd(txtRge, &end);
1310 ok(hres == S_OK, "got 0x%08x\n", hres);
1311 ok(end == 4, "got wrong end value: %d\n", end);
1312 ITextRange_Release(txtRge);
1313
1314 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
1315 ok(hres == S_OK, "got 0x%08x\n", hres);
1316 hres = ITextRange_Collapse(txtRge, tomStart);
1317 ok(hres == S_OK, "ITextRange_Collapse\n");
1318 hres = ITextRange_GetStart(txtRge, &start);
1319 ok(hres == S_OK, "got 0x%08x\n", hres);
1320 ok(start == 4, "got wrong start value: %d\n", start);
1321 hres = ITextRange_GetEnd(txtRge, &end);
1322 ok(hres == S_OK, "got 0x%08x\n", hres);
1323 ok(end == 4, "got wrong end value: %d\n", end);
1324 ITextRange_Release(txtRge);
1325
1326 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
1327 ok(hres == S_OK, "got 0x%08x\n", hres);
1328 hres = ITextRange_Collapse(txtRge, tomFalse);
1329 ok(hres == S_OK, "ITextRange_Collapse\n");
1330 hres = ITextRange_GetStart(txtRge, &start);
1331 ok(hres == S_OK, "got 0x%08x\n", hres);
1332 ok(start == 8, "got wrong start value: %d\n", start);
1333 hres = ITextRange_GetEnd(txtRge, &end);
1334 ok(hres == S_OK, "got 0x%08x\n", hres);
1335 ok(end == 8, "got wrong end value: %d\n", end);
1336 ITextRange_Release(txtRge);
1337
1338 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
1339 ok(hres == S_OK, "got 0x%08x\n", hres);
1340 hres = ITextRange_Collapse(txtRge, tomEnd);
1341 ok(hres == S_OK, "ITextRange_Collapse\n");
1342 hres = ITextRange_GetStart(txtRge, &start);
1343 ok(hres == S_OK, "got 0x%08x\n", hres);
1344 ok(start == 8, "got wrong start value: %d\n", start);
1345 hres = ITextRange_GetEnd(txtRge, &end);
1346 ok(hres == S_OK, "got 0x%08x\n", hres);
1347 ok(end == 8, "got wrong end value: %d\n", end);
1348 ITextRange_Release(txtRge);
1349
1350 /* tomStart is the default */
1351 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
1352 ok(hres == S_OK, "got 0x%08x\n", hres);
1353 hres = ITextRange_Collapse(txtRge, 256);
1354 ok(hres == S_OK, "ITextRange_Collapse\n");
1355 hres = ITextRange_GetStart(txtRge, &start);
1356 ok(hres == S_OK, "got 0x%08x\n", hres);
1357 ok(start == 4, "got wrong start value: %d\n", start);
1358 hres = ITextRange_GetEnd(txtRge, &end);
1359 ok(hres == S_OK, "got 0x%08x\n", hres);
1360 ok(end == 4, "got wrong end value: %d\n", end);
1361 ITextRange_Release(txtRge);
1362
1363 first = 6, lim = 6;
1364 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
1365 ok(hres == S_OK, "got 0x%08x\n", hres);
1366 hres = ITextRange_Collapse(txtRge, tomEnd);
1367 ok(hres == S_FALSE, "ITextRange_Collapse\n");
1368 hres = ITextRange_GetStart(txtRge, &start);
1369 ok(hres == S_OK, "got 0x%08x\n", hres);
1370 ok(start == 6, "got wrong start value: %d\n", start);
1371 hres = ITextRange_GetEnd(txtRge, &end);
1372 ok(hres == S_OK, "got 0x%08x\n", hres);
1373 ok(end == 6, "got wrong end value: %d\n", end);
1374 ITextRange_Release(txtRge);
1375
1376 first = 8, lim = 8;
1377 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
1378 ok(hres == S_OK, "got 0x%08x\n", hres);
1379 hres = ITextRange_Collapse(txtRge, tomStart);
1380 ok(hres == S_FALSE, "ITextRange_Collapse\n");
1381 hres = ITextRange_GetStart(txtRge, &start);
1382 ok(hres == S_OK, "got 0x%08x\n", hres);
1383 ok(start == 8, "got wrong start value: %d\n", start);
1384 hres = ITextRange_GetEnd(txtRge, &end);
1385 ok(hres == S_OK, "got 0x%08x\n", hres);
1386 ok(end == 8, "got wrong end value: %d\n", end);
1387
1388 release_interfaces(&w, &reOle, &txtDoc, NULL);
1389
1390 hres = ITextRange_Collapse(txtRge, tomStart);
1391 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1392
1393 hres = ITextRange_Collapse(txtRge, tomUndefined);
1394 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1395
1396 ITextRange_Release(txtRge);
1397 }
1398
1399 static void test_ITextSelection_Collapse(void)
1400 {
1401 HWND w;
1402 IRichEditOle *reOle = NULL;
1403 ITextDocument *txtDoc = NULL;
1404 ITextSelection *txtSel = NULL;
1405 HRESULT hres;
1406 LONG first, lim, start, end;
1407 static const CHAR test_text1[] = "TestSomeText";
1408
1409 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
1410 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
1411
1412 first = 4, lim = 8;
1413 SendMessageA(w, EM_SETSEL, first, lim);
1414 hres = ITextSelection_Collapse(txtSel, tomTrue);
1415 ok(hres == S_OK, "ITextSelection_Collapse\n");
1416 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1417 ok(start == 4, "got wrong start value: %d\n", start);
1418 ok(end == 4, "got wrong end value: %d\n", end);
1419
1420 SendMessageA(w, EM_SETSEL, first, lim);
1421 hres = ITextSelection_Collapse(txtSel, tomStart);
1422 ok(hres == S_OK, "ITextSelection_Collapse\n");
1423 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1424 ok(start == 4, "got wrong start value: %d\n", start);
1425 ok(end == 4, "got wrong end value: %d\n", end);
1426
1427 SendMessageA(w, EM_SETSEL, first, lim);
1428 hres = ITextSelection_Collapse(txtSel, tomFalse);
1429 ok(hres == S_OK, "ITextSelection_Collapse\n");
1430 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1431 ok(start == 8, "got wrong start value: %d\n", start);
1432 ok(end == 8, "got wrong end value: %d\n", end);
1433
1434 SendMessageA(w, EM_SETSEL, first, lim);
1435 hres = ITextSelection_Collapse(txtSel, tomEnd);
1436 ok(hres == S_OK, "ITextSelection_Collapse\n");
1437 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1438 ok(start == 8, "got wrong start value: %d\n", start);
1439 ok(end == 8, "got wrong end value: %d\n", end);
1440
1441 /* tomStart is the default */
1442 SendMessageA(w, EM_SETSEL, first, lim);
1443 hres = ITextSelection_Collapse(txtSel, 256);
1444 ok(hres == S_OK, "ITextSelection_Collapse\n");
1445 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1446 ok(start == 4, "got wrong start value: %d\n", start);
1447 ok(end == 4, "got wrong end value: %d\n", end);
1448
1449 first = 6, lim = 6;
1450 SendMessageA(w, EM_SETSEL, first, lim);
1451 hres = ITextSelection_Collapse(txtSel, tomEnd);
1452 ok(hres == S_FALSE, "ITextSelection_Collapse\n");
1453 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1454 ok(start == 6, "got wrong start value: %d\n", start);
1455 ok(end == 6, "got wrong end value: %d\n", end);
1456
1457 first = 8, lim = 8;
1458 SendMessageA(w, EM_SETSEL, first, lim);
1459 hres = ITextSelection_Collapse(txtSel, tomStart);
1460 ok(hres == S_FALSE, "ITextSelection_Collapse\n");
1461 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1462 ok(start == 8, "got wrong start value: %d\n", start);
1463 ok(end == 8, "got wrong end value: %d\n", end);
1464
1465 release_interfaces(&w, &reOle, &txtDoc, NULL);
1466
1467 hres = ITextSelection_Collapse(txtSel, tomStart);
1468 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1469
1470 hres = ITextSelection_Collapse(txtSel, tomUndefined);
1471 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1472
1473 ITextSelection_Release(txtSel);
1474 }
1475
1476 static void test_GetClientSite(void)
1477 {
1478 HWND w;
1479 IRichEditOle *reOle = NULL, *reOle1 = NULL;
1480 ITextDocument *txtDoc = NULL;
1481 IOleClientSite *clientSite = NULL, *clientSite1 = NULL, *clientSite2 = NULL;
1482 IOleWindow *oleWin = NULL, *oleWin1 = NULL;
1483 IOleInPlaceSite *olePlace = NULL, *olePlace1 = NULL;
1484 HRESULT hres;
1485 LONG refcount1, refcount2;
1486
1487 create_interfaces(&w, &reOle, &txtDoc, NULL);
1488 hres = IRichEditOle_GetClientSite(reOle, &clientSite);
1489 ok(hres == S_OK, "IRichEditOle_QueryInterface: 0x%08x\n", hres);
1490 EXPECT_REF(clientSite, 1);
1491
1492 hres = IOleClientSite_QueryInterface(clientSite, &IID_IRichEditOle, (void **)&reOle1);
1493 ok(hres == E_NOINTERFACE, "IOleClientSite_QueryInterface: %x\n", hres);
1494
1495 hres = IRichEditOle_GetClientSite(reOle, &clientSite1);
1496 ok(hres == S_OK, "got 0x%08x\n", hres);
1497 ok(clientSite != clientSite1, "got %p, %p\n", clientSite, clientSite1);
1498 IOleClientSite_Release(clientSite1);
1499
1500 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleClientSite, (void **)&clientSite1);
1501 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1502 ok(clientSite == clientSite1, "Should not return a new pointer.\n");
1503 EXPECT_REF(clientSite, 2);
1504
1505 /* IOleWindow interface */
1506 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleWindow, (void **)&oleWin);
1507 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1508 refcount1 = get_refcount((IUnknown *)clientSite);
1509 refcount2 = get_refcount((IUnknown *)oleWin);
1510 ok(refcount1 == refcount2, "got wrong ref count.\n");
1511
1512 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleWindow, (void **)&oleWin1);
1513 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1514 ok(oleWin == oleWin1, "Should not return a new pointer.\n");
1515 refcount1 = get_refcount((IUnknown *)clientSite);
1516 refcount2 = get_refcount((IUnknown *)oleWin);
1517 ok(refcount1 == refcount2, "got wrong ref count.\n");
1518
1519 hres = IOleWindow_QueryInterface(oleWin, &IID_IOleClientSite, (void **)&clientSite2);
1520 ok(hres == S_OK, "IOleWindow_QueryInterface: 0x%08x\n", hres);
1521 ok(clientSite2 == clientSite1, "got wrong pointer\n");
1522
1523 /* IOleInPlaceSite interface */
1524 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleInPlaceSite, (void **)&olePlace);
1525 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1526 refcount1 = get_refcount((IUnknown *)olePlace);
1527 refcount2 = get_refcount((IUnknown *)clientSite);
1528 ok(refcount1 == refcount2, "got wrong ref count.\n");
1529
1530 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleInPlaceSite, (void **)&olePlace1);
1531 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1532 ok(olePlace == olePlace1, "Should not return a new pointer.\n");
1533 IOleInPlaceSite_Release(olePlace1);
1534
1535 hres = IOleWindow_QueryInterface(oleWin, &IID_IOleInPlaceSite, (void **)&olePlace1);
1536 ok(hres == S_OK, "IOleWindow_QueryInterface: 0x%08x\n", hres);
1537 refcount1 = get_refcount((IUnknown *)olePlace1);
1538 refcount2 = get_refcount((IUnknown *)oleWin);
1539 ok(refcount1 == refcount2, "got wrong ref count.\n");
1540
1541 IOleInPlaceSite_Release(olePlace1);
1542 IOleInPlaceSite_Release(olePlace);
1543 IOleWindow_Release(oleWin1);
1544 IOleWindow_Release(oleWin);
1545 IOleClientSite_Release(clientSite2);
1546 IOleClientSite_Release(clientSite1);
1547 IOleClientSite_Release(clientSite);
1548 release_interfaces(&w, &reOle, &txtDoc, NULL);
1549 }
1550
1551 static void test_IOleWindow_GetWindow(void)
1552 {
1553 HWND w;
1554 IRichEditOle *reOle = NULL;
1555 ITextDocument *txtDoc = NULL;
1556 IOleClientSite *clientSite = NULL;
1557 IOleWindow *oleWin = NULL;
1558 HRESULT hres;
1559 HWND hwnd;
1560
1561 create_interfaces(&w, &reOle, &txtDoc, NULL);
1562 hres = IRichEditOle_GetClientSite(reOle, &clientSite);
1563 ok(hres == S_OK, "IRichEditOle_QueryInterface: 0x%08x\n", hres);
1564
1565 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleWindow, (void **)&oleWin);
1566 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1567 hres = IOleWindow_GetWindow(oleWin, &hwnd);
1568 ok(hres == S_OK, "IOleClientSite_GetWindow: 0x%08x\n", hres);
1569 ok(w == hwnd, "got wrong pointer\n");
1570
1571 hres = IOleWindow_GetWindow(oleWin, NULL);
1572 ok(hres == E_INVALIDARG, "IOleClientSite_GetWindow: 0x%08x\n", hres);
1573
1574 IOleWindow_Release(oleWin);
1575 IOleClientSite_Release(clientSite);
1576 release_interfaces(&w, &reOle, &txtDoc, NULL);
1577 }
1578
1579 static void test_IOleInPlaceSite_GetWindow(void)
1580 {
1581 HWND w;
1582 IRichEditOle *reOle = NULL;
1583 ITextDocument *txtDoc = NULL;
1584 IOleClientSite *clientSite = NULL;
1585 IOleInPlaceSite *olePlace = NULL;
1586 HRESULT hres;
1587 HWND hwnd;
1588
1589 create_interfaces(&w, &reOle, &txtDoc, NULL);
1590 hres = IRichEditOle_GetClientSite(reOle, &clientSite);
1591 ok(hres == S_OK, "IRichEditOle_QueryInterface: 0x%08x\n", hres);
1592
1593 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleInPlaceSite, (void **)&olePlace);
1594 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1595 hres = IOleInPlaceSite_GetWindow(olePlace, &hwnd);
1596 ok(hres == S_OK, "IOleInPlaceSite_GetWindow: 0x%08x\n", hres);
1597 ok(w == hwnd, "got wrong pointer.\n");
1598
1599 hres = IOleInPlaceSite_GetWindow(olePlace, NULL);
1600 ok(hres == E_INVALIDARG, "IOleInPlaceSite_GetWindow: 0x%08x\n", hres);
1601
1602 IOleInPlaceSite_Release(olePlace);
1603 IOleClientSite_Release(clientSite);
1604 release_interfaces(&w, &reOle, &txtDoc, NULL);
1605 }
1606
1607 static void test_GetFont(void)
1608 {
1609 static const CHAR test_text1[] = "TestSomeText";
1610 IRichEditOle *reOle = NULL;
1611 ITextDocument *doc = NULL;
1612 ITextRange *range = NULL;
1613 ITextSelection *selection;
1614 ITextFont *font, *font2;
1615 CHARFORMAT2A cf;
1616 LONG value;
1617 float size;
1618 HRESULT hr;
1619 HWND hwnd;
1620 BOOL ret;
1621
1622 create_interfaces(&hwnd, &reOle, &doc, NULL);
1623 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
1624
1625 hr = ITextDocument_GetSelection(doc, &selection);
1626 ok(hr == S_OK, "got 0x%08x\n", hr);
1627 hr = ITextSelection_GetFont(selection, &font);
1628 ok(hr == S_OK, "got 0x%08x\n", hr);
1629 hr = ITextSelection_GetFont(selection, &font2);
1630 ok(hr == S_OK, "got 0x%08x\n", hr);
1631 ok(font != font2, "got %p, %p\n", font, font2);
1632 ITextFont_Release(font2);
1633 ITextFont_Release(font);
1634 ITextSelection_Release(selection);
1635
1636 EXPECT_REF(reOle, 3);
1637 EXPECT_REF(doc, 3);
1638
1639 hr = ITextDocument_Range(doc, 0, 4, &range);
1640 ok(hr == S_OK, "got 0x%08x\n", hr);
1641
1642 EXPECT_REF(reOle, 3);
1643 EXPECT_REF(doc, 3);
1644 EXPECT_REF(range, 1);
1645
1646 hr = ITextRange_GetFont(range, NULL);
1647 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1648
1649 hr = ITextRange_GetFont(range, &font);
1650 ok(hr == S_OK, "got 0x%08x\n", hr);
1651
1652 EXPECT_REF(reOle, 3);
1653 EXPECT_REF(doc, 3);
1654 EXPECT_REF(range, 2);
1655 EXPECT_REF(font, 1);
1656
1657 hr = ITextRange_GetFont(range, &font2);
1658 ok(hr == S_OK, "got 0x%08x\n", hr);
1659 ok(font != font2, "got %p, %p\n", font, font2);
1660
1661 EXPECT_REF(reOle, 3);
1662 EXPECT_REF(doc, 3);
1663 EXPECT_REF(range, 3);
1664 EXPECT_REF(font, 1);
1665 EXPECT_REF(font2, 1);
1666
1667 ITextFont_Release(font2);
1668
1669 /* set different font style within a range */
1670 hr = ITextFont_GetItalic(font, NULL);
1671 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1672
1673 hr = ITextFont_GetSize(font, NULL);
1674 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1675
1676 size = 0.0;
1677 hr = ITextFont_GetSize(font, &size);
1678 ok(hr == S_OK, "got 0x%08x\n", hr);
1679 ok(size > 0.0, "size %.2f\n", size);
1680
1681 value = 0;
1682 hr = ITextFont_GetLanguageID(font, &value);
1683 ok(hr == S_OK, "got 0x%08x\n", hr);
1684 todo_wine
1685 ok(value == GetSystemDefaultLCID(), "got lcid %x, user lcid %x\n", value,
1686 GetSystemDefaultLCID());
1687
1688 /* range is non-italic */
1689 value = tomTrue;
1690 hr = ITextFont_GetItalic(font, &value);
1691 ok(hr == S_OK, "got 0x%08x\n", hr);
1692 ok(value == tomFalse, "got %d\n", value);
1693
1694 cf.cbSize = sizeof(CHARFORMAT2A);
1695 cf.dwMask = CFM_ITALIC|CFM_SIZE;
1696 cf.dwEffects = CFE_ITALIC;
1697 cf.yHeight = 24.0;
1698
1699 SendMessageA(hwnd, EM_SETSEL, 2, 3);
1700 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
1701 ok(ret, "got %d\n", ret);
1702
1703 /* now range is partially italicized */
1704 value = tomFalse;
1705 hr = ITextFont_GetItalic(font, &value);
1706 ok(hr == S_OK, "got 0x%08x\n", hr);
1707 ok(value == tomUndefined, "got %d\n", value);
1708
1709 size = 0.0;
1710 hr = ITextFont_GetSize(font, &size);
1711 ok(hr == S_OK, "got 0x%08x\n", hr);
1712 ok(size == tomUndefined, "size %.2f\n", size);
1713
1714 ITextFont_Release(font);
1715 release_interfaces(&hwnd, &reOle, &doc, NULL);
1716
1717 hr = ITextRange_GetFont(range, NULL);
1718 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
1719
1720 hr = ITextRange_GetFont(range, &font2);
1721 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
1722
1723 ITextRange_Release(range);
1724 }
1725
1726 static void test_GetPara(void)
1727 {
1728 static const CHAR test_text1[] = "TestSomeText";
1729 IRichEditOle *reOle = NULL;
1730 ITextDocument *doc = NULL;
1731 ITextSelection *selection;
1732 ITextRange *range = NULL;
1733 ITextPara *para, *para2;
1734 HRESULT hr;
1735 HWND hwnd;
1736
1737 create_interfaces(&hwnd, &reOle, &doc, &selection);
1738 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
1739
1740 EXPECT_REF(reOle, 3);
1741 EXPECT_REF(doc, 3);
1742
1743 hr = ITextDocument_Range(doc, 0, 4, &range);
1744 ok(hr == S_OK, "got 0x%08x\n", hr);
1745
1746 EXPECT_REF(reOle, 3);
1747 EXPECT_REF(doc, 3);
1748 EXPECT_REF(range, 1);
1749
1750 hr = ITextRange_GetPara(range, NULL);
1751 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1752
1753 hr = ITextRange_GetPara(range, &para);
1754 ok(hr == S_OK, "got 0x%08x\n", hr);
1755
1756 EXPECT_REF(reOle, 3);
1757 EXPECT_REF(doc, 3);
1758 EXPECT_REF(range, 2);
1759 EXPECT_REF(para, 1);
1760
1761 hr = ITextRange_GetPara(range, &para2);
1762 ok(hr == S_OK, "got 0x%08x\n", hr);
1763 ok(para != para2, "got %p, %p\n", para, para2);
1764
1765 EXPECT_REF(reOle, 3);
1766 EXPECT_REF(doc, 3);
1767 EXPECT_REF(range, 3);
1768 EXPECT_REF(para, 1);
1769 EXPECT_REF(para2, 1);
1770
1771 ITextPara_Release(para);
1772 ITextPara_Release(para2);
1773
1774 EXPECT_REF(reOle, 3);
1775 EXPECT_REF(doc, 3);
1776 EXPECT_REF(selection, 2);
1777
1778 hr = ITextSelection_GetPara(selection, &para);
1779 ok(hr == S_OK, "got 0x%08x\n", hr);
1780
1781 EXPECT_REF(reOle, 3);
1782 EXPECT_REF(doc, 3);
1783 EXPECT_REF(selection, 3);
1784 EXPECT_REF(para, 1);
1785
1786 hr = ITextSelection_GetPara(selection, &para2);
1787 ok(hr == S_OK, "got 0x%08x\n", hr);
1788 ok(para != para2, "got %p, %p\n", para, para2);
1789
1790 ITextPara_Release(para);
1791 ITextPara_Release(para2);
1792 release_interfaces(&hwnd, &reOle, &doc, NULL);
1793
1794 hr = ITextRange_GetPara(range, NULL);
1795 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
1796
1797 hr = ITextRange_GetPara(range, &para);
1798 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
1799
1800 hr = ITextSelection_GetPara(selection, NULL);
1801 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
1802
1803 hr = ITextSelection_GetPara(selection, &para);
1804 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
1805
1806 ITextSelection_Release(selection);
1807 ITextRange_Release(range);
1808 }
1809
1810 static void test_dispatch(void)
1811 {
1812 static const WCHAR testnameW[] = {'G','e','t','T','e','x','t',0};
1813 static const WCHAR testname2W[] = {'T','e','x','t',0};
1814 IRichEditOle *reOle = NULL;
1815 ITextDocument *doc = NULL;
1816 ITextRange *range = NULL;
1817 WCHAR *nameW;
1818 DISPID dispid;
1819 HRESULT hr;
1820 UINT count;
1821 HWND hwnd;
1822
1823 create_interfaces(&hwnd, &reOle, &doc, NULL);
1824
1825 range = NULL;
1826 hr = ITextDocument_Range(doc, 0, 0, &range);
1827 ok(hr == S_OK, "got 0x%08x\n", hr);
1828 ok(range != NULL, "got %p\n", range);
1829
1830 dispid = 123;
1831 nameW = (WCHAR*)testnameW;
1832 hr = ITextRange_GetIDsOfNames(range, &IID_NULL, &nameW, 1, LOCALE_USER_DEFAULT, &dispid);
1833 ok(hr == DISP_E_UNKNOWNNAME, "got 0x%08x\n", hr);
1834 ok(dispid == DISPID_UNKNOWN, "got %d\n", dispid);
1835
1836 dispid = 123;
1837 nameW = (WCHAR*)testname2W;
1838 hr = ITextRange_GetIDsOfNames(range, &IID_NULL, &nameW, 1, LOCALE_USER_DEFAULT, &dispid);
1839 ok(hr == S_OK, "got 0x%08x\n", hr);
1840 ok(dispid == DISPID_VALUE, "got %d\n", dispid);
1841
1842 release_interfaces(&hwnd, &reOle, &doc, NULL);
1843
1844 /* try dispatch methods on detached range */
1845 hr = ITextRange_GetTypeInfoCount(range, &count);
1846 ok(hr == S_OK, "got 0x%08x\n", hr);
1847
1848 dispid = 123;
1849 nameW = (WCHAR*)testname2W;
1850 hr = ITextRange_GetIDsOfNames(range, &IID_NULL, &nameW, 1, LOCALE_USER_DEFAULT, &dispid);
1851 ok(hr == S_OK, "got 0x%08x\n", hr);
1852 ok(dispid == DISPID_VALUE, "got %d\n", dispid);
1853
1854 ITextRange_Release(range);
1855 }
1856
1857 static void test_detached_font_getters(ITextFont *font, BOOL duplicate)
1858 {
1859 HRESULT hr, hrexp = duplicate ? S_OK : CO_E_RELEASED;
1860 LONG value;
1861 float size;
1862 BSTR str;
1863
1864 hr = ITextFont_GetBold(font, NULL);
1865 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1866
1867 hr = ITextFont_GetBold(font, &value);
1868 ok(hr == hrexp, "got 0x%08x\n", hr);
1869
1870 hr = ITextFont_GetForeColor(font, NULL);
1871 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1872
1873 hr = ITextFont_GetForeColor(font, &value);
1874 ok(hr == hrexp, "got 0x%08x\n", hr);
1875
1876 hr = ITextFont_GetItalic(font, NULL);
1877 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1878
1879 hr = ITextFont_GetItalic(font, &value);
1880 ok(hr == hrexp, "got 0x%08x\n", hr);
1881
1882 hr = ITextFont_GetLanguageID(font, NULL);
1883 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1884
1885 hr = ITextFont_GetLanguageID(font, &value);
1886 ok(hr == hrexp, "got 0x%08x\n", hr);
1887
1888 hr = ITextFont_GetName(font, NULL);
1889 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1890
1891 hr = ITextFont_GetName(font, &str);
1892 ok(hr == hrexp, "got 0x%08x\n", hr);
1893
1894 hr = ITextFont_GetSize(font, NULL);
1895 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1896
1897 hr = ITextFont_GetSize(font, &size);
1898 ok(hr == hrexp, "got 0x%08x\n", hr);
1899
1900 hr = ITextFont_GetStrikeThrough(font, NULL);
1901 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1902
1903 hr = ITextFont_GetStrikeThrough(font, &value);
1904 ok(hr == hrexp, "got 0x%08x\n", hr);
1905
1906 hr = ITextFont_GetSubscript(font, NULL);
1907 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1908
1909 hr = ITextFont_GetSubscript(font, &value);
1910 ok(hr == hrexp, "got 0x%08x\n", hr);
1911
1912 hr = ITextFont_GetSuperscript(font, NULL);
1913 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1914
1915 hr = ITextFont_GetSuperscript(font, &value);
1916 ok(hr == hrexp, "got 0x%08x\n", hr);
1917
1918 hr = ITextFont_GetUnderline(font, NULL);
1919 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1920
1921 hr = ITextFont_GetUnderline(font, &value);
1922 ok(hr == hrexp, "got 0x%08x\n", hr);
1923 }
1924
1925 static void test_textfont_global_defaults(ITextFont *font)
1926 {
1927 float valuef;
1928 LONG value;
1929 HRESULT hr;
1930 BSTR str;
1931
1932 value = tomUndefined;
1933 hr = ITextFont_GetAllCaps(font, &value);
1934 ok(hr == S_OK, "got 0x%08x\n", hr);
1935 ok(value == tomFalse, "got %d\n", value);
1936
1937 value = tomUndefined;
1938 hr = ITextFont_GetAnimation(font, &value);
1939 ok(hr == S_OK, "got 0x%08x\n", hr);
1940 ok(value == tomFalse, "got %d\n", value);
1941
1942 value = tomUndefined;
1943 hr = ITextFont_GetBackColor(font, &value);
1944 ok(hr == S_OK, "got 0x%08x\n", hr);
1945 ok(value == tomAutoColor, "got %d\n", value);
1946
1947 value = tomUndefined;
1948 hr = ITextFont_GetBold(font, &value);
1949 ok(hr == S_OK, "got 0x%08x\n", hr);
1950 ok(value == tomFalse || value == tomTrue, "got %d\n", value);
1951
1952 value = tomUndefined;
1953 hr = ITextFont_GetEmboss(font, &value);
1954 ok(hr == S_OK, "got 0x%08x\n", hr);
1955 ok(value == tomFalse, "got %d\n", value);
1956
1957 value = tomUndefined;
1958 hr = ITextFont_GetForeColor(font, &value);
1959 ok(hr == S_OK, "got 0x%08x\n", hr);
1960 ok(value == tomAutoColor, "got %d\n", value);
1961
1962 value = tomUndefined;
1963 hr = ITextFont_GetHidden(font, &value);
1964 ok(hr == S_OK, "got 0x%08x\n", hr);
1965 ok(value == tomFalse, "got %d\n", value);
1966
1967 value = tomUndefined;
1968 hr = ITextFont_GetEngrave(font, &value);
1969 ok(hr == S_OK, "got 0x%08x\n", hr);
1970 ok(value == tomFalse, "got %d\n", value);
1971
1972 value = tomUndefined;
1973 hr = ITextFont_GetItalic(font, &value);
1974 ok(hr == S_OK, "got 0x%08x\n", hr);
1975 ok(value == tomFalse, "got %d\n", value);
1976
1977 valuef = 1.0;
1978 hr = ITextFont_GetKerning(font, &valuef);
1979 ok(hr == S_OK, "got 0x%08x\n", hr);
1980 ok(valuef == 0.0, "got %.2f\n", valuef);
1981
1982 value = tomUndefined;
1983 hr = ITextFont_GetLanguageID(font, &value);
1984 ok(hr == S_OK, "got 0x%08x\n", hr);
1985 ok(value == GetSystemDefaultLCID(), "got %d\n", value);
1986
1987 str = NULL;
1988 hr = ITextFont_GetName(font, &str);
1989 ok(hr == S_OK, "got 0x%08x\n", hr);
1990 ok(!lstrcmpW(sysW, str), "%s\n", wine_dbgstr_w(str));
1991 SysFreeString(str);
1992
1993 value = tomUndefined;
1994 hr = ITextFont_GetOutline(font, &value);
1995 ok(hr == S_OK, "got 0x%08x\n", hr);
1996 ok(value == tomFalse, "got %d\n", value);
1997
1998 valuef = 1.0;
1999 hr = ITextFont_GetPosition(font, &valuef);
2000 ok(hr == S_OK, "got 0x%08x\n", hr);
2001 ok(valuef == 0.0, "got %.2f\n", valuef);
2002
2003 value = tomUndefined;
2004 hr = ITextFont_GetProtected(font, &value);
2005 ok(hr == S_OK, "got 0x%08x\n", hr);
2006 ok(value == tomFalse, "got %d\n", value);
2007
2008 value = tomUndefined;
2009 hr = ITextFont_GetShadow(font, &value);
2010 ok(hr == S_OK, "got 0x%08x\n", hr);
2011 ok(value == tomFalse, "got %d\n", value);
2012
2013 valuef = 0.0;
2014 hr = ITextFont_GetSize(font, &valuef);
2015 ok(hr == S_OK, "got 0x%08x\n", hr);
2016 ok(valuef >= 0.0, "got %.2f\n", valuef);
2017
2018 value = tomUndefined;
2019 hr = ITextFont_GetSmallCaps(font, &value);
2020 ok(hr == S_OK, "got 0x%08x\n", hr);
2021 ok(value == tomFalse, "got %d\n", value);
2022
2023 valuef = 1.0;
2024 hr = ITextFont_GetSpacing(font, &valuef);
2025 ok(hr == S_OK, "got 0x%08x\n", hr);
2026 ok(valuef == 0.0, "got %.2f\n", valuef);
2027
2028 value = tomUndefined;
2029 hr = ITextFont_GetStrikeThrough(font, &value);
2030 ok(hr == S_OK, "got 0x%08x\n", hr);
2031 ok(value == tomFalse, "got %d\n", value);
2032
2033 value = tomUndefined;
2034 hr = ITextFont_GetSubscript(font, &value);
2035 ok(hr == S_OK, "got 0x%08x\n", hr);
2036 ok(value == tomFalse, "got %d\n", value);
2037
2038 value = tomUndefined;
2039 hr = ITextFont_GetSuperscript(font, &value);
2040 ok(hr == S_OK, "got 0x%08x\n", hr);
2041 ok(value == tomFalse, "got %d\n", value);
2042
2043 value = tomUndefined;
2044 hr = ITextFont_GetUnderline(font, &value);
2045 ok(hr == S_OK, "got 0x%08x\n", hr);
2046 ok(value == tomFalse, "got %d\n", value);
2047
2048 value = tomUndefined;
2049 hr = ITextFont_GetWeight(font, &value);
2050 ok(hr == S_OK, "got 0x%08x\n", hr);
2051 ok(value == FW_NORMAL || value == FW_BOLD, "got %d\n", value);
2052 }
2053
2054 static void test_textfont_undefined(ITextFont *font)
2055 {
2056 float valuef;
2057 LONG value;
2058 HRESULT hr;
2059
2060 value = tomFalse;
2061 hr = ITextFont_GetAllCaps(font, &value);
2062 ok(hr == S_OK, "got 0x%08x\n", hr);
2063 ok(value == tomUndefined, "got %d\n", value);
2064
2065 value = tomFalse;
2066 hr = ITextFont_GetAnimation(font, &value);
2067 ok(hr == S_OK, "got 0x%08x\n", hr);
2068 ok(value == tomUndefined, "got %d\n", value);
2069
2070 value = tomFalse;
2071 hr = ITextFont_GetBackColor(font, &value);
2072 ok(hr == S_OK, "got 0x%08x\n", hr);
2073 ok(value == tomUndefined, "got %d\n", value);
2074
2075 value = tomFalse;
2076 hr = ITextFont_GetBold(font, &value);
2077 ok(hr == S_OK, "got 0x%08x\n", hr);
2078 ok(value == tomUndefined, "got %d\n", value);
2079
2080 value = tomFalse;
2081 hr = ITextFont_GetEmboss(font, &value);
2082 ok(hr == S_OK, "got 0x%08x\n", hr);
2083 ok(value == tomUndefined, "got %d\n", value);
2084
2085 value = tomFalse;
2086 hr = ITextFont_GetForeColor(font, &value);
2087 ok(hr == S_OK, "got 0x%08x\n", hr);
2088 ok(value == tomUndefined, "got %d\n", value);
2089
2090 value = tomFalse;
2091 hr = ITextFont_GetHidden(font, &value);
2092 ok(hr == S_OK, "got 0x%08x\n", hr);
2093 ok(value == tomUndefined, "got %d\n", value);
2094
2095 value = tomFalse;
2096 hr = ITextFont_GetEngrave(font, &value);
2097 ok(hr == S_OK, "got 0x%08x\n", hr);
2098 ok(value == tomUndefined, "got %d\n", value);
2099
2100 value = tomFalse;
2101 hr = ITextFont_GetItalic(font, &value);
2102 ok(hr == S_OK, "got 0x%08x\n", hr);
2103 ok(value == tomUndefined, "got %d\n", value);
2104
2105 valuef = 0.0;
2106 hr = ITextFont_GetKerning(font, &valuef);
2107 ok(hr == S_OK, "got 0x%08x\n", hr);
2108 ok(valuef == tomUndefined, "got %.2f\n", valuef);
2109
2110 value = tomFalse;
2111 hr = ITextFont_GetLanguageID(font, &value);
2112 ok(hr == S_OK, "got 0x%08x\n", hr);
2113 ok(value == tomUndefined, "got %d\n", value);
2114
2115 value = tomFalse;
2116 hr = ITextFont_GetOutline(font, &value);
2117 ok(hr == S_OK, "got 0x%08x\n", hr);
2118 ok(value == tomUndefined, "got %d\n", value);
2119
2120 valuef = 0.0;
2121 hr = ITextFont_GetPosition(font, &valuef);
2122 ok(hr == S_OK, "got 0x%08x\n", hr);
2123 ok(valuef == tomUndefined, "got %.2f\n", valuef);
2124
2125 value = tomFalse;
2126 hr = ITextFont_GetProtected(font, &value);
2127 ok(hr == S_OK, "got 0x%08x\n", hr);
2128 ok(value == tomUndefined, "got %d\n", value);
2129
2130 value = tomFalse;
2131 hr = ITextFont_GetShadow(font, &value);
2132 ok(hr == S_OK, "got 0x%08x\n", hr);
2133 ok(value == tomUndefined, "got %d\n", value);
2134
2135 valuef = 0.0;
2136 hr = ITextFont_GetSize(font, &valuef);
2137 ok(hr == S_OK, "got 0x%08x\n", hr);
2138 ok(valuef == tomUndefined, "got %.2f\n", valuef);
2139
2140 value = tomFalse;
2141 hr = ITextFont_GetSmallCaps(font, &value);
2142 ok(hr == S_OK, "got 0x%08x\n", hr);
2143 ok(value == tomUndefined, "got %d\n", value);
2144
2145 valuef = 0.0;
2146 hr = ITextFont_GetSpacing(font, &valuef);
2147 ok(hr == S_OK, "got 0x%08x\n", hr);
2148 ok(valuef == tomUndefined, "got %.2f\n", valuef);
2149
2150 value = tomFalse;
2151 hr = ITextFont_GetStrikeThrough(font, &value);
2152 ok(hr == S_OK, "got 0x%08x\n", hr);
2153 ok(value == tomUndefined, "got %d\n", value);
2154
2155 value = tomFalse;
2156 hr = ITextFont_GetSubscript(font, &value);
2157 ok(hr == S_OK, "got 0x%08x\n", hr);
2158 ok(value == tomUndefined, "got %d\n", value);
2159
2160 value = tomFalse;
2161 hr = ITextFont_GetSuperscript(font, &value);
2162 ok(hr == S_OK, "got 0x%08x\n", hr);
2163 ok(value == tomUndefined, "got %d\n", value);
2164
2165 value = tomFalse;
2166 hr = ITextFont_GetUnderline(font, &value);
2167 ok(hr == S_OK, "got 0x%08x\n", hr);
2168 ok(value == tomUndefined, "got %d\n", value);
2169
2170 value = tomFalse;
2171 hr = ITextFont_GetWeight(font, &value);
2172 ok(hr == S_OK, "got 0x%08x\n", hr);
2173 ok(value == tomUndefined, "got %d\n", value);
2174 }
2175
2176 static inline FLOAT twips_to_points(LONG value)
2177 {
2178 return value * 72.0 / 1440;
2179 }
2180
2181 static void test_ITextFont(void)
2182 {
2183 static const WCHAR arialW[] = {'A','r','i','a','l',0};
2184 static const CHAR test_text1[] = "TestSomeText";
2185 ITextFont *font, *font2, *font3;
2186 FLOAT size, position, kerning;
2187 IRichEditOle *reOle = NULL;
2188 ITextDocument *doc = NULL;
2189 ITextRange *range = NULL;
2190 CHARFORMAT2A cf;
2191 LONG value;
2192 HRESULT hr;
2193 HWND hwnd;
2194 BOOL ret;
2195 BSTR str;
2196
2197 create_interfaces(&hwnd, &reOle, &doc, NULL);
2198 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2199
2200 hr = ITextDocument_Range(doc, 0, 10, &range);
2201 ok(hr == S_OK, "got 0x%08x\n", hr);
2202
2203 hr = ITextRange_GetFont(range, &font);
2204 ok(hr == S_OK, "got 0x%08x\n", hr);
2205
2206 hr = ITextFont_Reset(font, tomUseTwips);
2207 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2208
2209 hr = ITextFont_Reset(font, tomUsePoints);
2210 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2211
2212 hr = ITextFont_GetName(font, NULL);
2213 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2214
2215 /* default font size unit is point */
2216 size = 0.0;
2217 hr = ITextFont_GetSize(font, &size);
2218 ok(hr == S_OK, "got 0x%08x\n", hr);
2219
2220 /* set to some non-zero values */
2221 hr = ITextFont_SetPosition(font, 20.0);
2222 ok(hr == S_OK, "got 0x%08x\n", hr);
2223
2224 hr = ITextFont_SetKerning(font, 10.0);
2225 ok(hr == S_OK, "got 0x%08x\n", hr);
2226
2227 position = 0.0;
2228 hr = ITextFont_GetPosition(font, &position);
2229 ok(hr == S_OK, "got 0x%08x\n", hr);
2230
2231 kerning = 0.0;
2232 hr = ITextFont_GetKerning(font, &kerning);
2233 ok(hr == S_OK, "got 0x%08x\n", hr);
2234
2235 memset(&cf, 0, sizeof(cf));
2236 cf.cbSize = sizeof(cf);
2237 cf.dwMask = CFM_SIZE|CFM_OFFSET|CFM_KERNING;
2238
2239 /* CHARFORMAT members are in twips */
2240 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2241 ret = SendMessageA(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2242 ok(ret, "got %d\n", ret);
2243 ok(size == twips_to_points(cf.yHeight), "got yHeight %d, size %.2f\n", cf.yHeight, size);
2244 ok(position == twips_to_points(cf.yOffset), "got yOffset %d, position %.2f\n", cf.yOffset, position);
2245 ok(kerning == twips_to_points(cf.wKerning), "got wKerning %d, kerning %.2f\n", cf.wKerning, kerning);
2246
2247 hr = ITextFont_Reset(font, tomUseTwips);
2248 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2249
2250 hr = ITextFont_Reset(font, tomUsePoints);
2251 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2252
2253 hr = ITextFont_GetDuplicate(font, &font2);
2254 ok(hr == S_OK, "got 0x%08x\n", hr);
2255
2256 hr = ITextFont_Reset(font2, tomUseTwips);
2257 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2258
2259 hr = ITextFont_Reset(font2, tomUsePoints);
2260 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2261
2262 ITextFont_Release(font2);
2263
2264 /* default font name */
2265 str = NULL;
2266 hr = ITextFont_GetName(font, &str);
2267 ok(hr == S_OK, "got 0x%08x\n", hr);
2268 ok(!lstrcmpW(str, sysW), "got %s\n", wine_dbgstr_w(str));
2269 SysFreeString(str);
2270
2271 /* change font name for an inner subrange */
2272 memset(&cf, 0, sizeof(cf));
2273 cf.cbSize = sizeof(cf);
2274 cf.dwMask = CFM_FACE;
2275 strcpy(cf.szFaceName, "Arial");
2276
2277 SendMessageA(hwnd, EM_SETSEL, 3, 4);
2278 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2279 ok(ret, "got %d\n", ret);
2280
2281 /* still original name */
2282 str = NULL;
2283 hr = ITextFont_GetName(font, &str);
2284 ok(hr == S_OK, "got 0x%08x\n", hr);
2285 ok(!lstrcmpW(str, sysW), "got %s\n", wine_dbgstr_w(str));
2286 SysFreeString(str);
2287
2288 SendMessageA(hwnd, EM_SETSEL, 1, 2);
2289 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2290 ok(ret, "got %d\n", ret);
2291
2292 str = NULL;
2293 hr = ITextFont_GetName(font, &str);
2294 ok(hr == S_OK, "got 0x%08x\n", hr);
2295 ok(!lstrcmpW(str, sysW), "got %s\n", wine_dbgstr_w(str));
2296 SysFreeString(str);
2297
2298 /* name is returned for first position within a range */
2299 SendMessageA(hwnd, EM_SETSEL, 0, 1);
2300 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2301 ok(ret, "got %d\n", ret);
2302
2303 str = NULL;
2304 hr = ITextFont_GetName(font, &str);
2305 ok(hr == S_OK, "got 0x%08x\n", hr);
2306 ok(!lstrcmpW(str, arialW), "got %s\n", wine_dbgstr_w(str));
2307 SysFreeString(str);
2308
2309 /* GetDuplicate() */
2310 hr = ITextFont_GetDuplicate(font, NULL);
2311 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2312
2313 EXPECT_REF(range, 2);
2314 font2 = NULL;
2315 hr = ITextFont_GetDuplicate(font, &font2);
2316 ok(hr == S_OK, "got 0x%08x\n", hr);
2317 EXPECT_REF(range, 2);
2318
2319 /* set whole range to italic */
2320 cf.cbSize = sizeof(CHARFORMAT2A);
2321 cf.dwMask = CFM_ITALIC;
2322 cf.dwEffects = CFE_ITALIC;
2323
2324 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2325 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2326 ok(ret, "got %d\n", ret);
2327
2328 value = tomFalse;
2329 hr = ITextFont_GetItalic(font, &value);
2330 ok(hr == S_OK, "got 0x%08x\n", hr);
2331 ok(value == tomTrue, "got %d\n", value);
2332
2333 /* duplicate retains original value */
2334 value = tomTrue;
2335 hr = ITextFont_GetItalic(font2, &value);
2336 ok(hr == S_OK, "got 0x%08x\n", hr);
2337 ok(value == tomFalse, "got %d\n", value);
2338
2339 /* get a duplicate from a cloned font */
2340 hr = ITextFont_GetDuplicate(font2, &font3);
2341 ok(hr == S_OK, "got 0x%08x\n", hr);
2342 ITextFont_Release(font3);
2343
2344 ITextRange_Release(range);
2345 release_interfaces(&hwnd, &reOle, &doc, NULL);
2346
2347 hr = ITextFont_GetDuplicate(font, NULL);
2348 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2349
2350 test_detached_font_getters(font, FALSE);
2351 test_detached_font_getters(font2, TRUE);
2352
2353 /* get a duplicate of detached font */
2354 hr = ITextFont_GetDuplicate(font2, &font3);
2355 ok(hr == S_OK, "got 0x%08x\n", hr);
2356 ITextFont_Release(font3);
2357
2358 /* reset detached font to undefined */
2359 value = tomUndefined;
2360 hr = ITextFont_GetBold(font2, &value);
2361 ok(hr == S_OK, "got 0x%08x\n", hr);
2362 ok(value != tomUndefined, "got %d\n", value);
2363
2364 /* reset to undefined for detached font */
2365 hr = ITextFont_Reset(font2, tomUndefined);
2366 ok(hr == S_OK, "got 0x%08x\n", hr);
2367 test_textfont_undefined(font2);
2368
2369 /* font is detached, default means global TOM defaults */
2370 hr = ITextFont_Reset(font2, tomDefault);
2371 ok(hr == S_OK, "got 0x%08x\n", hr);
2372 test_textfont_global_defaults(font2);
2373
2374 hr = ITextFont_GetDuplicate(font2, &font3);
2375 ok(hr == S_OK, "got 0x%08x\n", hr);
2376 test_textfont_global_defaults(font2);
2377
2378 hr = ITextFont_Reset(font2, tomApplyNow);
2379 ok(hr == S_OK, "got 0x%08x\n", hr);
2380 test_textfont_global_defaults(font2);
2381
2382 hr = ITextFont_Reset(font2, tomApplyLater);
2383 ok(hr == S_OK, "got 0x%08x\n", hr);
2384 test_textfont_global_defaults(font2);
2385
2386 hr = ITextFont_Reset(font2, tomTrackParms);
2387 ok(hr == S_OK, "got 0x%08x\n", hr);
2388 test_textfont_global_defaults(font2);
2389
2390 hr = ITextFont_SetItalic(font2, tomUndefined);
2391 ok(hr == S_OK, "got 0x%08x\n", hr);
2392
2393 hr = ITextFont_GetItalic(font2, &value);
2394 ok(hr == S_OK, "got 0x%08x\n", hr);
2395 ok(value == tomFalse, "got %d\n", value);
2396
2397 hr = ITextFont_Reset(font2, tomCacheParms);
2398 ok(hr == S_OK, "got 0x%08x\n", hr);
2399 test_textfont_global_defaults(font2);
2400
2401 ITextFont_Release(font3);
2402 ITextFont_Release(font2);
2403
2404 font2 = (void*)0xdeadbeef;
2405 hr = ITextFont_GetDuplicate(font, &font2);
2406 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2407 ok(font2 == NULL, "got %p\n", font2);
2408
2409 hr = ITextFont_Reset(font, tomDefault);
2410 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2411
2412 ITextFont_Release(font);
2413
2414 /* Reset() */
2415 create_interfaces(&hwnd, &reOle, &doc, NULL);
2416 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2417
2418 hr = ITextDocument_Range(doc, 0, 10, &range);
2419 ok(hr == S_OK, "got 0x%08x\n", hr);
2420
2421 hr = ITextRange_GetFont(range, &font);
2422 ok(hr == S_OK, "got 0x%08x\n", hr);
2423
2424 value = tomUndefined;
2425 hr = ITextFont_GetBold(font, &value);
2426 ok(hr == S_OK, "got 0x%08x\n", hr);
2427 ok(value != tomUndefined, "got %d\n", value);
2428
2429 /* reset to undefined for attached font */
2430 hr = ITextFont_Reset(font, tomUndefined);
2431 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2432
2433 value = tomUndefined;
2434 hr = ITextFont_GetBold(font, &value);
2435 ok(hr == S_OK, "got 0x%08x\n", hr);
2436 ok(value != tomUndefined, "got %d\n", value);
2437
2438 /* tomCacheParms/tomTrackParms */
2439 hr = ITextFont_Reset(font, tomCacheParms);
2440 ok(hr == S_OK, "got 0x%08x\n", hr);
2441
2442 hr = ITextFont_GetItalic(font, &value);
2443 ok(hr == S_OK, "got 0x%08x\n", hr);
2444 ok(value == tomFalse, "got %d\n", value);
2445
2446 memset(&cf, 0, sizeof(cf));
2447 cf.cbSize = sizeof(CHARFORMAT2A);
2448 cf.dwMask = CFM_ITALIC;
2449
2450 cf.dwEffects = CFE_ITALIC;
2451 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2452 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2453 ok(ret, "got %d\n", ret);
2454
2455 /* still cached value */
2456 hr = ITextFont_GetItalic(font, &value);
2457 ok(hr == S_OK, "got 0x%08x\n", hr);
2458 ok(value == tomFalse, "got %d\n", value);
2459
2460 hr = ITextFont_Reset(font, tomTrackParms);
2461 ok(hr == S_OK, "got 0x%08x\n", hr);
2462
2463 hr = ITextFont_GetItalic(font, &value);
2464 ok(hr == S_OK, "got 0x%08x\n", hr);
2465 ok(value == tomTrue, "got %d\n", value);
2466
2467 /* switch back to cache - value retained */
2468 hr = ITextFont_Reset(font, tomCacheParms);
2469 ok(hr == S_OK, "got 0x%08x\n", hr);
2470
2471 hr = ITextFont_GetItalic(font, &value);
2472 ok(hr == S_OK, "got 0x%08x\n", hr);
2473 ok(value == tomTrue, "got %d\n", value);
2474
2475 /* tomApplyLater */
2476 hr = ITextFont_Reset(font, tomApplyLater);
2477 ok(hr == S_OK, "got 0x%08x\n", hr);
2478
2479 hr = ITextFont_SetItalic(font, tomFalse);
2480 ok(hr == S_OK, "got 0x%08x\n", hr);
2481
2482 hr = ITextFont_GetItalic(font, &value);
2483 ok(hr == S_OK, "got 0x%08x\n", hr);
2484 ok(value == tomFalse, "got %d\n", value);
2485
2486 cf.dwEffects = 0;
2487 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2488 ret = SendMessageA(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2489 ok(ret, "got %d\n", ret);
2490 ok((cf.dwEffects & CFE_ITALIC) == CFE_ITALIC, "got 0x%08x\n", cf.dwEffects);
2491
2492 hr = ITextFont_Reset(font, tomApplyNow);
2493 ok(hr == S_OK, "got 0x%08x\n", hr);
2494
2495 cf.dwEffects = 0;
2496 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2497 ret = SendMessageA(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2498 ok(ret, "got %d\n", ret);
2499 ok((cf.dwEffects & CFE_ITALIC) == 0, "got 0x%08x\n", cf.dwEffects);
2500
2501 hr = ITextFont_SetItalic(font, tomUndefined);
2502 ok(hr == S_OK, "got 0x%08x\n", hr);
2503
2504 hr = ITextFont_GetItalic(font, &value);
2505 ok(hr == S_OK, "got 0x%08x\n", hr);
2506 ok(value == tomFalse, "got %d\n", value);
2507
2508 hr = ITextFont_SetItalic(font, tomAutoColor);
2509 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2510
2511 cf.dwEffects = 0;
2512 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2513 ret = SendMessageA(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2514 ok(ret, "got %d\n", ret);
2515 ok((cf.dwEffects & CFE_ITALIC) == 0, "got 0x%08x\n", cf.dwEffects);
2516
2517 ITextRange_Release(range);
2518 ITextFont_Release(font);
2519 release_interfaces(&hwnd, &reOle, &doc, NULL);
2520 }
2521
2522 static void test_Delete(void)
2523 {
2524 static const CHAR test_text1[] = "TestSomeText";
2525 IRichEditOle *reOle = NULL;
2526 ITextDocument *doc = NULL;
2527 ITextRange *range, *range2;
2528 LONG value;
2529 HRESULT hr;
2530 HWND hwnd;
2531
2532 create_interfaces(&hwnd, &reOle, &doc, NULL);
2533 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2534
2535 hr = ITextDocument_Range(doc, 0, 4, &range);
2536 ok(hr == S_OK, "got 0x%08x\n", hr);
2537
2538 hr = ITextDocument_Range(doc, 1, 2, &range2);
2539 ok(hr == S_OK, "got 0x%08x\n", hr);
2540
2541 hr = ITextRange_GetEnd(range, &value);
2542 ok(hr == S_OK, "got 0x%08x\n", hr);
2543 ok(value == 4, "got %d\n", value);
2544
2545 /* unit type doesn't matter is count is 0 */
2546 value = 0;
2547 hr = ITextRange_Delete(range2, tomSentence, 0, &value);
2548 todo_wine {
2549 ok(hr == S_OK, "got 0x%08x\n", hr);
2550 ok(value == 1, "got %d\n", value);
2551 }
2552 value = 1;
2553 hr = ITextRange_Delete(range2, tomCharacter, 0, &value);
2554 todo_wine {
2555 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2556 ok(value == 0, "got %d\n", value);
2557 }
2558 hr = ITextRange_GetEnd(range, &value);
2559 ok(hr == S_OK, "got 0x%08x\n", hr);
2560 todo_wine
2561 ok(value == 3, "got %d\n", value);
2562
2563 hr = ITextRange_GetStart(range2, &value);
2564 ok(hr == S_OK, "got 0x%08x\n", hr);
2565 ok(value == 1, "got %d\n", value);
2566
2567 hr = ITextRange_GetEnd(range2, &value);
2568 ok(hr == S_OK, "got 0x%08x\n", hr);
2569 todo_wine
2570 ok(value == 1, "got %d\n", value);
2571
2572 ITextRange_Release(range);
2573 ITextRange_Release(range2);
2574 release_interfaces(&hwnd, &reOle, &doc, NULL);
2575 }
2576
2577 static void test_SetText(void)
2578 {
2579 static const CHAR test_text1[] = "TestSomeText";
2580 static const WCHAR textW[] = {'a','b','c','d','e','f','g','h','i',0};
2581 IRichEditOle *reOle = NULL;
2582 ITextDocument *doc = NULL;
2583 ITextRange *range, *range2;
2584 LONG value;
2585 HRESULT hr;
2586 HWND hwnd;
2587 BSTR str;
2588
2589 create_interfaces(&hwnd, &reOle, &doc, NULL);
2590 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2591
2592 hr = ITextDocument_Range(doc, 0, 4, &range);
2593 ok(hr == S_OK, "got 0x%08x\n", hr);
2594
2595 hr = ITextDocument_Range(doc, 0, 4, &range2);
2596 ok(hr == S_OK, "got 0x%08x\n", hr);
2597
2598 value = 1;
2599 hr = ITextRange_GetStart(range2, &value);
2600 ok(hr == S_OK, "got 0x%08x\n", hr);
2601 ok(value == 0, "got %d\n", value);
2602
2603 value = 0;
2604 hr = ITextRange_GetEnd(range2, &value);
2605 ok(hr == S_OK, "got 0x%08x\n", hr);
2606 ok(value == 4, "got %d\n", value);
2607
2608 hr = ITextRange_SetText(range, NULL);
2609 ok(hr == S_OK, "got 0x%08x\n", hr);
2610
2611 value = 1;
2612 hr = ITextRange_GetEnd(range2, &value);
2613 ok(hr == S_OK, "got 0x%08x\n", hr);
2614 ok(value == 0, "got %d\n", value);
2615
2616 str = SysAllocString(textW);
2617 hr = ITextRange_SetText(range, str);
2618 ok(hr == S_OK, "got 0x%08x\n", hr);
2619 SysFreeString(str);
2620
2621 value = 1;
2622 hr = ITextRange_GetStart(range, &value);
2623 ok(hr == S_OK, "got 0x%08x\n", hr);
2624 ok(value == 0, "got %d\n", value);
2625
2626 value = 0;
2627 hr = ITextRange_GetEnd(range, &value);
2628 ok(hr == S_OK, "got 0x%08x\n", hr);
2629 ok(value == 9, "got %d\n", value);
2630
2631 value = 1;
2632 hr = ITextRange_GetStart(range2, &value);
2633 ok(hr == S_OK, "got 0x%08x\n", hr);
2634 ok(value == 0, "got %d\n", value);
2635
2636 value = 0;
2637 hr = ITextRange_GetEnd(range2, &value);
2638 ok(hr == S_OK, "got 0x%08x\n", hr);
2639 ok(value == 0, "got %d\n", value);
2640
2641 str = SysAllocStringLen(NULL, 0);
2642 hr = ITextRange_SetText(range, str);
2643 ok(hr == S_OK, "got 0x%08x\n", hr);
2644 value = 1;
2645 hr = ITextRange_GetEnd(range, &value);
2646 ok(hr == S_OK, "got 0x%08x\n", hr);
2647 ok(value == 0, "got %d\n", value);
2648 SysFreeString(str);
2649
2650 ITextRange_Release(range2);
2651 release_interfaces(&hwnd, &reOle, &doc, NULL);
2652
2653 hr = ITextRange_SetText(range, NULL);
2654 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2655
2656 str = SysAllocStringLen(NULL, 0);
2657 hr = ITextRange_SetText(range, str);
2658 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2659 SysFreeString(str);
2660
2661 ITextRange_Release(range);
2662 }
2663
2664 static void test_InRange(void)
2665 {
2666 static const CHAR test_text1[] = "TestSomeText";
2667 ITextRange *range, *range2, *range3;
2668 IRichEditOle *reOle = NULL;
2669 ITextDocument *doc = NULL;
2670 ITextSelection *selection;
2671 LONG value;
2672 HRESULT hr;
2673 HWND hwnd;
2674
2675 create_interfaces(&hwnd, &reOle, &doc, &selection);
2676 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2677 SendMessageA(hwnd, EM_SETSEL, 1, 2);
2678
2679 hr = ITextDocument_Range(doc, 0, 4, &range);
2680 ok(hr == S_OK, "got 0x%08x\n", hr);
2681
2682 hr = ITextDocument_Range(doc, 0, 4, &range2);
2683 ok(hr == S_OK, "got 0x%08x\n", hr);
2684
2685 /* matches selection */
2686 hr = ITextDocument_Range(doc, 1, 2, &range3);
2687 ok(hr == S_OK, "got 0x%08x\n", hr);
2688
2689 hr = ITextRange_InRange(range, NULL, NULL);
2690 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2691
2692 value = tomTrue;
2693 hr = ITextRange_InRange(range, NULL, &value);
2694 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2695 ok(value == tomFalse, "got %d\n", value);
2696
2697 hr = ITextRange_InRange(range, range2, NULL);
2698 ok(hr == S_OK, "got 0x%08x\n", hr);
2699
2700 value = tomFalse;
2701 hr = ITextRange_InRange(range, range2, &value);
2702 ok(hr == S_OK, "got 0x%08x\n", hr);
2703 ok(value == tomTrue, "got %d\n", value);
2704
2705 /* selection */
2706 hr = ITextSelection_InRange(selection, NULL, NULL);
2707 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2708
2709 value = tomTrue;
2710 hr = ITextSelection_InRange(selection, NULL, &value);
2711 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2712 ok(value == tomFalse, "got %d\n", value);
2713
2714 hr = ITextSelection_InRange(selection, range2, NULL);
2715 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2716
2717 value = tomTrue;
2718 hr = ITextSelection_InRange(selection, range2, &value);
2719 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2720 ok(value == tomFalse, "got %d\n", value);
2721
2722 value = tomTrue;
2723 hr = ITextSelection_InRange(selection, range3, &value);
2724 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2725 ok(value == tomFalse, "got %d\n", value);
2726
2727 /* seems to work on ITextSelection ranges only */
2728 value = tomFalse;
2729 hr = ITextSelection_InRange(selection, (ITextRange*)selection, &value);
2730 ok(hr == S_OK, "got 0x%08x\n", hr);
2731 ok(value == tomTrue, "got %d\n", value);
2732
2733 release_interfaces(&hwnd, &reOle, &doc, NULL);
2734
2735 hr = ITextRange_InRange(range, NULL, NULL);
2736 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2737
2738 value = tomTrue;
2739 hr = ITextRange_InRange(range, NULL, &value);
2740 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2741 ok(value == tomFalse, "got %d\n", value);
2742
2743 hr = ITextRange_InRange(range, range2, NULL);
2744 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2745
2746 value = tomTrue;
2747 hr = ITextRange_InRange(range, range2, &value);
2748 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2749 ok(value == tomFalse, "got %d\n", value);
2750
2751 /* selection */
2752 hr = ITextSelection_InRange(selection, NULL, NULL);
2753 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2754
2755 value = tomTrue;
2756 hr = ITextSelection_InRange(selection, NULL, &value);
2757 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2758 ok(value == tomFalse, "got %d\n", value);
2759
2760 hr = ITextSelection_InRange(selection, range2, NULL);
2761 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2762
2763 value = tomTrue;
2764 hr = ITextSelection_InRange(selection, range2, &value);
2765 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2766 ok(value == tomFalse, "got %d\n", value);
2767
2768 ITextRange_Release(range);
2769 ITextRange_Release(range2);
2770 ITextRange_Release(range3);
2771 ITextSelection_Release(selection);
2772 }
2773
2774 static void test_ITextRange_IsEqual(void)
2775 {
2776 static const CHAR test_text1[] = "TestSomeText";
2777 ITextRange *range, *range2, *range3;
2778 IRichEditOle *reOle = NULL;
2779 ITextDocument *doc = NULL;
2780 ITextSelection *selection;
2781 LONG value;
2782 HRESULT hr;
2783 HWND hwnd;
2784
2785 create_interfaces(&hwnd, &reOle, &doc, &selection);
2786 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2787 SendMessageA(hwnd, EM_SETSEL, 1, 2);
2788
2789 hr = ITextDocument_Range(doc, 0, 4, &range);
2790 ok(hr == S_OK, "got 0x%08x\n", hr);
2791
2792 hr = ITextDocument_Range(doc, 0, 4, &range2);
2793 ok(hr == S_OK, "got 0x%08x\n", hr);
2794
2795 /* matches selection */
2796 hr = ITextDocument_Range(doc, 1, 2, &range3);
2797 ok(hr == S_OK, "got 0x%08x\n", hr);
2798
2799 hr = ITextRange_IsEqual(range, NULL, NULL);
2800 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2801
2802 value = tomTrue;
2803 hr = ITextRange_IsEqual(range, NULL, &value);
2804 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2805 ok(value == tomFalse, "got %d\n", value);
2806
2807 hr = ITextRange_IsEqual(range, range2, NULL);
2808 ok(hr == S_OK, "got 0x%08x\n", hr);
2809
2810 value = tomFalse;
2811 hr = ITextRange_IsEqual(range, range2, &value);
2812 ok(hr == S_OK, "got 0x%08x\n", hr);
2813 ok(value == tomTrue, "got %d\n", value);
2814
2815 value = tomTrue;
2816 hr = ITextRange_IsEqual(range, range3, &value);
2817 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2818 ok(value == tomFalse, "got %d\n", value);
2819
2820 /* selection */
2821 hr = ITextSelection_IsEqual(selection, NULL, NULL);
2822 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2823
2824 value = tomTrue;
2825 hr = ITextSelection_IsEqual(selection, NULL, &value);
2826 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2827 ok(value == tomFalse, "got %d\n", value);
2828
2829 hr = ITextSelection_IsEqual(selection, range2, NULL);
2830 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2831
2832 value = tomTrue;
2833 hr = ITextSelection_IsEqual(selection, range2, &value);
2834 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2835 ok(value == tomFalse, "got %d\n", value);
2836
2837 value = tomTrue;
2838 hr = ITextSelection_IsEqual(selection, range3, &value);
2839 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2840 ok(value == tomFalse, "got %d\n", value);
2841
2842 /* seems to work on ITextSelection ranges only */
2843 value = tomFalse;
2844 hr = ITextSelection_IsEqual(selection, (ITextRange*)selection, &value);
2845 ok(hr == S_OK, "got 0x%08x\n", hr);
2846 ok(value == tomTrue, "got %d\n", value);
2847
2848 release_interfaces(&hwnd, &reOle, &doc, NULL);
2849
2850 hr = ITextRange_IsEqual(range, NULL, NULL);
2851 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2852
2853 value = tomTrue;
2854 hr = ITextRange_IsEqual(range, NULL, &value);
2855 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2856 ok(value == tomFalse, "got %d\n", value);
2857
2858 hr = ITextRange_IsEqual(range, range2, NULL);
2859 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2860
2861 value = tomTrue;
2862 hr = ITextRange_IsEqual(range, range2, &value);
2863 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2864 ok(value == tomFalse, "got %d\n", value);
2865
2866 /* selection */
2867 hr = ITextSelection_IsEqual(selection, NULL, NULL);
2868 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2869
2870 value = tomTrue;
2871 hr = ITextSelection_IsEqual(selection, NULL, &value);
2872 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2873 ok(value == tomFalse, "got %d\n", value);
2874
2875 hr = ITextSelection_IsEqual(selection, range2, NULL);
2876 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2877
2878 value = tomTrue;
2879 hr = ITextSelection_IsEqual(selection, range2, &value);
2880 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2881 ok(value == tomFalse, "got %d\n", value);
2882
2883 ITextRange_Release(range);
2884 ITextRange_Release(range2);
2885 ITextRange_Release(range3);
2886 ITextSelection_Release(selection);
2887 }
2888
2889 static void test_Select(void)
2890 {
2891 static const CHAR test_text1[] = "TestSomeText";
2892 IRichEditOle *reOle = NULL;
2893 ITextDocument *doc = NULL;
2894 ITextSelection *selection;
2895 ITextRange *range;
2896 LONG value;
2897 HRESULT hr;
2898 HWND hwnd;
2899
2900 create_interfaces(&hwnd, &reOle, &doc, &selection);
2901 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2902 SendMessageA(hwnd, EM_SETSEL, 1, 2);
2903
2904 hr = ITextDocument_Range(doc, 0, 4, &range);
2905 ok(hr == S_OK, "got 0x%08x\n", hr);
2906
2907 hr = ITextRange_Select(range);
2908 ok(hr == S_OK, "got 0x%08x\n", hr);
2909
2910 value = 1;
2911 hr = ITextSelection_GetStart(selection, &value);
2912 ok(hr == S_OK, "got 0x%08x\n", hr);
2913 ok(value == 0, "got %d\n", value);
2914
2915 hr = ITextRange_Select(range);
2916 ok(hr == S_OK, "got 0x%08x\n", hr);
2917
2918 hr = ITextSelection_Select(selection);
2919 ok(hr == S_OK, "got 0x%08x\n", hr);
2920
2921 release_interfaces(&hwnd, &reOle, &doc, NULL);
2922
2923 hr = ITextRange_Select(range);
2924 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2925
2926 hr = ITextSelection_Select(selection);
2927 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2928
2929 ITextRange_Release(range);
2930 ITextSelection_Release(selection);
2931 }
2932
2933 static void test_GetStoryType(void)
2934 {
2935 static const CHAR test_text1[] = "TestSomeText";
2936 IRichEditOle *reOle = NULL;
2937 ITextDocument *doc = NULL;
2938 ITextSelection *selection;
2939 ITextRange *range;
2940 LONG value;
2941 HRESULT hr;
2942 HWND hwnd;
2943
2944 create_interfaces(&hwnd, &reOle, &doc, &selection);
2945 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2946 SendMessageA(hwnd, EM_SETSEL, 1, 2);
2947
2948 hr = ITextDocument_Range(doc, 0, 4, &range);
2949 ok(hr == S_OK, "got 0x%08x\n", hr);
2950
2951 hr = ITextRange_GetStoryType(range, NULL);
2952 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2953
2954 value = tomTextFrameStory;
2955 hr = ITextRange_GetStoryType(range, &value);
2956 ok(hr == S_OK, "got 0x%08x\n", hr);
2957 ok(value == tomUnknownStory, "got %d\n", value);
2958
2959 hr = ITextSelection_GetStoryType(selection, NULL);
2960 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2961
2962 value = tomTextFrameStory;
2963 hr = ITextSelection_GetStoryType(selection, &value);
2964 ok(hr == S_OK, "got 0x%08x\n", hr);
2965 ok(value == tomUnknownStory, "got %d\n", value);
2966
2967 release_interfaces(&hwnd, &reOle, &doc, NULL);
2968
2969 hr = ITextRange_GetStoryType(range, NULL);
2970 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2971
2972 value = 123;
2973 hr = ITextRange_GetStoryType(range, &value);
2974 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2975 ok(value == 123, "got %d\n", value);
2976
2977 hr = ITextSelection_GetStoryType(selection, NULL);
2978 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2979
2980 value = 123;
2981 hr = ITextSelection_GetStoryType(selection, &value);
2982 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2983 ok(value == 123, "got %d\n", value);
2984
2985 ITextRange_Release(range);
2986 ITextSelection_Release(selection);
2987 }
2988
2989 static void test_SetFont(void)
2990 {
2991 static const CHAR test_text1[] = "TestSomeText";
2992 IRichEditOle *reOle = NULL;
2993 ITextDocument *doc = NULL;
2994 ITextSelection *selection;
2995 ITextRange *range, *range2;
2996 ITextFont *font, *font2;
2997 LONG value;
2998 HRESULT hr;
2999 HWND hwnd;
3000
3001 create_interfaces(&hwnd, &reOle, &doc, &selection);
3002 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
3003 SendMessageA(hwnd, EM_SETSEL, 1, 2);
3004
3005 hr = ITextDocument_Range(doc, 0, 4, &range);
3006 ok(hr == S_OK, "got 0x%08x\n", hr);
3007
3008 hr = ITextDocument_Range(doc, 5, 2, &range2);
3009 ok(hr == S_OK, "got 0x%08x\n", hr);
3010
3011 EXPECT_REF(range, 1);
3012 hr = ITextRange_GetFont(range, &font);
3013 ok(hr == S_OK, "got 0x%08x\n", hr);
3014 EXPECT_REF(range, 2);
3015
3016 EXPECT_REF(range2, 1);
3017 hr = ITextRange_GetFont(range2, &font2);
3018 ok(hr == S_OK, "got 0x%08x\n", hr);
3019 EXPECT_REF(range2, 2);
3020
3021 hr = ITextRange_SetFont(range, NULL);
3022 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3023
3024 /* setting same font, no-op */
3025 EXPECT_REF(range, 2);
3026 hr = ITextRange_SetFont(range, font);
3027 ok(hr == S_OK, "got 0x%08x\n", hr);
3028 EXPECT_REF(range, 2);
3029
3030 EXPECT_REF(range2, 2);
3031 EXPECT_REF(range, 2);
3032 hr = ITextRange_SetFont(range, font2);
3033 ok(hr == S_OK, "got 0x%08x\n", hr);
3034 EXPECT_REF(range2, 2);
3035 EXPECT_REF(range, 2);
3036
3037 /* originally range 0-4 is non-italic */
3038 value = tomTrue;
3039 hr = ITextFont_GetItalic(font, &value);
3040 ok(hr == S_OK, "got 0x%08x\n", hr);
3041 ok(value == tomFalse, "got %d\n", value);
3042
3043 /* set range 5-2 to italic, then set this font to range 0-4 */
3044 hr = ITextFont_SetItalic(font2, tomTrue);
3045 ok(hr == S_OK, "got 0x%08x\n", hr);
3046
3047 hr = ITextRange_SetFont(range, font2);
3048 ok(hr == S_OK, "got 0x%08x\n", hr);
3049
3050 value = tomFalse;
3051 hr = ITextFont_GetItalic(font, &value);
3052 ok(hr == S_OK, "got 0x%08x\n", hr);
3053 ok(value == tomTrue, "got %d\n", value);
3054
3055 release_interfaces(&hwnd, &reOle, &doc, NULL);
3056
3057 hr = ITextRange_SetFont(range, NULL);
3058 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3059
3060 hr = ITextRange_SetFont(range, font);
3061 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3062
3063 hr = ITextSelection_SetFont(selection, NULL);
3064 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3065
3066 hr = ITextSelection_SetFont(selection, font);
3067 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3068
3069 ITextFont_Release(font);
3070 ITextFont_Release(font2);
3071 ITextRange_Release(range);
3072 ITextRange_Release(range2);
3073 ITextSelection_Release(selection);
3074 }
3075
3076 static void test_InsertObject(void)
3077 {
3078 IRichEditOle *reole = NULL;
3079 ITextDocument *doc = NULL;
3080 IOleClientSite *clientsite;
3081 REOBJECT reo;
3082 HRESULT hr;
3083 HWND hwnd;
3084
3085 create_interfaces(&hwnd, &reole, &doc, NULL);
3086
3087 hr = IRichEditOle_InsertObject(reole, NULL);
3088 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3089
3090 hr = IRichEditOle_GetClientSite(reole, &clientsite);
3091 ok(hr == S_OK, "got 0x%08x\n", hr);
3092
3093 reo.cbStruct = sizeof(reo);
3094 reo.cp = 0;
3095 memset(&reo.clsid, 0, sizeof(reo.clsid));
3096 reo.poleobj = NULL;
3097 reo.pstg = NULL;
3098 reo.polesite = clientsite;
3099 reo.sizel.cx = 10;
3100 reo.sizel.cy = 10;
3101 reo.dvaspect = DVASPECT_CONTENT;
3102 reo.dwFlags = 0;
3103 reo.dwUser = 0;
3104
3105 hr = IRichEditOle_InsertObject(reole, &reo);
3106 ok(hr == S_OK, "got 0x%08x\n", hr);
3107
3108 IOleClientSite_Release(clientsite);
3109 release_interfaces(&hwnd, &reole, &doc, NULL);
3110 }
3111
3112 static void test_GetStoryLength(void)
3113 {
3114 static const CHAR test_text1[] = "TestSomeText";
3115 IRichEditOle *reOle = NULL;
3116 ITextDocument *doc = NULL;
3117 ITextSelection *selection;
3118 ITextRange *range;
3119 LONG value;
3120 HRESULT hr;
3121 HWND hwnd;
3122
3123 create_interfaces(&hwnd, &reOle, &doc, &selection);
3124 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
3125 SendMessageA(hwnd, EM_SETSEL, 1, 2);
3126
3127 hr = ITextDocument_Range(doc, 0, 4, &range);
3128 ok(hr == S_OK, "got 0x%08x\n", hr);
3129
3130 hr = ITextRange_GetStoryLength(range, NULL);
3131 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3132
3133 value = 0;
3134 hr = ITextRange_GetStoryLength(range, &value);
3135 ok(hr == S_OK, "got 0x%08x\n", hr);
3136 ok(value == 13, "got %d\n", value);
3137
3138 hr = ITextSelection_GetStoryLength(selection, NULL);
3139 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3140
3141 value = 0;
3142 hr = ITextSelection_GetStoryLength(selection, &value);
3143 ok(hr == S_OK, "got 0x%08x\n", hr);
3144 ok(value == 13, "got %d\n", value);
3145
3146 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)"");
3147
3148 value = 0;
3149 hr = ITextRange_GetStoryLength(range, &value);
3150 ok(hr == S_OK, "got 0x%08x\n", hr);
3151 ok(value == 1, "got %d\n", value);
3152
3153 value = 0;
3154 hr = ITextSelection_GetStoryLength(selection, &value);
3155 ok(hr == S_OK, "got 0x%08x\n", hr);
3156 ok(value == 1, "got %d\n", value);
3157
3158 release_interfaces(&hwnd, &reOle, &doc, NULL);
3159
3160 hr = ITextRange_GetStoryLength(range, NULL);
3161 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3162
3163 value = 100;
3164 hr = ITextRange_GetStoryLength(range, &value);
3165 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3166 ok(value == 100, "got %d\n", value);
3167
3168 hr = ITextSelection_GetStoryLength(selection, NULL);
3169 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3170
3171 value = 100;
3172 hr = ITextSelection_GetStoryLength(selection, &value);
3173 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3174 ok(value == 100, "got %d\n", value);
3175
3176 ITextSelection_Release(selection);
3177 ITextRange_Release(range);
3178 }
3179
3180 static void test_ITextSelection_GetDuplicate(void)
3181 {
3182 static const CHAR test_text1[] = "TestSomeText";
3183 IRichEditOle *reOle = NULL;
3184 ITextDocument *doc = NULL;
3185 ITextSelection *selection, *sel2;
3186 ITextRange *range, *range2;
3187 ITextFont *font;
3188 LONG value;
3189 HRESULT hr;
3190 HWND hwnd;
3191
3192 create_interfaces(&hwnd, &reOle, &doc, &selection);
3193 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
3194 SendMessageA(hwnd, EM_SETSEL, 1, 2);
3195
3196 hr = ITextSelection_GetDuplicate(selection, NULL);
3197 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3198
3199 EXPECT_REF(selection, 2);
3200
3201 hr = ITextSelection_GetDuplicate(selection, &range);
3202 ok(hr == S_OK, "got 0x%08x\n", hr);
3203
3204 hr = ITextSelection_GetDuplicate(selection, &range2);
3205 ok(hr == S_OK, "got 0x%08x\n", hr);
3206 ok(range != range2, "got %p, %p\n", range, range2);
3207
3208 EXPECT_REF(selection, 2);
3209 EXPECT_REF(range, 1);
3210 EXPECT_REF(range2, 1);
3211
3212 ITextRange_Release(range2);
3213
3214 value = 0;
3215 hr = ITextRange_GetStart(range, &value);
3216 ok(hr == S_OK, "got 0x%08x\n", hr);
3217 ok(value == 1, "got %d\n", value);
3218
3219 value = 0;
3220 hr = ITextRange_GetEnd(range, &value);
3221 ok(hr == S_OK, "got 0x%08x\n", hr);
3222 ok(value == 2, "got %d\n", value);
3223
3224 SendMessageA(hwnd, EM_SETSEL, 2, 3);
3225
3226 value = 0;
3227 hr = ITextRange_GetStart(range, &value);
3228 ok(hr == S_OK, "got 0x%08x\n", hr);
3229 ok(value == 1, "got %d\n", value);
3230
3231 value = 0;
3232 hr = ITextRange_GetEnd(range, &value);
3233 ok(hr == S_OK, "got 0x%08x\n", hr);
3234 ok(value == 2, "got %d\n", value);
3235
3236 hr = ITextRange_QueryInterface(range, &IID_ITextSelection, (void**)&sel2);
3237 ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);
3238
3239 release_interfaces(&hwnd, &reOle, &doc, NULL);
3240
3241 hr = ITextSelection_GetDuplicate(selection, NULL);
3242 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3243
3244 hr = ITextSelection_GetDuplicate(selection, &range);
3245 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3246
3247 hr = ITextRange_GetFont(range, &font);
3248 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3249
3250 ITextSelection_Release(selection);
3251 ITextRange_Release(range);
3252 }
3253
3254 static void test_Expand(void)
3255 {
3256 static const char test_text1[] = "TestSomeText";
3257 IRichEditOle *reole = NULL;
3258 ITextDocument *doc = NULL;
3259 ITextSelection *selection;
3260 ITextRange *range;
3261 LONG value;
3262 HRESULT hr;
3263 HWND hwnd;
3264
3265 create_interfaces(&hwnd, &reole, &doc, &selection);
3266 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
3267 SendMessageA(hwnd, EM_SETSEL, 1, 2);
3268
3269 hr = ITextDocument_Range(doc, 0, 4, &range);
3270 ok(hr == S_OK, "got 0x%08x\n", hr);
3271
3272 hr = ITextRange_Expand(range, tomStory, NULL);
3273 ok(hr == S_OK, "got 0x%08x\n", hr);
3274 hr = ITextRange_GetStart(range, &value);
3275 ok(hr == S_OK, "got 0x%08x\n", hr);
3276 ok(value == 0, "got %d\n", value);
3277 hr = ITextRange_GetEnd(range, &value);
3278 ok(hr == S_OK, "got 0x%08x\n", hr);
3279 ok(value == 13, "got %d\n", value);
3280
3281 hr = ITextSelection_Expand(selection, tomStory, NULL);
3282 ok(hr == S_OK, "got 0x%08x\n", hr);
3283 hr = ITextSelection_GetStart(selection, &value);
3284 ok(hr == S_OK, "got 0x%08x\n", hr);
3285 ok(value == 0, "got %d\n", value);
3286 hr = ITextSelection_GetEnd(selection, &value);
3287 ok(hr == S_OK, "got 0x%08x\n", hr);
3288 ok(value == 13, "got %d\n", value);
3289
3290 hr = ITextRange_SetStart(range, 1);
3291 ok(hr == S_OK, "got 0x%08x\n", hr);
3292 hr = ITextRange_SetEnd(range, 2);
3293 ok(hr == S_OK, "got 0x%08x\n", hr);
3294
3295 hr = ITextSelection_SetStart(selection, 1);
3296 ok(hr == S_OK, "got 0x%08x\n", hr);
3297 hr = ITextSelection_SetEnd(selection, 2);
3298 ok(hr == S_OK, "got 0x%08x\n", hr);
3299
3300 value = 0;
3301 hr = ITextRange_Expand(range, tomStory, &value);
3302 ok(hr == S_OK, "got 0x%08x\n", hr);
3303 ok(value == 12, "got %d\n", value);
3304 hr = ITextRange_GetStart(range, &value);
3305 ok(hr == S_OK, "got 0x%08x\n", hr);
3306 ok(value == 0, "got %d\n", value);
3307 hr = ITextRange_GetEnd(range, &value);
3308 ok(hr == S_OK, "got 0x%08x\n", hr);
3309 ok(value == 13, "got %d\n", value);
3310
3311 value = 0;
3312 hr = ITextSelection_Expand(selection, tomStory, &value);
3313 ok(hr == S_OK, "got 0x%08x\n", hr);
3314 ok(value == 12, "got %d\n", value);
3315 hr = ITextSelection_GetStart(selection, &value);
3316 ok(hr == S_OK, "got 0x%08x\n", hr);
3317 ok(value == 0, "got %d\n", value);
3318 hr = ITextSelection_GetEnd(selection, &value);
3319 ok(hr == S_OK, "got 0x%08x\n", hr);
3320 ok(value == 13, "got %d\n", value);
3321
3322 release_interfaces(&hwnd, &reole, &doc, NULL);
3323
3324 hr = ITextRange_Expand(range, tomStory, NULL);
3325 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3326
3327 hr = ITextRange_Expand(range, tomStory, &value);
3328 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3329
3330 hr = ITextSelection_Expand(selection, tomStory, NULL);
3331 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3332
3333 hr = ITextSelection_Expand(selection, tomStory, &value);
3334 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
3335
3336 ITextSelection_Release(selection);
3337 ITextRange_Release(range);
3338 }
3339
3340 static void test_ITextRange_SetStart(void)
3341 {
3342 HWND w;
3343 IRichEditOle *reOle = NULL;
3344 ITextDocument *txtDoc = NULL;
3345 ITextRange *txtRge = NULL;
3346 HRESULT hres;
3347 LONG first, lim, start, end;
3348 static const CHAR test_text1[] = "TestSomeText";
3349
3350 create_interfaces(&w, &reOle, &txtDoc, NULL);
3351 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
3352
3353 first = 4, lim = 8;
3354 ITextDocument_Range(txtDoc, first, lim, &txtRge);
3355 hres = ITextRange_SetStart(txtRge, first);
3356 ok(hres == S_FALSE, "ITextRange_SetStart\n");
3357
3358 #define TEST_TXTRGE_SETSTART(cp, expected_start, expected_end) \
3359 hres = ITextRange_SetStart(txtRge, cp); \
3360 ok(hres == S_OK, "ITextRange_SetStart\n"); \
3361 ITextRange_GetStart(txtRge, &start); \
3362 ITextRange_GetEnd(txtRge, &end); \
3363 ok(start == expected_start, "got wrong start value: %d\n", start); \
3364 ok(end == expected_end, "got wrong end value: %d\n", end);
3365
3366 TEST_TXTRGE_SETSTART(2, 2, 8)
3367 TEST_TXTRGE_SETSTART(-1, 0, 8)
3368 TEST_TXTRGE_SETSTART(13, 12, 12)
3369
3370 release_interfaces(&w, &reOle, &txtDoc, NULL);
3371 }
3372
3373 static void test_ITextRange_SetEnd(void)
3374 {
3375 HWND w;
3376 IRichEditOle *reOle = NULL;
3377 ITextDocument *txtDoc = NULL;
3378 ITextRange *txtRge = NULL;
3379 HRESULT hres;
3380 LONG first, lim, start, end;
3381 static const CHAR test_text1[] = "TestSomeText";
3382
3383 create_interfaces(&w, &reOle, &txtDoc, NULL);
3384 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
3385
3386 first = 4, lim = 8;
3387 ITextDocument_Range(txtDoc, first, lim, &txtRge);
3388 hres = ITextRange_SetEnd(txtRge, lim);
3389 ok(hres == S_FALSE, "ITextRange_SetEnd\n");
3390
3391 #define TEST_TXTRGE_SETEND(cp, expected_start, expected_end) \
3392 hres = ITextRange_SetEnd(txtRge, cp); \
3393 ok(hres == S_OK, "ITextRange_SetEnd\n"); \
3394 ITextRange_GetStart(txtRge, &start); \
3395 ITextRange_GetEnd(txtRge, &end); \
3396 ok(start == expected_start, "got wrong start value: %d\n", start); \
3397 ok(end == expected_end, "got wrong end value: %d\n", end);
3398
3399 TEST_TXTRGE_SETEND(6, 4, 6)
3400 TEST_TXTRGE_SETEND(14, 4, 13)
3401 TEST_TXTRGE_SETEND(-1, 0, 0)
3402
3403 ITextRange_Release(txtRge);
3404 release_interfaces(&w, &reOle, &txtDoc, NULL);
3405 }
3406
3407 static void test_ITextSelection_SetStart(void)
3408 {
3409 HWND w;
3410 IRichEditOle *reOle = NULL;
3411 ITextDocument *txtDoc = NULL;
3412 ITextSelection *txtSel = NULL;
3413 HRESULT hres;
3414 LONG first, lim, start, end;
3415 static const CHAR test_text1[] = "TestSomeText";
3416
3417 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
3418 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
3419
3420 first = 4, lim = 8;
3421 SendMessageA(w, EM_SETSEL, first, lim);
3422 hres = ITextSelection_SetStart(txtSel, first);
3423 ok(hres == S_FALSE, "ITextSelection_SetStart\n");
3424
3425 #define TEST_TXTSEL_SETSTART(cp, expected_start, expected_end) \
3426 hres = ITextSelection_SetStart(txtSel, cp); \
3427 ok(hres == S_OK, "ITextSelection_SetStart\n"); \
3428 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end); \
3429 ok(start == expected_start, "got wrong start value: %d\n", start); \
3430 ok(end == expected_end, "got wrong end value: %d\n", end);
3431
3432 TEST_TXTSEL_SETSTART(2, 2, 8)
3433 TEST_TXTSEL_SETSTART(-1, 0, 8)
3434 TEST_TXTSEL_SETSTART(13, 12, 12)
3435
3436 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
3437 }
3438
3439 static void test_ITextSelection_SetEnd(void)
3440 {
3441 HWND w;
3442 IRichEditOle *reOle = NULL;
3443 ITextDocument *txtDoc = NULL;
3444 ITextSelection *txtSel = NULL;
3445 HRESULT hres;
3446 LONG first, lim, start, end;
3447 static const CHAR test_text1[] = "TestSomeText";
3448
3449 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
3450 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
3451
3452 first = 4, lim = 8;
3453 SendMessageA(w, EM_SETSEL, first, lim);
3454 hres = ITextSelection_SetEnd(txtSel, lim);
3455 ok(hres == S_FALSE, "ITextSelection_SetEnd\n");
3456
3457 #define TEST_TXTSEL_SETEND(cp, expected_start, expected_end) \
3458 hres = ITextSelection_SetEnd(txtSel, cp); \
3459 ok(hres == S_OK, "ITextSelection_SetEnd\n"); \
3460 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end); \
3461 ok(start == expected_start, "got wrong start value: %d\n", start); \
3462 ok(end == expected_end, "got wrong end value: %d\n", end);
3463
3464 TEST_TXTSEL_SETEND(6, 4, 6)
3465 TEST_TXTSEL_SETEND(14, 4, 13)
3466 TEST_TXTSEL_SETEND(-1, 0, 0)
3467
3468 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
3469 }
3470
3471 static void test_ITextRange_GetFont(void)
3472 {
3473 HWND w;
3474 IRichEditOle *reOle = NULL;
3475 ITextDocument *txtDoc = NULL;
3476 ITextRange *txtRge = NULL;
3477 ITextFont *txtFont = NULL, *txtFont1 = NULL;
3478 HRESULT hres;
3479 int first, lim;
3480 int refcount;
3481 static const CHAR test_text1[] = "TestSomeText";
3482 LONG value;
3483
3484 create_interfaces(&w, &reOle, &txtDoc, NULL);
3485 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
3486
3487 first = 4, lim = 4;
3488 ITextDocument_Range(txtDoc, first, lim, &txtRge);
3489 refcount = get_refcount((IUnknown *)txtRge);
3490 ok(refcount == 1, "got wrong ref count: %d\n", refcount);
3491
3492 hres = ITextRange_GetFont(txtRge, &txtFont);
3493 ok(hres == S_OK, "ITextRange_GetFont\n");
3494 refcount = get_refcount((IUnknown *)txtFont);
3495 ok(refcount == 1, "got wrong ref count: %d\n", refcount);
3496 refcount = get_refcount((IUnknown *)txtRge);
3497 ok(refcount == 2, "got wrong ref count: %d\n", refcount);
3498
3499 hres = ITextRange_GetFont(txtRge, &txtFont1);
3500 ok(hres == S_OK, "ITextRange_GetFont\n");
3501 ok(txtFont1 != txtFont, "A new pointer should be return\n");
3502 refcount = get_refcount((IUnknown *)txtFont1);
3503 ok(refcount == 1, "got wrong ref count: %d\n", refcount);
3504 ITextFont_Release(txtFont1);
3505 refcount = get_refcount((IUnknown *)txtRge);
3506 ok(refcount == 2, "got wrong ref count: %d\n", refcount);
3507
3508 ITextRange_Release(txtRge);
3509 release_interfaces(&w, &reOle, &txtDoc, NULL);
3510
3511 hres = ITextFont_GetOutline(txtFont, &value);
3512 ok(hres == CO_E_RELEASED, "ITextFont after ITextDocument destroyed\n");
3513
3514 ITextFont_Release(txtFont);
3515 }
3516
3517 static void test_ITextSelection_GetFont(void)
3518 {
3519 HWND w;
3520 IRichEditOle *reOle = NULL;
3521 ITextDocument *txtDoc = NULL;
3522 ITextSelection *txtSel = NULL;
3523 ITextFont *txtFont = NULL, *txtFont1 = NULL;
3524 HRESULT hres;
3525 int first, lim;
3526 int refcount;
3527 static const CHAR test_text1[] = "TestSomeText";
3528 LONG value;
3529
3530 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
3531 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
3532
3533 first = 4, lim = 4;
3534 SendMessageA(w, EM_SETSEL, first, lim);
3535 refcount = get_refcount((IUnknown *)txtSel);
3536 ok(refcount == 2, "got wrong ref count: %d\n", refcount);
3537
3538 hres = ITextSelection_GetFont(txtSel, &txtFont);
3539 ok(hres == S_OK, "ITextSelection_GetFont\n");
3540 refcount = get_refcount((IUnknown *)txtFont);
3541 ok(refcount == 1, "got wrong ref count: %d\n", refcount);
3542 refcount = get_refcount((IUnknown *)txtSel);
3543 ok(refcount == 3, "got wrong ref count: %d\n", refcount);
3544
3545 hres = ITextSelection_GetFont(txtSel, &txtFont1);
3546 ok(hres == S_OK, "ITextSelection_GetFont\n");
3547 ok(txtFont1 != txtFont, "A new pointer should be return\n");
3548 refcount = get_refcount((IUnknown *)txtFont1);
3549 ok(refcount == 1, "got wrong ref count: %d\n", refcount);
3550 ITextFont_Release(txtFont1);
3551 refcount = get_refcount((IUnknown *)txtSel);
3552 ok(refcount == 3, "got wrong ref count: %d\n", refcount);
3553
3554 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
3555
3556 hres = ITextFont_GetOutline(txtFont, &value);
3557 ok(hres == CO_E_RELEASED, "ITextFont after ITextDocument destroyed\n");
3558
3559 ITextFont_Release(txtFont);
3560 }
3561
3562 static void test_ITextRange_GetPara(void)
3563 {
3564 HWND w;
3565 IRichEditOle *reOle = NULL;
3566 ITextDocument *txtDoc = NULL;
3567 ITextRange *txtRge = NULL;
3568 ITextPara *txtPara = NULL, *txtPara1 = NULL;
3569 HRESULT hres;
3570 int first, lim;
3571 int refcount;
3572 static const CHAR test_text1[] = "TestSomeText";
3573 LONG value;
3574
3575 create_interfaces(&w, &reOle, &txtDoc, NULL);
3576 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
3577
3578 first = 4, lim = 4;
3579 ITextDocument_Range(txtDoc, first, lim, &txtRge);
3580 refcount = get_refcount((IUnknown *)txtRge);
3581 ok(refcount == 1, "got wrong ref count: %d\n", refcount);
3582
3583 hres = ITextRange_GetPara(txtRge, &txtPara);
3584 ok(hres == S_OK, "ITextRange_GetPara\n");
3585 refcount = get_refcount((IUnknown *)txtPara);
3586 ok(refcount == 1, "got wrong ref count: %d\n", refcount);
3587 refcount = get_refcount((IUnknown *)txtRge);
3588 ok(refcount == 2, "got wrong ref count: %d\n", refcount);
3589
3590 hres = ITextRange_GetPara(txtRge, &txtPara1);
3591 ok(hres == S_OK, "ITextRange_GetPara\n");
3592 ok(txtPara1 != txtPara, "A new pointer should be return\n");
3593 refcount = get_refcount((IUnknown *)txtPara1);
3594 ok(refcount == 1, "got wrong ref count: %d\n", refcount);
3595 ITextPara_Release(txtPara1);
3596 refcount = get_refcount((IUnknown *)txtRge);
3597 ok(refcount == 2, "got wrong ref count: %d\n", refcount);
3598
3599 ITextRange_Release(txtRge);
3600 release_interfaces(&w, &reOle, &txtDoc, NULL);
3601
3602 hres = ITextPara_GetStyle(txtPara, &value);
3603 ok(hres == CO_E_RELEASED, "ITextPara after ITextDocument destroyed\n");
3604
3605 ITextPara_Release(txtPara);
3606 }
3607
3608 static void test_ITextRange_GetText(void)
3609 {
3610 HWND w;
3611 IRichEditOle *reOle = NULL;
3612 ITextDocument *txtDoc = NULL;
3613 ITextRange *txtRge = NULL;
3614 HRESULT hres;
3615 BSTR bstr = NULL;
3616 static const CHAR test_text1[] = "TestSomeText";
3617 static const WCHAR bufW1[] = {'T', 'e', 's', 't', 0};
3618 static const WCHAR bufW2[] = {'T', 'e', 'x', 't', '\r', 0};
3619 static const WCHAR bufW3[] = {'T', 'e', 'x', 't', 0};
3620 static const WCHAR bufW4[] = {'T', 'e', 's', 't', 'S', 'o', 'm',
3621 'e', 'T', 'e', 'x', 't', '\r', 0};
3622 static const WCHAR bufW5[] = {'\r', 0};
3623
3624
3625 #define TEST_TXTRGE_GETTEXT(first, lim, expected_string) \
3626 create_interfaces(&w, &reOle, &txtDoc, NULL); \
3627 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); \
3628 ITextDocument_Range(txtDoc, first, lim, &txtRge); \
3629 hres = ITextRange_GetText(txtRge, &bstr); \
3630 ok(hres == S_OK, "ITextRange_GetText\n"); \
3631 ok(!lstrcmpW(bstr, expected_string), "got wrong text: %s\n", wine_dbgstr_w(bstr)); \
3632 SysFreeString(bstr); \
3633 ITextRange_Release(txtRge); \
3634 release_interfaces(&w, &reOle, &txtDoc, NULL);
3635
3636 TEST_TXTRGE_GETTEXT(0, 4, bufW1)
3637 TEST_TXTRGE_GETTEXT(4, 0, bufW1)
3638 TEST_TXTRGE_GETTEXT(8, 12, bufW3)
3639 TEST_TXTRGE_GETTEXT(8, 13, bufW2)
3640 TEST_TXTRGE_GETTEXT(12, 13, bufW5)
3641 TEST_TXTRGE_GETTEXT(0, 13, bufW4)
3642 TEST_TXTRGE_GETTEXT(1, 1, NULL)
3643 }
3644
3645 static void test_ITextRange_SetRange(void)
3646 {
3647 HWND w;
3648 IRichEditOle *reOle = NULL;
3649 ITextDocument *txtDoc = NULL;
3650 ITextRange *txtRge = NULL;
3651 HRESULT hres;
3652 int start, end;
3653 static const CHAR test_text1[] = "TestSomeText";
3654
3655 create_interfaces(&w, &reOle, &txtDoc, NULL);
3656 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
3657 ITextDocument_Range(txtDoc, 0, 0, &txtRge);
3658
3659 #define TEST_TXTRGE_SETRANGE(first, lim, expected_start, expected_end, expected_return) \
3660 hres = ITextRange_SetRange(txtRge, first, lim); \
3661 ok(hres == expected_return, "ITextRange_SetRange\n"); \
3662 ITextRange_GetStart(txtRge, &start); \
3663 ITextRange_GetEnd(txtRge, &end); \
3664 ok(start == expected_start, "got wrong start value: %d\n", start); \
3665 ok(end == expected_end, "got wrong end value: %d\n", end);
3666
3667 TEST_TXTRGE_SETRANGE(2, 4, 2, 4, S_OK)
3668 TEST_TXTRGE_SETRANGE(2, 4, 2, 4, S_FALSE)
3669 TEST_TXTRGE_SETRANGE(4, 2, 2, 4, S_FALSE)
3670 TEST_TXTRGE_SETRANGE(14, 14, 12, 12, S_OK)
3671 TEST_TXTRGE_SETRANGE(15, 15, 12, 12, S_FALSE)
3672 TEST_TXTRGE_SETRANGE(14, 1, 1, 13, S_OK)
3673 TEST_TXTRGE_SETRANGE(-1, 4, 0, 4, S_OK)
3674
3675 ITextRange_Release(txtRge);
3676 release_interfaces(&w, &reOle, &txtDoc, NULL);
3677 }
3678
3679 static void test_ITextRange_IsEqual2(void)
3680 {
3681 HWND w;
3682 IRichEditOle *reOle = NULL;
3683 ITextDocument *txtDoc = NULL;
3684 ITextRange *txtRge1 = NULL, *txtRge2 = NULL;
3685 HRESULT hres;
3686 static const CHAR test_text1[] = "TestSomeText";
3687 LONG res;
3688
3689 create_interfaces(&w, &reOle, &txtDoc, NULL);
3690 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
3691 ITextDocument_Range(txtDoc, 2, 4, &txtRge1);
3692 ITextDocument_Range(txtDoc, 2, 4, &txtRge2);
3693
3694 #define TEST_TXTRGE_ISEQUAL(expected_hres, expected_res) \
3695 hres = ITextRange_IsEqual(txtRge1, txtRge2, &res); \
3696 ok(hres == expected_hres, "ITextRange_IsEqual\n"); \
3697 ok(res == expected_res, "got wrong return value: %d\n", res);
3698
3699 TEST_TXTRGE_ISEQUAL(S_OK, tomTrue)
3700 ITextRange_SetRange(txtRge2, 1, 2);
3701 TEST_TXTRGE_ISEQUAL(S_FALSE, tomFalse)
3702
3703 ITextRange_SetRange(txtRge1, 1, 1);
3704 ITextRange_SetRange(txtRge2, 2, 2);
3705 TEST_TXTRGE_ISEQUAL(S_FALSE, tomFalse)
3706
3707 ITextRange_SetRange(txtRge2, 1, 1);
3708 TEST_TXTRGE_ISEQUAL(S_OK, tomTrue)
3709
3710 hres = ITextRange_IsEqual(txtRge1, txtRge1, &res);
3711 ok(hres == S_OK, "ITextRange_IsEqual\n");
3712 ok(res == tomTrue, "got wrong return value: %d\n", res);
3713
3714 hres = ITextRange_IsEqual(txtRge1, txtRge2, NULL);
3715 ok(hres == S_OK, "ITextRange_IsEqual\n");
3716
3717 hres = ITextRange_IsEqual(txtRge1, NULL, NULL);
3718 ok(hres == S_FALSE, "ITextRange_IsEqual\n");
3719
3720 ITextRange_Release(txtRge1);
3721 ITextRange_Release(txtRge2);
3722 release_interfaces(&w, &reOle, &txtDoc, NULL);
3723 }
3724
3725 static void test_ITextRange_GetStoryLength(void)
3726 {
3727 HWND w;
3728 IRichEditOle *reOle = NULL;
3729 ITextDocument *txtDoc = NULL;
3730 ITextRange *txtRge = NULL;
3731 HRESULT hres;
3732 LONG count;
3733 static const CHAR test_text1[] = "TestSomeText";
3734 int len = strlen(test_text1) + 1;
3735
3736 create_interfaces(&w, &reOle, &txtDoc, NULL);
3737 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
3738 ITextDocument_Range(txtDoc, 0, 0, &txtRge);
3739
3740 hres = ITextRange_GetStoryLength(txtRge, &count);
3741 ok(hres == S_OK, "ITextRange_GetStoryLength\n");
3742 ok(count == len, "got wrong length: %d\n", count);
3743
3744 ITextRange_SetRange(txtRge, 1, 2);
3745 hres = ITextRange_GetStoryLength(txtRge, &count);
3746 ok(hres == S_OK, "ITextRange_GetStoryLength\n");
3747 ok(count == len, "got wrong length: %d\n", count);
3748
3749 hres = ITextRange_GetStoryLength(txtRge, NULL);
3750 ok(hres == E_INVALIDARG, "ITextRange_GetStoryLength\n");
3751
3752 ITextRange_Release(txtRge);
3753 release_interfaces(&w, &reOle, &txtDoc, NULL);
3754 }
3755
3756 static void test_ITextSelection_GetStoryLength(void)
3757 {
3758 HWND w;
3759 IRichEditOle *reOle = NULL;
3760 ITextDocument *txtDoc = NULL;
3761 ITextSelection *txtSel = NULL;
3762 HRESULT hres;
3763 LONG count;
3764 static const CHAR test_text1[] = "TestSomeText";
3765 int len = strlen(test_text1) + 1;
3766
3767 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
3768 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
3769
3770 hres = ITextSelection_GetStoryLength(txtSel, &count);
3771 ok(hres == S_OK, "ITextSelection_GetStoryLength\n");
3772 ok(count == len, "got wrong length: %d\n", count);
3773
3774 SendMessageA(w, EM_SETSEL, 1, 2);
3775 hres = ITextSelection_GetStoryLength(txtSel, &count);
3776 ok(hres == S_OK, "ITextSelection_GetStoryLength\n");
3777 ok(count == len, "got wrong length: %d\n", count);
3778
3779 hres = ITextSelection_GetStoryLength(txtSel, NULL);
3780 ok(hres == E_INVALIDARG, "ITextSelection_GetStoryLength\n");
3781
3782 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
3783 }
3784
3785 START_TEST(richole)
3786 {
3787 /* Must explicitly LoadLibrary(). The test has no references to functions in
3788 * RICHED20.DLL, so the linker doesn't actually link to it. */
3789 hmoduleRichEdit = LoadLibraryA("riched20.dll");
3790 ok(hmoduleRichEdit != NULL, "error: %d\n", (int) GetLastError());
3791
3792 test_Interfaces();
3793 test_ITextDocument_Open();
3794 test_GetText();
3795 test_ITextSelection_GetChar();
3796 test_ITextSelection_GetStart_GetEnd();
3797 test_ITextSelection_SetStart();
3798 test_ITextSelection_SetEnd();
3799 test_ITextSelection_Collapse();
3800 test_ITextSelection_GetFont();
3801 test_ITextSelection_GetStoryLength();
3802 test_ITextDocument_Range();
3803 test_ITextRange_GetChar();
3804 test_ITextRange_GetStart_GetEnd();
3805 test_ITextRange_GetDuplicate();
3806 test_ITextRange_SetStart();
3807 test_ITextRange_SetEnd();
3808 test_ITextRange_Collapse();
3809 test_ITextRange_GetFont();
3810 test_ITextRange_GetPara();
3811 test_ITextRange_GetText();
3812 test_ITextRange_SetRange();
3813 test_ITextRange_IsEqual2();
3814 test_ITextRange_GetStoryLength();
3815 test_GetClientSite();
3816 test_IOleWindow_GetWindow();
3817 test_IOleInPlaceSite_GetWindow();
3818 test_GetFont();
3819 test_GetPara();
3820 test_dispatch();
3821 test_ITextFont();
3822 test_Delete();
3823 test_SetText();
3824 test_InRange();
3825 test_ITextRange_IsEqual();
3826 test_Select();
3827 test_GetStoryType();
3828 test_SetFont();
3829 test_InsertObject();
3830 test_GetStoryLength();
3831 test_ITextSelection_GetDuplicate();
3832 test_Expand();
3833 }