[RICHED20_WINETEST] Sync with Wine Staging 1.9.23. CORE-12409
[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 ok(hwnd != NULL, "class: %s, error: %d\n", lpClassName, (int) GetLastError());
57 return hwnd;
58 }
59
60 static HWND new_richedit(HWND parent)
61 {
62 return new_window(RICHEDIT_CLASS20A, ES_MULTILINE, parent);
63 }
64
65 static BOOL touch_file(LPCWSTR filename)
66 {
67 HANDLE file;
68
69 file = CreateFileW(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL,
70 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
71
72 if(file == INVALID_HANDLE_VALUE)
73 return FALSE;
74 CloseHandle(file);
75 return TRUE;
76 }
77
78 static BOOL is_existing_file(LPCWSTR filename)
79 {
80 HANDLE file;
81
82 file = CreateFileW(filename, GENERIC_READ, 0, NULL,
83 OPEN_EXISTING, 0, NULL);
84 if(file == INVALID_HANDLE_VALUE)
85 return FALSE;
86 CloseHandle(file);
87 return TRUE;
88 }
89
90 static void create_interfaces(HWND *w, IRichEditOle **reOle, ITextDocument **txtDoc,
91 ITextSelection **txtSel)
92 {
93 *w = new_richedit(NULL);
94 SendMessageA(*w, EM_GETOLEINTERFACE, 0, (LPARAM)reOle);
95 IRichEditOle_QueryInterface(*reOle, &IID_ITextDocument,
96 (void **) txtDoc);
97 ITextDocument_GetSelection(*txtDoc, txtSel);
98 }
99
100 static void release_interfaces(HWND *w, IRichEditOle **reOle, ITextDocument **txtDoc,
101 ITextSelection **txtSel)
102 {
103 if(txtSel)
104 ITextSelection_Release(*txtSel);
105 ITextDocument_Release(*txtDoc);
106 IRichEditOle_Release(*reOle);
107 DestroyWindow(*w);
108 }
109
110 static ULONG get_refcount(IUnknown *iface)
111 {
112 IUnknown_AddRef(iface);
113 return IUnknown_Release(iface);
114 }
115
116 static void test_Interfaces(void)
117 {
118 IRichEditOle *reOle = NULL, *reOle1 = NULL;
119 ITextDocument *txtDoc = NULL;
120 ITextSelection *txtSel = NULL, *txtSel2;
121 IUnknown *punk;
122 HRESULT hres;
123 LRESULT res;
124 HWND w;
125 ULONG refcount;
126
127 w = new_richedit(NULL);
128 if (!w) {
129 skip("Couldn't create window\n");
130 return;
131 }
132
133 res = SendMessageA(w, EM_GETOLEINTERFACE, 0, (LPARAM)&reOle);
134 ok(res, "SendMessage\n");
135 ok(reOle != NULL, "EM_GETOLEINTERFACE\n");
136 EXPECT_REF(reOle, 2);
137
138 res = SendMessageA(w, EM_GETOLEINTERFACE, 0, (LPARAM)&reOle1);
139 ok(res == 1, "SendMessage\n");
140 ok(reOle1 == reOle, "Should not return a new IRichEditOle interface\n");
141 EXPECT_REF(reOle, 3);
142
143 hres = IRichEditOle_QueryInterface(reOle, &IID_ITextDocument,
144 (void **) &txtDoc);
145 ok(hres == S_OK, "IRichEditOle_QueryInterface\n");
146 ok(txtDoc != NULL, "IRichEditOle_QueryInterface\n");
147
148 hres = ITextDocument_GetSelection(txtDoc, NULL);
149 ok(hres == E_INVALIDARG, "ITextDocument_GetSelection: 0x%x\n", hres);
150
151 EXPECT_REF(txtDoc, 4);
152
153 hres = ITextDocument_GetSelection(txtDoc, &txtSel);
154 ok(hres == S_OK, "got 0x%08x\n", hres);
155
156 EXPECT_REF(txtDoc, 4);
157 EXPECT_REF(txtSel, 2);
158
159 hres = ITextDocument_GetSelection(txtDoc, &txtSel2);
160 ok(hres == S_OK, "got 0x%08x\n", hres);
161 ok(txtSel2 == txtSel, "got %p, %p\n", txtSel, txtSel2);
162
163 EXPECT_REF(txtDoc, 4);
164 EXPECT_REF(txtSel, 3);
165
166 ITextSelection_Release(txtSel2);
167
168 punk = NULL;
169 hres = ITextSelection_QueryInterface(txtSel, &IID_ITextSelection, (void **) &punk);
170 ok(hres == S_OK, "ITextSelection_QueryInterface\n");
171 ok(punk != NULL, "ITextSelection_QueryInterface\n");
172 IUnknown_Release(punk);
173
174 punk = NULL;
175 hres = ITextSelection_QueryInterface(txtSel, &IID_ITextRange, (void **) &punk);
176 ok(hres == S_OK, "ITextSelection_QueryInterface\n");
177 ok(punk != NULL, "ITextSelection_QueryInterface\n");
178 IUnknown_Release(punk);
179
180 punk = NULL;
181 hres = ITextSelection_QueryInterface(txtSel, &IID_IDispatch, (void **) &punk);
182 ok(hres == S_OK, "ITextSelection_QueryInterface\n");
183 ok(punk != NULL, "ITextSelection_QueryInterface\n");
184 IUnknown_Release(punk);
185
186 punk = NULL;
187 hres = IRichEditOle_QueryInterface(reOle, &IID_IOleClientSite, (void **) &punk);
188 ok(hres == E_NOINTERFACE, "IRichEditOle_QueryInterface\n");
189
190 punk = NULL;
191 hres = IRichEditOle_QueryInterface(reOle, &IID_IOleWindow, (void **) &punk);
192 ok(hres == E_NOINTERFACE, "IRichEditOle_QueryInterface\n");
193
194 punk = NULL;
195 hres = IRichEditOle_QueryInterface(reOle, &IID_IOleInPlaceSite, (void **) &punk);
196 ok(hres == E_NOINTERFACE, "IRichEditOle_QueryInterface\n");
197
198 ITextDocument_Release(txtDoc);
199 IRichEditOle_Release(reOle);
200 refcount = IRichEditOle_Release(reOle);
201 ok(refcount == 1, "got wrong ref count: %d\n", refcount);
202 DestroyWindow(w);
203
204 /* Methods should return CO_E_RELEASED if the backing document has
205 been released. One test should suffice. */
206 hres = ITextSelection_CanEdit(txtSel, NULL);
207 ok(hres == CO_E_RELEASED, "ITextSelection after ITextDocument destroyed\n");
208
209 ITextSelection_Release(txtSel);
210 }
211
212 static void test_ITextDocument_Open(void)
213 {
214 IRichEditOle *reOle = NULL;
215 ITextDocument *txtDoc = NULL;
216 ITextSelection *txtSel = NULL;
217 HRESULT hres;
218 HWND w;
219 HANDLE hFile;
220 VARIANT testfile;
221 WCHAR filename[] = {'t', 'e', 's', 't','.','t','x','t', 0};
222 int result;
223 DWORD dw;
224 static const CHAR chACP[] = "TestSomeText";
225 static const CHAR chUTF8[] = "\xef\xbb\xbfTextWithUTF8BOM";
226 static const WCHAR chUTF16[] = {0xfeff, 'T', 'e', 's', 't', 'S', 'o', 'm',
227 'e', 'T', 'e', 'x', 't', 0};
228
229 #define MAX_BUF_LEN 1024
230 CHAR bufACP[MAX_BUF_LEN];
231 WCHAR bufUnicode[MAX_BUF_LEN];
232
233 static const int tomConstantsSingle[] =
234 {
235 tomReadOnly, tomShareDenyRead, tomShareDenyWrite,
236 tomCreateAlways, tomOpenExisting, tomOpenAlways,
237 tomTruncateExisting, tomRTF, tomText
238 };
239
240 static const int tomConstantsMulti[] =
241 {
242 tomReadOnly|tomShareDenyRead|tomPasteFile, tomReadOnly|tomPasteFile,
243 tomReadOnly|tomShareDenyWrite|tomPasteFile,
244 tomReadOnly|tomShareDenyRead|tomShareDenyWrite|tomPasteFile, tomShareDenyWrite|tomPasteFile,
245 tomShareDenyRead|tomShareDenyWrite|tomPasteFile, tomShareDenyRead|tomPasteFile,
246 tomShareDenyRead|tomShareDenyWrite, tomReadOnly|tomShareDenyRead|tomShareDenyWrite,
247 tomReadOnly|tomShareDenyWrite, tomReadOnly|tomShareDenyRead
248 };
249
250 int tomNumSingle = sizeof(tomConstantsSingle)/sizeof(tomConstantsSingle[0]);
251 int tomNumMulti = sizeof(tomConstantsMulti)/sizeof(tomConstantsMulti[0]);
252 int i;
253
254 V_VT(&testfile) = VT_BSTR;
255 V_BSTR(&testfile) = SysAllocString(filename);
256
257 for(i=0; i < tomNumSingle; i++)
258 {
259 touch_file(filename);
260 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
261 hres = ITextDocument_Open(txtDoc, &testfile, tomConstantsSingle[i], CP_ACP);
262 todo_wine ok(hres == S_OK, "ITextDocument_Open: Filename:test.txt Flags:0x%x Codepage:CP_ACP hres:0x%x\n",
263 tomConstantsSingle[i], hres);
264 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
265 DeleteFileW(filename);
266
267 touch_file(filename);
268 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
269 hres = ITextDocument_Open(txtDoc, &testfile, tomConstantsSingle[i], CP_UTF8);
270 todo_wine ok(hres == S_OK, "ITextDocument_Open: Filename:test.txt Flags:0x%x Codepage:CP_UTF8 hres:0x%x\n",
271 tomConstantsSingle[i], hres);
272 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
273 DeleteFileW(filename);
274 }
275
276 for(i=0; i < tomNumMulti; i++)
277 {
278 touch_file(filename);
279 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
280 hres = ITextDocument_Open(txtDoc, &testfile, tomConstantsMulti[i], CP_ACP);
281 todo_wine ok(hres == S_OK, "ITextDocument_Open: Filename:test.txt Flags:0x%x Codepage:CP_ACP hres:0x%x\n",
282 tomConstantsMulti[i], hres);
283 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
284 DeleteFileW(filename);
285
286 touch_file(filename);
287 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
288 hres = ITextDocument_Open(txtDoc, &testfile, tomConstantsMulti[i], CP_UTF8);
289 todo_wine ok(hres == S_OK, "ITextDocument_Open: Filename:test.txt Flags:0x%x Codepage:CP_UTF8 hres:0x%x\n",
290 tomConstantsMulti[i], hres);
291 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
292 DeleteFileW(filename);
293 }
294
295 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
296 hres = ITextDocument_Open(txtDoc, &testfile, tomCreateAlways, CP_ACP);
297 todo_wine ok(hres == S_OK, "ITextDocument_Open should success Codepage:CP_ACP\n");
298 todo_wine ok(is_existing_file(filename), "ITextDocument_Open should create a file\n");
299 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
300 DeleteFileW(filename);
301
302 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
303 hres = ITextDocument_Open(txtDoc, &testfile, tomCreateAlways, CP_UTF8);
304 todo_wine ok(hres == S_OK, "ITextDocument_Open should success Codepage:CP_UTF8\n");
305 todo_wine ok(is_existing_file(filename), "ITextDocument_Open should create a file\n");
306 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
307 DeleteFileW(filename);
308
309 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
310 hres = ITextDocument_Open(txtDoc, &testfile, tomOpenAlways, CP_ACP);
311 todo_wine ok(hres == S_OK, "ITextDocument_Open should success Codepage:CP_ACP\n");
312 todo_wine ok(is_existing_file(filename), "ITextDocument_Open should create a file\n");
313 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
314 DeleteFileW(filename);
315
316 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
317 hres = ITextDocument_Open(txtDoc, &testfile, tomOpenAlways, CP_UTF8);
318 todo_wine ok(hres == S_OK, "ITextDocument_Open should success Codepage:CP_UTF8\n");
319 todo_wine ok(is_existing_file(filename), "ITextDocument_Open should create a file\n");
320 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
321 DeleteFileW(filename);
322
323 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
324 hres = ITextDocument_Open(txtDoc, &testfile, tomCreateNew, CP_ACP);
325 todo_wine ok(hres == S_OK, "ITextDocument_Open should success Codepage:CP_ACP\n");
326 todo_wine ok(is_existing_file(filename), "ITextDocument_Open should create a file\n");
327 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
328 DeleteFileW(filename);
329
330 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
331 hres = ITextDocument_Open(txtDoc, &testfile, tomCreateNew, CP_UTF8);
332 todo_wine ok(hres == S_OK, "ITextDocument_Open should success Codepage:CP_UTF8\n");
333 todo_wine ok(is_existing_file(filename), "ITextDocument_Open should create a file\n");
334 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
335 DeleteFileW(filename);
336
337 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
338 touch_file(filename);
339 hres = ITextDocument_Open(txtDoc, &testfile, tomCreateNew, CP_ACP);
340 todo_wine ok(hres == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "ITextDocument_Open should fail Codepage:CP_ACP\n");
341 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
342 DeleteFileW(filename);
343
344 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
345 touch_file(filename);
346 hres = ITextDocument_Open(txtDoc, &testfile, tomCreateNew, CP_UTF8);
347 todo_wine ok(hres == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "ITextDocument_Open should fail Codepage:CP_UTF8\n");
348 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
349 DeleteFileW(filename);
350
351 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
352 hres = ITextDocument_Open(txtDoc, &testfile, tomOpenExisting, CP_ACP);
353 todo_wine ok(hres == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "ITextDocument_Open should fail Codepage:CP_ACP\n");
354 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
355
356 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
357 hres = ITextDocument_Open(txtDoc, &testfile, tomOpenExisting, CP_UTF8);
358 todo_wine ok(hres == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "ITextDocument_Open should fail Codepage:CP_UTF8\n");
359 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
360
361 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
362 DeleteFileW(filename);
363 hres = ITextDocument_Open(txtDoc, &testfile, tomText, CP_ACP);
364 todo_wine {
365 ok(hres == S_OK, "got 0x%08x\n", hres);
366 ok(is_existing_file(filename) == TRUE, "a file should be created default\n");
367 }
368 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
369 DeleteFileW(filename);
370
371 /* test of share mode */
372 touch_file(filename);
373 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
374 hres = ITextDocument_Open(txtDoc, &testfile, tomShareDenyRead, CP_ACP);
375 todo_wine
376 ok(hres == S_OK, "got 0x%08x\n", hres);
377 SetLastError(0xdeadbeef);
378 hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
379 FILE_ATTRIBUTE_NORMAL, NULL);
380 todo_wine ok(GetLastError() == ERROR_SHARING_VIOLATION, "ITextDocument_Open should fail\n");
381 CloseHandle(hFile);
382 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
383 DeleteFileW(filename);
384
385 touch_file(filename);
386 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
387 hres = ITextDocument_Open(txtDoc, &testfile, tomShareDenyWrite, CP_ACP);
388 todo_wine
389 ok(hres == S_OK, "got 0x%08x\n", hres);
390 SetLastError(0xdeadbeef);
391 hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
392 FILE_ATTRIBUTE_NORMAL, NULL);
393 todo_wine ok(GetLastError() == ERROR_SHARING_VIOLATION, "ITextDocument_Open should fail\n");
394 CloseHandle(hFile);
395 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
396 DeleteFileW(filename);
397
398 touch_file(filename);
399 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
400 SetLastError(0xdeadbeef);
401 hres = ITextDocument_Open(txtDoc, &testfile, tomShareDenyWrite|tomShareDenyRead, CP_ACP);
402 todo_wine
403 ok(hres == S_OK, "got 0x%08x\n", hres);
404 hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
405 FILE_ATTRIBUTE_NORMAL, NULL);
406 todo_wine ok(GetLastError() == ERROR_SHARING_VIOLATION, "ITextDocument_Open should fail\n");
407 CloseHandle(hFile);
408 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
409 DeleteFileW(filename);
410
411 /* tests to check the content */
412 hFile = CreateFileW(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS,
413 FILE_ATTRIBUTE_NORMAL, NULL);
414 WriteFile(hFile, chACP, sizeof(chACP)-sizeof(CHAR), &dw, NULL);
415 CloseHandle(hFile);
416 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
417 hres = ITextDocument_Open(txtDoc, &testfile, tomReadOnly, CP_ACP);
418 todo_wine
419 ok(hres == S_OK, "got 0x%08x\n", hres);
420 result = SendMessageA(w, WM_GETTEXT, 1024, (LPARAM)bufACP);
421 todo_wine ok(result == 12, "ITextDocument_Open: Test ASCII returned %d, expected 12\n", result);
422 result = strcmp(bufACP, chACP);
423 todo_wine ok(result == 0, "ITextDocument_Open: Test ASCII set wrong text: Result: %s\n", bufACP);
424 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
425 DeleteFileW(filename);
426
427 hFile = CreateFileW(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS,
428 FILE_ATTRIBUTE_NORMAL, NULL);
429 WriteFile(hFile, chUTF8, sizeof(chUTF8)-sizeof(CHAR), &dw, NULL);
430 CloseHandle(hFile);
431 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
432 hres = ITextDocument_Open(txtDoc, &testfile, tomReadOnly, CP_UTF8);
433 todo_wine
434 ok(hres == S_OK, "got 0x%08x\n", hres);
435 result = SendMessageA(w, WM_GETTEXT, 1024, (LPARAM)bufACP);
436 todo_wine ok(result == 15, "ITextDocument_Open: Test UTF-8 returned %d, expected 15\n", result);
437 result = strcmp(bufACP, &chUTF8[3]);
438 todo_wine ok(result == 0, "ITextDocument_Open: Test UTF-8 set wrong text: Result: %s\n", bufACP);
439 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
440 DeleteFileW(filename);
441
442 hFile = CreateFileW(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS,
443 FILE_ATTRIBUTE_NORMAL, NULL);
444 WriteFile(hFile, chUTF16, sizeof(chUTF16)-sizeof(WCHAR), &dw, NULL);
445 CloseHandle(hFile);
446 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
447 hres = ITextDocument_Open(txtDoc, &testfile, tomReadOnly, 1200);
448 todo_wine
449 ok(hres == S_OK, "got 0x%08x\n", hres);
450 result = SendMessageW(w, WM_GETTEXT, 1024, (LPARAM)bufUnicode);
451 todo_wine ok(result == 12, "ITextDocument_Open: Test UTF-16 returned %d, expected 12\n", result);
452 result = lstrcmpW(bufUnicode, &chUTF16[1]);
453 todo_wine ok(result == 0, "ITextDocument_Open: Test UTF-16 set wrong text: Result: %s\n", wine_dbgstr_w(bufUnicode));
454 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
455 DeleteFileW(filename);
456
457 VariantClear(&testfile);
458 }
459
460 static void test_GetText(void)
461 {
462 HWND w;
463 IRichEditOle *reOle = NULL;
464 ITextDocument *txtDoc = NULL;
465 ITextSelection *txtSel = NULL;
466 HRESULT hres;
467 BSTR bstr = NULL;
468 int first, lim;
469 static const CHAR test_text1[] = "TestSomeText";
470 static const WCHAR bufW1[] = {'T', 'e', 's', 't', 0};
471 static const WCHAR bufW2[] = {'T', 'e', 'x', 't', '\r', 0};
472 static const WCHAR bufW3[] = {'T', 'e', 'x', 't', 0};
473 static const WCHAR bufW4[] = {'T', 'e', 's', 't', 'S', 'o', 'm',
474 'e', 'T', 'e', 'x', 't', '\r', 0};
475 static const WCHAR bufW5[] = {'\r', 0};
476 static const WCHAR bufW6[] = {'T','e','s','t','S','o','m','e','T',0};
477 BOOL is64bit = sizeof(void *) > sizeof(int);
478 ITextRange *range;
479
480 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
481 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
482
483 /* ITextSelection */
484 first = 0, lim = 4;
485 SendMessageA(w, EM_SETSEL, first, lim);
486 hres = ITextSelection_GetText(txtSel, &bstr);
487 ok(hres == S_OK, "ITextSelection_GetText\n");
488 ok(!lstrcmpW(bstr, bufW1), "got wrong text: %s\n", wine_dbgstr_w(bstr));
489 SysFreeString(bstr);
490
491 first = 4, lim = 0;
492 SendMessageA(w, EM_SETSEL, first, lim);
493 hres = ITextSelection_GetText(txtSel, &bstr);
494 ok(hres == S_OK, "ITextSelection_GetText\n");
495 ok(!lstrcmpW(bstr, bufW1), "got wrong text: %s\n", wine_dbgstr_w(bstr));
496 SysFreeString(bstr);
497
498 first = 1, lim = 1;
499 SendMessageA(w, EM_SETSEL, first, lim);
500 hres = ITextSelection_GetText(txtSel, &bstr);
501 ok(hres == S_OK, "ITextSelection_GetText\n");
502 ok(!bstr, "got wrong text: %s\n", wine_dbgstr_w(bstr));
503
504 if (!is64bit)
505 {
506 hres = ITextSelection_GetText(txtSel, NULL);
507 ok(hres == E_INVALIDARG, "ITextSelection_GetText\n");
508 }
509
510 first = 8, lim = 12;
511 SendMessageA(w, EM_SETSEL, first, lim);
512 hres = ITextSelection_GetText(txtSel, &bstr);
513 ok(hres == S_OK, "ITextSelection_GetText\n");
514 ok(!lstrcmpW(bstr, bufW3), "got wrong text: %s\n", wine_dbgstr_w(bstr));
515 SysFreeString(bstr);
516
517 first = 8, lim = 13;
518 SendMessageA(w, EM_SETSEL, first, lim);
519 hres = ITextSelection_GetText(txtSel, &bstr);
520 ok(hres == S_OK, "ITextSelection_GetText\n");
521 ok(!lstrcmpW(bstr, bufW2), "got wrong text: %s\n", wine_dbgstr_w(bstr));
522 SysFreeString(bstr);
523
524 first = 12, lim = 13;
525 SendMessageA(w, EM_SETSEL, first, lim);
526 hres = ITextSelection_GetText(txtSel, &bstr);
527 ok(hres == S_OK, "ITextSelection_GetText\n");
528 ok(!lstrcmpW(bstr, bufW5), "got wrong text: %s\n", wine_dbgstr_w(bstr));
529 SysFreeString(bstr);
530
531 first = 0, lim = -1;
532 SendMessageA(w, EM_SETSEL, first, lim);
533 hres = ITextSelection_GetText(txtSel, &bstr);
534 ok(hres == S_OK, "ITextSelection_GetText\n");
535 ok(!lstrcmpW(bstr, bufW4), "got wrong text: %s\n", wine_dbgstr_w(bstr));
536 SysFreeString(bstr);
537
538 first = -1, lim = 9;
539 SendMessageA(w, EM_SETSEL, first, lim);
540 hres = ITextSelection_GetText(txtSel, &bstr);
541 ok(hres == S_OK, "ITextSelection_GetText\n");
542 ok(!bstr, "got wrong text: %s\n", wine_dbgstr_w(bstr));
543
544 /* ITextRange */
545 hres = ITextDocument_Range(txtDoc, 0, 4, &range);
546 ok(hres == S_OK, "got 0x%08x\n", hres);
547 hres = ITextRange_GetText(range, &bstr);
548 ok(hres == S_OK, "got 0x%08x\n", hres);
549 ok(!lstrcmpW(bstr, bufW1), "got wrong text: %s\n", wine_dbgstr_w(bstr));
550
551 SysFreeString(bstr);
552 ITextRange_Release(range);
553
554 hres = ITextDocument_Range(txtDoc, 4, 0, &range);
555 ok(hres == S_OK, "got 0x%08x\n", hres);
556 hres = ITextRange_GetText(range, &bstr);
557 ok(hres == S_OK, "got 0x%08x\n", hres);
558 ok(!lstrcmpW(bstr, bufW1), "got wrong text: %s\n", wine_dbgstr_w(bstr));
559
560 SysFreeString(bstr);
561 ITextRange_Release(range);
562
563 hres = ITextDocument_Range(txtDoc, 1, 1, &range);
564 ok(hres == S_OK, "got 0x%08x\n", hres);
565 hres = ITextRange_GetText(range, &bstr);
566 ok(hres == S_OK, "got 0x%08x\n", hres);
567 ok(!bstr, "got wrong text: %s\n", wine_dbgstr_w(bstr));
568 if (!is64bit)
569 {
570 hres = ITextRange_GetText(range, NULL);
571 ok(hres == E_INVALIDARG, "got 0x%08x\n", hres);
572 }
573 ITextRange_Release(range);
574
575 hres = ITextDocument_Range(txtDoc, 8, 12, &range);
576 ok(hres == S_OK, "got 0x%08x\n", hres);
577 hres = ITextRange_GetText(range, &bstr);
578 ok(hres == S_OK, "got 0x%08x\n", hres);
579 ok(!lstrcmpW(bstr, bufW3), "got wrong text: %s\n", wine_dbgstr_w(bstr));
580
581 SysFreeString(bstr);
582 ITextRange_Release(range);
583
584 hres = ITextDocument_Range(txtDoc, 8, 13, &range);
585 ok(hres == S_OK, "got 0x%08x\n", hres);
586 hres = ITextRange_GetText(range, &bstr);
587 ok(hres == S_OK, "got 0x%08x\n", hres);
588 ok(!lstrcmpW(bstr, bufW2), "got wrong text: %s\n", wine_dbgstr_w(bstr));
589
590 SysFreeString(bstr);
591 ITextRange_Release(range);
592
593 hres = ITextDocument_Range(txtDoc, 12, 13, &range);
594 ok(hres == S_OK, "got 0x%08x\n", hres);
595 hres = ITextRange_GetText(range, &bstr);
596 ok(hres == S_OK, "got 0x%08x\n", hres);
597 ok(!lstrcmpW(bstr, bufW5), "got wrong text: %s\n", wine_dbgstr_w(bstr));
598
599 SysFreeString(bstr);
600 ITextRange_Release(range);
601
602 hres = ITextDocument_Range(txtDoc, 0, -1, &range);
603 ok(hres == S_OK, "got 0x%08x\n", hres);
604 hres = ITextRange_GetText(range, &bstr);
605 ok(hres == S_OK, "got 0x%08x\n", hres);
606 ok(!bstr, "got wrong text: %s\n", wine_dbgstr_w(bstr));
607 ITextRange_Release(range);
608
609 hres = ITextDocument_Range(txtDoc, -1, 9, &range);
610 ok(hres == S_OK, "got 0x%08x\n", hres);
611 hres = ITextRange_GetText(range, &bstr);
612 ok(hres == S_OK, "got 0x%08x\n", hres);
613 ok(!lstrcmpW(bstr, bufW6), "got wrong text: %s\n", wine_dbgstr_w(bstr));
614
615 SysFreeString(bstr);
616
617 release_interfaces(&w, &reOle, &txtDoc, NULL);
618
619 /* detached selection/range */
620 if (is64bit) {
621 bstr = (void*)0xdeadbeef;
622 hres = ITextSelection_GetText(txtSel, &bstr);
623 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
624 todo_wine
625 ok(bstr == NULL, "got %p\n", bstr);
626
627 bstr = (void*)0xdeadbeef;
628 hres = ITextRange_GetText(range, &bstr);
629 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
630 todo_wine
631 ok(bstr == NULL, "got %p\n", bstr);
632 }
633 else {
634 hres = ITextSelection_GetText(txtSel, NULL);
635 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
636
637 hres = ITextRange_GetText(range, NULL);
638 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
639 }
640
641 ITextRange_Release(range);
642 ITextSelection_Release(txtSel);
643 }
644
645 static void test_ITextDocument_Range(void)
646 {
647 static const CHAR test_text1[] = "TestSomeText";
648 HWND w;
649 IRichEditOle *reOle = NULL;
650 ITextDocument *txtDoc = NULL;
651 ITextRange *txtRge, *range2;
652 HRESULT hres;
653 LONG value;
654
655 create_interfaces(&w, &reOle, &txtDoc, NULL);
656 hres = ITextDocument_Range(txtDoc, 0, 0, &txtRge);
657 ok(hres == S_OK, "ITextDocument_Range fails 0x%x.\n", hres);
658 EXPECT_REF(txtRge, 1);
659
660 hres = ITextDocument_Range(txtDoc, 0, 0, &range2);
661 ok(hres == S_OK, "ITextDocument_Range fails 0x%x.\n", hres);
662 ok(range2 != txtRge, "A new pointer should be returned\n");
663 ITextRange_Release(range2);
664
665 hres = ITextDocument_Range(txtDoc, 0, 0, NULL);
666 ok(hres == E_INVALIDARG, "ITextDocument_Range should fail 0x%x.\n", hres);
667
668 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
669
670 hres = ITextDocument_Range(txtDoc, 8, 30, &range2);
671 ok(hres == S_OK, "ITextDocument_Range fails 0x%x.\n", hres);
672 hres = ITextRange_GetStart(range2, &value);
673 ok(hres == S_OK, "got 0x%08x\n", hres);
674 ok(value == 8, "got %d\n", value);
675
676 hres = ITextRange_GetEnd(range2, &value);
677 ok(hres == S_OK, "got 0x%08x\n", hres);
678 ok(value == 13, "got %d\n", value);
679 ITextRange_Release(range2);
680
681 release_interfaces(&w, &reOle, &txtDoc, NULL);
682 hres = ITextRange_CanEdit(txtRge, NULL);
683 ok(hres == CO_E_RELEASED, "ITextRange after ITextDocument destroyed\n");
684 ITextRange_Release(txtRge);
685 }
686
687 static void test_ITextRange_GetChar(void)
688 {
689 HWND w;
690 IRichEditOle *reOle = NULL;
691 ITextDocument *txtDoc = NULL;
692 ITextRange *txtRge = NULL;
693 HRESULT hres;
694 LONG pch;
695 int first, lim;
696 static const CHAR test_text1[] = "TestSomeText";
697
698 first = 0, lim = 4;
699 create_interfaces(&w, &reOle, &txtDoc, NULL);
700 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
701 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
702 ok(hres == S_OK, "got 0x%08x\n", hres);
703 pch = 0xdeadbeef;
704 hres = ITextRange_GetChar(txtRge, &pch);
705 ok(hres == S_OK, "ITextRange_GetChar\n");
706 ok(pch == 'T', "got wrong char: %c\n", pch);
707 ITextRange_Release(txtRge);
708 release_interfaces(&w, &reOle, &txtDoc, NULL);
709
710 first = 0, lim = 0;
711 create_interfaces(&w, &reOle, &txtDoc, NULL);
712 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
713 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
714 ok(hres == S_OK, "got 0x%08x\n", hres);
715 pch = 0xdeadbeef;
716 hres = ITextRange_GetChar(txtRge, &pch);
717 ok(hres == S_OK, "ITextRange_GetChar\n");
718 ok(pch == 'T', "got wrong char: %c\n", pch);
719 ITextRange_Release(txtRge);
720 release_interfaces(&w, &reOle, &txtDoc, NULL);
721
722 first = 12, lim = 12;
723 create_interfaces(&w, &reOle, &txtDoc, NULL);
724 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
725 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
726 ok(hres == S_OK, "got 0x%08x\n", hres);
727 pch = 0xdeadbeef;
728 hres = ITextRange_GetChar(txtRge, &pch);
729 ok(hres == S_OK, "ITextRange_GetChar\n");
730 ok(pch == '\r', "got wrong char: %c\n", pch);
731 ITextRange_Release(txtRge);
732 release_interfaces(&w, &reOle, &txtDoc, NULL);
733
734 first = 13, lim = 13;
735 create_interfaces(&w, &reOle, &txtDoc, NULL);
736 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
737 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
738 ok(hres == S_OK, "got 0x%08x\n", hres);
739 pch = 0xdeadbeef;
740 hres = ITextRange_GetChar(txtRge, &pch);
741 ok(hres == S_OK, "ITextRange_GetChar\n");
742 ok(pch == '\r', "got wrong char: %c\n", pch);
743 ITextRange_Release(txtRge);
744 release_interfaces(&w, &reOle, &txtDoc, NULL);
745
746 create_interfaces(&w, &reOle, &txtDoc, NULL);
747 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
748 first = 12, lim = 12;
749 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
750 ok(hres == S_OK, "got 0x%08x\n", hres);
751 hres = ITextRange_GetChar(txtRge, NULL);
752 ok(hres == E_INVALIDARG, "ITextRange_GetChar\n");
753
754 release_interfaces(&w, &reOle, &txtDoc, NULL);
755
756 hres = ITextRange_GetChar(txtRge, NULL);
757 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
758
759 hres = ITextRange_GetChar(txtRge, &pch);
760 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
761
762 ITextRange_Release(txtRge);
763 }
764
765 /* Helper function for testing ITextRange_ScrollIntoView */
766 static void check_range(HWND w, ITextDocument* doc, int first, int lim,
767 LONG bStart, int expected_nonzero)
768 {
769 SCROLLINFO si;
770 ITextRange *txtRge = NULL;
771 HRESULT hres;
772
773 si.cbSize = sizeof(SCROLLINFO);
774 si.fMask = SIF_POS | SIF_RANGE;
775
776 hres = ITextDocument_Range(doc, first, lim, &txtRge);
777 ok(hres == S_OK, "got 0x%08x\n", hres);
778 hres = ITextRange_ScrollIntoView(txtRge, bStart);
779 ok(hres == S_OK, "got 0x%08x\n", hres);
780 GetScrollInfo(w, SB_VERT, &si);
781 if (expected_nonzero) {
782 ok(si.nPos != 0,
783 "Scrollbar at 0, should be >0. (TextRange %d-%d, scroll range %d-%d.)\n",
784 first, lim, si.nMin, si.nMax);
785 } else {
786 ok(si.nPos == 0,
787 "Scrollbar at %d, should be 0. (TextRange %d-%d, scroll range %d-%d.)\n",
788 si.nPos, first, lim, si.nMin, si.nMax);
789 }
790 }
791
792 static void test_ITextRange_ScrollIntoView(void)
793 {
794 HWND w;
795 IRichEditOle *reOle = NULL;
796 ITextDocument *txtDoc = NULL;
797 ITextRange *txtRge = NULL;
798 HRESULT hres;
799 static const CHAR test_text1[] = "1\n2\n3\n4\n5\n6\n7\n8\n9\n10";
800
801 create_interfaces(&w, &reOle, &txtDoc, NULL);
802 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
803
804 /* Scroll to the top. */
805 check_range(w, txtDoc, 0, 1, tomStart, 0);
806
807 /* Scroll to the bottom. */
808 check_range(w, txtDoc, 19, 20, tomStart, 1);
809
810 /* Back up to the top. */
811 check_range(w, txtDoc, 0, 1, tomStart, 0);
812
813 /* Large range */
814 check_range(w, txtDoc, 0, 20, tomStart, 0);
815
816 hres = ITextDocument_Range(txtDoc, 0, 0, &txtRge);
817 ok(hres == S_OK, "got 0x%08x\n", hres);
818 release_interfaces(&w, &reOle, &txtDoc, NULL);
819 hres = ITextRange_ScrollIntoView(txtRge, tomStart);
820 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
821 ITextRange_Release(txtRge);
822 }
823
824 static void test_ITextSelection_GetChar(void)
825 {
826 HWND w;
827 IRichEditOle *reOle = NULL;
828 ITextDocument *txtDoc = NULL;
829 ITextSelection *txtSel = NULL;
830 HRESULT hres;
831 LONG pch;
832 int first, lim;
833 static const CHAR test_text1[] = "TestSomeText";
834
835 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
836 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
837
838 first = 0, lim = 4;
839 SendMessageA(w, EM_SETSEL, first, lim);
840 pch = 0xdeadbeef;
841 hres = ITextSelection_GetChar(txtSel, &pch);
842 ok(hres == S_OK, "ITextSelection_GetChar\n");
843 ok(pch == 'T', "got wrong char: %c\n", pch);
844
845 first = 0, lim = 0;
846 SendMessageA(w, EM_SETSEL, first, lim);
847 pch = 0xdeadbeef;
848 hres = ITextSelection_GetChar(txtSel, &pch);
849 ok(hres == S_OK, "ITextSelection_GetChar\n");
850 ok(pch == 'T', "got wrong char: %c\n", pch);
851
852 first = 12, lim = 12;
853 SendMessageA(w, EM_SETSEL, first, lim);
854 pch = 0xdeadbeef;
855 hres = ITextSelection_GetChar(txtSel, &pch);
856 ok(hres == S_OK, "ITextSelection_GetChar\n");
857 ok(pch == '\r', "got wrong char: %c\n", pch);
858
859 first = 13, lim = 13;
860 SendMessageA(w, EM_SETSEL, first, lim);
861 pch = 0xdeadbeef;
862 hres = ITextSelection_GetChar(txtSel, &pch);
863 ok(hres == S_OK, "ITextSelection_GetChar\n");
864 ok(pch == '\r', "got wrong char: %c\n", pch);
865
866 hres = ITextSelection_GetChar(txtSel, NULL);
867 ok(hres == E_INVALIDARG, "ITextSelection_GetChar\n");
868
869 release_interfaces(&w, &reOle, &txtDoc, NULL);
870
871 hres = ITextSelection_GetChar(txtSel, NULL);
872 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
873
874 hres = ITextSelection_GetChar(txtSel, &pch);
875 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
876
877 ITextSelection_Release(txtSel);
878 }
879
880 static void test_ITextRange_GetStart_GetEnd(void)
881 {
882 HWND w;
883 IRichEditOle *reOle = NULL;
884 ITextDocument *txtDoc = NULL;
885 ITextRange *txtRge = NULL;
886 HRESULT hres;
887 int first, lim, start, end;
888 static const CHAR test_text1[] = "TestSomeText";
889
890 create_interfaces(&w, &reOle, &txtDoc, NULL);
891 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
892
893 first = 1, lim = 6;
894 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
895 ok(hres == S_OK, "got 0x%08x\n", hres);
896 start = 0xdeadbeef;
897 hres = ITextRange_GetStart(txtRge, &start);
898 ok(hres == S_OK, "ITextRange_GetStart\n");
899 ok(start == 1, "got wrong start value: %d\n", start);
900 end = 0xdeadbeef;
901 hres = ITextRange_GetEnd(txtRge, &end);
902 ok(hres == S_OK, "ITextRange_GetEnd\n");
903 ok(end == 6, "got wrong end value: %d\n", end);
904 ITextRange_Release(txtRge);
905
906 first = 6, lim = 1;
907 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
908 ok(hres == S_OK, "got 0x%08x\n", hres);
909 start = 0xdeadbeef;
910 hres = ITextRange_GetStart(txtRge, &start);
911 ok(hres == S_OK, "ITextRange_GetStart\n");
912 ok(start == 1, "got wrong start value: %d\n", start);
913 end = 0xdeadbeef;
914 hres = ITextRange_GetEnd(txtRge, &end);
915 ok(hres == S_OK, "ITextRange_GetEnd\n");
916 ok(end == 6, "got wrong end value: %d\n", end);
917 ITextRange_Release(txtRge);
918
919 first = -1, lim = 13;
920 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
921 ok(hres == S_OK, "got 0x%08x\n", hres);
922 start = 0xdeadbeef;
923 hres = ITextRange_GetStart(txtRge, &start);
924 ok(hres == S_OK, "ITextRange_GetStart\n");
925 ok(start == 0, "got wrong start value: %d\n", start);
926 end = 0xdeadbeef;
927 hres = ITextRange_GetEnd(txtRge, &end);
928 ok(hres == S_OK, "ITextRange_GetEnd\n");
929 ok(end == 13, "got wrong end value: %d\n", end);
930 ITextRange_Release(txtRge);
931
932 first = 13, lim = 13;
933 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
934 ok(hres == S_OK, "got 0x%08x\n", hres);
935 start = 0xdeadbeef;
936 hres = ITextRange_GetStart(txtRge, &start);
937 ok(hres == S_OK, "ITextRange_GetStart\n");
938 ok(start == 12, "got wrong start value: %d\n", start);
939 end = 0xdeadbeef;
940 hres = ITextRange_GetEnd(txtRge, &end);
941 ok(hres == S_OK, "ITextRange_GetEnd\n");
942 ok(end == 12, "got wrong end value: %d\n", end);
943
944 /* SetStart */
945 hres = ITextRange_SetStart(txtRge, 0);
946 ok(hres == S_OK, "got 0x%08x\n", hres);
947
948 /* same value */
949 hres = ITextRange_SetStart(txtRge, 0);
950 ok(hres == S_FALSE, "got 0x%08x\n", hres);
951
952 hres = ITextRange_SetStart(txtRge, 1);
953 ok(hres == S_OK, "got 0x%08x\n", hres);
954
955 /* negative resets to 0, return value is S_FALSE when
956 position wasn't changed */
957 hres = ITextRange_SetStart(txtRge, -1);
958 ok(hres == S_OK, "got 0x%08x\n", hres);
959
960 hres = ITextRange_SetStart(txtRge, -1);
961 ok(hres == S_FALSE, "got 0x%08x\n", hres);
962
963 hres = ITextRange_SetStart(txtRge, 0);
964 ok(hres == S_FALSE, "got 0x%08x\n", hres);
965
966 start = -1;
967 hres = ITextRange_GetStart(txtRge, &start);
968 ok(hres == S_OK, "got 0x%08x\n", hres);
969 ok(start == 0, "got %d\n", start);
970
971 /* greater than initial end, but less than total char count */
972 hres = ITextRange_SetStart(txtRge, 1);
973 ok(hres == S_OK, "got 0x%08x\n", hres);
974
975 hres = ITextRange_SetEnd(txtRge, 3);
976 ok(hres == S_OK, "got 0x%08x\n", hres);
977
978 hres = ITextRange_SetStart(txtRge, 10);
979 ok(hres == S_OK, "got 0x%08x\n", hres);
980
981 start = 0;
982 hres = ITextRange_GetStart(txtRge, &start);
983 ok(hres == S_OK, "got 0x%08x\n", hres);
984 ok(start == 10, "got %d\n", start);
985
986 end = 0;
987 hres = ITextRange_GetEnd(txtRge, &end);
988 ok(hres == S_OK, "got 0x%08x\n", hres);
989 ok(end == 10, "got %d\n", end);
990
991 /* more that total text length */
992 hres = ITextRange_SetStart(txtRge, 50);
993 ok(hres == S_OK, "got 0x%08x\n", hres);
994
995 start = 0;
996 hres = ITextRange_GetStart(txtRge, &start);
997 ok(hres == S_OK, "got 0x%08x\n", hres);
998 ok(start == 12, "got %d\n", start);
999
1000 end = 0;
1001 hres = ITextRange_GetEnd(txtRge, &end);
1002 ok(hres == S_OK, "got 0x%08x\n", hres);
1003 ok(end == 12, "got %d\n", end);
1004
1005 /* SetEnd */
1006 hres = ITextRange_SetStart(txtRge, 0);
1007 ok(hres == S_OK, "got 0x%08x\n", hres);
1008
1009 /* same value */
1010 hres = ITextRange_SetEnd(txtRge, 5);
1011 ok(hres == S_OK, "got 0x%08x\n", hres);
1012
1013 hres = ITextRange_SetEnd(txtRge, 5);
1014 ok(hres == S_FALSE, "got 0x%08x\n", hres);
1015
1016 /* negative resets to 0 */
1017 hres = ITextRange_SetEnd(txtRge, -1);
1018 ok(hres == S_OK, "got 0x%08x\n", hres);
1019
1020 end = -1;
1021 hres = ITextRange_GetEnd(txtRge, &end);
1022 ok(hres == S_OK, "got 0x%08x\n", hres);
1023 ok(end == 0, "got %d\n", end);
1024
1025 start = -1;
1026 hres = ITextRange_GetStart(txtRge, &start);
1027 ok(hres == S_OK, "got 0x%08x\n", hres);
1028 ok(start == 0, "got %d\n", start);
1029
1030 /* greater than initial end, but less than total char count */
1031 hres = ITextRange_SetStart(txtRge, 3);
1032 ok(hres == S_OK, "got 0x%08x\n", hres);
1033
1034 hres = ITextRange_SetEnd(txtRge, 1);
1035 ok(hres == S_OK, "got 0x%08x\n", hres);
1036
1037 start = 0;
1038 hres = ITextRange_GetStart(txtRge, &start);
1039 ok(hres == S_OK, "got 0x%08x\n", hres);
1040 ok(start == 1, "got %d\n", start);
1041
1042 end = 0;
1043 hres = ITextRange_GetEnd(txtRge, &end);
1044 ok(hres == S_OK, "got 0x%08x\n", hres);
1045 ok(end == 1, "got %d\n", end);
1046
1047 /* more than total count */
1048 hres = ITextRange_SetEnd(txtRge, 50);
1049 ok(hres == S_OK, "got 0x%08x\n", hres);
1050
1051 start = 0;
1052 hres = ITextRange_GetStart(txtRge, &start);
1053 ok(hres == S_OK, "got 0x%08x\n", hres);
1054 ok(start == 1, "got %d\n", start);
1055
1056 end = 0;
1057 hres = ITextRange_GetEnd(txtRge, &end);
1058 ok(hres == S_OK, "got 0x%08x\n", hres);
1059 ok(end == 13, "got %d\n", end);
1060
1061 /* zero */
1062 hres = ITextRange_SetEnd(txtRge, 0);
1063 ok(hres == S_OK, "got 0x%08x\n", hres);
1064
1065 start = 0;
1066 hres = ITextRange_GetStart(txtRge, &start);
1067 ok(hres == S_OK, "got 0x%08x\n", hres);
1068 ok(start == 0, "got %d\n", start);
1069
1070 end = 0;
1071 hres = ITextRange_GetEnd(txtRge, &end);
1072 ok(hres == S_OK, "got 0x%08x\n", hres);
1073 ok(end == 0, "got %d\n", end);
1074
1075 release_interfaces(&w, &reOle, &txtDoc, NULL);
1076
1077 /* detached range */
1078 hres = ITextRange_SetStart(txtRge, 0);
1079 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1080
1081 hres = ITextRange_SetEnd(txtRge, 3);
1082 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1083
1084 hres = ITextRange_GetStart(txtRge, &start);
1085 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1086
1087 hres = ITextRange_GetStart(txtRge, NULL);
1088 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1089
1090 hres = ITextRange_GetEnd(txtRge, &end);
1091 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1092
1093 hres = ITextRange_GetEnd(txtRge, NULL);
1094 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1095
1096 ITextRange_Release(txtRge);
1097 }
1098
1099 static void test_ITextSelection_GetStart_GetEnd(void)
1100 {
1101 HWND w;
1102 IRichEditOle *reOle = NULL;
1103 ITextDocument *txtDoc = NULL;
1104 ITextSelection *txtSel = NULL;
1105 HRESULT hres;
1106 int first, lim, start, end;
1107 static const CHAR test_text1[] = "TestSomeText";
1108
1109 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
1110 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
1111
1112 first = 2, lim = 5;
1113 SendMessageA(w, EM_SETSEL, first, lim);
1114 start = 0xdeadbeef;
1115 hres = ITextSelection_GetStart(txtSel, &start);
1116 ok(hres == S_OK, "ITextSelection_GetStart\n");
1117 ok(start == 2, "got wrong start value: %d\n", start);
1118 end = 0xdeadbeef;
1119 hres = ITextSelection_GetEnd(txtSel, &end);
1120 ok(hres == S_OK, "ITextSelection_GetEnd\n");
1121 ok(end == 5, "got wrong end value: %d\n", end);
1122
1123 first = 5, lim = 2;
1124 SendMessageA(w, EM_SETSEL, first, lim);
1125 start = 0xdeadbeef;
1126 hres = ITextSelection_GetStart(txtSel, &start);
1127 ok(hres == S_OK, "ITextSelection_GetStart\n");
1128 ok(start == 2, "got wrong start value: %d\n", start);
1129 end = 0xdeadbeef;
1130 hres = ITextSelection_GetEnd(txtSel, &end);
1131 ok(hres == S_OK, "ITextSelection_GetEnd\n");
1132 ok(end == 5, "got wrong end value: %d\n", end);
1133
1134 first = 0, lim = -1;
1135 SendMessageA(w, EM_SETSEL, first, lim);
1136 start = 0xdeadbeef;
1137 hres = ITextSelection_GetStart(txtSel, &start);
1138 ok(hres == S_OK, "ITextSelection_GetStart\n");
1139 ok(start == 0, "got wrong start value: %d\n", start);
1140 end = 0xdeadbeef;
1141 hres = ITextSelection_GetEnd(txtSel, &end);
1142 ok(hres == S_OK, "ITextSelection_GetEnd\n");
1143 ok(end == 13, "got wrong end value: %d\n", end);
1144
1145 first = 13, lim = 13;
1146 SendMessageA(w, EM_SETSEL, first, lim);
1147 start = 0xdeadbeef;
1148 hres = ITextSelection_GetStart(txtSel, &start);
1149 ok(hres == S_OK, "ITextSelection_GetStart\n");
1150 ok(start == 12, "got wrong start value: %d\n", start);
1151 end = 0xdeadbeef;
1152 hres = ITextSelection_GetEnd(txtSel, &end);
1153 ok(hres == S_OK, "ITextSelection_GetEnd\n");
1154 ok(end == 12, "got wrong end value: %d\n", end);
1155
1156 /* SetStart/SetEnd */
1157 hres = ITextSelection_SetStart(txtSel, 0);
1158 ok(hres == S_OK, "got 0x%08x\n", hres);
1159
1160 /* same value */
1161 hres = ITextSelection_SetStart(txtSel, 0);
1162 ok(hres == S_FALSE, "got 0x%08x\n", hres);
1163
1164 hres = ITextSelection_SetStart(txtSel, 1);
1165 ok(hres == S_OK, "got 0x%08x\n", hres);
1166
1167 /* negative resets to 0, return value is S_FALSE when
1168 position wasn't changed */
1169 hres = ITextSelection_SetStart(txtSel, -1);
1170 ok(hres == S_OK, "got 0x%08x\n", hres);
1171
1172 hres = ITextSelection_SetStart(txtSel, -1);
1173 ok(hres == S_FALSE, "got 0x%08x\n", hres);
1174
1175 hres = ITextSelection_SetStart(txtSel, 0);
1176 ok(hres == S_FALSE, "got 0x%08x\n", hres);
1177
1178 start = -1;
1179 hres = ITextSelection_GetStart(txtSel, &start);
1180 ok(hres == S_OK, "got 0x%08x\n", hres);
1181 ok(start == 0, "got %d\n", start);
1182
1183 /* greater than initial end, but less than total char count */
1184 hres = ITextSelection_SetStart(txtSel, 1);
1185 ok(hres == S_OK, "got 0x%08x\n", hres);
1186
1187 hres = ITextSelection_SetEnd(txtSel, 3);
1188 ok(hres == S_OK, "got 0x%08x\n", hres);
1189
1190 hres = ITextSelection_SetStart(txtSel, 10);
1191 ok(hres == S_OK, "got 0x%08x\n", hres);
1192
1193 start = 0;
1194 hres = ITextSelection_GetStart(txtSel, &start);
1195 ok(hres == S_OK, "got 0x%08x\n", hres);
1196 ok(start == 10, "got %d\n", start);
1197
1198 end = 0;
1199 hres = ITextSelection_GetEnd(txtSel, &end);
1200 ok(hres == S_OK, "got 0x%08x\n", hres);
1201 ok(end == 10, "got %d\n", end);
1202
1203 /* more that total text length */
1204 hres = ITextSelection_SetStart(txtSel, 50);
1205 ok(hres == S_OK, "got 0x%08x\n", hres);
1206
1207 start = 0;
1208 hres = ITextSelection_GetStart(txtSel, &start);
1209 ok(hres == S_OK, "got 0x%08x\n", hres);
1210 ok(start == 12, "got %d\n", start);
1211
1212 end = 0;
1213 hres = ITextSelection_GetEnd(txtSel, &end);
1214 ok(hres == S_OK, "got 0x%08x\n", hres);
1215 ok(end == 12, "got %d\n", end);
1216
1217 /* SetEnd */
1218 hres = ITextSelection_SetStart(txtSel, 0);
1219 ok(hres == S_OK, "got 0x%08x\n", hres);
1220
1221 /* same value */
1222 hres = ITextSelection_SetEnd(txtSel, 5);
1223 ok(hres == S_OK, "got 0x%08x\n", hres);
1224
1225 hres = ITextSelection_SetEnd(txtSel, 5);
1226 ok(hres == S_FALSE, "got 0x%08x\n", hres);
1227
1228 /* negative resets to 0 */
1229 hres = ITextSelection_SetEnd(txtSel, -1);
1230 ok(hres == S_OK, "got 0x%08x\n", hres);
1231
1232 end = -1;
1233 hres = ITextSelection_GetEnd(txtSel, &end);
1234 ok(hres == S_OK, "got 0x%08x\n", hres);
1235 ok(end == 0, "got %d\n", end);
1236
1237 start = -1;
1238 hres = ITextSelection_GetStart(txtSel, &start);
1239 ok(hres == S_OK, "got 0x%08x\n", hres);
1240 ok(start == 0, "got %d\n", start);
1241
1242 /* greater than initial end, but less than total char count */
1243 hres = ITextSelection_SetStart(txtSel, 3);
1244 ok(hres == S_OK, "got 0x%08x\n", hres);
1245
1246 hres = ITextSelection_SetEnd(txtSel, 1);
1247 ok(hres == S_OK, "got 0x%08x\n", hres);
1248
1249 start = 0;
1250 hres = ITextSelection_GetStart(txtSel, &start);
1251 ok(hres == S_OK, "got 0x%08x\n", hres);
1252 ok(start == 1, "got %d\n", start);
1253
1254 end = 0;
1255 hres = ITextSelection_GetEnd(txtSel, &end);
1256 ok(hres == S_OK, "got 0x%08x\n", hres);
1257 ok(end == 1, "got %d\n", end);
1258
1259 /* more than total count */
1260 hres = ITextSelection_SetEnd(txtSel, 50);
1261 ok(hres == S_OK, "got 0x%08x\n", hres);
1262
1263 start = 0;
1264 hres = ITextSelection_GetStart(txtSel, &start);
1265 ok(hres == S_OK, "got 0x%08x\n", hres);
1266 ok(start == 1, "got %d\n", start);
1267
1268 end = 0;
1269 hres = ITextSelection_GetEnd(txtSel, &end);
1270 ok(hres == S_OK, "got 0x%08x\n", hres);
1271 ok(end == 13, "got %d\n", end);
1272
1273 /* zero */
1274 hres = ITextSelection_SetEnd(txtSel, 0);
1275 ok(hres == S_OK, "got 0x%08x\n", hres);
1276
1277 start = 0;
1278 hres = ITextSelection_GetStart(txtSel, &start);
1279 ok(hres == S_OK, "got 0x%08x\n", hres);
1280 ok(start == 0, "got %d\n", start);
1281
1282 end = 0;
1283 hres = ITextSelection_GetEnd(txtSel, &end);
1284 ok(hres == S_OK, "got 0x%08x\n", hres);
1285 ok(end == 0, "got %d\n", end);
1286
1287 release_interfaces(&w, &reOle, &txtDoc, NULL);
1288
1289 /* detached selection */
1290 hres = ITextSelection_GetStart(txtSel, NULL);
1291 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1292
1293 hres = ITextSelection_GetStart(txtSel, &start);
1294 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1295
1296 hres = ITextSelection_GetEnd(txtSel, NULL);
1297 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1298
1299 hres = ITextSelection_GetEnd(txtSel, &end);
1300 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1301
1302 ITextSelection_Release(txtSel);
1303 }
1304
1305 static void test_ITextRange_GetDuplicate(void)
1306 {
1307 HWND w;
1308 IRichEditOle *reOle = NULL;
1309 ITextDocument *txtDoc = NULL;
1310 ITextRange *txtRge = NULL;
1311 ITextRange *txtRgeDup = NULL;
1312 HRESULT hres;
1313 LONG first, lim, start, end;
1314 static const CHAR test_text1[] = "TestSomeText";
1315
1316 create_interfaces(&w, &reOle, &txtDoc, NULL);
1317 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
1318 first = 0, lim = 4;
1319 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
1320 ok(hres == S_OK, "ITextDocument_Range fails 0x%x.\n", hres);
1321
1322 hres = ITextRange_GetDuplicate(txtRge, &txtRgeDup);
1323 ok(hres == S_OK, "ITextRange_GetDuplicate\n");
1324 ok(txtRgeDup != txtRge, "A new pointer should be returned\n");
1325 hres = ITextRange_GetStart(txtRgeDup, &start);
1326 ok(hres == S_OK, "got 0x%08x\n", hres);
1327 ok(start == first, "got wrong value: %d\n", start);
1328 hres = ITextRange_GetEnd(txtRgeDup, &end);
1329 ok(hres == S_OK, "got 0x%08x\n", hres);
1330 ok(end == lim, "got wrong value: %d\n", end);
1331
1332 ITextRange_Release(txtRgeDup);
1333
1334 hres = ITextRange_GetDuplicate(txtRge, NULL);
1335 ok(hres == E_INVALIDARG, "ITextRange_GetDuplicate\n");
1336
1337 release_interfaces(&w, &reOle, &txtDoc, NULL);
1338
1339 hres = ITextRange_GetDuplicate(txtRge, NULL);
1340 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1341
1342 hres = ITextRange_GetDuplicate(txtRge, &txtRgeDup);
1343 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1344
1345 ITextRange_Release(txtRge);
1346 }
1347
1348 static void test_ITextRange_Collapse(void)
1349 {
1350 HWND w;
1351 IRichEditOle *reOle = NULL;
1352 ITextDocument *txtDoc = NULL;
1353 ITextRange *txtRge = NULL;
1354 HRESULT hres;
1355 LONG first, lim, start, end;
1356 static const CHAR test_text1[] = "TestSomeText";
1357
1358 create_interfaces(&w, &reOle, &txtDoc, NULL);
1359 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
1360
1361 first = 4, lim = 8;
1362 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
1363 ok(hres == S_OK, "got 0x%08x\n", hres);
1364 hres = ITextRange_Collapse(txtRge, tomTrue);
1365 ok(hres == S_OK, "ITextRange_Collapse\n");
1366 hres = ITextRange_GetStart(txtRge, &start);
1367 ok(hres == S_OK, "got 0x%08x\n", hres);
1368 ok(start == 4, "got wrong start value: %d\n", start);
1369 hres = ITextRange_GetEnd(txtRge, &end);
1370 ok(hres == S_OK, "got 0x%08x\n", hres);
1371 ok(end == 4, "got wrong end value: %d\n", end);
1372 ITextRange_Release(txtRge);
1373
1374 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
1375 ok(hres == S_OK, "got 0x%08x\n", hres);
1376 hres = ITextRange_Collapse(txtRge, tomStart);
1377 ok(hres == S_OK, "ITextRange_Collapse\n");
1378 hres = ITextRange_GetStart(txtRge, &start);
1379 ok(hres == S_OK, "got 0x%08x\n", hres);
1380 ok(start == 4, "got wrong start value: %d\n", start);
1381 hres = ITextRange_GetEnd(txtRge, &end);
1382 ok(hres == S_OK, "got 0x%08x\n", hres);
1383 ok(end == 4, "got wrong end value: %d\n", end);
1384 ITextRange_Release(txtRge);
1385
1386 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
1387 ok(hres == S_OK, "got 0x%08x\n", hres);
1388 hres = ITextRange_Collapse(txtRge, tomFalse);
1389 ok(hres == S_OK, "ITextRange_Collapse\n");
1390 hres = ITextRange_GetStart(txtRge, &start);
1391 ok(hres == S_OK, "got 0x%08x\n", hres);
1392 ok(start == 8, "got wrong start value: %d\n", start);
1393 hres = ITextRange_GetEnd(txtRge, &end);
1394 ok(hres == S_OK, "got 0x%08x\n", hres);
1395 ok(end == 8, "got wrong end value: %d\n", end);
1396 ITextRange_Release(txtRge);
1397
1398 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
1399 ok(hres == S_OK, "got 0x%08x\n", hres);
1400 hres = ITextRange_Collapse(txtRge, tomEnd);
1401 ok(hres == S_OK, "ITextRange_Collapse\n");
1402 hres = ITextRange_GetStart(txtRge, &start);
1403 ok(hres == S_OK, "got 0x%08x\n", hres);
1404 ok(start == 8, "got wrong start value: %d\n", start);
1405 hres = ITextRange_GetEnd(txtRge, &end);
1406 ok(hres == S_OK, "got 0x%08x\n", hres);
1407 ok(end == 8, "got wrong end value: %d\n", end);
1408 ITextRange_Release(txtRge);
1409
1410 /* tomStart is the default */
1411 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
1412 ok(hres == S_OK, "got 0x%08x\n", hres);
1413 hres = ITextRange_Collapse(txtRge, 256);
1414 ok(hres == S_OK, "ITextRange_Collapse\n");
1415 hres = ITextRange_GetStart(txtRge, &start);
1416 ok(hres == S_OK, "got 0x%08x\n", hres);
1417 ok(start == 4, "got wrong start value: %d\n", start);
1418 hres = ITextRange_GetEnd(txtRge, &end);
1419 ok(hres == S_OK, "got 0x%08x\n", hres);
1420 ok(end == 4, "got wrong end value: %d\n", end);
1421 ITextRange_Release(txtRge);
1422
1423 first = 6, lim = 6;
1424 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
1425 ok(hres == S_OK, "got 0x%08x\n", hres);
1426 hres = ITextRange_Collapse(txtRge, tomEnd);
1427 ok(hres == S_FALSE, "ITextRange_Collapse\n");
1428 hres = ITextRange_GetStart(txtRge, &start);
1429 ok(hres == S_OK, "got 0x%08x\n", hres);
1430 ok(start == 6, "got wrong start value: %d\n", start);
1431 hres = ITextRange_GetEnd(txtRge, &end);
1432 ok(hres == S_OK, "got 0x%08x\n", hres);
1433 ok(end == 6, "got wrong end value: %d\n", end);
1434 ITextRange_Release(txtRge);
1435
1436 first = 8, lim = 8;
1437 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
1438 ok(hres == S_OK, "got 0x%08x\n", hres);
1439 hres = ITextRange_Collapse(txtRge, tomStart);
1440 ok(hres == S_FALSE, "ITextRange_Collapse\n");
1441 hres = ITextRange_GetStart(txtRge, &start);
1442 ok(hres == S_OK, "got 0x%08x\n", hres);
1443 ok(start == 8, "got wrong start value: %d\n", start);
1444 hres = ITextRange_GetEnd(txtRge, &end);
1445 ok(hres == S_OK, "got 0x%08x\n", hres);
1446 ok(end == 8, "got wrong end value: %d\n", end);
1447
1448 release_interfaces(&w, &reOle, &txtDoc, NULL);
1449
1450 hres = ITextRange_Collapse(txtRge, tomStart);
1451 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1452
1453 hres = ITextRange_Collapse(txtRge, tomUndefined);
1454 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1455
1456 ITextRange_Release(txtRge);
1457 }
1458
1459 static void test_ITextSelection_Collapse(void)
1460 {
1461 HWND w;
1462 IRichEditOle *reOle = NULL;
1463 ITextDocument *txtDoc = NULL;
1464 ITextSelection *txtSel = NULL;
1465 HRESULT hres;
1466 LONG first, lim, start, end;
1467 static const CHAR test_text1[] = "TestSomeText";
1468
1469 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
1470 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
1471
1472 first = 4, lim = 8;
1473 SendMessageA(w, EM_SETSEL, first, lim);
1474 hres = ITextSelection_Collapse(txtSel, tomTrue);
1475 ok(hres == S_OK, "ITextSelection_Collapse\n");
1476 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1477 ok(start == 4, "got wrong start value: %d\n", start);
1478 ok(end == 4, "got wrong end value: %d\n", end);
1479
1480 SendMessageA(w, EM_SETSEL, first, lim);
1481 hres = ITextSelection_Collapse(txtSel, tomStart);
1482 ok(hres == S_OK, "ITextSelection_Collapse\n");
1483 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1484 ok(start == 4, "got wrong start value: %d\n", start);
1485 ok(end == 4, "got wrong end value: %d\n", end);
1486
1487 SendMessageA(w, EM_SETSEL, first, lim);
1488 hres = ITextSelection_Collapse(txtSel, tomFalse);
1489 ok(hres == S_OK, "ITextSelection_Collapse\n");
1490 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1491 ok(start == 8, "got wrong start value: %d\n", start);
1492 ok(end == 8, "got wrong end value: %d\n", end);
1493
1494 SendMessageA(w, EM_SETSEL, first, lim);
1495 hres = ITextSelection_Collapse(txtSel, tomEnd);
1496 ok(hres == S_OK, "ITextSelection_Collapse\n");
1497 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1498 ok(start == 8, "got wrong start value: %d\n", start);
1499 ok(end == 8, "got wrong end value: %d\n", end);
1500
1501 /* tomStart is the default */
1502 SendMessageA(w, EM_SETSEL, first, lim);
1503 hres = ITextSelection_Collapse(txtSel, 256);
1504 ok(hres == S_OK, "ITextSelection_Collapse\n");
1505 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1506 ok(start == 4, "got wrong start value: %d\n", start);
1507 ok(end == 4, "got wrong end value: %d\n", end);
1508
1509 first = 6, lim = 6;
1510 SendMessageA(w, EM_SETSEL, first, lim);
1511 hres = ITextSelection_Collapse(txtSel, tomEnd);
1512 ok(hres == S_FALSE, "ITextSelection_Collapse\n");
1513 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1514 ok(start == 6, "got wrong start value: %d\n", start);
1515 ok(end == 6, "got wrong end value: %d\n", end);
1516
1517 first = 8, lim = 8;
1518 SendMessageA(w, EM_SETSEL, first, lim);
1519 hres = ITextSelection_Collapse(txtSel, tomStart);
1520 ok(hres == S_FALSE, "ITextSelection_Collapse\n");
1521 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1522 ok(start == 8, "got wrong start value: %d\n", start);
1523 ok(end == 8, "got wrong end value: %d\n", end);
1524
1525 release_interfaces(&w, &reOle, &txtDoc, NULL);
1526
1527 hres = ITextSelection_Collapse(txtSel, tomStart);
1528 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1529
1530 hres = ITextSelection_Collapse(txtSel, tomUndefined);
1531 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1532
1533 ITextSelection_Release(txtSel);
1534 }
1535
1536 static void test_GetClientSite(void)
1537 {
1538 HWND w;
1539 IRichEditOle *reOle = NULL, *reOle1 = NULL;
1540 ITextDocument *txtDoc = NULL;
1541 IOleClientSite *clientSite = NULL, *clientSite1 = NULL, *clientSite2 = NULL;
1542 IOleWindow *oleWin = NULL, *oleWin1 = NULL;
1543 IOleInPlaceSite *olePlace = NULL, *olePlace1 = NULL;
1544 HRESULT hres;
1545 LONG refcount1, refcount2;
1546
1547 create_interfaces(&w, &reOle, &txtDoc, NULL);
1548 hres = IRichEditOle_GetClientSite(reOle, &clientSite);
1549 ok(hres == S_OK, "IRichEditOle_QueryInterface: 0x%08x\n", hres);
1550 EXPECT_REF(clientSite, 1);
1551
1552 hres = IOleClientSite_QueryInterface(clientSite, &IID_IRichEditOle, (void **)&reOle1);
1553 ok(hres == E_NOINTERFACE, "IOleClientSite_QueryInterface: %x\n", hres);
1554
1555 hres = IRichEditOle_GetClientSite(reOle, &clientSite1);
1556 ok(hres == S_OK, "got 0x%08x\n", hres);
1557 ok(clientSite != clientSite1, "got %p, %p\n", clientSite, clientSite1);
1558 IOleClientSite_Release(clientSite1);
1559
1560 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleClientSite, (void **)&clientSite1);
1561 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1562 ok(clientSite == clientSite1, "Should not return a new pointer.\n");
1563 EXPECT_REF(clientSite, 2);
1564
1565 /* IOleWindow interface */
1566 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleWindow, (void **)&oleWin);
1567 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1568 refcount1 = get_refcount((IUnknown *)clientSite);
1569 refcount2 = get_refcount((IUnknown *)oleWin);
1570 ok(refcount1 == refcount2, "got wrong ref count.\n");
1571
1572 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleWindow, (void **)&oleWin1);
1573 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1574 ok(oleWin == oleWin1, "Should not return a new pointer.\n");
1575 refcount1 = get_refcount((IUnknown *)clientSite);
1576 refcount2 = get_refcount((IUnknown *)oleWin);
1577 ok(refcount1 == refcount2, "got wrong ref count.\n");
1578
1579 hres = IOleWindow_QueryInterface(oleWin, &IID_IOleClientSite, (void **)&clientSite2);
1580 ok(hres == S_OK, "IOleWindow_QueryInterface: 0x%08x\n", hres);
1581 ok(clientSite2 == clientSite1, "got wrong pointer\n");
1582
1583 /* IOleInPlaceSite interface */
1584 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleInPlaceSite, (void **)&olePlace);
1585 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1586 refcount1 = get_refcount((IUnknown *)olePlace);
1587 refcount2 = get_refcount((IUnknown *)clientSite);
1588 ok(refcount1 == refcount2, "got wrong ref count.\n");
1589
1590 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleInPlaceSite, (void **)&olePlace1);
1591 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1592 ok(olePlace == olePlace1, "Should not return a new pointer.\n");
1593 IOleInPlaceSite_Release(olePlace1);
1594
1595 hres = IOleWindow_QueryInterface(oleWin, &IID_IOleInPlaceSite, (void **)&olePlace1);
1596 ok(hres == S_OK, "IOleWindow_QueryInterface: 0x%08x\n", hres);
1597 refcount1 = get_refcount((IUnknown *)olePlace1);
1598 refcount2 = get_refcount((IUnknown *)oleWin);
1599 ok(refcount1 == refcount2, "got wrong ref count.\n");
1600
1601 IOleInPlaceSite_Release(olePlace1);
1602 IOleInPlaceSite_Release(olePlace);
1603 IOleWindow_Release(oleWin1);
1604 IOleWindow_Release(oleWin);
1605 IOleClientSite_Release(clientSite2);
1606 IOleClientSite_Release(clientSite1);
1607 IOleClientSite_Release(clientSite);
1608 release_interfaces(&w, &reOle, &txtDoc, NULL);
1609 }
1610
1611 static void test_IOleWindow_GetWindow(void)
1612 {
1613 HWND w;
1614 IRichEditOle *reOle = NULL;
1615 ITextDocument *txtDoc = NULL;
1616 IOleClientSite *clientSite = NULL;
1617 IOleWindow *oleWin = NULL;
1618 HRESULT hres;
1619 HWND hwnd;
1620
1621 create_interfaces(&w, &reOle, &txtDoc, NULL);
1622 hres = IRichEditOle_GetClientSite(reOle, &clientSite);
1623 ok(hres == S_OK, "IRichEditOle_QueryInterface: 0x%08x\n", hres);
1624
1625 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleWindow, (void **)&oleWin);
1626 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1627 hres = IOleWindow_GetWindow(oleWin, &hwnd);
1628 ok(hres == S_OK, "IOleClientSite_GetWindow: 0x%08x\n", hres);
1629 ok(w == hwnd, "got wrong pointer\n");
1630
1631 hres = IOleWindow_GetWindow(oleWin, NULL);
1632 ok(hres == E_INVALIDARG, "IOleClientSite_GetWindow: 0x%08x\n", hres);
1633
1634 IOleWindow_Release(oleWin);
1635 IOleClientSite_Release(clientSite);
1636 release_interfaces(&w, &reOle, &txtDoc, NULL);
1637 }
1638
1639 static void test_IOleInPlaceSite_GetWindow(void)
1640 {
1641 HWND w;
1642 IRichEditOle *reOle = NULL;
1643 ITextDocument *txtDoc = NULL;
1644 IOleClientSite *clientSite = NULL;
1645 IOleInPlaceSite *olePlace = NULL;
1646 HRESULT hres;
1647 HWND hwnd;
1648
1649 create_interfaces(&w, &reOle, &txtDoc, NULL);
1650 hres = IRichEditOle_GetClientSite(reOle, &clientSite);
1651 ok(hres == S_OK, "IRichEditOle_QueryInterface: 0x%08x\n", hres);
1652
1653 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleInPlaceSite, (void **)&olePlace);
1654 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1655 hres = IOleInPlaceSite_GetWindow(olePlace, &hwnd);
1656 ok(hres == S_OK, "IOleInPlaceSite_GetWindow: 0x%08x\n", hres);
1657 ok(w == hwnd, "got wrong pointer.\n");
1658
1659 hres = IOleInPlaceSite_GetWindow(olePlace, NULL);
1660 ok(hres == E_INVALIDARG, "IOleInPlaceSite_GetWindow: 0x%08x\n", hres);
1661
1662 IOleInPlaceSite_Release(olePlace);
1663 IOleClientSite_Release(clientSite);
1664 release_interfaces(&w, &reOle, &txtDoc, NULL);
1665 }
1666
1667 static void test_GetFont(void)
1668 {
1669 static const CHAR test_text1[] = "TestSomeText";
1670 IRichEditOle *reOle = NULL;
1671 ITextDocument *doc = NULL;
1672 ITextRange *range = NULL;
1673 ITextSelection *selection;
1674 ITextFont *font, *font2;
1675 CHARFORMAT2A cf;
1676 LONG value;
1677 float size;
1678 HRESULT hr;
1679 HWND hwnd;
1680 BOOL ret;
1681
1682 create_interfaces(&hwnd, &reOle, &doc, NULL);
1683 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
1684
1685 hr = ITextDocument_GetSelection(doc, &selection);
1686 ok(hr == S_OK, "got 0x%08x\n", hr);
1687 hr = ITextSelection_GetFont(selection, &font);
1688 ok(hr == S_OK, "got 0x%08x\n", hr);
1689 hr = ITextSelection_GetFont(selection, &font2);
1690 ok(hr == S_OK, "got 0x%08x\n", hr);
1691 ok(font != font2, "got %p, %p\n", font, font2);
1692 ITextFont_Release(font2);
1693 ITextFont_Release(font);
1694 ITextSelection_Release(selection);
1695
1696 EXPECT_REF(reOle, 3);
1697 EXPECT_REF(doc, 3);
1698
1699 hr = ITextDocument_Range(doc, 0, 4, &range);
1700 ok(hr == S_OK, "got 0x%08x\n", hr);
1701
1702 EXPECT_REF(reOle, 3);
1703 EXPECT_REF(doc, 3);
1704 EXPECT_REF(range, 1);
1705
1706 hr = ITextRange_GetFont(range, NULL);
1707 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1708
1709 hr = ITextRange_GetFont(range, &font);
1710 ok(hr == S_OK, "got 0x%08x\n", hr);
1711
1712 EXPECT_REF(reOle, 3);
1713 EXPECT_REF(doc, 3);
1714 EXPECT_REF(range, 2);
1715 EXPECT_REF(font, 1);
1716
1717 hr = ITextRange_GetFont(range, &font2);
1718 ok(hr == S_OK, "got 0x%08x\n", hr);
1719 ok(font != font2, "got %p, %p\n", font, font2);
1720
1721 EXPECT_REF(reOle, 3);
1722 EXPECT_REF(doc, 3);
1723 EXPECT_REF(range, 3);
1724 EXPECT_REF(font, 1);
1725 EXPECT_REF(font2, 1);
1726
1727 ITextFont_Release(font2);
1728
1729 /* set different font style within a range */
1730 hr = ITextFont_GetItalic(font, NULL);
1731 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1732
1733 hr = ITextFont_GetSize(font, NULL);
1734 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1735
1736 size = 0.0;
1737 hr = ITextFont_GetSize(font, &size);
1738 ok(hr == S_OK, "got 0x%08x\n", hr);
1739 ok(size > 0.0, "size %.2f\n", size);
1740
1741 value = 0;
1742 hr = ITextFont_GetLanguageID(font, &value);
1743 ok(hr == S_OK, "got 0x%08x\n", hr);
1744 ok(value == GetSystemDefaultLCID(), "got lcid %x, user lcid %x\n", value,
1745 GetSystemDefaultLCID());
1746
1747 /* range is non-italic */
1748 value = tomTrue;
1749 hr = ITextFont_GetItalic(font, &value);
1750 ok(hr == S_OK, "got 0x%08x\n", hr);
1751 ok(value == tomFalse, "got %d\n", value);
1752
1753 cf.cbSize = sizeof(CHARFORMAT2A);
1754 cf.dwMask = CFM_ITALIC|CFM_SIZE;
1755 cf.dwEffects = CFE_ITALIC;
1756 cf.yHeight = 24.0;
1757
1758 SendMessageA(hwnd, EM_SETSEL, 2, 3);
1759 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
1760 ok(ret, "got %d\n", ret);
1761
1762 /* now range is partially italicized */
1763 value = tomFalse;
1764 hr = ITextFont_GetItalic(font, &value);
1765 ok(hr == S_OK, "got 0x%08x\n", hr);
1766 ok(value == tomUndefined, "got %d\n", value);
1767
1768 size = 0.0;
1769 hr = ITextFont_GetSize(font, &size);
1770 ok(hr == S_OK, "got 0x%08x\n", hr);
1771 ok(size == tomUndefined, "size %.2f\n", size);
1772
1773 ITextFont_Release(font);
1774 release_interfaces(&hwnd, &reOle, &doc, NULL);
1775
1776 hr = ITextRange_GetFont(range, NULL);
1777 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
1778
1779 hr = ITextRange_GetFont(range, &font2);
1780 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
1781
1782 ITextRange_Release(range);
1783 }
1784
1785 static void test_GetPara(void)
1786 {
1787 static const CHAR test_text1[] = "TestSomeText";
1788 IRichEditOle *reOle = NULL;
1789 ITextDocument *doc = NULL;
1790 ITextSelection *selection;
1791 ITextRange *range = NULL;
1792 ITextPara *para, *para2;
1793 HRESULT hr;
1794 HWND hwnd;
1795
1796 create_interfaces(&hwnd, &reOle, &doc, &selection);
1797 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
1798
1799 EXPECT_REF(reOle, 3);
1800 EXPECT_REF(doc, 3);
1801
1802 hr = ITextDocument_Range(doc, 0, 4, &range);
1803 ok(hr == S_OK, "got 0x%08x\n", hr);
1804
1805 EXPECT_REF(reOle, 3);
1806 EXPECT_REF(doc, 3);
1807 EXPECT_REF(range, 1);
1808
1809 hr = ITextRange_GetPara(range, NULL);
1810 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1811
1812 hr = ITextRange_GetPara(range, &para);
1813 ok(hr == S_OK, "got 0x%08x\n", hr);
1814
1815 EXPECT_REF(reOle, 3);
1816 EXPECT_REF(doc, 3);
1817 EXPECT_REF(range, 2);
1818 EXPECT_REF(para, 1);
1819
1820 hr = ITextRange_GetPara(range, &para2);
1821 ok(hr == S_OK, "got 0x%08x\n", hr);
1822 ok(para != para2, "got %p, %p\n", para, para2);
1823
1824 EXPECT_REF(reOle, 3);
1825 EXPECT_REF(doc, 3);
1826 EXPECT_REF(range, 3);
1827 EXPECT_REF(para, 1);
1828 EXPECT_REF(para2, 1);
1829
1830 ITextPara_Release(para);
1831 ITextPara_Release(para2);
1832
1833 EXPECT_REF(reOle, 3);
1834 EXPECT_REF(doc, 3);
1835 EXPECT_REF(selection, 2);
1836
1837 hr = ITextSelection_GetPara(selection, &para);
1838 ok(hr == S_OK, "got 0x%08x\n", hr);
1839
1840 EXPECT_REF(reOle, 3);
1841 EXPECT_REF(doc, 3);
1842 EXPECT_REF(selection, 3);
1843 EXPECT_REF(para, 1);
1844
1845 hr = ITextSelection_GetPara(selection, &para2);
1846 ok(hr == S_OK, "got 0x%08x\n", hr);
1847 ok(para != para2, "got %p, %p\n", para, para2);
1848
1849 ITextPara_Release(para);
1850 ITextPara_Release(para2);
1851 release_interfaces(&hwnd, &reOle, &doc, NULL);
1852
1853 hr = ITextRange_GetPara(range, NULL);
1854 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
1855
1856 hr = ITextRange_GetPara(range, &para);
1857 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
1858
1859 hr = ITextSelection_GetPara(selection, NULL);
1860 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
1861
1862 hr = ITextSelection_GetPara(selection, &para);
1863 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
1864
1865 ITextSelection_Release(selection);
1866 ITextRange_Release(range);
1867 }
1868
1869 static void test_dispatch(void)
1870 {
1871 static const WCHAR testnameW[] = {'G','e','t','T','e','x','t',0};
1872 static const WCHAR testname2W[] = {'T','e','x','t',0};
1873 IRichEditOle *reOle = NULL;
1874 ITextDocument *doc = NULL;
1875 ITextRange *range = NULL;
1876 WCHAR *nameW;
1877 DISPID dispid;
1878 HRESULT hr;
1879 UINT count;
1880 HWND hwnd;
1881
1882 create_interfaces(&hwnd, &reOle, &doc, NULL);
1883
1884 range = NULL;
1885 hr = ITextDocument_Range(doc, 0, 0, &range);
1886 ok(hr == S_OK, "got 0x%08x\n", hr);
1887 ok(range != NULL, "got %p\n", range);
1888
1889 dispid = 123;
1890 nameW = (WCHAR*)testnameW;
1891 hr = ITextRange_GetIDsOfNames(range, &IID_NULL, &nameW, 1, LOCALE_USER_DEFAULT, &dispid);
1892 ok(hr == DISP_E_UNKNOWNNAME, "got 0x%08x\n", hr);
1893 ok(dispid == DISPID_UNKNOWN, "got %d\n", dispid);
1894
1895 dispid = 123;
1896 nameW = (WCHAR*)testname2W;
1897 hr = ITextRange_GetIDsOfNames(range, &IID_NULL, &nameW, 1, LOCALE_USER_DEFAULT, &dispid);
1898 ok(hr == S_OK, "got 0x%08x\n", hr);
1899 ok(dispid == DISPID_VALUE, "got %d\n", dispid);
1900
1901 release_interfaces(&hwnd, &reOle, &doc, NULL);
1902
1903 /* try dispatch methods on detached range */
1904 hr = ITextRange_GetTypeInfoCount(range, &count);
1905 ok(hr == S_OK, "got 0x%08x\n", hr);
1906
1907 dispid = 123;
1908 nameW = (WCHAR*)testname2W;
1909 hr = ITextRange_GetIDsOfNames(range, &IID_NULL, &nameW, 1, LOCALE_USER_DEFAULT, &dispid);
1910 ok(hr == S_OK, "got 0x%08x\n", hr);
1911 ok(dispid == DISPID_VALUE, "got %d\n", dispid);
1912
1913 ITextRange_Release(range);
1914 }
1915
1916 static void test_detached_font_getters(ITextFont *font, BOOL duplicate)
1917 {
1918 HRESULT hr, hrexp = duplicate ? S_OK : CO_E_RELEASED;
1919 LONG value;
1920 float size;
1921 BSTR str;
1922
1923 hr = ITextFont_GetBold(font, NULL);
1924 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1925
1926 hr = ITextFont_GetBold(font, &value);
1927 ok(hr == hrexp, "got 0x%08x\n", hr);
1928
1929 hr = ITextFont_GetForeColor(font, NULL);
1930 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1931
1932 hr = ITextFont_GetForeColor(font, &value);
1933 ok(hr == hrexp, "got 0x%08x\n", hr);
1934
1935 hr = ITextFont_GetItalic(font, NULL);
1936 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1937
1938 hr = ITextFont_GetItalic(font, &value);
1939 ok(hr == hrexp, "got 0x%08x\n", hr);
1940
1941 hr = ITextFont_GetLanguageID(font, NULL);
1942 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1943
1944 hr = ITextFont_GetLanguageID(font, &value);
1945 ok(hr == hrexp, "got 0x%08x\n", hr);
1946
1947 hr = ITextFont_GetName(font, NULL);
1948 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1949
1950 hr = ITextFont_GetName(font, &str);
1951 ok(hr == hrexp, "got 0x%08x\n", hr);
1952
1953 hr = ITextFont_GetSize(font, NULL);
1954 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1955
1956 hr = ITextFont_GetSize(font, &size);
1957 ok(hr == hrexp, "got 0x%08x\n", hr);
1958
1959 hr = ITextFont_GetStrikeThrough(font, NULL);
1960 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1961
1962 hr = ITextFont_GetStrikeThrough(font, &value);
1963 ok(hr == hrexp, "got 0x%08x\n", hr);
1964
1965 hr = ITextFont_GetSubscript(font, NULL);
1966 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1967
1968 hr = ITextFont_GetSubscript(font, &value);
1969 ok(hr == hrexp, "got 0x%08x\n", hr);
1970
1971 hr = ITextFont_GetSuperscript(font, NULL);
1972 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1973
1974 hr = ITextFont_GetSuperscript(font, &value);
1975 ok(hr == hrexp, "got 0x%08x\n", hr);
1976
1977 hr = ITextFont_GetUnderline(font, NULL);
1978 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1979
1980 hr = ITextFont_GetUnderline(font, &value);
1981 ok(hr == hrexp, "got 0x%08x\n", hr);
1982 }
1983
1984 static void test_textfont_global_defaults(ITextFont *font)
1985 {
1986 float valuef;
1987 LONG value;
1988 HRESULT hr;
1989 BSTR str;
1990
1991 value = tomUndefined;
1992 hr = ITextFont_GetAllCaps(font, &value);
1993 ok(hr == S_OK, "got 0x%08x\n", hr);
1994 ok(value == tomFalse, "got %d\n", value);
1995
1996 value = tomUndefined;
1997 hr = ITextFont_GetAnimation(font, &value);
1998 ok(hr == S_OK, "got 0x%08x\n", hr);
1999 ok(value == tomFalse, "got %d\n", value);
2000
2001 value = tomUndefined;
2002 hr = ITextFont_GetBackColor(font, &value);
2003 ok(hr == S_OK, "got 0x%08x\n", hr);
2004 ok(value == tomAutoColor, "got %d\n", value);
2005
2006 value = tomUndefined;
2007 hr = ITextFont_GetBold(font, &value);
2008 ok(hr == S_OK, "got 0x%08x\n", hr);
2009 ok(value == tomFalse || value == tomTrue, "got %d\n", value);
2010
2011 value = tomUndefined;
2012 hr = ITextFont_GetEmboss(font, &value);
2013 ok(hr == S_OK, "got 0x%08x\n", hr);
2014 ok(value == tomFalse, "got %d\n", value);
2015
2016 value = tomUndefined;
2017 hr = ITextFont_GetForeColor(font, &value);
2018 ok(hr == S_OK, "got 0x%08x\n", hr);
2019 ok(value == tomAutoColor, "got %d\n", value);
2020
2021 value = tomUndefined;
2022 hr = ITextFont_GetHidden(font, &value);
2023 ok(hr == S_OK, "got 0x%08x\n", hr);
2024 ok(value == tomFalse, "got %d\n", value);
2025
2026 value = tomUndefined;
2027 hr = ITextFont_GetEngrave(font, &value);
2028 ok(hr == S_OK, "got 0x%08x\n", hr);
2029 ok(value == tomFalse, "got %d\n", value);
2030
2031 value = tomUndefined;
2032 hr = ITextFont_GetItalic(font, &value);
2033 ok(hr == S_OK, "got 0x%08x\n", hr);
2034 ok(value == tomFalse, "got %d\n", value);
2035
2036 valuef = 1.0;
2037 hr = ITextFont_GetKerning(font, &valuef);
2038 ok(hr == S_OK, "got 0x%08x\n", hr);
2039 ok(valuef == 0.0, "got %.2f\n", valuef);
2040
2041 value = tomUndefined;
2042 hr = ITextFont_GetLanguageID(font, &value);
2043 ok(hr == S_OK, "got 0x%08x\n", hr);
2044 ok(value == GetSystemDefaultLCID(), "got %d\n", value);
2045
2046 str = NULL;
2047 hr = ITextFont_GetName(font, &str);
2048 ok(hr == S_OK, "got 0x%08x\n", hr);
2049 ok(!lstrcmpW(sysW, str), "%s\n", wine_dbgstr_w(str));
2050 SysFreeString(str);
2051
2052 value = tomUndefined;
2053 hr = ITextFont_GetOutline(font, &value);
2054 ok(hr == S_OK, "got 0x%08x\n", hr);
2055 ok(value == tomFalse, "got %d\n", value);
2056
2057 valuef = 1.0;
2058 hr = ITextFont_GetPosition(font, &valuef);
2059 ok(hr == S_OK, "got 0x%08x\n", hr);
2060 ok(valuef == 0.0, "got %.2f\n", valuef);
2061
2062 value = tomUndefined;
2063 hr = ITextFont_GetProtected(font, &value);
2064 ok(hr == S_OK, "got 0x%08x\n", hr);
2065 ok(value == tomFalse, "got %d\n", value);
2066
2067 value = tomUndefined;
2068 hr = ITextFont_GetShadow(font, &value);
2069 ok(hr == S_OK, "got 0x%08x\n", hr);
2070 ok(value == tomFalse, "got %d\n", value);
2071
2072 valuef = 0.0;
2073 hr = ITextFont_GetSize(font, &valuef);
2074 ok(hr == S_OK, "got 0x%08x\n", hr);
2075 ok(valuef >= 0.0, "got %.2f\n", valuef);
2076
2077 value = tomUndefined;
2078 hr = ITextFont_GetSmallCaps(font, &value);
2079 ok(hr == S_OK, "got 0x%08x\n", hr);
2080 ok(value == tomFalse, "got %d\n", value);
2081
2082 valuef = 1.0;
2083 hr = ITextFont_GetSpacing(font, &valuef);
2084 ok(hr == S_OK, "got 0x%08x\n", hr);
2085 ok(valuef == 0.0, "got %.2f\n", valuef);
2086
2087 value = tomUndefined;
2088 hr = ITextFont_GetStrikeThrough(font, &value);
2089 ok(hr == S_OK, "got 0x%08x\n", hr);
2090 ok(value == tomFalse, "got %d\n", value);
2091
2092 value = tomUndefined;
2093 hr = ITextFont_GetSubscript(font, &value);
2094 ok(hr == S_OK, "got 0x%08x\n", hr);
2095 ok(value == tomFalse, "got %d\n", value);
2096
2097 value = tomUndefined;
2098 hr = ITextFont_GetSuperscript(font, &value);
2099 ok(hr == S_OK, "got 0x%08x\n", hr);
2100 ok(value == tomFalse, "got %d\n", value);
2101
2102 value = tomUndefined;
2103 hr = ITextFont_GetUnderline(font, &value);
2104 ok(hr == S_OK, "got 0x%08x\n", hr);
2105 ok(value == tomFalse, "got %d\n", value);
2106
2107 value = tomUndefined;
2108 hr = ITextFont_GetWeight(font, &value);
2109 ok(hr == S_OK, "got 0x%08x\n", hr);
2110 ok(value == FW_NORMAL || value == FW_BOLD, "got %d\n", value);
2111 }
2112
2113 static void test_textfont_undefined(ITextFont *font)
2114 {
2115 float valuef;
2116 LONG value;
2117 HRESULT hr;
2118
2119 value = tomFalse;
2120 hr = ITextFont_GetAllCaps(font, &value);
2121 ok(hr == S_OK, "got 0x%08x\n", hr);
2122 ok(value == tomUndefined, "got %d\n", value);
2123
2124 value = tomFalse;
2125 hr = ITextFont_GetAnimation(font, &value);
2126 ok(hr == S_OK, "got 0x%08x\n", hr);
2127 ok(value == tomUndefined, "got %d\n", value);
2128
2129 value = tomFalse;
2130 hr = ITextFont_GetBackColor(font, &value);
2131 ok(hr == S_OK, "got 0x%08x\n", hr);
2132 ok(value == tomUndefined, "got %d\n", value);
2133
2134 value = tomFalse;
2135 hr = ITextFont_GetBold(font, &value);
2136 ok(hr == S_OK, "got 0x%08x\n", hr);
2137 ok(value == tomUndefined, "got %d\n", value);
2138
2139 value = tomFalse;
2140 hr = ITextFont_GetEmboss(font, &value);
2141 ok(hr == S_OK, "got 0x%08x\n", hr);
2142 ok(value == tomUndefined, "got %d\n", value);
2143
2144 value = tomFalse;
2145 hr = ITextFont_GetForeColor(font, &value);
2146 ok(hr == S_OK, "got 0x%08x\n", hr);
2147 ok(value == tomUndefined, "got %d\n", value);
2148
2149 value = tomFalse;
2150 hr = ITextFont_GetHidden(font, &value);
2151 ok(hr == S_OK, "got 0x%08x\n", hr);
2152 ok(value == tomUndefined, "got %d\n", value);
2153
2154 value = tomFalse;
2155 hr = ITextFont_GetEngrave(font, &value);
2156 ok(hr == S_OK, "got 0x%08x\n", hr);
2157 ok(value == tomUndefined, "got %d\n", value);
2158
2159 value = tomFalse;
2160 hr = ITextFont_GetItalic(font, &value);
2161 ok(hr == S_OK, "got 0x%08x\n", hr);
2162 ok(value == tomUndefined, "got %d\n", value);
2163
2164 valuef = 0.0;
2165 hr = ITextFont_GetKerning(font, &valuef);
2166 ok(hr == S_OK, "got 0x%08x\n", hr);
2167 ok(valuef == tomUndefined, "got %.2f\n", valuef);
2168
2169 value = tomFalse;
2170 hr = ITextFont_GetLanguageID(font, &value);
2171 ok(hr == S_OK, "got 0x%08x\n", hr);
2172 ok(value == tomUndefined, "got %d\n", value);
2173
2174 value = tomFalse;
2175 hr = ITextFont_GetOutline(font, &value);
2176 ok(hr == S_OK, "got 0x%08x\n", hr);
2177 ok(value == tomUndefined, "got %d\n", value);
2178
2179 valuef = 0.0;
2180 hr = ITextFont_GetPosition(font, &valuef);
2181 ok(hr == S_OK, "got 0x%08x\n", hr);
2182 ok(valuef == tomUndefined, "got %.2f\n", valuef);
2183
2184 value = tomFalse;
2185 hr = ITextFont_GetProtected(font, &value);
2186 ok(hr == S_OK, "got 0x%08x\n", hr);
2187 ok(value == tomUndefined, "got %d\n", value);
2188
2189 value = tomFalse;
2190 hr = ITextFont_GetShadow(font, &value);
2191 ok(hr == S_OK, "got 0x%08x\n", hr);
2192 ok(value == tomUndefined, "got %d\n", value);
2193
2194 valuef = 0.0;
2195 hr = ITextFont_GetSize(font, &valuef);
2196 ok(hr == S_OK, "got 0x%08x\n", hr);
2197 ok(valuef == tomUndefined, "got %.2f\n", valuef);
2198
2199 value = tomFalse;
2200 hr = ITextFont_GetSmallCaps(font, &value);
2201 ok(hr == S_OK, "got 0x%08x\n", hr);
2202 ok(value == tomUndefined, "got %d\n", value);
2203
2204 valuef = 0.0;
2205 hr = ITextFont_GetSpacing(font, &valuef);
2206 ok(hr == S_OK, "got 0x%08x\n", hr);
2207 ok(valuef == tomUndefined, "got %.2f\n", valuef);
2208
2209 value = tomFalse;
2210 hr = ITextFont_GetStrikeThrough(font, &value);
2211 ok(hr == S_OK, "got 0x%08x\n", hr);
2212 ok(value == tomUndefined, "got %d\n", value);
2213
2214 value = tomFalse;
2215 hr = ITextFont_GetSubscript(font, &value);
2216 ok(hr == S_OK, "got 0x%08x\n", hr);
2217 ok(value == tomUndefined, "got %d\n", value);
2218
2219 value = tomFalse;
2220 hr = ITextFont_GetSuperscript(font, &value);
2221 ok(hr == S_OK, "got 0x%08x\n", hr);
2222 ok(value == tomUndefined, "got %d\n", value);
2223
2224 value = tomFalse;
2225 hr = ITextFont_GetUnderline(font, &value);
2226 ok(hr == S_OK, "got 0x%08x\n", hr);
2227 ok(value == tomUndefined, "got %d\n", value);
2228
2229 value = tomFalse;
2230 hr = ITextFont_GetWeight(font, &value);
2231 ok(hr == S_OK, "got 0x%08x\n", hr);
2232 ok(value == tomUndefined, "got %d\n", value);
2233 }
2234
2235 static inline FLOAT twips_to_points(LONG value)
2236 {
2237 return value * 72.0 / 1440;
2238 }
2239
2240 static void test_ITextFont(void)
2241 {
2242 static const WCHAR arialW[] = {'A','r','i','a','l',0};
2243 static const CHAR test_text1[] = "TestSomeText";
2244 ITextFont *font, *font2, *font3;
2245 FLOAT size, position, kerning;
2246 IRichEditOle *reOle = NULL;
2247 ITextDocument *doc = NULL;
2248 ITextRange *range = NULL;
2249 CHARFORMAT2A cf;
2250 LONG value;
2251 HRESULT hr;
2252 HWND hwnd;
2253 BOOL ret;
2254 BSTR str;
2255
2256 create_interfaces(&hwnd, &reOle, &doc, NULL);
2257 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2258
2259 hr = ITextDocument_Range(doc, 0, 10, &range);
2260 ok(hr == S_OK, "got 0x%08x\n", hr);
2261
2262 hr = ITextRange_GetFont(range, &font);
2263 ok(hr == S_OK, "got 0x%08x\n", hr);
2264
2265 hr = ITextFont_Reset(font, tomUseTwips);
2266 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2267
2268 hr = ITextFont_Reset(font, tomUsePoints);
2269 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2270
2271 hr = ITextFont_GetName(font, NULL);
2272 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2273
2274 /* default font size unit is point */
2275 size = 0.0;
2276 hr = ITextFont_GetSize(font, &size);
2277 ok(hr == S_OK, "got 0x%08x\n", hr);
2278
2279 /* set to some non-zero values */
2280 hr = ITextFont_SetPosition(font, 20.0);
2281 ok(hr == S_OK, "got 0x%08x\n", hr);
2282
2283 hr = ITextFont_SetKerning(font, 10.0);
2284 ok(hr == S_OK, "got 0x%08x\n", hr);
2285
2286 position = 0.0;
2287 hr = ITextFont_GetPosition(font, &position);
2288 ok(hr == S_OK, "got 0x%08x\n", hr);
2289
2290 kerning = 0.0;
2291 hr = ITextFont_GetKerning(font, &kerning);
2292 ok(hr == S_OK, "got 0x%08x\n", hr);
2293
2294 memset(&cf, 0, sizeof(cf));
2295 cf.cbSize = sizeof(cf);
2296 cf.dwMask = CFM_SIZE|CFM_OFFSET|CFM_KERNING;
2297
2298 /* CHARFORMAT members are in twips */
2299 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2300 ret = SendMessageA(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2301 ok(ret, "got %d\n", ret);
2302 ok(size == twips_to_points(cf.yHeight), "got yHeight %d, size %.2f\n", cf.yHeight, size);
2303 ok(position == twips_to_points(cf.yOffset), "got yOffset %d, position %.2f\n", cf.yOffset, position);
2304 ok(kerning == twips_to_points(cf.wKerning), "got wKerning %d, kerning %.2f\n", cf.wKerning, kerning);
2305
2306 hr = ITextFont_Reset(font, tomUseTwips);
2307 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2308
2309 hr = ITextFont_Reset(font, tomUsePoints);
2310 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2311
2312 hr = ITextFont_GetDuplicate(font, &font2);
2313 ok(hr == S_OK, "got 0x%08x\n", hr);
2314
2315 hr = ITextFont_Reset(font2, tomUseTwips);
2316 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2317
2318 hr = ITextFont_Reset(font2, tomUsePoints);
2319 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2320
2321 ITextFont_Release(font2);
2322
2323 /* default font name */
2324 str = NULL;
2325 hr = ITextFont_GetName(font, &str);
2326 ok(hr == S_OK, "got 0x%08x\n", hr);
2327 ok(!lstrcmpW(str, sysW), "got %s\n", wine_dbgstr_w(str));
2328 SysFreeString(str);
2329
2330 /* change font name for an inner subrange */
2331 memset(&cf, 0, sizeof(cf));
2332 cf.cbSize = sizeof(cf);
2333 cf.dwMask = CFM_FACE;
2334 strcpy(cf.szFaceName, "Arial");
2335
2336 SendMessageA(hwnd, EM_SETSEL, 3, 4);
2337 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2338 ok(ret, "got %d\n", ret);
2339
2340 /* still original name */
2341 str = NULL;
2342 hr = ITextFont_GetName(font, &str);
2343 ok(hr == S_OK, "got 0x%08x\n", hr);
2344 ok(!lstrcmpW(str, sysW), "got %s\n", wine_dbgstr_w(str));
2345 SysFreeString(str);
2346
2347 SendMessageA(hwnd, EM_SETSEL, 1, 2);
2348 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2349 ok(ret, "got %d\n", ret);
2350
2351 str = NULL;
2352 hr = ITextFont_GetName(font, &str);
2353 ok(hr == S_OK, "got 0x%08x\n", hr);
2354 ok(!lstrcmpW(str, sysW), "got %s\n", wine_dbgstr_w(str));
2355 SysFreeString(str);
2356
2357 /* name is returned for first position within a range */
2358 SendMessageA(hwnd, EM_SETSEL, 0, 1);
2359 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2360 ok(ret, "got %d\n", ret);
2361
2362 str = NULL;
2363 hr = ITextFont_GetName(font, &str);
2364 ok(hr == S_OK, "got 0x%08x\n", hr);
2365 ok(!lstrcmpW(str, arialW), "got %s\n", wine_dbgstr_w(str));
2366 SysFreeString(str);
2367
2368 /* GetDuplicate() */
2369 hr = ITextFont_GetDuplicate(font, NULL);
2370 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2371
2372 EXPECT_REF(range, 2);
2373 font2 = NULL;
2374 hr = ITextFont_GetDuplicate(font, &font2);
2375 ok(hr == S_OK, "got 0x%08x\n", hr);
2376 EXPECT_REF(range, 2);
2377
2378 /* set whole range to italic */
2379 cf.cbSize = sizeof(CHARFORMAT2A);
2380 cf.dwMask = CFM_ITALIC;
2381 cf.dwEffects = CFE_ITALIC;
2382
2383 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2384 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2385 ok(ret, "got %d\n", ret);
2386
2387 value = tomFalse;
2388 hr = ITextFont_GetItalic(font, &value);
2389 ok(hr == S_OK, "got 0x%08x\n", hr);
2390 ok(value == tomTrue, "got %d\n", value);
2391
2392 /* duplicate retains original value */
2393 value = tomTrue;
2394 hr = ITextFont_GetItalic(font2, &value);
2395 ok(hr == S_OK, "got 0x%08x\n", hr);
2396 ok(value == tomFalse, "got %d\n", value);
2397
2398 /* get a duplicate from a cloned font */
2399 hr = ITextFont_GetDuplicate(font2, &font3);
2400 ok(hr == S_OK, "got 0x%08x\n", hr);
2401 ITextFont_Release(font3);
2402
2403 ITextRange_Release(range);
2404 release_interfaces(&hwnd, &reOle, &doc, NULL);
2405
2406 hr = ITextFont_GetDuplicate(font, NULL);
2407 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2408
2409 test_detached_font_getters(font, FALSE);
2410 test_detached_font_getters(font2, TRUE);
2411
2412 /* get a duplicate of detached font */
2413 hr = ITextFont_GetDuplicate(font2, &font3);
2414 ok(hr == S_OK, "got 0x%08x\n", hr);
2415 ITextFont_Release(font3);
2416
2417 /* reset detached font to undefined */
2418 value = tomUndefined;
2419 hr = ITextFont_GetBold(font2, &value);
2420 ok(hr == S_OK, "got 0x%08x\n", hr);
2421 ok(value != tomUndefined, "got %d\n", value);
2422
2423 /* reset to undefined for detached font */
2424 hr = ITextFont_Reset(font2, tomUndefined);
2425 ok(hr == S_OK, "got 0x%08x\n", hr);
2426 test_textfont_undefined(font2);
2427
2428 /* font is detached, default means global TOM defaults */
2429 hr = ITextFont_Reset(font2, tomDefault);
2430 ok(hr == S_OK, "got 0x%08x\n", hr);
2431 test_textfont_global_defaults(font2);
2432
2433 hr = ITextFont_GetDuplicate(font2, &font3);
2434 ok(hr == S_OK, "got 0x%08x\n", hr);
2435 test_textfont_global_defaults(font2);
2436
2437 hr = ITextFont_Reset(font2, tomApplyNow);
2438 ok(hr == S_OK, "got 0x%08x\n", hr);
2439 test_textfont_global_defaults(font2);
2440
2441 hr = ITextFont_Reset(font2, tomApplyLater);
2442 ok(hr == S_OK, "got 0x%08x\n", hr);
2443 test_textfont_global_defaults(font2);
2444
2445 hr = ITextFont_Reset(font2, tomTrackParms);
2446 ok(hr == S_OK, "got 0x%08x\n", hr);
2447 test_textfont_global_defaults(font2);
2448
2449 hr = ITextFont_SetItalic(font2, tomUndefined);
2450 ok(hr == S_OK, "got 0x%08x\n", hr);
2451
2452 hr = ITextFont_GetItalic(font2, &value);
2453 ok(hr == S_OK, "got 0x%08x\n", hr);
2454 ok(value == tomFalse, "got %d\n", value);
2455
2456 hr = ITextFont_Reset(font2, tomCacheParms);
2457 ok(hr == S_OK, "got 0x%08x\n", hr);
2458 test_textfont_global_defaults(font2);
2459
2460 ITextFont_Release(font3);
2461 ITextFont_Release(font2);
2462
2463 font2 = (void*)0xdeadbeef;
2464 hr = ITextFont_GetDuplicate(font, &font2);
2465 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2466 ok(font2 == NULL, "got %p\n", font2);
2467
2468 hr = ITextFont_Reset(font, tomDefault);
2469 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2470
2471 ITextFont_Release(font);
2472
2473 /* Reset() */
2474 create_interfaces(&hwnd, &reOle, &doc, NULL);
2475 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2476
2477 hr = ITextDocument_Range(doc, 0, 10, &range);
2478 ok(hr == S_OK, "got 0x%08x\n", hr);
2479
2480 hr = ITextRange_GetFont(range, &font);
2481 ok(hr == S_OK, "got 0x%08x\n", hr);
2482
2483 value = tomUndefined;
2484 hr = ITextFont_GetBold(font, &value);
2485 ok(hr == S_OK, "got 0x%08x\n", hr);
2486 ok(value != tomUndefined, "got %d\n", value);
2487
2488 /* reset to undefined for attached font */
2489 hr = ITextFont_Reset(font, tomUndefined);
2490 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2491
2492 value = tomUndefined;
2493 hr = ITextFont_GetBold(font, &value);
2494 ok(hr == S_OK, "got 0x%08x\n", hr);
2495 ok(value != tomUndefined, "got %d\n", value);
2496
2497 /* tomCacheParms/tomTrackParms */
2498 hr = ITextFont_Reset(font, tomCacheParms);
2499 ok(hr == S_OK, "got 0x%08x\n", hr);
2500
2501 hr = ITextFont_GetItalic(font, &value);
2502 ok(hr == S_OK, "got 0x%08x\n", hr);
2503 ok(value == tomFalse, "got %d\n", value);
2504
2505 memset(&cf, 0, sizeof(cf));
2506 cf.cbSize = sizeof(CHARFORMAT2A);
2507 cf.dwMask = CFM_ITALIC;
2508
2509 cf.dwEffects = CFE_ITALIC;
2510 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2511 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2512 ok(ret, "got %d\n", ret);
2513
2514 /* still cached value */
2515 hr = ITextFont_GetItalic(font, &value);
2516 ok(hr == S_OK, "got 0x%08x\n", hr);
2517 ok(value == tomFalse, "got %d\n", value);
2518
2519 hr = ITextFont_Reset(font, tomTrackParms);
2520 ok(hr == S_OK, "got 0x%08x\n", hr);
2521
2522 hr = ITextFont_GetItalic(font, &value);
2523 ok(hr == S_OK, "got 0x%08x\n", hr);
2524 ok(value == tomTrue, "got %d\n", value);
2525
2526 /* switch back to cache - value retained */
2527 hr = ITextFont_Reset(font, tomCacheParms);
2528 ok(hr == S_OK, "got 0x%08x\n", hr);
2529
2530 hr = ITextFont_GetItalic(font, &value);
2531 ok(hr == S_OK, "got 0x%08x\n", hr);
2532 ok(value == tomTrue, "got %d\n", value);
2533
2534 /* tomApplyLater */
2535 hr = ITextFont_Reset(font, tomApplyLater);
2536 ok(hr == S_OK, "got 0x%08x\n", hr);
2537
2538 hr = ITextFont_SetItalic(font, tomFalse);
2539 ok(hr == S_OK, "got 0x%08x\n", hr);
2540
2541 hr = ITextFont_GetItalic(font, &value);
2542 ok(hr == S_OK, "got 0x%08x\n", hr);
2543 ok(value == tomFalse, "got %d\n", value);
2544
2545 cf.dwEffects = 0;
2546 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2547 ret = SendMessageA(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2548 ok(ret, "got %d\n", ret);
2549 ok((cf.dwEffects & CFE_ITALIC) == CFE_ITALIC, "got 0x%08x\n", cf.dwEffects);
2550
2551 hr = ITextFont_Reset(font, tomApplyNow);
2552 ok(hr == S_OK, "got 0x%08x\n", hr);
2553
2554 cf.dwEffects = 0;
2555 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2556 ret = SendMessageA(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2557 ok(ret, "got %d\n", ret);
2558 ok((cf.dwEffects & CFE_ITALIC) == 0, "got 0x%08x\n", cf.dwEffects);
2559
2560 hr = ITextFont_SetItalic(font, tomUndefined);
2561 ok(hr == S_OK, "got 0x%08x\n", hr);
2562
2563 hr = ITextFont_GetItalic(font, &value);
2564 ok(hr == S_OK, "got 0x%08x\n", hr);
2565 ok(value == tomFalse, "got %d\n", value);
2566
2567 hr = ITextFont_SetItalic(font, tomAutoColor);
2568 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2569
2570 cf.dwEffects = 0;
2571 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2572 ret = SendMessageA(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2573 ok(ret, "got %d\n", ret);
2574 ok((cf.dwEffects & CFE_ITALIC) == 0, "got 0x%08x\n", cf.dwEffects);
2575
2576 ITextRange_Release(range);
2577 ITextFont_Release(font);
2578 release_interfaces(&hwnd, &reOle, &doc, NULL);
2579 }
2580
2581 static void test_Delete(void)
2582 {
2583 static const CHAR test_text1[] = "TestSomeText";
2584 IRichEditOle *reOle = NULL;
2585 ITextDocument *doc = NULL;
2586 ITextRange *range, *range2;
2587 LONG value;
2588 HRESULT hr;
2589 HWND hwnd;
2590
2591 create_interfaces(&hwnd, &reOle, &doc, NULL);
2592 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2593
2594 hr = ITextDocument_Range(doc, 0, 4, &range);
2595 ok(hr == S_OK, "got 0x%08x\n", hr);
2596
2597 hr = ITextDocument_Range(doc, 1, 2, &range2);
2598 ok(hr == S_OK, "got 0x%08x\n", hr);
2599
2600 hr = ITextRange_GetEnd(range, &value);
2601 ok(hr == S_OK, "got 0x%08x\n", hr);
2602 ok(value == 4, "got %d\n", value);
2603
2604 /* unit type doesn't matter is count is 0 */
2605 value = 0;
2606 hr = ITextRange_Delete(range2, tomSentence, 0, &value);
2607 todo_wine {
2608 ok(hr == S_OK, "got 0x%08x\n", hr);
2609 ok(value == 1, "got %d\n", value);
2610 }
2611 value = 1;
2612 hr = ITextRange_Delete(range2, tomCharacter, 0, &value);
2613 todo_wine {
2614 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2615 ok(value == 0, "got %d\n", value);
2616 }
2617 hr = ITextRange_GetEnd(range, &value);
2618 ok(hr == S_OK, "got 0x%08x\n", hr);
2619 todo_wine
2620 ok(value == 3, "got %d\n", value);
2621
2622 hr = ITextRange_GetStart(range2, &value);
2623 ok(hr == S_OK, "got 0x%08x\n", hr);
2624 ok(value == 1, "got %d\n", value);
2625
2626 hr = ITextRange_GetEnd(range2, &value);
2627 ok(hr == S_OK, "got 0x%08x\n", hr);
2628 todo_wine
2629 ok(value == 1, "got %d\n", value);
2630
2631 ITextRange_Release(range);
2632 ITextRange_Release(range2);
2633 release_interfaces(&hwnd, &reOle, &doc, NULL);
2634 }
2635
2636 static void test_SetText(void)
2637 {
2638 static const CHAR test_text1[] = "TestSomeText";
2639 static const WCHAR textW[] = {'a','b','c','d','e','f','g','h','i',0};
2640 IRichEditOle *reOle = NULL;
2641 ITextDocument *doc = NULL;
2642 ITextRange *range, *range2;
2643 LONG value;
2644 HRESULT hr;
2645 HWND hwnd;
2646 BSTR str;
2647
2648 create_interfaces(&hwnd, &reOle, &doc, NULL);
2649 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2650
2651 hr = ITextDocument_Range(doc, 0, 4, &range);
2652 ok(hr == S_OK, "got 0x%08x\n", hr);
2653
2654 hr = ITextDocument_Range(doc, 0, 4, &range2);
2655 ok(hr == S_OK, "got 0x%08x\n", hr);
2656
2657 value = 1;
2658 hr = ITextRange_GetStart(range2, &value);
2659 ok(hr == S_OK, "got 0x%08x\n", hr);
2660 ok(value == 0, "got %d\n", value);
2661
2662 value = 0;
2663 hr = ITextRange_GetEnd(range2, &value);
2664 ok(hr == S_OK, "got 0x%08x\n", hr);
2665 ok(value == 4, "got %d\n", value);
2666
2667 hr = ITextRange_SetText(range, NULL);
2668 ok(hr == S_OK, "got 0x%08x\n", hr);
2669
2670 value = 1;
2671 hr = ITextRange_GetEnd(range2, &value);
2672 ok(hr == S_OK, "got 0x%08x\n", hr);
2673 ok(value == 0, "got %d\n", value