[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_interface