38a8f8039e9aa33604fd59cd277188a461413e33
[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 todo_wine
1745 ok(value == GetSystemDefaultLCID(), "got lcid %x, user lcid %x\n", value,
1746 GetSystemDefaultLCID());
1747
1748 /* range is non-italic */
1749 value = tomTrue;
1750 hr = ITextFont_GetItalic(font, &value);
1751 ok(hr == S_OK, "got 0x%08x\n", hr);
1752 ok(value == tomFalse, "got %d\n", value);
1753
1754 cf.cbSize = sizeof(CHARFORMAT2A);
1755 cf.dwMask = CFM_ITALIC|CFM_SIZE;
1756 cf.dwEffects = CFE_ITALIC;
1757 cf.yHeight = 24.0;
1758
1759 SendMessageA(hwnd, EM_SETSEL, 2, 3);
1760 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
1761 ok(ret, "got %d\n", ret);
1762
1763 /* now range is partially italicized */
1764 value = tomFalse;
1765 hr = ITextFont_GetItalic(font, &value);
1766 ok(hr == S_OK, "got 0x%08x\n", hr);
1767 ok(value == tomUndefined, "got %d\n", value);
1768
1769 size = 0.0;
1770 hr = ITextFont_GetSize(font, &size);
1771 ok(hr == S_OK, "got 0x%08x\n", hr);
1772 ok(size == tomUndefined, "size %.2f\n", size);
1773
1774 ITextFont_Release(font);
1775 release_interfaces(&hwnd, &reOle, &doc, NULL);
1776
1777 hr = ITextRange_GetFont(range, NULL);
1778 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
1779
1780 hr = ITextRange_GetFont(range, &font2);
1781 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
1782
1783 ITextRange_Release(range);
1784 }
1785
1786 static void test_GetPara(void)
1787 {
1788 static const CHAR test_text1[] = "TestSomeText";
1789 IRichEditOle *reOle = NULL;
1790 ITextDocument *doc = NULL;
1791 ITextSelection *selection;
1792 ITextRange *range = NULL;
1793 ITextPara *para, *para2;
1794 HRESULT hr;
1795 HWND hwnd;
1796
1797 create_interfaces(&hwnd, &reOle, &doc, &selection);
1798 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
1799
1800 EXPECT_REF(reOle, 3);
1801 EXPECT_REF(doc, 3);
1802
1803 hr = ITextDocument_Range(doc, 0, 4, &range);
1804 ok(hr == S_OK, "got 0x%08x\n", hr);
1805
1806 EXPECT_REF(reOle, 3);
1807 EXPECT_REF(doc, 3);
1808 EXPECT_REF(range, 1);
1809
1810 hr = ITextRange_GetPara(range, NULL);
1811 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1812
1813 hr = ITextRange_GetPara(range, &para);
1814 ok(hr == S_OK, "got 0x%08x\n", hr);
1815
1816 EXPECT_REF(reOle, 3);
1817 EXPECT_REF(doc, 3);
1818 EXPECT_REF(range, 2);
1819 EXPECT_REF(para, 1);
1820
1821 hr = ITextRange_GetPara(range, &para2);
1822 ok(hr == S_OK, "got 0x%08x\n", hr);
1823 ok(para != para2, "got %p, %p\n", para, para2);
1824
1825 EXPECT_REF(reOle, 3);
1826 EXPECT_REF(doc, 3);
1827 EXPECT_REF(range, 3);
1828 EXPECT_REF(para, 1);
1829 EXPECT_REF(para2, 1);
1830
1831 ITextPara_Release(para);
1832 ITextPara_Release(para2);
1833
1834 EXPECT_REF(reOle, 3);
1835 EXPECT_REF(doc, 3);
1836 EXPECT_REF(selection, 2);
1837
1838 hr = ITextSelection_GetPara(selection, &para);
1839 ok(hr == S_OK, "got 0x%08x\n", hr);
1840
1841 EXPECT_REF(reOle, 3);
1842 EXPECT_REF(doc, 3);
1843 EXPECT_REF(selection, 3);
1844 EXPECT_REF(para, 1);
1845
1846 hr = ITextSelection_GetPara(selection, &para2);
1847 ok(hr == S_OK, "got 0x%08x\n", hr);
1848 ok(para != para2, "got %p, %p\n", para, para2);
1849
1850 ITextPara_Release(para);
1851 ITextPara_Release(para2);
1852 release_interfaces(&hwnd, &reOle, &doc, NULL);
1853
1854 hr = ITextRange_GetPara(range, NULL);
1855 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
1856
1857 hr = ITextRange_GetPara(range, &para);
1858 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
1859
1860 hr = ITextSelection_GetPara(selection, NULL);
1861 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
1862
1863 hr = ITextSelection_GetPara(selection, &para);
1864 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
1865
1866 ITextSelection_Release(selection);
1867 ITextRange_Release(range);
1868 }
1869
1870 static void test_dispatch(void)
1871 {
1872 static const WCHAR testnameW[] = {'G','e','t','T','e','x','t',0};
1873 static const WCHAR testname2W[] = {'T','e','x','t',0};
1874 IRichEditOle *reOle = NULL;
1875 ITextDocument *doc = NULL;
1876 ITextRange *range = NULL;
1877 WCHAR *nameW;
1878 DISPID dispid;
1879 HRESULT hr;
1880 UINT count;
1881 HWND hwnd;
1882
1883 create_interfaces(&hwnd, &reOle, &doc, NULL);
1884
1885 range = NULL;
1886 hr = ITextDocument_Range(doc, 0, 0, &range);
1887 ok(hr == S_OK, "got 0x%08x\n", hr);
1888 ok(range != NULL, "got %p\n", range);
1889
1890 dispid = 123;
1891 nameW = (WCHAR*)testnameW;
1892 hr = ITextRange_GetIDsOfNames(range, &IID_NULL, &nameW, 1, LOCALE_USER_DEFAULT, &dispid);
1893 ok(hr == DISP_E_UNKNOWNNAME, "got 0x%08x\n", hr);
1894 ok(dispid == DISPID_UNKNOWN, "got %d\n", dispid);
1895
1896 dispid = 123;
1897 nameW = (WCHAR*)testname2W;
1898 hr = ITextRange_GetIDsOfNames(range, &IID_NULL, &nameW, 1, LOCALE_USER_DEFAULT, &dispid);
1899 ok(hr == S_OK, "got 0x%08x\n", hr);
1900 ok(dispid == DISPID_VALUE, "got %d\n", dispid);
1901
1902 release_interfaces(&hwnd, &reOle, &doc, NULL);
1903
1904 /* try dispatch methods on detached range */
1905 hr = ITextRange_GetTypeInfoCount(range, &count);
1906 ok(hr == S_OK, "got 0x%08x\n", hr);
1907
1908 dispid = 123;
1909 nameW = (WCHAR*)testname2W;
1910 hr = ITextRange_GetIDsOfNames(range, &IID_NULL, &nameW, 1, LOCALE_USER_DEFAULT, &dispid);
1911 ok(hr == S_OK, "got 0x%08x\n", hr);
1912 ok(dispid == DISPID_VALUE, "got %d\n", dispid);
1913
1914 ITextRange_Release(range);
1915 }
1916
1917 static void test_detached_font_getters(ITextFont *font, BOOL duplicate)
1918 {
1919 HRESULT hr, hrexp = duplicate ? S_OK : CO_E_RELEASED;
1920 LONG value;
1921 float size;
1922 BSTR str;
1923
1924 hr = ITextFont_GetBold(font, NULL);
1925 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1926
1927 hr = ITextFont_GetBold(font, &value);
1928 ok(hr == hrexp, "got 0x%08x\n", hr);
1929
1930 hr = ITextFont_GetForeColor(font, NULL);
1931 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1932
1933 hr = ITextFont_GetForeColor(font, &value);
1934 ok(hr == hrexp, "got 0x%08x\n", hr);
1935
1936 hr = ITextFont_GetItalic(font, NULL);
1937 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1938
1939 hr = ITextFont_GetItalic(font, &value);
1940 ok(hr == hrexp, "got 0x%08x\n", hr);
1941
1942 hr = ITextFont_GetLanguageID(font, NULL);
1943 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1944
1945 hr = ITextFont_GetLanguageID(font, &value);
1946 ok(hr == hrexp, "got 0x%08x\n", hr);
1947
1948 hr = ITextFont_GetName(font, NULL);
1949 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1950
1951 hr = ITextFont_GetName(font, &str);
1952 ok(hr == hrexp, "got 0x%08x\n", hr);
1953
1954 hr = ITextFont_GetSize(font, NULL);
1955 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1956
1957 hr = ITextFont_GetSize(font, &size);
1958 ok(hr == hrexp, "got 0x%08x\n", hr);
1959
1960 hr = ITextFont_GetStrikeThrough(font, NULL);
1961 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1962
1963 hr = ITextFont_GetStrikeThrough(font, &value);
1964 ok(hr == hrexp, "got 0x%08x\n", hr);
1965
1966 hr = ITextFont_GetSubscript(font, NULL);
1967 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1968
1969 hr = ITextFont_GetSubscript(font, &value);
1970 ok(hr == hrexp, "got 0x%08x\n", hr);
1971
1972 hr = ITextFont_GetSuperscript(font, NULL);
1973 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1974
1975 hr = ITextFont_GetSuperscript(font, &value);
1976 ok(hr == hrexp, "got 0x%08x\n", hr);
1977
1978 hr = ITextFont_GetUnderline(font, NULL);
1979 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1980
1981 hr = ITextFont_GetUnderline(font, &value);
1982 ok(hr == hrexp, "got 0x%08x\n", hr);
1983 }
1984
1985 static void test_textfont_global_defaults(ITextFont *font)
1986 {
1987 float valuef;
1988 LONG value;
1989 HRESULT hr;
1990 BSTR str;
1991
1992 value = tomUndefined;
1993 hr = ITextFont_GetAllCaps(font, &value);
1994 ok(hr == S_OK, "got 0x%08x\n", hr);
1995 ok(value == tomFalse, "got %d\n", value);
1996
1997 value = tomUndefined;
1998 hr = ITextFont_GetAnimation(font, &value);
1999 ok(hr == S_OK, "got 0x%08x\n", hr);
2000 ok(value == tomFalse, "got %d\n", value);
2001
2002 value = tomUndefined;
2003 hr = ITextFont_GetBackColor(font, &value);
2004 ok(hr == S_OK, "got 0x%08x\n", hr);
2005 ok(value == tomAutoColor, "got %d\n", value);
2006
2007 value = tomUndefined;
2008 hr = ITextFont_GetBold(font, &value);
2009 ok(hr == S_OK, "got 0x%08x\n", hr);
2010 ok(value == tomFalse || value == tomTrue, "got %d\n", value);
2011
2012 value = tomUndefined;
2013 hr = ITextFont_GetEmboss(font, &value);
2014 ok(hr == S_OK, "got 0x%08x\n", hr);
2015 ok(value == tomFalse, "got %d\n", value);
2016
2017 value = tomUndefined;
2018 hr = ITextFont_GetForeColor(font, &value);
2019 ok(hr == S_OK, "got 0x%08x\n", hr);
2020 ok(value == tomAutoColor, "got %d\n", value);
2021
2022 value = tomUndefined;
2023 hr = ITextFont_GetHidden(font, &value);
2024 ok(hr == S_OK, "got 0x%08x\n", hr);
2025 ok(value == tomFalse, "got %d\n", value);
2026
2027 value = tomUndefined;
2028 hr = ITextFont_GetEngrave(font, &value);
2029 ok(hr == S_OK, "got 0x%08x\n", hr);
2030 ok(value == tomFalse, "got %d\n", value);
2031
2032 value = tomUndefined;
2033 hr = ITextFont_GetItalic(font, &value);
2034 ok(hr == S_OK, "got 0x%08x\n", hr);
2035 ok(value == tomFalse, "got %d\n", value);
2036
2037 valuef = 1.0;
2038 hr = ITextFont_GetKerning(font, &valuef);
2039 ok(hr == S_OK, "got 0x%08x\n", hr);
2040 ok(valuef == 0.0, "got %.2f\n", valuef);
2041
2042 value = tomUndefined;
2043 hr = ITextFont_GetLanguageID(font, &value);
2044 ok(hr == S_OK, "got 0x%08x\n", hr);
2045 ok(value == GetSystemDefaultLCID(), "got %d\n", value);
2046
2047 str = NULL;
2048 hr = ITextFont_GetName(font, &str);
2049 ok(hr == S_OK, "got 0x%08x\n", hr);
2050 ok(!lstrcmpW(sysW, str), "%s\n", wine_dbgstr_w(str));
2051 SysFreeString(str);
2052
2053 value = tomUndefined;
2054 hr = ITextFont_GetOutline(font, &value);
2055 ok(hr == S_OK, "got 0x%08x\n", hr);
2056 ok(value == tomFalse, "got %d\n", value);
2057
2058 valuef = 1.0;
2059 hr = ITextFont_GetPosition(font, &valuef);
2060 ok(hr == S_OK, "got 0x%08x\n", hr);
2061 ok(valuef == 0.0, "got %.2f\n", valuef);
2062
2063 value = tomUndefined;
2064 hr = ITextFont_GetProtected(font, &value);
2065 ok(hr == S_OK, "got 0x%08x\n", hr);
2066 ok(value == tomFalse, "got %d\n", value);
2067
2068 value = tomUndefined;
2069 hr = ITextFont_GetShadow(font, &value);
2070 ok(hr == S_OK, "got 0x%08x\n", hr);
2071 ok(value == tomFalse, "got %d\n", value);
2072
2073 valuef = 0.0;
2074 hr = ITextFont_GetSize(font, &valuef);
2075 ok(hr == S_OK, "got 0x%08x\n", hr);
2076 ok(valuef >= 0.0, "got %.2f\n", valuef);
2077
2078 value = tomUndefined;
2079 hr = ITextFont_GetSmallCaps(font, &value);
2080 ok(hr == S_OK, "got 0x%08x\n", hr);
2081 ok(value == tomFalse, "got %d\n", value);
2082
2083 valuef = 1.0;
2084 hr = ITextFont_GetSpacing(font, &valuef);
2085 ok(hr == S_OK, "got 0x%08x\n", hr);
2086 ok(valuef == 0.0, "got %.2f\n", valuef);
2087
2088 value = tomUndefined;
2089 hr = ITextFont_GetStrikeThrough(font, &value);
2090 ok(hr == S_OK, "got 0x%08x\n", hr);
2091 ok(value == tomFalse, "got %d\n", value);
2092
2093 value = tomUndefined;
2094 hr = ITextFont_GetSubscript(font, &value);
2095 ok(hr == S_OK, "got 0x%08x\n", hr);
2096 ok(value == tomFalse, "got %d\n", value);
2097
2098 value = tomUndefined;
2099 hr = ITextFont_GetSuperscript(font, &value);
2100 ok(hr == S_OK, "got 0x%08x\n", hr);
2101 ok(value == tomFalse, "got %d\n", value);
2102
2103 value = tomUndefined;
2104 hr = ITextFont_GetUnderline(font, &value);
2105 ok(hr == S_OK, "got 0x%08x\n", hr);
2106 ok(value == tomFalse, "got %d\n", value);
2107
2108 value = tomUndefined;
2109 hr = ITextFont_GetWeight(font, &value);
2110 ok(hr == S_OK, "got 0x%08x\n", hr);
2111 ok(value == FW_NORMAL || value == FW_BOLD, "got %d\n", value);
2112 }
2113
2114 static void test_textfont_undefined(ITextFont *font)
2115 {
2116 float valuef;
2117 LONG value;
2118 HRESULT hr;
2119
2120 value = tomFalse;
2121 hr = ITextFont_GetAllCaps(font, &value);
2122 ok(hr == S_OK, "got 0x%08x\n", hr);
2123 ok(value == tomUndefined, "got %d\n", value);
2124
2125 value = tomFalse;
2126 hr = ITextFont_GetAnimation(font, &value);
2127 ok(hr == S_OK, "got 0x%08x\n", hr);
2128 ok(value == tomUndefined, "got %d\n", value);
2129
2130 value = tomFalse;
2131 hr = ITextFont_GetBackColor(font, &value);
2132 ok(hr == S_OK, "got 0x%08x\n", hr);
2133 ok(value == tomUndefined, "got %d\n", value);
2134
2135 value = tomFalse;
2136 hr = ITextFont_GetBold(font, &value);
2137 ok(hr == S_OK, "got 0x%08x\n", hr);
2138 ok(value == tomUndefined, "got %d\n", value);
2139
2140 value = tomFalse;
2141 hr = ITextFont_GetEmboss(font, &value);
2142 ok(hr == S_OK, "got 0x%08x\n", hr);
2143 ok(value == tomUndefined, "got %d\n", value);
2144
2145 value = tomFalse;
2146 hr = ITextFont_GetForeColor(font, &value);
2147 ok(hr == S_OK, "got 0x%08x\n", hr);
2148 ok(value == tomUndefined, "got %d\n", value);
2149
2150 value = tomFalse;
2151 hr = ITextFont_GetHidden(font, &value);
2152 ok(hr == S_OK, "got 0x%08x\n", hr);
2153 ok(value == tomUndefined, "got %d\n", value);
2154
2155 value = tomFalse;
2156 hr = ITextFont_GetEngrave(font, &value);
2157 ok(hr == S_OK, "got 0x%08x\n", hr);
2158 ok(value == tomUndefined, "got %d\n", value);
2159
2160 value = tomFalse;
2161 hr = ITextFont_GetItalic(font, &value);
2162 ok(hr == S_OK, "got 0x%08x\n", hr);
2163 ok(value == tomUndefined, "got %d\n", value);
2164
2165 valuef = 0.0;
2166 hr = ITextFont_GetKerning(font, &valuef);
2167 ok(hr == S_OK, "got 0x%08x\n", hr);
2168 ok(valuef == tomUndefined, "got %.2f\n", valuef);
2169
2170 value = tomFalse;
2171 hr = ITextFont_GetLanguageID(font, &value);
2172 ok(hr == S_OK, "got 0x%08x\n", hr);
2173 ok(value == tomUndefined, "got %d\n", value);
2174
2175 value = tomFalse;
2176 hr = ITextFont_GetOutline(font, &value);
2177 ok(hr == S_OK, "got 0x%08x\n", hr);
2178 ok(value == tomUndefined, "got %d\n", value);
2179
2180 valuef = 0.0;
2181 hr = ITextFont_GetPosition(font, &valuef);
2182 ok(hr == S_OK, "got 0x%08x\n", hr);
2183 ok(valuef == tomUndefined, "got %.2f\n", valuef);
2184
2185 value = tomFalse;
2186 hr = ITextFont_GetProtected(font, &value);
2187 ok(hr == S_OK, "got 0x%08x\n", hr);
2188 ok(value == tomUndefined, "got %d\n", value);
2189
2190 value = tomFalse;
2191 hr = ITextFont_GetShadow(font, &value);
2192 ok(hr == S_OK, "got 0x%08x\n", hr);
2193 ok(value == tomUndefined, "got %d\n", value);
2194
2195 valuef = 0.0;
2196 hr = ITextFont_GetSize(font, &valuef);
2197 ok(hr == S_OK, "got 0x%08x\n", hr);
2198 ok(valuef == tomUndefined, "got %.2f\n", valuef);
2199
2200 value = tomFalse;
2201 hr = ITextFont_GetSmallCaps(font, &value);
2202 ok(hr == S_OK, "got 0x%08x\n", hr);
2203 ok(value == tomUndefined, "got %d\n", value);
2204
2205 valuef = 0.0;
2206 hr = ITextFont_GetSpacing(font, &valuef);
2207 ok(hr == S_OK, "got 0x%08x\n", hr);
2208 ok(valuef == tomUndefined, "got %.2f\n", valuef);
2209
2210 value = tomFalse;
2211 hr = ITextFont_GetStrikeThrough(font, &value);
2212 ok(hr == S_OK, "got 0x%08x\n", hr);
2213 ok(value == tomUndefined, "got %d\n", value);
2214
2215 value = tomFalse;
2216 hr = ITextFont_GetSubscript(font, &value);
2217 ok(hr == S_OK, "got 0x%08x\n", hr);
2218 ok(value == tomUndefined, "got %d\n", value);
2219
2220 value = tomFalse;
2221 hr = ITextFont_GetSuperscript(font, &value);
2222 ok(hr == S_OK, "got 0x%08x\n", hr);
2223 ok(value == tomUndefined, "got %d\n", value);
2224
2225 value = tomFalse;
2226 hr = ITextFont_GetUnderline(font, &value);
2227 ok(hr == S_OK, "got 0x%08x\n", hr);
2228 ok(value == tomUndefined, "got %d\n", value);
2229
2230 value = tomFalse;
2231 hr = ITextFont_GetWeight(font, &value);
2232 ok(hr == S_OK, "got 0x%08x\n", hr);
2233 ok(value == tomUndefined, "got %d\n", value);
2234 }
2235
2236 static inline FLOAT twips_to_points(LONG value)
2237 {
2238 return value * 72.0 / 1440;
2239 }
2240
2241 static void test_ITextFont(void)
2242 {
2243 static const WCHAR arialW[] = {'A','r','i','a','l',0};
2244 static const CHAR test_text1[] = "TestSomeText";
2245 ITextFont *font, *font2, *font3;
2246 FLOAT size, position, kerning;
2247 IRichEditOle *reOle = NULL;
2248 ITextDocument *doc = NULL;
2249 ITextRange *range = NULL;
2250 CHARFORMAT2A cf;
2251 LONG value;
2252 HRESULT hr;
2253 HWND hwnd;
2254 BOOL ret;
2255 BSTR str;
2256
2257 create_interfaces(&hwnd, &reOle, &doc, NULL);
2258 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2259
2260 hr = ITextDocument_Range(doc, 0, 10, &range);
2261 ok(hr == S_OK, "got 0x%08x\n", hr);
2262
2263 hr = ITextRange_GetFont(range, &font);
2264 ok(hr == S_OK, "got 0x%08x\n", hr);
2265
2266 hr = ITextFont_Reset(font, tomUseTwips);
2267 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2268
2269 hr = ITextFont_Reset(font, tomUsePoints);
2270 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2271
2272 hr = ITextFont_GetName(font, NULL);
2273 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2274
2275 /* default font size unit is point */
2276 size = 0.0;
2277 hr = ITextFont_GetSize(font, &size);
2278 ok(hr == S_OK, "got 0x%08x\n", hr);
2279
2280 /* set to some non-zero values */
2281 hr = ITextFont_SetPosition(font, 20.0);
2282 ok(hr == S_OK, "got 0x%08x\n", hr);
2283
2284 hr = ITextFont_SetKerning(font, 10.0);
2285 ok(hr == S_OK, "got 0x%08x\n", hr);
2286
2287 position = 0.0;
2288 hr = ITextFont_GetPosition(font, &position);
2289 ok(hr == S_OK, "got 0x%08x\n", hr);
2290
2291 kerning = 0.0;
2292 hr = ITextFont_GetKerning(font, &kerning);
2293 ok(hr == S_OK, "got 0x%08x\n", hr);
2294
2295 memset(&cf, 0, sizeof(cf));
2296 cf.cbSize = sizeof(cf);
2297 cf.dwMask = CFM_SIZE|CFM_OFFSET|CFM_KERNING;
2298
2299 /* CHARFORMAT members are in twips */
2300 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2301 ret = SendMessageA(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2302 ok(ret, "got %d\n", ret);
2303 ok(size == twips_to_points(cf.yHeight), "got yHeight %d, size %.2f\n", cf.yHeight, size);
2304 ok(position == twips_to_points(cf.yOffset), "got yOffset %d, position %.2f\n", cf.yOffset, position);
2305 ok(kerning == twips_to_points(cf.wKerning), "got wKerning %d, kerning %.2f\n", cf.wKerning, kerning);
2306
2307 hr = ITextFont_Reset(font, tomUseTwips);
2308 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2309
2310 hr = ITextFont_Reset(font, tomUsePoints);
2311 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2312
2313 hr = ITextFont_GetDuplicate(font, &font2);
2314 ok(hr == S_OK, "got 0x%08x\n", hr);
2315
2316 hr = ITextFont_Reset(font2, tomUseTwips);
2317 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2318
2319 hr = ITextFont_Reset(font2, tomUsePoints);
2320 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2321
2322 ITextFont_Release(font2);
2323
2324 /* default font name */
2325 str = NULL;
2326 hr = ITextFont_GetName(font, &str);
2327 ok(hr == S_OK, "got 0x%08x\n", hr);
2328 ok(!lstrcmpW(str, sysW), "got %s\n", wine_dbgstr_w(str));
2329 SysFreeString(str);
2330
2331 /* change font name for an inner subrange */
2332 memset(&cf, 0, sizeof(cf));
2333 cf.cbSize = sizeof(cf);
2334 cf.dwMask = CFM_FACE;
2335 strcpy(cf.szFaceName, "Arial");
2336
2337 SendMessageA(hwnd, EM_SETSEL, 3, 4);
2338 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2339 ok(ret, "got %d\n", ret);
2340
2341 /* still original name */
2342 str = NULL;
2343 hr = ITextFont_GetName(font, &str);
2344 ok(hr == S_OK, "got 0x%08x\n", hr);
2345 ok(!lstrcmpW(str, sysW), "got %s\n", wine_dbgstr_w(str));
2346 SysFreeString(str);
2347
2348 SendMessageA(hwnd, EM_SETSEL, 1, 2);
2349 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2350 ok(ret, "got %d\n", ret);
2351
2352 str = NULL;
2353 hr = ITextFont_GetName(font, &str);
2354 ok(hr == S_OK, "got 0x%08x\n", hr);
2355 ok(!lstrcmpW(str, sysW), "got %s\n", wine_dbgstr_w(str));
2356 SysFreeString(str);
2357
2358 /* name is returned for first position within a range */
2359 SendMessageA(hwnd, EM_SETSEL, 0, 1);
2360 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2361 ok(ret, "got %d\n", ret);
2362
2363 str = NULL;
2364 hr = ITextFont_GetName(font, &str);
2365 ok(hr == S_OK, "got 0x%08x\n", hr);
2366 ok(!lstrcmpW(str, arialW), "got %s\n", wine_dbgstr_w(str));
2367 SysFreeString(str);
2368
2369 /* GetDuplicate() */
2370 hr = ITextFont_GetDuplicate(font, NULL);
2371 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2372
2373 EXPECT_REF(range, 2);
2374 font2 = NULL;
2375 hr = ITextFont_GetDuplicate(font, &font2);
2376 ok(hr == S_OK, "got 0x%08x\n", hr);
2377 EXPECT_REF(range, 2);
2378
2379 /* set whole range to italic */
2380 cf.cbSize = sizeof(CHARFORMAT2A);
2381 cf.dwMask = CFM_ITALIC;
2382 cf.dwEffects = CFE_ITALIC;
2383
2384 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2385 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2386 ok(ret, "got %d\n", ret);
2387
2388 value = tomFalse;
2389 hr = ITextFont_GetItalic(font, &value);
2390 ok(hr == S_OK, "got 0x%08x\n", hr);
2391 ok(value == tomTrue, "got %d\n", value);
2392
2393 /* duplicate retains original value */
2394 value = tomTrue;
2395 hr = ITextFont_GetItalic(font2, &value);
2396 ok(hr == S_OK, "got 0x%08x\n", hr);
2397 ok(value == tomFalse, "got %d\n", value);
2398
2399 /* get a duplicate from a cloned font */
2400 hr = ITextFont_GetDuplicate(font2, &font3);
2401 ok(hr == S_OK, "got 0x%08x\n", hr);
2402 ITextFont_Release(font3);
2403
2404 ITextRange_Release(range);
2405 release_interfaces(&hwnd, &reOle, &doc, NULL);
2406
2407 hr = ITextFont_GetDuplicate(font, NULL);
2408 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2409
2410 test_detached_font_getters(font, FALSE);
2411 test_detached_font_getters(font2, TRUE);
2412
2413 /* get a duplicate of detached font */
2414 hr = ITextFont_GetDuplicate(font2, &font3);
2415 ok(hr == S_OK, "got 0x%08x\n", hr);
2416 ITextFont_Release(font3);
2417
2418 /* reset detached font to undefined */
2419 value = tomUndefined;
2420 hr = ITextFont_GetBold(font2, &value);
2421 ok(hr == S_OK, "got 0x%08x\n", hr);
2422 ok(value != tomUndefined, "got %d\n", value);
2423
2424 /* reset to undefined for detached font */
2425 hr = ITextFont_Reset(font2, tomUndefined);
2426 ok(hr == S_OK, "got 0x%08x\n", hr);
2427 test_textfont_undefined(font2);
2428
2429 /* font is detached, default means global TOM defaults */
2430 hr = ITextFont_Reset(font2, tomDefault);
2431 ok(hr == S_OK, "got 0x%08x\n", hr);
2432 test_textfont_global_defaults(font2);
2433
2434 hr = ITextFont_GetDuplicate(font2, &font3);
2435 ok(hr == S_OK, "got 0x%08x\n", hr);
2436 test_textfont_global_defaults(font2);
2437
2438 hr = ITextFont_Reset(font2, tomApplyNow);
2439 ok(hr == S_OK, "got 0x%08x\n", hr);
2440 test_textfont_global_defaults(font2);
2441
2442 hr = ITextFont_Reset(font2, tomApplyLater);
2443 ok(hr == S_OK, "got 0x%08x\n", hr);
2444 test_textfont_global_defaults(font2);
2445
2446 hr = ITextFont_Reset(font2, tomTrackParms);
2447 ok(hr == S_OK, "got 0x%08x\n", hr);
2448 test_textfont_global_defaults(font2);
2449
2450 hr = ITextFont_SetItalic(font2, tomUndefined);
2451 ok(hr == S_OK, "got 0x%08x\n", hr);
2452
2453 hr = ITextFont_GetItalic(font2, &value);
2454 ok(hr == S_OK, "got 0x%08x\n", hr);
2455 ok(value == tomFalse, "got %d\n", value);
2456
2457 hr = ITextFont_Reset(font2, tomCacheParms);
2458 ok(hr == S_OK, "got 0x%08x\n", hr);
2459 test_textfont_global_defaults(font2);
2460
2461 ITextFont_Release(font3);
2462 ITextFont_Release(font2);
2463
2464 font2 = (void*)0xdeadbeef;
2465 hr = ITextFont_GetDuplicate(font, &font2);
2466 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2467 ok(font2 == NULL, "got %p\n", font2);
2468
2469 hr = ITextFont_Reset(font, tomDefault);
2470 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2471
2472 ITextFont_Release(font);
2473
2474 /* Reset() */
2475 create_interfaces(&hwnd, &reOle, &doc, NULL);
2476 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2477
2478 hr = ITextDocument_Range(doc, 0, 10, &range);
2479 ok(hr == S_OK, "got 0x%08x\n", hr);
2480
2481 hr = ITextRange_GetFont(range, &font);
2482 ok(hr == S_OK, "got 0x%08x\n", hr);
2483
2484 value = tomUndefined;
2485 hr = ITextFont_GetBold(font, &value);
2486 ok(hr == S_OK, "got 0x%08x\n", hr);
2487 ok(value != tomUndefined, "got %d\n", value);
2488
2489 /* reset to undefined for attached font */
2490 hr = ITextFont_Reset(font, tomUndefined);
2491 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2492
2493 value = tomUndefined;
2494 hr = ITextFont_GetBold(font, &value);
2495 ok(hr == S_OK, "got 0x%08x\n", hr);
2496 ok(value != tomUndefined, "got %d\n", value);
2497
2498 /* tomCacheParms/tomTrackParms */
2499 hr = ITextFont_Reset(font, tomCacheParms);
2500 ok(hr == S_OK, "got 0x%08x\n", hr);
2501
2502 hr = ITextFont_GetItalic(font, &value);
2503 ok(hr == S_OK, "got 0x%08x\n", hr);
2504 ok(value == tomFalse, "got %d\n", value);
2505
2506 memset(&cf, 0, sizeof(cf));
2507 cf.cbSize = sizeof(CHARFORMAT2A);
2508 cf.dwMask = CFM_ITALIC;
2509
2510 cf.dwEffects = CFE_ITALIC;
2511 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2512 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2513 ok(ret, "got %d\n", ret);
2514
2515 /* still cached value */
2516 hr = ITextFont_GetItalic(font, &value);
2517 ok(hr == S_OK, "got 0x%08x\n", hr);
2518 ok(value == tomFalse, "got %d\n", value);
2519
2520 hr = ITextFont_Reset(font, tomTrackParms);
2521 ok(hr == S_OK, "got 0x%08x\n", hr);
2522
2523 hr = ITextFont_GetItalic(font, &value);
2524 ok(hr == S_OK, "got 0x%08x\n", hr);
2525 ok(value == tomTrue, "got %d\n", value);
2526
2527 /* switch back to cache - value retained */
2528 hr = ITextFont_Reset(font, tomCacheParms);
2529 ok(hr == S_OK, "got 0x%08x\n", hr);
2530
2531 hr = ITextFont_GetItalic(font, &value);
2532 ok(hr == S_OK, "got 0x%08x\n", hr);
2533 ok(value == tomTrue, "got %d\n", value);
2534
2535 /* tomApplyLater */
2536 hr = ITextFont_Reset(font, tomApplyLater);
2537 ok(hr == S_OK, "got 0x%08x\n", hr);
2538
2539 hr = ITextFont_SetItalic(font, tomFalse);
2540 ok(hr == S_OK, "got 0x%08x\n", hr);
2541
2542 hr = ITextFont_GetItalic(font, &value);
2543 ok(hr == S_OK, "got 0x%08x\n", hr);
2544 ok(value == tomFalse, "got %d\n", value);
2545
2546 cf.dwEffects = 0;
2547 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2548 ret = SendMessageA(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2549 ok(ret, "got %d\n", ret);
2550 ok((cf.dwEffects & CFE_ITALIC) == CFE_ITALIC, "got 0x%08x\n", cf.dwEffects);
2551
2552 hr = ITextFont_Reset(font, tomApplyNow);
2553 ok(hr == S_OK, "got 0x%08x\n", hr);
2554
2555 cf.dwEffects = 0;
2556 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2557 ret = SendMessageA(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2558 ok(ret, "got %d\n", ret);
2559 ok((cf.dwEffects & CFE_ITALIC) == 0, "got 0x%08x\n", cf.dwEffects);
2560
2561 hr = ITextFont_SetItalic(font, tomUndefined);
2562 ok(hr == S_OK, "got 0x%08x\n", hr);
2563
2564 hr = ITextFont_GetItalic(font, &value);
2565 ok(hr == S_OK, "got 0x%08x\n", hr);
2566 ok(value == tomFalse, "got %d\n", value);
2567
2568 hr = ITextFont_SetItalic(font, tomAutoColor);
2569 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2570
2571 cf.dwEffects = 0;
2572 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2573 ret = SendMessageA(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2574 ok(ret, "got %d\n", ret);
2575 ok((cf.dwEffects & CFE_ITALIC) == 0, "got 0x%08x\n", cf.dwEffects);
2576
2577 ITextRange_Release(range);
2578 ITextFont_Release(font);
2579 release_interfaces(&hwnd, &reOle, &doc, NULL);
2580 }
2581
2582 static void test_Delete(void)
2583 {
2584 static const CHAR test_text1[] = "TestSomeText";
2585 IRichEditOle *reOle = NULL;
2586 ITextDocument *doc = NULL;
2587 ITextRange *range, *range2;
2588 LONG value;
2589 HRESULT hr;
2590 HWND hwnd;
2591
2592 create_interfaces(&hwnd, &reOle, &doc, NULL);
2593 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2594
2595 hr = ITextDocument_Range(doc, 0, 4, &range);
2596 ok(hr == S_OK, "got 0x%08x\n", hr);
2597
2598 hr = ITextDocument_Range(doc, 1, 2, &range2);
2599 ok(hr == S_OK, "got 0x%08x\n", hr);
2600
2601 hr = ITextRange_GetEnd(range, &value);
2602 ok(hr == S_OK, "got 0x%08x\n", hr);
2603 ok(value == 4, "got %d\n", value);
2604
2605 /* unit type doesn't matter is count is 0 */
2606 value = 0;
2607 hr = ITextRange_Delete(range2, tomSentence, 0, &value);
2608 todo_wine {
2609 ok(hr == S_OK, "got 0x%08x\n", hr);
2610 ok(value == 1, "got %d\n", value);
2611 }
2612 value = 1;
2613 hr = ITextRange_Delete(range2, tomCharacter, 0, &value);
2614 todo_wine {
2615 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2616 ok(value == 0, "got %d\n", value);
2617 }
2618 hr = ITextRange_GetEnd(range, &value);
2619 ok(hr == S_OK, "got 0x%08x\n", hr);
2620 todo_wine
2621 ok(value == 3, "got %d\n", value);
2622
2623 hr = ITextRange_GetStart(range2, &value);
2624 ok(hr == S_OK, "got 0x%08x\n", hr);
2625 ok(value == 1, "got %d\n", value);
2626
2627 hr = ITextRange_GetEnd(range2, &value);
2628 ok(hr == S_OK, "got 0x%08x\n", hr);
2629 todo_wine
2630 ok(value == 1, "got %d\n", value);
2631
2632 ITextRange_Release(range);
2633 ITextRange_Release(range2);
2634 release_interfaces(&hwnd, &reOle, &doc, NULL);
2635 }
2636
2637 static void test_SetText(void)
2638 {
2639 static const CHAR test_text1[] = "TestSomeText";
2640 static const WCHAR textW[] = {'a','b','c','d','e','f','g','h','i',0};
2641 IRichEditOle *reOle = NULL;
2642 ITextDocument *doc = NULL;
2643 ITextRange *range, *range2;
2644 LONG value;
2645 HRESULT hr;
2646 HWND hwnd;
2647 BSTR str;
2648
2649 create_interfaces(&hwnd, &reOle, &doc, NULL);
2650 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2651
2652 hr = ITextDocument_Range(doc, 0, 4, &range);
2653 ok(hr == S_OK, "got 0x%08x\n", hr);
2654
2655 hr = ITextDocument_Range(doc, 0, 4, &range2);
2656 ok(hr == S_OK, "got 0x%08x\n", hr);
2657
2658 value = 1;
2659 hr = ITextRange_GetStart(range2, &value);
2660 ok(hr == S_OK, "got 0x%08x\n", hr);
2661 ok(value == 0, "got %d\n", value);
2662
2663 value = 0;
2664 hr = ITextRange_GetEnd(range2, &value);
2665 ok(hr == S_OK, "got 0x%08x\n", hr);
2666 ok(value == 4, "got %d\n", value);
2667
2668 hr = ITextRange_SetText(range, NULL);
2669 ok(hr == S_OK, "got 0x%08x\n", hr);
2670
2671 value = 1;
2672 hr = ITextRange_GetEnd(range2, &value);
2673 ok(hr == S_OK, "got 0x%08x\n", hr);
2674 ok(value == 0, "got %d\n", value);
2675
2676 str = SysAllocString(textW);
2677 hr = ITextRange_SetText(range, str);
2678 ok(hr == S_OK, "got 0x%08x\n", hr);
2679 SysFreeString(str);
2680
2681 value = 1;
2682 hr = ITextRange_GetStart(range, &value);
2683 ok(hr == S_OK, "got 0x%08x\n", hr);
2684 ok(value == 0, "got %d\n", value);
2685
2686 value = 0;
2687 hr = ITextRange_GetEnd(range, &value);
2688 ok(hr == S_OK, "got 0x%08x\n", hr);
2689 ok(value == 9, "got %d\n", value);
2690
2691 value = 1;
2692 hr = ITextRange_GetStart(range2, &value);
2693 ok(hr == S_OK, "got 0x%08x\n", hr);
2694 ok(value == 0, "got %d\n", value);
2695
2696 value = 0;
2697 hr = ITextRange_GetEnd(range2, &value);
2698 ok(hr == S_OK, "got 0x%08x\n", hr);
2699 ok(value == 0, "got %d\n", value);
2700
2701 str = SysAllocStringLen(NULL, 0);
2702 hr = ITextRange_SetText(range, str);
2703 ok(hr == S_OK, "got 0x%08x\n", hr);
2704 value = 1;
2705 hr = ITextRange_GetEnd(range, &value);
2706 ok(hr == S_OK, "got 0x%08x\n", hr);
2707 ok(value == 0, "got %d\n", value);
2708 SysFreeString(str);
2709
2710 ITextRange_Release(range2);
2711 release_interfaces(&hwnd, &reOle, &doc, NULL);
2712
2713 hr = ITextRange_SetText(range, NULL);
2714 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2715
2716 str = SysAllocStringLen(NULL, 0);
2717 hr = ITextRange_SetText(range, str);
2718 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2719 SysFreeString(str);
2720
2721 ITextRange_Release(range);
2722 }
2723
2724 static void test_InRange(void)
2725 {
2726 static const CHAR test_text1[] = "TestSomeText";
2727 ITextRange *range, *range2, *range3;
2728 IRichEditOle *reOle = NULL;
2729 ITextDocument *doc = NULL;
2730 ITextSelection *selection;
2731 LONG value;
2732 HRESULT hr;
2733 HWND hwnd;
2734
2735 create_interfaces(&hwnd, &reOle, &doc, &selection);
2736 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2737 SendMessageA(hwnd, EM_SETSEL, 1, 2);
2738
2739 hr = ITextDocument_Range(doc, 0, 4, &range);
2740 ok(hr == S_OK, "got 0x%08x\n", hr);
2741
2742 hr = ITextDocument_Range(doc, 0, 4, &range2);
2743 ok(hr == S_OK, "got 0x%08x\n", hr);
2744
2745 /* matches selection */
2746 hr = ITextDocument_Range(doc, 1, 2, &range3);
2747 ok(hr == S_OK, "got 0x%08x\n", hr);
2748
2749 hr = ITextRange_InRange(range, NULL, NULL);
2750 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2751
2752 value = tomTrue;
2753 hr = ITextRange_InRange(range, NULL, &value);
2754 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2755 ok(value == tomFalse, "got %d\n", value);
2756
2757 hr = ITextRange_InRange(range, range2, NULL);
2758 ok(hr == S_OK, "got 0x%08x\n", hr);
2759
2760 value = tomFalse;
2761 hr = ITextRange_InRange(range, range2, &value);
2762 ok(hr == S_OK, "got 0x%08x\n", hr);
2763 ok(value == tomTrue, "got %d\n", value);
2764
2765 /* selection */
2766 hr = ITextSelection_InRange(selection, NULL, NULL);
2767 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2768
2769 value = tomTrue;
2770 hr = ITextSelection_InRange(selection, NULL, &value);
2771 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2772 ok(value == tomFalse, "got %d\n", value);
2773
2774 hr = ITextSelection_InRange(selection, range2, NULL);
2775 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2776
2777 value = tomTrue;
2778 hr = ITextSelection_InRange(selection, range2, &value);
2779 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2780 ok(value == tomFalse, "got %d\n", value);
2781
2782 value = tomTrue;
2783 hr = ITextSelection_InRange(selection, range3, &value);
2784 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2785 ok(value == tomFalse, "got %d\n", value);
2786
2787 /* seems to work on ITextSelection ranges only */
2788 value = tomFalse;
2789 hr = ITextSelection_InRange(selection, (ITextRange*)selection, &value);
2790 ok(hr == S_OK, "got 0x%08x\n", hr);
2791 ok(value == tomTrue, "got %d\n", value);
2792
2793 release_interfaces(&hwnd, &reOle, &doc, NULL);
2794
2795 hr = ITextRange_InRange(range, NULL, NULL);
2796 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2797
2798 value = tomTrue;
2799 hr = ITextRange_InRange(range, NULL, &value);
2800 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2801 ok(value == tomFalse, "got %d\n", value);
2802
2803 hr = ITextRange_InRange(range, range2, NULL);
2804 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2805
2806 value = tomTrue;
2807 hr = ITextRange_InRange(range, range2, &value);
2808 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2809 ok(value == tomFalse, "got %d\n", value);
2810
2811 /* selection */
2812 hr = ITextSelection_InRange(selection, NULL, NULL);
2813 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2814
2815 value = tomTrue;
2816 hr = ITextSelection_InRange(selection, NULL, &value);
2817 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2818 ok(value == tomFalse, "got %d\n", value);
2819
2820 hr = ITextSelection_InRange(selection, range2, NULL);
2821 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2822
2823 value = tomTrue;
2824 hr = ITextSelection_InRange(selection, range2, &value);
2825 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2826 ok(value == tomFalse, "got %d\n", value);
2827
2828 ITextRange_Release(range);
2829 ITextRange_Release(range2);
2830 ITextRange_Release(range3);
2831 ITextSelection_Release(selection);
2832 }
2833
2834 static void test_ITextRange_IsEqual(void)
2835 {
2836 static const CHAR test_text1[] = "TestSomeText";
2837 ITextRange *range, *range2, *range3;
2838 IRichEditOle *reOle = NULL;
2839 ITextDocument *doc = NULL;
2840 ITextSelection *selection;
2841 LONG value;
2842 HRESULT hr;
2843 HWND hwnd;
2844
2845 create_interfaces(&hwnd, &reOle, &doc, &selection);
2846 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2847 SendMessageA(hwnd, EM_SETSEL, 1, 2);
2848
2849 hr = ITextDocument_Range(doc, 0, 4, &range);
2850 ok(hr == S_OK, "got 0x%08x\n", hr);
2851
2852 hr = ITextDocument_Range(doc, 0, 4, &range2);
2853 ok(hr == S_OK, "got 0x%08x\n", hr);
2854
2855 /* matches selection */
2856 hr = ITextDocument_Range(doc, 1, 2, &range3);
2857 ok(hr == S_OK, "got 0x%08x\n", hr);
2858
2859 hr = ITextRange_IsEqual(range, NULL, NULL);
2860 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2861
2862 value = tomTrue;
2863 hr = ITextRange_IsEqual(range, NULL, &value);
2864 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2865 ok(value == tomFalse, "got %d\n", value);
2866
2867 hr = ITextRange_IsEqual(range, range2, NULL);
2868 ok(hr == S_OK, "got 0x%08x\n", hr);
2869
2870 value = tomFalse;
2871 hr = ITextRange_IsEqual(range, range2, &value);
2872 ok(hr == S_OK, "got 0x%08x\n", hr);
2873 ok(value == tomTrue, "got %d\n", value);
2874
2875 value = tomTrue;
2876 hr = ITextRange_IsEqual(range, range3, &value);
2877 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2878 ok(value == tomFalse, "got %d\n", value);
2879
2880 /* selection */
2881 hr = ITextSelection_IsEqual(selection, NULL, NULL);
2882 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2883
2884 value = tomTrue;
2885 hr = ITextSelection_IsEqual(selection, NULL, &value);
2886 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2887 ok(value == tomFalse, "got %d\n", value);
2888
2889 hr = ITextSelection_IsEqual(selection, range2, NULL);
2890 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2891
2892 value = tomTrue;
2893 hr = ITextSelection_IsEqual(selection, range2, &value);
2894 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2895 ok(value == tomFalse, "got %d\n", value);
2896
2897 value = tomTrue;
2898 hr = ITextSelection_IsEqual(selection, range3, &value);
2899 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2900 ok(value == tomFalse, "got %d\n", value);
2901
2902 /* seems to work on ITextSelection ranges only */
2903 value = tomFalse;
2904 hr = ITextSelection_IsEqual(selection, (ITextRange*)selection, &value);
2905 ok(hr == S_OK, "got 0x%08x\n", hr);
2906 ok(value == tomTrue, "got %d\n", value);
2907
2908 release_interfaces(&hwnd, &reOle, &doc, NULL);
2909
2910 hr = ITextRange_IsEqual(range, NULL, NULL);
2911 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2912
2913 value = tomTrue;
2914 hr = ITextRange_IsEqual(range, NULL, &value);
2915 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2916 ok(value == tomFalse, "got %d\n", value);
2917
2918 hr = ITextRange_IsEqual(range, range2, NULL);
2919 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2920
2921 value = tomTrue;
2922 hr = ITextRange_IsEqual(range, range2, &value);
2923 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2924 ok(value == tomFalse, "got %d\n", value);
2925
2926 /* selection */
2927 hr = ITextSelection_IsEqual(selection, NULL, NULL);
2928 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2929
2930 value = tomTrue;
2931 hr = ITextSelection_IsEqual(selection, NULL, &value);
2932 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2933 ok(value == tomFalse, "got %d\n", value);
2934
2935 hr = ITextSelection_IsEqual(selection, range2, NULL);
2936 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2937
2938 value = tomTrue;
2939 hr = ITextSelection_IsEqual(selection, range2, &value);
2940 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2941 ok(value == tomFalse, "got %d\n", value);
2942
2943 ITextRange_Release(range);
2944 ITextRange_Release(range2);
2945 ITextRange_Release(range3);
2946 ITextSelection_Release(selection);
2947 }
2948
2949 static void test_Select(void)
2950 {
2951 static const CHAR test_text1[] = "TestSomeText";
2952 IRichEditOle *reOle = NULL;
2953 ITextDocument *doc = NULL;
2954 ITextSelection *selection;
2955 ITextRange *range;
2956 LONG value;
2957 HRESULT hr;
2958 HWND hwnd;
2959
2960 create_interfaces(&hwnd, &reOle, &doc, &selection);
2961 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2962 SendMessageA(hwnd, EM_SETSEL, 1, 2);
2963
2964 hr = ITextDocument_Range(doc, 0, 4, &range);
2965 ok(hr == S_OK, "got 0x%08x\n", hr);
2966
2967 hr = ITextRange_Select(range);
2968 ok(hr == S_OK, "got 0x%08x\n", hr);
2969
2970 value = 1;
2971 hr = ITextSelection_GetStart(selection, &value);
2972 ok(hr == S_OK, "got 0x%08x\n", hr);
2973 ok(value == 0, "got %d\n", value);
2974
2975 hr = ITextRange_Select(range);
2976 ok(hr == S_OK, "got 0x%08x\n", hr);
2977
2978 hr = ITextSelection_Select(selection);
2979 ok(hr == S_OK, "got 0x%08x\n", hr);
2980
2981 release_interfaces(&hwnd, &reOle, &doc, NULL);
2982
2983 hr = ITextRange_Select(range);
2984 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2985
2986 hr = ITextSelection_Select(selection);
2987 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2988
2989 ITextRange_Release(range);
2990 ITextSelection_Release(selection);
2991 }
2992
2993 static void test_GetStoryType(void)
2994 {
2995 static const CHAR test_text1[] = "TestSomeText";
2996 IRichEditOle *reOle = NULL;
2997 ITextDocument *doc = NULL;
2998 ITextSelection *selection;
2999 ITextRange *range;
3000 LONG value;
3001 HRESULT hr;
3002 HWND hwnd;
3003
3004 create_interfaces(&hwnd, &reOle, &doc, &selection);
3005 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
3006 SendMessageA(hwnd, EM_SETSEL, 1, 2);
3007
3008 hr = ITextDocument_Range(doc, 0, 4, &range);
3009 ok(hr == S_OK, "got 0x%08x\n", hr);
3010
3011 hr = ITextRange_GetStoryType(range, NULL);
3012 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3013
3014 value = tomTextFrameStory;
3015 hr = ITextRange_GetStoryType(range, &value);
3016 ok(hr == S_OK, "got 0x%08x\n", hr);
3017 ok(value == tomUnknownStory, "got %d\n", value);
3018
3019 hr = ITextSelection_GetStoryType(selection, NULL);
3020 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3021
3022 value = tomTextFrameStory;
3023 hr = ITextSelection_GetStoryType(selection, &value);
3024 ok(hr == S_OK, "got 0x%08x\n", hr);
3025 ok(value == tomUnknownStory, "got %d\n