riched20: Implement SetText for regular range.
[wine/multimedia.git] / dlls / riched20 / tests / richole.c
blob7d90a983c4aae75c63ccedea8a9138cd28a52ee7
1 /*
2 * Tests for IRichEditOle and friends.
4 * Copyright 2008 Google (Dan Hipschman)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define COBJMACROS
23 #include <stdarg.h>
25 #include <windef.h>
26 #include <winbase.h>
27 #include <wingdi.h>
28 #include <winuser.h>
29 #include <initguid.h>
30 #include <ole2.h>
31 #include <richedit.h>
32 #include <richole.h>
33 #include <tom.h>
34 #include <wine/test.h>
36 static HMODULE hmoduleRichEdit;
38 DEFINE_GUID(GUID_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
40 static const WCHAR sysW[] = {'S','y','s','t','e','m',0};
42 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
43 static void _expect_ref(IUnknown* obj, ULONG ref, int line)
45 ULONG rc;
46 IUnknown_AddRef(obj);
47 rc = IUnknown_Release(obj);
48 ok_(__FILE__,line)(rc == ref, "expected refcount %d, got %d\n", ref, rc);
51 static HWND new_window(LPCSTR lpClassName, DWORD dwStyle, HWND parent)
53 HWND hwnd = CreateWindowA(lpClassName, NULL,
54 dwStyle | WS_POPUP | WS_HSCROLL | WS_VSCROLL | WS_VISIBLE,
55 0, 0, 200, 60, parent, NULL, hmoduleRichEdit, NULL);
56 return hwnd;
59 static HWND new_richedit(HWND parent)
61 return new_window(RICHEDIT_CLASS20A, ES_MULTILINE, parent);
64 static BOOL touch_file(LPCWSTR filename)
66 HANDLE file;
68 file = CreateFileW(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL,
69 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
71 if(file == INVALID_HANDLE_VALUE)
72 return FALSE;
73 CloseHandle(file);
74 return TRUE;
77 static BOOL is_existing_file(LPCWSTR filename)
79 HANDLE file;
81 file = CreateFileW(filename, GENERIC_READ, 0, NULL,
82 OPEN_EXISTING, 0, NULL);
83 if(file == INVALID_HANDLE_VALUE)
84 return FALSE;
85 CloseHandle(file);
86 return TRUE;
89 static void create_interfaces(HWND *w, IRichEditOle **reOle, ITextDocument **txtDoc,
90 ITextSelection **txtSel)
92 *w = new_richedit(NULL);
93 SendMessageA(*w, EM_GETOLEINTERFACE, 0, (LPARAM)reOle);
94 IRichEditOle_QueryInterface(*reOle, &IID_ITextDocument,
95 (void **) txtDoc);
96 ITextDocument_GetSelection(*txtDoc, txtSel);
99 static void release_interfaces(HWND *w, IRichEditOle **reOle, ITextDocument **txtDoc,
100 ITextSelection **txtSel)
102 if(txtSel)
103 ITextSelection_Release(*txtSel);
104 ITextDocument_Release(*txtDoc);
105 IRichEditOle_Release(*reOle);
106 DestroyWindow(*w);
109 static ULONG get_refcount(IUnknown *iface)
111 IUnknown_AddRef(iface);
112 return IUnknown_Release(iface);
115 static void test_Interfaces(void)
117 IRichEditOle *reOle = NULL, *reOle1 = NULL;
118 ITextDocument *txtDoc = NULL;
119 ITextSelection *txtSel = NULL, *txtSel2;
120 IUnknown *punk;
121 HRESULT hres;
122 LRESULT res;
123 HWND w;
124 ULONG refcount;
126 w = new_richedit(NULL);
127 if (!w) {
128 skip("Couldn't create window\n");
129 return;
132 res = SendMessageA(w, EM_GETOLEINTERFACE, 0, (LPARAM)&reOle);
133 ok(res, "SendMessage\n");
134 ok(reOle != NULL, "EM_GETOLEINTERFACE\n");
135 EXPECT_REF(reOle, 2);
137 res = SendMessageA(w, EM_GETOLEINTERFACE, 0, (LPARAM)&reOle1);
138 ok(res == 1, "SendMessage\n");
139 ok(reOle1 == reOle, "Should not return a new IRichEditOle interface\n");
140 EXPECT_REF(reOle, 3);
142 hres = IRichEditOle_QueryInterface(reOle, &IID_ITextDocument,
143 (void **) &txtDoc);
144 ok(hres == S_OK, "IRichEditOle_QueryInterface\n");
145 ok(txtDoc != NULL, "IRichEditOle_QueryInterface\n");
147 hres = ITextDocument_GetSelection(txtDoc, NULL);
148 ok(hres == E_INVALIDARG, "ITextDocument_GetSelection: 0x%x\n", hres);
150 EXPECT_REF(txtDoc, 4);
152 hres = ITextDocument_GetSelection(txtDoc, &txtSel);
153 ok(hres == S_OK, "got 0x%08x\n", hres);
155 EXPECT_REF(txtDoc, 4);
156 EXPECT_REF(txtSel, 2);
158 hres = ITextDocument_GetSelection(txtDoc, &txtSel2);
159 ok(hres == S_OK, "got 0x%08x\n", hres);
160 ok(txtSel2 == txtSel, "got %p, %p\n", txtSel, txtSel2);
162 EXPECT_REF(txtDoc, 4);
163 EXPECT_REF(txtSel, 3);
165 ITextSelection_Release(txtSel2);
167 punk = NULL;
168 hres = ITextSelection_QueryInterface(txtSel, &IID_ITextSelection, (void **) &punk);
169 ok(hres == S_OK, "ITextSelection_QueryInterface\n");
170 ok(punk != NULL, "ITextSelection_QueryInterface\n");
171 IUnknown_Release(punk);
173 punk = NULL;
174 hres = ITextSelection_QueryInterface(txtSel, &IID_ITextRange, (void **) &punk);
175 ok(hres == S_OK, "ITextSelection_QueryInterface\n");
176 ok(punk != NULL, "ITextSelection_QueryInterface\n");
177 IUnknown_Release(punk);
179 punk = NULL;
180 hres = ITextSelection_QueryInterface(txtSel, &IID_IDispatch, (void **) &punk);
181 ok(hres == S_OK, "ITextSelection_QueryInterface\n");
182 ok(punk != NULL, "ITextSelection_QueryInterface\n");
183 IUnknown_Release(punk);
185 punk = NULL;
186 hres = IRichEditOle_QueryInterface(reOle, &IID_IOleClientSite, (void **) &punk);
187 ok(hres == E_NOINTERFACE, "IRichEditOle_QueryInterface\n");
189 punk = NULL;
190 hres = IRichEditOle_QueryInterface(reOle, &IID_IOleWindow, (void **) &punk);
191 ok(hres == E_NOINTERFACE, "IRichEditOle_QueryInterface\n");
193 punk = NULL;
194 hres = IRichEditOle_QueryInterface(reOle, &IID_IOleInPlaceSite, (void **) &punk);
195 ok(hres == E_NOINTERFACE, "IRichEditOle_QueryInterface\n");
197 ITextDocument_Release(txtDoc);
198 IRichEditOle_Release(reOle);
199 refcount = IRichEditOle_Release(reOle);
200 ok(refcount == 1, "got wrong ref count: %d\n", refcount);
201 DestroyWindow(w);
203 /* Methods should return CO_E_RELEASED if the backing document has
204 been released. One test should suffice. */
205 hres = ITextSelection_CanEdit(txtSel, NULL);
206 ok(hres == CO_E_RELEASED, "ITextSelection after ITextDocument destroyed\n");
208 ITextSelection_Release(txtSel);
211 static void test_ITextDocument_Open(void)
213 IRichEditOle *reOle = NULL;
214 ITextDocument *txtDoc = NULL;
215 ITextSelection *txtSel = NULL;
216 HRESULT hres;
217 HWND w;
218 HANDLE hFile;
219 VARIANT testfile;
220 WCHAR filename[] = {'t', 'e', 's', 't','.','t','x','t', 0};
221 int result;
222 DWORD dw;
223 static const CHAR chACP[] = "TestSomeText";
224 static const CHAR chUTF8[] = "\xef\xbb\xbfTextWithUTF8BOM";
225 static const WCHAR chUTF16[] = {0xfeff, 'T', 'e', 's', 't', 'S', 'o', 'm',
226 'e', 'T', 'e', 'x', 't', 0};
228 #define MAX_BUF_LEN 1024
229 CHAR bufACP[MAX_BUF_LEN];
230 WCHAR bufUnicode[MAX_BUF_LEN];
232 static const int tomConstantsSingle[] =
234 tomReadOnly, tomShareDenyRead, tomShareDenyWrite,
235 tomCreateAlways, tomOpenExisting, tomOpenAlways,
236 tomTruncateExisting, tomRTF, tomText
239 static const int tomConstantsMulti[] =
241 tomReadOnly|tomShareDenyRead|tomPasteFile, tomReadOnly|tomPasteFile,
242 tomReadOnly|tomShareDenyWrite|tomPasteFile,
243 tomReadOnly|tomShareDenyRead|tomShareDenyWrite|tomPasteFile, tomShareDenyWrite|tomPasteFile,
244 tomShareDenyRead|tomShareDenyWrite|tomPasteFile, tomShareDenyRead|tomPasteFile,
245 tomShareDenyRead|tomShareDenyWrite, tomReadOnly|tomShareDenyRead|tomShareDenyWrite,
246 tomReadOnly|tomShareDenyWrite, tomReadOnly|tomShareDenyRead
249 int tomNumSingle = sizeof(tomConstantsSingle)/sizeof(tomConstantsSingle[0]);
250 int tomNumMulti = sizeof(tomConstantsMulti)/sizeof(tomConstantsMulti[0]);
251 int i;
253 V_VT(&testfile) = VT_BSTR;
254 V_BSTR(&testfile) = SysAllocString(filename);
256 for(i=0; i < tomNumSingle; i++)
258 touch_file(filename);
259 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
260 hres = ITextDocument_Open(txtDoc, &testfile, tomConstantsSingle[i], CP_ACP);
261 todo_wine ok(hres == S_OK, "ITextDocument_Open: Filename:test.txt Flags:0x%x Codepage:CP_ACP hres:0x%x\n",
262 tomConstantsSingle[i], hres);
263 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
264 DeleteFileW(filename);
266 touch_file(filename);
267 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
268 hres = ITextDocument_Open(txtDoc, &testfile, tomConstantsSingle[i], CP_UTF8);
269 todo_wine ok(hres == S_OK, "ITextDocument_Open: Filename:test.txt Flags:0x%x Codepage:CP_UTF8 hres:0x%x\n",
270 tomConstantsSingle[i], hres);
271 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
272 DeleteFileW(filename);
275 for(i=0; i < tomNumMulti; i++)
277 touch_file(filename);
278 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
279 hres = ITextDocument_Open(txtDoc, &testfile, tomConstantsMulti[i], CP_ACP);
280 todo_wine ok(hres == S_OK, "ITextDocument_Open: Filename:test.txt Flags:0x%x Codepage:CP_ACP hres:0x%x\n",
281 tomConstantsMulti[i], hres);
282 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
283 DeleteFileW(filename);
285 touch_file(filename);
286 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
287 hres = ITextDocument_Open(txtDoc, &testfile, tomConstantsMulti[i], CP_UTF8);
288 todo_wine ok(hres == S_OK, "ITextDocument_Open: Filename:test.txt Flags:0x%x Codepage:CP_UTF8 hres:0x%x\n",
289 tomConstantsMulti[i], hres);
290 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
291 DeleteFileW(filename);
294 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
295 hres = ITextDocument_Open(txtDoc, &testfile, tomCreateAlways, CP_ACP);
296 todo_wine ok(hres == S_OK, "ITextDocument_Open should success Codepage:CP_ACP\n");
297 todo_wine ok(is_existing_file(filename), "ITextDocument_Open should create a file\n");
298 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
299 DeleteFileW(filename);
301 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
302 hres = ITextDocument_Open(txtDoc, &testfile, tomCreateAlways, CP_UTF8);
303 todo_wine ok(hres == S_OK, "ITextDocument_Open should success Codepage:CP_UTF8\n");
304 todo_wine ok(is_existing_file(filename), "ITextDocument_Open should create a file\n");
305 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
306 DeleteFileW(filename);
308 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
309 hres = ITextDocument_Open(txtDoc, &testfile, tomOpenAlways, CP_ACP);
310 todo_wine ok(hres == S_OK, "ITextDocument_Open should success Codepage:CP_ACP\n");
311 todo_wine ok(is_existing_file(filename), "ITextDocument_Open should create a file\n");
312 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
313 DeleteFileW(filename);
315 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
316 hres = ITextDocument_Open(txtDoc, &testfile, tomOpenAlways, CP_UTF8);
317 todo_wine ok(hres == S_OK, "ITextDocument_Open should success Codepage:CP_UTF8\n");
318 todo_wine ok(is_existing_file(filename), "ITextDocument_Open should create a file\n");
319 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
320 DeleteFileW(filename);
322 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
323 hres = ITextDocument_Open(txtDoc, &testfile, tomCreateNew, CP_ACP);
324 todo_wine ok(hres == S_OK, "ITextDocument_Open should success Codepage:CP_ACP\n");
325 todo_wine ok(is_existing_file(filename), "ITextDocument_Open should create a file\n");
326 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
327 DeleteFileW(filename);
329 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
330 hres = ITextDocument_Open(txtDoc, &testfile, tomCreateNew, CP_UTF8);
331 todo_wine ok(hres == S_OK, "ITextDocument_Open should success Codepage:CP_UTF8\n");
332 todo_wine ok(is_existing_file(filename), "ITextDocument_Open should create a file\n");
333 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
334 DeleteFileW(filename);
336 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
337 touch_file(filename);
338 hres = ITextDocument_Open(txtDoc, &testfile, tomCreateNew, CP_ACP);
339 todo_wine ok(hres == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "ITextDocument_Open should fail Codepage:CP_ACP\n");
340 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
341 DeleteFileW(filename);
343 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
344 touch_file(filename);
345 hres = ITextDocument_Open(txtDoc, &testfile, tomCreateNew, CP_UTF8);
346 todo_wine ok(hres == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "ITextDocument_Open should fail Codepage:CP_UTF8\n");
347 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
348 DeleteFileW(filename);
350 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
351 hres = ITextDocument_Open(txtDoc, &testfile, tomOpenExisting, CP_ACP);
352 todo_wine ok(hres == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "ITextDocument_Open should fail Codepage:CP_ACP\n");
353 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
355 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
356 hres = ITextDocument_Open(txtDoc, &testfile, tomOpenExisting, CP_UTF8);
357 todo_wine ok(hres == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "ITextDocument_Open should fail Codepage:CP_UTF8\n");
358 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
360 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
361 DeleteFileW(filename);
362 ITextDocument_Open(txtDoc, &testfile, tomText, CP_ACP);
363 todo_wine ok(is_existing_file(filename) == TRUE, "a file should be created default\n");
364 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
365 DeleteFileW(filename);
367 /* test of share mode */
368 touch_file(filename);
369 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
370 ITextDocument_Open(txtDoc, &testfile, tomShareDenyRead, CP_ACP);
371 SetLastError(0xdeadbeef);
372 hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
373 FILE_ATTRIBUTE_NORMAL, NULL);
374 todo_wine ok(GetLastError() == ERROR_SHARING_VIOLATION, "ITextDocument_Open should fail\n");
375 CloseHandle(hFile);
376 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
377 DeleteFileW(filename);
379 touch_file(filename);
380 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
381 ITextDocument_Open(txtDoc, &testfile, tomShareDenyWrite, CP_ACP);
382 SetLastError(0xdeadbeef);
383 hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
384 FILE_ATTRIBUTE_NORMAL, NULL);
385 todo_wine ok(GetLastError() == ERROR_SHARING_VIOLATION, "ITextDocument_Open should fail\n");
386 CloseHandle(hFile);
387 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
388 DeleteFileW(filename);
390 touch_file(filename);
391 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
392 SetLastError(0xdeadbeef);
393 ITextDocument_Open(txtDoc, &testfile, tomShareDenyWrite|tomShareDenyRead, CP_ACP);
394 hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
395 FILE_ATTRIBUTE_NORMAL, NULL);
396 todo_wine ok(GetLastError() == ERROR_SHARING_VIOLATION, "ITextDocument_Open should fail\n");
397 CloseHandle(hFile);
398 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
399 DeleteFileW(filename);
401 /* tests to check the content */
402 hFile = CreateFileW(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS,
403 FILE_ATTRIBUTE_NORMAL, NULL);
404 WriteFile(hFile, chACP, sizeof(chACP)-sizeof(CHAR), &dw, NULL);
405 CloseHandle(hFile);
406 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
407 ITextDocument_Open(txtDoc, &testfile, tomReadOnly, CP_ACP);
408 result = SendMessageA(w, WM_GETTEXT, 1024, (LPARAM)bufACP);
409 todo_wine ok(result == 12, "ITextDocument_Open: Test ASCII returned %d, expected 12\n", result);
410 result = strcmp(bufACP, chACP);
411 todo_wine ok(result == 0, "ITextDocument_Open: Test ASCII set wrong text: Result: %s\n", bufACP);
412 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
413 DeleteFileW(filename);
415 hFile = CreateFileW(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS,
416 FILE_ATTRIBUTE_NORMAL, NULL);
417 WriteFile(hFile, chUTF8, sizeof(chUTF8)-sizeof(CHAR), &dw, NULL);
418 CloseHandle(hFile);
419 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
420 ITextDocument_Open(txtDoc, &testfile, tomReadOnly, CP_UTF8);
421 result = SendMessageA(w, WM_GETTEXT, 1024, (LPARAM)bufACP);
422 todo_wine ok(result == 15, "ITextDocument_Open: Test UTF-8 returned %d, expected 15\n", result);
423 result = strcmp(bufACP, &chUTF8[3]);
424 todo_wine ok(result == 0, "ITextDocument_Open: Test UTF-8 set wrong text: Result: %s\n", bufACP);
425 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
426 DeleteFileW(filename);
428 hFile = CreateFileW(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS,
429 FILE_ATTRIBUTE_NORMAL, NULL);
430 WriteFile(hFile, chUTF16, sizeof(chUTF16)-sizeof(WCHAR), &dw, NULL);
431 CloseHandle(hFile);
432 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
433 ITextDocument_Open(txtDoc, &testfile, tomReadOnly, 1200);
434 result = SendMessageW(w, WM_GETTEXT, 1024, (LPARAM)bufUnicode);
435 todo_wine ok(result == 12, "ITextDocument_Open: Test UTF-16 returned %d, expected 12\n", result);
436 result = lstrcmpW(bufUnicode, &chUTF16[1]);
437 todo_wine ok(result == 0, "ITextDocument_Open: Test UTF-16 set wrong text: Result: %s\n", wine_dbgstr_w(bufUnicode));
438 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
439 DeleteFileW(filename);
441 VariantClear(&testfile);
444 static void test_GetText(void)
446 HWND w;
447 IRichEditOle *reOle = NULL;
448 ITextDocument *txtDoc = NULL;
449 ITextSelection *txtSel = NULL;
450 HRESULT hres;
451 BSTR bstr = NULL;
452 int first, lim;
453 static const CHAR test_text1[] = "TestSomeText";
454 static const WCHAR bufW1[] = {'T', 'e', 's', 't', 0};
455 static const WCHAR bufW2[] = {'T', 'e', 'x', 't', '\r', 0};
456 static const WCHAR bufW3[] = {'T', 'e', 'x', 't', 0};
457 static const WCHAR bufW4[] = {'T', 'e', 's', 't', 'S', 'o', 'm',
458 'e', 'T', 'e', 'x', 't', '\r', 0};
459 static const WCHAR bufW5[] = {'\r', 0};
460 static const WCHAR bufW6[] = {'T','e','s','t','S','o','m','e','T',0};
461 BOOL is64bit = sizeof(void *) > sizeof(int);
462 ITextRange *range;
464 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
465 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
467 /* ITextSelection */
468 first = 0, lim = 4;
469 SendMessageA(w, EM_SETSEL, first, lim);
470 hres = ITextSelection_GetText(txtSel, &bstr);
471 ok(hres == S_OK, "ITextSelection_GetText\n");
472 ok(!lstrcmpW(bstr, bufW1), "got wrong text: %s\n", wine_dbgstr_w(bstr));
473 SysFreeString(bstr);
475 first = 4, lim = 0;
476 SendMessageA(w, EM_SETSEL, first, lim);
477 hres = ITextSelection_GetText(txtSel, &bstr);
478 ok(hres == S_OK, "ITextSelection_GetText\n");
479 ok(!lstrcmpW(bstr, bufW1), "got wrong text: %s\n", wine_dbgstr_w(bstr));
480 SysFreeString(bstr);
482 first = 1, lim = 1;
483 SendMessageA(w, EM_SETSEL, first, lim);
484 hres = ITextSelection_GetText(txtSel, &bstr);
485 ok(hres == S_OK, "ITextSelection_GetText\n");
486 ok(!bstr, "got wrong text: %s\n", wine_dbgstr_w(bstr));
488 if (!is64bit)
490 hres = ITextSelection_GetText(txtSel, NULL);
491 ok(hres == E_INVALIDARG, "ITextSelection_GetText\n");
494 first = 8, lim = 12;
495 SendMessageA(w, EM_SETSEL, first, lim);
496 hres = ITextSelection_GetText(txtSel, &bstr);
497 ok(hres == S_OK, "ITextSelection_GetText\n");
498 ok(!lstrcmpW(bstr, bufW3), "got wrong text: %s\n", wine_dbgstr_w(bstr));
499 SysFreeString(bstr);
501 first = 8, lim = 13;
502 SendMessageA(w, EM_SETSEL, first, lim);
503 hres = ITextSelection_GetText(txtSel, &bstr);
504 ok(hres == S_OK, "ITextSelection_GetText\n");
505 ok(!lstrcmpW(bstr, bufW2), "got wrong text: %s\n", wine_dbgstr_w(bstr));
506 SysFreeString(bstr);
508 first = 12, lim = 13;
509 SendMessageA(w, EM_SETSEL, first, lim);
510 hres = ITextSelection_GetText(txtSel, &bstr);
511 ok(hres == S_OK, "ITextSelection_GetText\n");
512 ok(!lstrcmpW(bstr, bufW5), "got wrong text: %s\n", wine_dbgstr_w(bstr));
513 SysFreeString(bstr);
515 first = 0, lim = -1;
516 SendMessageA(w, EM_SETSEL, first, lim);
517 hres = ITextSelection_GetText(txtSel, &bstr);
518 ok(hres == S_OK, "ITextSelection_GetText\n");
519 ok(!lstrcmpW(bstr, bufW4), "got wrong text: %s\n", wine_dbgstr_w(bstr));
520 SysFreeString(bstr);
522 first = -1, lim = 9;
523 SendMessageA(w, EM_SETSEL, first, lim);
524 hres = ITextSelection_GetText(txtSel, &bstr);
525 ok(hres == S_OK, "ITextSelection_GetText\n");
526 ok(!bstr, "got wrong text: %s\n", wine_dbgstr_w(bstr));
528 /* ITextRange */
529 hres = ITextDocument_Range(txtDoc, 0, 4, &range);
530 ok(hres == S_OK, "got 0x%08x\n", hres);
531 hres = ITextRange_GetText(range, &bstr);
532 todo_wine {
533 ok(hres == S_OK, "got 0x%08x\n", hres);
534 ok(!lstrcmpW(bstr, bufW1), "got wrong text: %s\n", wine_dbgstr_w(bstr));
536 SysFreeString(bstr);
537 ITextRange_Release(range);
539 hres = ITextDocument_Range(txtDoc, 4, 0, &range);
540 ok(hres == S_OK, "got 0x%08x\n", hres);
541 hres = ITextRange_GetText(range, &bstr);
542 todo_wine {
543 ok(hres == S_OK, "got 0x%08x\n", hres);
544 ok(!lstrcmpW(bstr, bufW1), "got wrong text: %s\n", wine_dbgstr_w(bstr));
546 SysFreeString(bstr);
547 ITextRange_Release(range);
549 hres = ITextDocument_Range(txtDoc, 1, 1, &range);
550 ok(hres == S_OK, "got 0x%08x\n", hres);
551 hres = ITextRange_GetText(range, &bstr);
552 todo_wine
553 ok(hres == S_OK, "got 0x%08x\n", hres);
554 ok(!bstr, "got wrong text: %s\n", wine_dbgstr_w(bstr));
555 if (!is64bit)
557 hres = ITextRange_GetText(range, NULL);
558 ok(hres == E_INVALIDARG, "got 0x%08x\n", hres);
560 ITextRange_Release(range);
562 hres = ITextDocument_Range(txtDoc, 8, 12, &range);
563 ok(hres == S_OK, "got 0x%08x\n", hres);
564 hres = ITextRange_GetText(range, &bstr);
565 todo_wine {
566 ok(hres == S_OK, "got 0x%08x\n", hres);
567 ok(!lstrcmpW(bstr, bufW3), "got wrong text: %s\n", wine_dbgstr_w(bstr));
569 SysFreeString(bstr);
570 ITextRange_Release(range);
572 hres = ITextDocument_Range(txtDoc, 8, 13, &range);
573 ok(hres == S_OK, "got 0x%08x\n", hres);
574 hres = ITextRange_GetText(range, &bstr);
575 todo_wine {
576 ok(hres == S_OK, "got 0x%08x\n", hres);
577 ok(!lstrcmpW(bstr, bufW2), "got wrong text: %s\n", wine_dbgstr_w(bstr));
579 SysFreeString(bstr);
580 ITextRange_Release(range);
582 hres = ITextDocument_Range(txtDoc, 12, 13, &range);
583 ok(hres == S_OK, "got 0x%08x\n", hres);
584 hres = ITextRange_GetText(range, &bstr);
585 todo_wine {
586 ok(hres == S_OK, "got 0x%08x\n", hres);
587 ok(!lstrcmpW(bstr, bufW5), "got wrong text: %s\n", wine_dbgstr_w(bstr));
589 SysFreeString(bstr);
590 ITextRange_Release(range);
592 hres = ITextDocument_Range(txtDoc, 0, -1, &range);
593 ok(hres == S_OK, "got 0x%08x\n", hres);
594 hres = ITextRange_GetText(range, &bstr);
595 todo_wine
596 ok(hres == S_OK, "got 0x%08x\n", hres);
597 ok(!bstr, "got wrong text: %s\n", wine_dbgstr_w(bstr));
598 ITextRange_Release(range);
600 hres = ITextDocument_Range(txtDoc, -1, 9, &range);
601 ok(hres == S_OK, "got 0x%08x\n", hres);
602 hres = ITextRange_GetText(range, &bstr);
603 todo_wine {
604 ok(hres == S_OK, "got 0x%08x\n", hres);
605 ok(!lstrcmpW(bstr, bufW6), "got wrong text: %s\n", wine_dbgstr_w(bstr));
607 SysFreeString(bstr);
609 release_interfaces(&w, &reOle, &txtDoc, NULL);
611 /* detached selection/range */
612 if (is64bit) {
613 bstr = (void*)0xdeadbeef;
614 hres = ITextSelection_GetText(txtSel, &bstr);
615 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
616 todo_wine
617 ok(bstr == NULL, "got %p\n", bstr);
619 bstr = (void*)0xdeadbeef;
620 hres = ITextRange_GetText(range, &bstr);
621 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
622 todo_wine
623 ok(bstr == NULL, "got %p\n", bstr);
625 else {
626 hres = ITextSelection_GetText(txtSel, NULL);
627 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
629 hres = ITextRange_GetText(range, NULL);
630 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
633 ITextRange_Release(range);
634 ITextSelection_Release(txtSel);
637 static void test_ITextDocument_Range(void)
639 static const CHAR test_text1[] = "TestSomeText";
640 HWND w;
641 IRichEditOle *reOle = NULL;
642 ITextDocument *txtDoc = NULL;
643 ITextRange *txtRge, *range2;
644 HRESULT hres;
645 LONG value;
647 create_interfaces(&w, &reOle, &txtDoc, NULL);
648 hres = ITextDocument_Range(txtDoc, 0, 0, &txtRge);
649 ok(hres == S_OK, "ITextDocument_Range fails 0x%x.\n", hres);
650 EXPECT_REF(txtRge, 1);
652 hres = ITextDocument_Range(txtDoc, 0, 0, &range2);
653 ok(hres == S_OK, "ITextDocument_Range fails 0x%x.\n", hres);
654 ok(range2 != txtRge, "A new pointer should be returned\n");
655 ITextRange_Release(range2);
657 hres = ITextDocument_Range(txtDoc, 0, 0, NULL);
658 ok(hres == E_INVALIDARG, "ITextDocument_Range should fail 0x%x.\n", hres);
660 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
662 hres = ITextDocument_Range(txtDoc, 8, 30, &range2);
663 ok(hres == S_OK, "ITextDocument_Range fails 0x%x.\n", hres);
664 hres = ITextRange_GetStart(range2, &value);
665 ok(hres == S_OK, "got 0x%08x\n", hres);
666 ok(value == 8, "got %d\n", value);
668 hres = ITextRange_GetEnd(range2, &value);
669 ok(hres == S_OK, "got 0x%08x\n", hres);
670 ok(value == 13, "got %d\n", value);
671 ITextRange_Release(range2);
673 release_interfaces(&w, &reOle, &txtDoc, NULL);
674 hres = ITextRange_CanEdit(txtRge, NULL);
675 ok(hres == CO_E_RELEASED, "ITextRange after ITextDocument destroyed\n");
676 ITextRange_Release(txtRge);
679 static void test_ITextRange_GetChar(void)
681 HWND w;
682 IRichEditOle *reOle = NULL;
683 ITextDocument *txtDoc = NULL;
684 ITextRange *txtRge = NULL;
685 HRESULT hres;
686 LONG pch = 0xdeadbeef;
687 int first, lim;
688 static const CHAR test_text1[] = "TestSomeText";
690 first = 0, lim = 4;
691 create_interfaces(&w, &reOle, &txtDoc, NULL);
692 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
693 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
694 ok(hres == S_OK, "got 0x%08x\n", hres);
695 pch = 0xdeadbeef;
696 hres = ITextRange_GetChar(txtRge, &pch);
697 ok(hres == S_OK, "ITextRange_GetChar\n");
698 ok(pch == 'T', "got wrong char: %c\n", pch);
699 ITextRange_Release(txtRge);
700 release_interfaces(&w, &reOle, &txtDoc, NULL);
702 first = 0, lim = 0;
703 create_interfaces(&w, &reOle, &txtDoc, NULL);
704 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
705 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
706 ok(hres == S_OK, "got 0x%08x\n", hres);
707 pch = 0xdeadbeef;
708 hres = ITextRange_GetChar(txtRge, &pch);
709 ok(hres == S_OK, "ITextRange_GetChar\n");
710 ok(pch == 'T', "got wrong char: %c\n", pch);
711 ITextRange_Release(txtRge);
712 release_interfaces(&w, &reOle, &txtDoc, NULL);
714 first = 12, lim = 12;
715 create_interfaces(&w, &reOle, &txtDoc, NULL);
716 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
717 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
718 ok(hres == S_OK, "got 0x%08x\n", hres);
719 pch = 0xdeadbeef;
720 hres = ITextRange_GetChar(txtRge, &pch);
721 ok(hres == S_OK, "ITextRange_GetChar\n");
722 ok(pch == '\r', "got wrong char: %c\n", pch);
723 ITextRange_Release(txtRge);
724 release_interfaces(&w, &reOle, &txtDoc, NULL);
726 first = 13, lim = 13;
727 create_interfaces(&w, &reOle, &txtDoc, NULL);
728 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
729 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
730 ok(hres == S_OK, "got 0x%08x\n", hres);
731 pch = 0xdeadbeef;
732 hres = ITextRange_GetChar(txtRge, &pch);
733 ok(hres == S_OK, "ITextRange_GetChar\n");
734 ok(pch == '\r', "got wrong char: %c\n", pch);
735 ITextRange_Release(txtRge);
736 release_interfaces(&w, &reOle, &txtDoc, NULL);
738 create_interfaces(&w, &reOle, &txtDoc, NULL);
739 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
740 first = 12, lim = 12;
741 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
742 ok(hres == S_OK, "got 0x%08x\n", hres);
743 hres = ITextRange_GetChar(txtRge, NULL);
744 ok(hres == E_INVALIDARG, "ITextRange_GetChar\n");
745 ITextRange_Release(txtRge);
746 release_interfaces(&w, &reOle, &txtDoc, NULL);
749 static void test_ITextSelection_GetChar(void)
751 HWND w;
752 IRichEditOle *reOle = NULL;
753 ITextDocument *txtDoc = NULL;
754 ITextSelection *txtSel = NULL;
755 HRESULT hres;
756 LONG pch = 0xdeadbeef;
757 int first, lim;
758 static const CHAR test_text1[] = "TestSomeText";
760 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
761 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
763 first = 0, lim = 4;
764 SendMessageA(w, EM_SETSEL, first, lim);
765 pch = 0xdeadbeef;
766 hres = ITextSelection_GetChar(txtSel, &pch);
767 ok(hres == S_OK, "ITextSelection_GetChar\n");
768 ok(pch == 'T', "got wrong char: %c\n", pch);
770 first = 0, lim = 0;
771 SendMessageA(w, EM_SETSEL, first, lim);
772 pch = 0xdeadbeef;
773 hres = ITextSelection_GetChar(txtSel, &pch);
774 ok(hres == S_OK, "ITextSelection_GetChar\n");
775 ok(pch == 'T', "got wrong char: %c\n", pch);
777 first = 12, lim = 12;
778 SendMessageA(w, EM_SETSEL, first, lim);
779 pch = 0xdeadbeef;
780 hres = ITextSelection_GetChar(txtSel, &pch);
781 ok(hres == S_OK, "ITextSelection_GetChar\n");
782 ok(pch == '\r', "got wrong char: %c\n", pch);
784 first = 13, lim = 13;
785 SendMessageA(w, EM_SETSEL, first, lim);
786 pch = 0xdeadbeef;
787 hres = ITextSelection_GetChar(txtSel, &pch);
788 ok(hres == S_OK, "ITextSelection_GetChar\n");
789 ok(pch == '\r', "got wrong char: %c\n", pch);
791 hres = ITextSelection_GetChar(txtSel, NULL);
792 ok(hres == E_INVALIDARG, "ITextSelection_GetChar\n");
794 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
797 static void test_ITextRange_GetStart_GetEnd(void)
799 HWND w;
800 IRichEditOle *reOle = NULL;
801 ITextDocument *txtDoc = NULL;
802 ITextRange *txtRge = NULL;
803 HRESULT hres;
804 int first, lim, start, end;
805 static const CHAR test_text1[] = "TestSomeText";
807 create_interfaces(&w, &reOle, &txtDoc, NULL);
808 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
810 first = 1, lim = 6;
811 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
812 ok(hres == S_OK, "got 0x%08x\n", hres);
813 start = 0xdeadbeef;
814 hres = ITextRange_GetStart(txtRge, &start);
815 ok(hres == S_OK, "ITextRange_GetStart\n");
816 ok(start == 1, "got wrong start value: %d\n", start);
817 end = 0xdeadbeef;
818 hres = ITextRange_GetEnd(txtRge, &end);
819 ok(hres == S_OK, "ITextRange_GetEnd\n");
820 ok(end == 6, "got wrong end value: %d\n", end);
821 ITextRange_Release(txtRge);
823 first = 6, lim = 1;
824 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
825 ok(hres == S_OK, "got 0x%08x\n", hres);
826 start = 0xdeadbeef;
827 hres = ITextRange_GetStart(txtRge, &start);
828 ok(hres == S_OK, "ITextRange_GetStart\n");
829 ok(start == 1, "got wrong start value: %d\n", start);
830 end = 0xdeadbeef;
831 hres = ITextRange_GetEnd(txtRge, &end);
832 ok(hres == S_OK, "ITextRange_GetEnd\n");
833 ok(end == 6, "got wrong end value: %d\n", end);
834 ITextRange_Release(txtRge);
836 first = -1, lim = 13;
837 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
838 ok(hres == S_OK, "got 0x%08x\n", hres);
839 start = 0xdeadbeef;
840 hres = ITextRange_GetStart(txtRge, &start);
841 ok(hres == S_OK, "ITextRange_GetStart\n");
842 ok(start == 0, "got wrong start value: %d\n", start);
843 end = 0xdeadbeef;
844 hres = ITextRange_GetEnd(txtRge, &end);
845 ok(hres == S_OK, "ITextRange_GetEnd\n");
846 ok(end == 13, "got wrong end value: %d\n", end);
847 ITextRange_Release(txtRge);
849 first = 13, lim = 13;
850 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
851 ok(hres == S_OK, "got 0x%08x\n", hres);
852 start = 0xdeadbeef;
853 hres = ITextRange_GetStart(txtRge, &start);
854 ok(hres == S_OK, "ITextRange_GetStart\n");
855 ok(start == 12, "got wrong start value: %d\n", start);
856 end = 0xdeadbeef;
857 hres = ITextRange_GetEnd(txtRge, &end);
858 ok(hres == S_OK, "ITextRange_GetEnd\n");
859 ok(end == 12, "got wrong end value: %d\n", end);
861 /* SetStart */
862 hres = ITextRange_SetStart(txtRge, 0);
863 ok(hres == S_OK, "got 0x%08x\n", hres);
865 /* same value */
866 hres = ITextRange_SetStart(txtRge, 0);
867 ok(hres == S_FALSE, "got 0x%08x\n", hres);
869 hres = ITextRange_SetStart(txtRge, 1);
870 ok(hres == S_OK, "got 0x%08x\n", hres);
872 /* negative resets to 0, return value is S_FALSE when
873 position wasn't changed */
874 hres = ITextRange_SetStart(txtRge, -1);
875 ok(hres == S_OK, "got 0x%08x\n", hres);
877 hres = ITextRange_SetStart(txtRge, -1);
878 ok(hres == S_FALSE, "got 0x%08x\n", hres);
880 hres = ITextRange_SetStart(txtRge, 0);
881 ok(hres == S_FALSE, "got 0x%08x\n", hres);
883 start = -1;
884 hres = ITextRange_GetStart(txtRge, &start);
885 ok(hres == S_OK, "got 0x%08x\n", hres);
886 ok(start == 0, "got %d\n", start);
888 /* greater than initial end, but less than total char count */
889 hres = ITextRange_SetStart(txtRge, 1);
890 ok(hres == S_OK, "got 0x%08x\n", hres);
892 hres = ITextRange_SetEnd(txtRge, 3);
893 ok(hres == S_OK, "got 0x%08x\n", hres);
895 hres = ITextRange_SetStart(txtRge, 10);
896 ok(hres == S_OK, "got 0x%08x\n", hres);
898 start = 0;
899 hres = ITextRange_GetStart(txtRge, &start);
900 ok(hres == S_OK, "got 0x%08x\n", hres);
901 ok(start == 10, "got %d\n", start);
903 end = 0;
904 hres = ITextRange_GetEnd(txtRge, &end);
905 ok(hres == S_OK, "got 0x%08x\n", hres);
906 ok(end == 10, "got %d\n", end);
908 /* more that total text length */
909 hres = ITextRange_SetStart(txtRge, 50);
910 ok(hres == S_OK, "got 0x%08x\n", hres);
912 start = 0;
913 hres = ITextRange_GetStart(txtRge, &start);
914 ok(hres == S_OK, "got 0x%08x\n", hres);
915 ok(start == 12, "got %d\n", start);
917 end = 0;
918 hres = ITextRange_GetEnd(txtRge, &end);
919 ok(hres == S_OK, "got 0x%08x\n", hres);
920 ok(end == 12, "got %d\n", end);
922 /* SetEnd */
923 hres = ITextRange_SetStart(txtRge, 0);
924 ok(hres == S_OK, "got 0x%08x\n", hres);
926 /* same value */
927 hres = ITextRange_SetEnd(txtRge, 5);
928 ok(hres == S_OK, "got 0x%08x\n", hres);
930 hres = ITextRange_SetEnd(txtRge, 5);
931 ok(hres == S_FALSE, "got 0x%08x\n", hres);
933 /* negative resets to 0 */
934 hres = ITextRange_SetEnd(txtRge, -1);
935 ok(hres == S_OK, "got 0x%08x\n", hres);
937 end = -1;
938 hres = ITextRange_GetEnd(txtRge, &end);
939 ok(hres == S_OK, "got 0x%08x\n", hres);
940 ok(end == 0, "got %d\n", end);
942 start = -1;
943 hres = ITextRange_GetStart(txtRge, &start);
944 ok(hres == S_OK, "got 0x%08x\n", hres);
945 ok(start == 0, "got %d\n", start);
947 /* greater than initial end, but less than total char count */
948 hres = ITextRange_SetStart(txtRge, 3);
949 ok(hres == S_OK, "got 0x%08x\n", hres);
951 hres = ITextRange_SetEnd(txtRge, 1);
952 ok(hres == S_OK, "got 0x%08x\n", hres);
954 start = 0;
955 hres = ITextRange_GetStart(txtRge, &start);
956 ok(hres == S_OK, "got 0x%08x\n", hres);
957 ok(start == 1, "got %d\n", start);
959 end = 0;
960 hres = ITextRange_GetEnd(txtRge, &end);
961 ok(hres == S_OK, "got 0x%08x\n", hres);
962 ok(end == 1, "got %d\n", end);
964 /* more than total count */
965 hres = ITextRange_SetEnd(txtRge, 50);
966 ok(hres == S_OK, "got 0x%08x\n", hres);
968 start = 0;
969 hres = ITextRange_GetStart(txtRge, &start);
970 ok(hres == S_OK, "got 0x%08x\n", hres);
971 ok(start == 1, "got %d\n", start);
973 end = 0;
974 hres = ITextRange_GetEnd(txtRge, &end);
975 ok(hres == S_OK, "got 0x%08x\n", hres);
976 ok(end == 13, "got %d\n", end);
978 /* zero */
979 hres = ITextRange_SetEnd(txtRge, 0);
980 ok(hres == S_OK, "got 0x%08x\n", hres);
982 start = 0;
983 hres = ITextRange_GetStart(txtRge, &start);
984 ok(hres == S_OK, "got 0x%08x\n", hres);
985 ok(start == 0, "got %d\n", start);
987 end = 0;
988 hres = ITextRange_GetEnd(txtRge, &end);
989 ok(hres == S_OK, "got 0x%08x\n", hres);
990 ok(end == 0, "got %d\n", end);
992 release_interfaces(&w, &reOle, &txtDoc, NULL);
994 /* detached range */
995 hres = ITextRange_SetStart(txtRge, 0);
996 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
998 hres = ITextRange_SetEnd(txtRge, 3);
999 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1001 hres = ITextRange_GetStart(txtRge, &start);
1002 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1004 hres = ITextRange_GetStart(txtRge, NULL);
1005 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1007 hres = ITextRange_GetEnd(txtRge, &end);
1008 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1010 hres = ITextRange_GetEnd(txtRge, NULL);
1011 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1013 ITextRange_Release(txtRge);
1016 static void test_ITextSelection_GetStart_GetEnd(void)
1018 HWND w;
1019 IRichEditOle *reOle = NULL;
1020 ITextDocument *txtDoc = NULL;
1021 ITextSelection *txtSel = NULL;
1022 HRESULT hres;
1023 int first, lim, start, end;
1024 static const CHAR test_text1[] = "TestSomeText";
1026 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
1027 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
1029 first = 2, lim = 5;
1030 SendMessageA(w, EM_SETSEL, first, lim);
1031 start = 0xdeadbeef;
1032 hres = ITextSelection_GetStart(txtSel, &start);
1033 ok(hres == S_OK, "ITextSelection_GetStart\n");
1034 ok(start == 2, "got wrong start value: %d\n", start);
1035 end = 0xdeadbeef;
1036 hres = ITextSelection_GetEnd(txtSel, &end);
1037 ok(hres == S_OK, "ITextSelection_GetEnd\n");
1038 ok(end == 5, "got wrong end value: %d\n", end);
1040 first = 5, lim = 2;
1041 SendMessageA(w, EM_SETSEL, first, lim);
1042 start = 0xdeadbeef;
1043 hres = ITextSelection_GetStart(txtSel, &start);
1044 ok(hres == S_OK, "ITextSelection_GetStart\n");
1045 ok(start == 2, "got wrong start value: %d\n", start);
1046 end = 0xdeadbeef;
1047 hres = ITextSelection_GetEnd(txtSel, &end);
1048 ok(hres == S_OK, "ITextSelection_GetEnd\n");
1049 ok(end == 5, "got wrong end value: %d\n", end);
1051 first = 0, lim = -1;
1052 SendMessageA(w, EM_SETSEL, first, lim);
1053 start = 0xdeadbeef;
1054 hres = ITextSelection_GetStart(txtSel, &start);
1055 ok(hres == S_OK, "ITextSelection_GetStart\n");
1056 ok(start == 0, "got wrong start value: %d\n", start);
1057 end = 0xdeadbeef;
1058 hres = ITextSelection_GetEnd(txtSel, &end);
1059 ok(hres == S_OK, "ITextSelection_GetEnd\n");
1060 ok(end == 13, "got wrong end value: %d\n", end);
1062 first = 13, lim = 13;
1063 SendMessageA(w, EM_SETSEL, first, lim);
1064 start = 0xdeadbeef;
1065 hres = ITextSelection_GetStart(txtSel, &start);
1066 ok(hres == S_OK, "ITextSelection_GetStart\n");
1067 ok(start == 12, "got wrong start value: %d\n", start);
1068 end = 0xdeadbeef;
1069 hres = ITextSelection_GetEnd(txtSel, &end);
1070 ok(hres == S_OK, "ITextSelection_GetEnd\n");
1071 ok(end == 12, "got wrong end value: %d\n", end);
1073 /* SetStart/SetEnd */
1074 hres = ITextSelection_SetStart(txtSel, 0);
1075 ok(hres == S_OK, "got 0x%08x\n", hres);
1077 /* same value */
1078 hres = ITextSelection_SetStart(txtSel, 0);
1079 ok(hres == S_FALSE, "got 0x%08x\n", hres);
1081 hres = ITextSelection_SetStart(txtSel, 1);
1082 ok(hres == S_OK, "got 0x%08x\n", hres);
1084 /* negative resets to 0, return value is S_FALSE when
1085 position wasn't changed */
1086 hres = ITextSelection_SetStart(txtSel, -1);
1087 ok(hres == S_OK, "got 0x%08x\n", hres);
1089 hres = ITextSelection_SetStart(txtSel, -1);
1090 ok(hres == S_FALSE, "got 0x%08x\n", hres);
1092 hres = ITextSelection_SetStart(txtSel, 0);
1093 ok(hres == S_FALSE, "got 0x%08x\n", hres);
1095 start = -1;
1096 hres = ITextSelection_GetStart(txtSel, &start);
1097 ok(hres == S_OK, "got 0x%08x\n", hres);
1098 ok(start == 0, "got %d\n", start);
1100 /* greater than initial end, but less than total char count */
1101 hres = ITextSelection_SetStart(txtSel, 1);
1102 ok(hres == S_OK, "got 0x%08x\n", hres);
1104 hres = ITextSelection_SetEnd(txtSel, 3);
1105 ok(hres == S_OK, "got 0x%08x\n", hres);
1107 hres = ITextSelection_SetStart(txtSel, 10);
1108 ok(hres == S_OK, "got 0x%08x\n", hres);
1110 start = 0;
1111 hres = ITextSelection_GetStart(txtSel, &start);
1112 ok(hres == S_OK, "got 0x%08x\n", hres);
1113 ok(start == 10, "got %d\n", start);
1115 end = 0;
1116 hres = ITextSelection_GetEnd(txtSel, &end);
1117 ok(hres == S_OK, "got 0x%08x\n", hres);
1118 ok(end == 10, "got %d\n", end);
1120 /* more that total text length */
1121 hres = ITextSelection_SetStart(txtSel, 50);
1122 ok(hres == S_OK, "got 0x%08x\n", hres);
1124 start = 0;
1125 hres = ITextSelection_GetStart(txtSel, &start);
1126 ok(hres == S_OK, "got 0x%08x\n", hres);
1127 ok(start == 12, "got %d\n", start);
1129 end = 0;
1130 hres = ITextSelection_GetEnd(txtSel, &end);
1131 ok(hres == S_OK, "got 0x%08x\n", hres);
1132 ok(end == 12, "got %d\n", end);
1134 /* SetEnd */
1135 hres = ITextSelection_SetStart(txtSel, 0);
1136 ok(hres == S_OK, "got 0x%08x\n", hres);
1138 /* same value */
1139 hres = ITextSelection_SetEnd(txtSel, 5);
1140 ok(hres == S_OK, "got 0x%08x\n", hres);
1142 hres = ITextSelection_SetEnd(txtSel, 5);
1143 ok(hres == S_FALSE, "got 0x%08x\n", hres);
1145 /* negative resets to 0 */
1146 hres = ITextSelection_SetEnd(txtSel, -1);
1147 ok(hres == S_OK, "got 0x%08x\n", hres);
1149 end = -1;
1150 hres = ITextSelection_GetEnd(txtSel, &end);
1151 ok(hres == S_OK, "got 0x%08x\n", hres);
1152 ok(end == 0, "got %d\n", end);
1154 start = -1;
1155 hres = ITextSelection_GetStart(txtSel, &start);
1156 ok(hres == S_OK, "got 0x%08x\n", hres);
1157 ok(start == 0, "got %d\n", start);
1159 /* greater than initial end, but less than total char count */
1160 hres = ITextSelection_SetStart(txtSel, 3);
1161 ok(hres == S_OK, "got 0x%08x\n", hres);
1163 hres = ITextSelection_SetEnd(txtSel, 1);
1164 ok(hres == S_OK, "got 0x%08x\n", hres);
1166 start = 0;
1167 hres = ITextSelection_GetStart(txtSel, &start);
1168 ok(hres == S_OK, "got 0x%08x\n", hres);
1169 ok(start == 1, "got %d\n", start);
1171 end = 0;
1172 hres = ITextSelection_GetEnd(txtSel, &end);
1173 ok(hres == S_OK, "got 0x%08x\n", hres);
1174 ok(end == 1, "got %d\n", end);
1176 /* more than total count */
1177 hres = ITextSelection_SetEnd(txtSel, 50);
1178 ok(hres == S_OK, "got 0x%08x\n", hres);
1180 start = 0;
1181 hres = ITextSelection_GetStart(txtSel, &start);
1182 ok(hres == S_OK, "got 0x%08x\n", hres);
1183 ok(start == 1, "got %d\n", start);
1185 end = 0;
1186 hres = ITextSelection_GetEnd(txtSel, &end);
1187 ok(hres == S_OK, "got 0x%08x\n", hres);
1188 ok(end == 13, "got %d\n", end);
1190 /* zero */
1191 hres = ITextSelection_SetEnd(txtSel, 0);
1192 ok(hres == S_OK, "got 0x%08x\n", hres);
1194 start = 0;
1195 hres = ITextSelection_GetStart(txtSel, &start);
1196 ok(hres == S_OK, "got 0x%08x\n", hres);
1197 ok(start == 0, "got %d\n", start);
1199 end = 0;
1200 hres = ITextSelection_GetEnd(txtSel, &end);
1201 ok(hres == S_OK, "got 0x%08x\n", hres);
1202 ok(end == 0, "got %d\n", end);
1204 release_interfaces(&w, &reOle, &txtDoc, NULL);
1206 /* detached selection */
1207 hres = ITextSelection_GetStart(txtSel, NULL);
1208 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1210 hres = ITextSelection_GetStart(txtSel, &start);
1211 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1213 hres = ITextSelection_GetEnd(txtSel, NULL);
1214 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1216 hres = ITextSelection_GetEnd(txtSel, &end);
1217 ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres);
1219 ITextSelection_Release(txtSel);
1222 static void test_ITextRange_GetDuplicate(void)
1224 HWND w;
1225 IRichEditOle *reOle = NULL;
1226 ITextDocument *txtDoc = NULL;
1227 ITextRange *txtRge = NULL;
1228 ITextRange *txtRgeDup = NULL;
1229 HRESULT hres;
1230 LONG first, lim, start, end;
1231 static const CHAR test_text1[] = "TestSomeText";
1233 create_interfaces(&w, &reOle, &txtDoc, NULL);
1234 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
1235 first = 0, lim = 4;
1236 hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
1237 ok(hres == S_OK, "ITextDocument_Range fails 0x%x.\n", hres);
1239 hres = ITextRange_GetDuplicate(txtRge, &txtRgeDup);
1240 ok(hres == S_OK, "ITextRange_GetDuplicate\n");
1241 ok(txtRgeDup != txtRge, "A new pointer should be returned\n");
1242 ITextRange_GetStart(txtRgeDup, &start);
1243 ok(start == first, "got wrong value: %d\n", start);
1244 ITextRange_GetEnd(txtRgeDup, &end);
1245 ok(end == lim, "got wrong value: %d\n", end);
1247 ITextRange_Release(txtRgeDup);
1249 hres = ITextRange_GetDuplicate(txtRge, NULL);
1250 ok(hres == E_INVALIDARG, "ITextRange_GetDuplicate\n");
1252 ITextRange_Release(txtRge);
1253 release_interfaces(&w, &reOle, &txtDoc, NULL);
1256 static void test_ITextRange_Collapse(void)
1258 HWND w;
1259 IRichEditOle *reOle = NULL;
1260 ITextDocument *txtDoc = NULL;
1261 ITextRange *txtRge = NULL;
1262 HRESULT hres;
1263 LONG first, lim, start, end;
1264 static const CHAR test_text1[] = "TestSomeText";
1266 create_interfaces(&w, &reOle, &txtDoc, NULL);
1267 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
1269 first = 4, lim = 8;
1270 ITextDocument_Range(txtDoc, first, lim, &txtRge);
1271 hres = ITextRange_Collapse(txtRge, tomTrue);
1272 ok(hres == S_OK, "ITextRange_Collapse\n");
1273 ITextRange_GetStart(txtRge, &start);
1274 ok(start == 4, "got wrong start value: %d\n", start);
1275 ITextRange_GetEnd(txtRge, &end);
1276 ok(end == 4, "got wrong end value: %d\n", end);
1277 ITextRange_Release(txtRge);
1279 ITextDocument_Range(txtDoc, first, lim, &txtRge);
1280 hres = ITextRange_Collapse(txtRge, tomStart);
1281 ok(hres == S_OK, "ITextRange_Collapse\n");
1282 ITextRange_GetStart(txtRge, &start);
1283 ok(start == 4, "got wrong start value: %d\n", start);
1284 ITextRange_GetEnd(txtRge, &end);
1285 ok(end == 4, "got wrong end value: %d\n", end);
1286 ITextRange_Release(txtRge);
1288 ITextDocument_Range(txtDoc, first, lim, &txtRge);
1289 hres = ITextRange_Collapse(txtRge, tomFalse);
1290 ok(hres == S_OK, "ITextRange_Collapse\n");
1291 ITextRange_GetStart(txtRge, &start);
1292 ok(start == 8, "got wrong start value: %d\n", start);
1293 ITextRange_GetEnd(txtRge, &end);
1294 ok(end == 8, "got wrong end value: %d\n", end);
1295 ITextRange_Release(txtRge);
1297 ITextDocument_Range(txtDoc, first, lim, &txtRge);
1298 hres = ITextRange_Collapse(txtRge, tomEnd);
1299 ok(hres == S_OK, "ITextRange_Collapse\n");
1300 ITextRange_GetStart(txtRge, &start);
1301 ok(start == 8, "got wrong start value: %d\n", start);
1302 ITextRange_GetEnd(txtRge, &end);
1303 ok(end == 8, "got wrong end value: %d\n", end);
1304 ITextRange_Release(txtRge);
1306 /* tomStart is the default */
1307 ITextDocument_Range(txtDoc, first, lim, &txtRge);
1308 hres = ITextRange_Collapse(txtRge, 256);
1309 ok(hres == S_OK, "ITextRange_Collapse\n");
1310 ITextRange_GetStart(txtRge, &start);
1311 ok(start == 4, "got wrong start value: %d\n", start);
1312 ITextRange_GetEnd(txtRge, &end);
1313 ok(end == 4, "got wrong end value: %d\n", end);
1314 ITextRange_Release(txtRge);
1316 first = 6, lim = 6;
1317 ITextDocument_Range(txtDoc, first, lim, &txtRge);
1318 hres = ITextRange_Collapse(txtRge, tomEnd);
1319 ok(hres == S_FALSE, "ITextRange_Collapse\n");
1320 ITextRange_GetStart(txtRge, &start);
1321 ok(start == 6, "got wrong start value: %d\n", start);
1322 ITextRange_GetEnd(txtRge, &end);
1323 ok(end == 6, "got wrong end value: %d\n", end);
1324 ITextRange_Release(txtRge);
1326 first = 8, lim = 8;
1327 ITextDocument_Range(txtDoc, first, lim, &txtRge);
1328 hres = ITextRange_Collapse(txtRge, tomStart);
1329 ok(hres == S_FALSE, "ITextRange_Collapse\n");
1330 ITextRange_GetStart(txtRge, &start);
1331 ok(start == 8, "got wrong start value: %d\n", start);
1332 ITextRange_GetEnd(txtRge, &end);
1333 ok(end == 8, "got wrong end value: %d\n", end);
1334 ITextRange_Release(txtRge);
1336 release_interfaces(&w, &reOle, &txtDoc, NULL);
1339 static void test_ITextSelection_Collapse(void)
1341 HWND w;
1342 IRichEditOle *reOle = NULL;
1343 ITextDocument *txtDoc = NULL;
1344 ITextSelection *txtSel = NULL;
1345 HRESULT hres;
1346 LONG first, lim, start, end;
1347 static const CHAR test_text1[] = "TestSomeText";
1349 create_interfaces(&w, &reOle, &txtDoc, &txtSel);
1350 SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
1352 first = 4, lim = 8;
1353 SendMessageA(w, EM_SETSEL, first, lim);
1354 hres = ITextSelection_Collapse(txtSel, tomTrue);
1355 ok(hres == S_OK, "ITextSelection_Collapse\n");
1356 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1357 ok(start == 4, "got wrong start value: %d\n", start);
1358 ok(end == 4, "got wrong end value: %d\n", end);
1360 SendMessageA(w, EM_SETSEL, first, lim);
1361 hres = ITextSelection_Collapse(txtSel, tomStart);
1362 ok(hres == S_OK, "ITextSelection_Collapse\n");
1363 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1364 ok(start == 4, "got wrong start value: %d\n", start);
1365 ok(end == 4, "got wrong end value: %d\n", end);
1367 SendMessageA(w, EM_SETSEL, first, lim);
1368 hres = ITextSelection_Collapse(txtSel, tomFalse);
1369 ok(hres == S_OK, "ITextSelection_Collapse\n");
1370 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1371 ok(start == 8, "got wrong start value: %d\n", start);
1372 ok(end == 8, "got wrong end value: %d\n", end);
1374 SendMessageA(w, EM_SETSEL, first, lim);
1375 hres = ITextSelection_Collapse(txtSel, tomEnd);
1376 ok(hres == S_OK, "ITextSelection_Collapse\n");
1377 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1378 ok(start == 8, "got wrong start value: %d\n", start);
1379 ok(end == 8, "got wrong end value: %d\n", end);
1381 /* tomStart is the default */
1382 SendMessageA(w, EM_SETSEL, first, lim);
1383 hres = ITextSelection_Collapse(txtSel, 256);
1384 ok(hres == S_OK, "ITextSelection_Collapse\n");
1385 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1386 ok(start == 4, "got wrong start value: %d\n", start);
1387 ok(end == 4, "got wrong end value: %d\n", end);
1389 first = 6, lim = 6;
1390 SendMessageA(w, EM_SETSEL, first, lim);
1391 hres = ITextSelection_Collapse(txtSel, tomEnd);
1392 ok(hres == S_FALSE, "ITextSelection_Collapse\n");
1393 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1394 ok(start == 6, "got wrong start value: %d\n", start);
1395 ok(end == 6, "got wrong end value: %d\n", end);
1397 first = 8, lim = 8;
1398 SendMessageA(w, EM_SETSEL, first, lim);
1399 hres = ITextSelection_Collapse(txtSel, tomStart);
1400 ok(hres == S_FALSE, "ITextSelection_Collapse\n");
1401 SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end);
1402 ok(start == 8, "got wrong start value: %d\n", start);
1403 ok(end == 8, "got wrong end value: %d\n", end);
1405 release_interfaces(&w, &reOle, &txtDoc, &txtSel);
1408 static void test_IOleClientSite_QueryInterface(void)
1410 HWND w;
1411 IRichEditOle *reOle = NULL, *reOle1 = NULL;
1412 ITextDocument *txtDoc = NULL;
1413 IOleClientSite *clientSite = NULL, *clientSite1 = NULL, *clientSite2 = NULL;
1414 IOleWindow *oleWin = NULL, *oleWin1 = NULL;
1415 IOleInPlaceSite *olePlace = NULL, *olePlace1 = NULL;
1416 HRESULT hres;
1417 LONG refcount1, refcount2;
1419 create_interfaces(&w, &reOle, &txtDoc, NULL);
1420 hres = IRichEditOle_GetClientSite(reOle, &clientSite);
1421 ok(hres == S_OK, "IRichEditOle_QueryInterface: 0x%08x\n", hres);
1422 refcount1 = get_refcount((IUnknown *)clientSite);
1423 todo_wine ok(refcount1 == 1, "got wrong ref count: %d\n", refcount1);
1425 hres = IOleClientSite_QueryInterface(clientSite, &IID_IRichEditOle, (void **)&reOle1);
1426 ok(hres == E_NOINTERFACE, "IOleClientSite_QueryInterface: %x\n", hres);
1428 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleClientSite, (void **)&clientSite1);
1429 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1430 ok(clientSite == clientSite1, "Should not return a new pointer.\n");
1431 refcount1 = get_refcount((IUnknown *)clientSite);
1432 todo_wine ok(refcount1 == 2, "got wrong ref count: %d\n", refcount1);
1434 /* IOleWindow interface */
1435 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleWindow, (void **)&oleWin);
1436 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1437 refcount1 = get_refcount((IUnknown *)clientSite);
1438 refcount2 = get_refcount((IUnknown *)oleWin);
1439 ok(refcount1 == refcount2, "got wrong ref count.\n");
1441 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleWindow, (void **)&oleWin1);
1442 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1443 ok(oleWin == oleWin1, "Should not return a new pointer.\n");
1444 refcount1 = get_refcount((IUnknown *)clientSite);
1445 refcount2 = get_refcount((IUnknown *)oleWin);
1446 ok(refcount1 == refcount2, "got wrong ref count.\n");
1448 hres = IOleWindow_QueryInterface(oleWin, &IID_IOleClientSite, (void **)&clientSite2);
1449 ok(hres == S_OK, "IOleWindow_QueryInterface: 0x%08x\n", hres);
1450 ok(clientSite2 == clientSite1, "got wrong pointer\n");
1452 /* IOleInPlaceSite interface */
1453 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleInPlaceSite, (void **)&olePlace);
1454 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1455 refcount1 = get_refcount((IUnknown *)olePlace);
1456 refcount2 = get_refcount((IUnknown *)clientSite);
1457 ok(refcount1 == refcount2, "got wrong ref count.\n");
1459 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleInPlaceSite, (void **)&olePlace1);
1460 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1461 ok(olePlace == olePlace1, "Should not return a new pointer.\n");
1462 IOleInPlaceSite_Release(olePlace1);
1464 hres = IOleWindow_QueryInterface(oleWin, &IID_IOleInPlaceSite, (void **)&olePlace1);
1465 ok(hres == S_OK, "IOleWindow_QueryInterface: 0x%08x\n", hres);
1466 refcount1 = get_refcount((IUnknown *)olePlace1);
1467 refcount2 = get_refcount((IUnknown *)oleWin);
1468 ok(refcount1 == refcount2, "got wrong ref count.\n");
1470 IOleInPlaceSite_Release(olePlace1);
1471 IOleInPlaceSite_Release(olePlace);
1472 IOleWindow_Release(oleWin1);
1473 IOleWindow_Release(oleWin);
1474 IOleClientSite_Release(clientSite2);
1475 IOleClientSite_Release(clientSite1);
1476 IOleClientSite_Release(clientSite);
1477 release_interfaces(&w, &reOle, &txtDoc, NULL);
1480 static void test_IOleWindow_GetWindow(void)
1482 HWND w;
1483 IRichEditOle *reOle = NULL;
1484 ITextDocument *txtDoc = NULL;
1485 IOleClientSite *clientSite = NULL;
1486 IOleWindow *oleWin = NULL;
1487 HRESULT hres;
1488 HWND hwnd;
1490 create_interfaces(&w, &reOle, &txtDoc, NULL);
1491 hres = IRichEditOle_GetClientSite(reOle, &clientSite);
1492 ok(hres == S_OK, "IRichEditOle_QueryInterface: 0x%08x\n", hres);
1494 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleWindow, (void **)&oleWin);
1495 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1496 hres = IOleWindow_GetWindow(oleWin, &hwnd);
1497 ok(hres == S_OK, "IOleClientSite_GetWindow: 0x%08x\n", hres);
1498 ok(w == hwnd, "got wrong pointer\n");
1500 hres = IOleWindow_GetWindow(oleWin, NULL);
1501 ok(hres == E_INVALIDARG, "IOleClientSite_GetWindow: 0x%08x\n", hres);
1503 IOleWindow_Release(oleWin);
1504 IOleClientSite_Release(clientSite);
1505 release_interfaces(&w, &reOle, &txtDoc, NULL);
1508 static void test_IOleInPlaceSite_GetWindow(void)
1510 HWND w;
1511 IRichEditOle *reOle = NULL;
1512 ITextDocument *txtDoc = NULL;
1513 IOleClientSite *clientSite = NULL;
1514 IOleInPlaceSite *olePlace = NULL;
1515 HRESULT hres;
1516 HWND hwnd;
1518 create_interfaces(&w, &reOle, &txtDoc, NULL);
1519 hres = IRichEditOle_GetClientSite(reOle, &clientSite);
1520 ok(hres == S_OK, "IRichEditOle_QueryInterface: 0x%08x\n", hres);
1522 hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleInPlaceSite, (void **)&olePlace);
1523 ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
1524 hres = IOleInPlaceSite_GetWindow(olePlace, &hwnd);
1525 ok(hres == S_OK, "IOleInPlaceSite_GetWindow: 0x%08x\n", hres);
1526 ok(w == hwnd, "got wrong pointer.\n");
1528 hres = IOleInPlaceSite_GetWindow(olePlace, NULL);
1529 ok(hres == E_INVALIDARG, "IOleInPlaceSite_GetWindow: 0x%08x\n", hres);
1531 IOleInPlaceSite_Release(olePlace);
1532 IOleClientSite_Release(clientSite);
1533 release_interfaces(&w, &reOle, &txtDoc, NULL);
1536 static void test_GetFont(void)
1538 static const CHAR test_text1[] = "TestSomeText";
1539 IRichEditOle *reOle = NULL;
1540 ITextDocument *doc = NULL;
1541 ITextRange *range = NULL;
1542 ITextSelection *selection;
1543 ITextFont *font, *font2;
1544 CHARFORMAT2A cf;
1545 LONG value;
1546 float size;
1547 HRESULT hr;
1548 HWND hwnd;
1549 BOOL ret;
1551 create_interfaces(&hwnd, &reOle, &doc, NULL);
1552 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
1554 hr = ITextDocument_GetSelection(doc, &selection);
1555 ok(hr == S_OK, "got 0x%08x\n", hr);
1556 hr = ITextSelection_GetFont(selection, &font);
1557 ok(hr == S_OK, "got 0x%08x\n", hr);
1558 hr = ITextSelection_GetFont(selection, &font2);
1559 ok(hr == S_OK, "got 0x%08x\n", hr);
1560 ok(font != font2, "got %p, %p\n", font, font2);
1561 ITextFont_Release(font2);
1562 ITextFont_Release(font);
1563 ITextSelection_Release(selection);
1565 EXPECT_REF(reOle, 3);
1566 EXPECT_REF(doc, 3);
1568 hr = ITextDocument_Range(doc, 0, 4, &range);
1569 ok(hr == S_OK, "got 0x%08x\n", hr);
1571 EXPECT_REF(reOle, 3);
1572 EXPECT_REF(doc, 3);
1573 EXPECT_REF(range, 1);
1575 hr = ITextRange_GetFont(range, NULL);
1576 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1578 hr = ITextRange_GetFont(range, &font);
1579 ok(hr == S_OK, "got 0x%08x\n", hr);
1581 EXPECT_REF(reOle, 3);
1582 EXPECT_REF(doc, 3);
1583 EXPECT_REF(range, 2);
1584 EXPECT_REF(font, 1);
1586 hr = ITextRange_GetFont(range, &font2);
1587 ok(hr == S_OK, "got 0x%08x\n", hr);
1588 ok(font != font2, "got %p, %p\n", font, font2);
1590 EXPECT_REF(reOle, 3);
1591 EXPECT_REF(doc, 3);
1592 EXPECT_REF(range, 3);
1593 EXPECT_REF(font, 1);
1594 EXPECT_REF(font2, 1);
1596 ITextFont_Release(font2);
1598 /* set different font style within a range */
1599 hr = ITextFont_GetItalic(font, NULL);
1600 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1602 hr = ITextFont_GetSize(font, NULL);
1603 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1605 size = 0.0;
1606 hr = ITextFont_GetSize(font, &size);
1607 ok(hr == S_OK, "got 0x%08x\n", hr);
1608 ok(size > 0.0, "size %.2f\n", size);
1610 value = 0;
1611 hr = ITextFont_GetLanguageID(font, &value);
1612 ok(hr == S_OK, "got 0x%08x\n", hr);
1613 todo_wine
1614 ok(value == GetSystemDefaultLCID(), "got lcid %x, user lcid %x\n", value,
1615 GetSystemDefaultLCID());
1617 /* range is non-italic */
1618 value = tomTrue;
1619 hr = ITextFont_GetItalic(font, &value);
1620 ok(hr == S_OK, "got 0x%08x\n", hr);
1621 ok(value == tomFalse, "got %d\n", value);
1623 cf.cbSize = sizeof(CHARFORMAT2A);
1624 cf.dwMask = CFM_ITALIC|CFM_SIZE;
1625 cf.dwEffects = CFE_ITALIC;
1626 cf.yHeight = 24.0;
1628 SendMessageA(hwnd, EM_SETSEL, 2, 3);
1629 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
1630 ok(ret, "got %d\n", ret);
1632 /* now range is partially italicized */
1633 value = tomFalse;
1634 hr = ITextFont_GetItalic(font, &value);
1635 ok(hr == S_OK, "got 0x%08x\n", hr);
1636 ok(value == tomUndefined, "got %d\n", value);
1638 size = 0.0;
1639 hr = ITextFont_GetSize(font, &size);
1640 ok(hr == S_OK, "got 0x%08x\n", hr);
1641 ok(size == tomUndefined, "size %.2f\n", size);
1643 ITextFont_Release(font);
1644 ITextRange_Release(range);
1645 release_interfaces(&hwnd, &reOle, &doc, NULL);
1648 static void test_GetPara(void)
1650 static const CHAR test_text1[] = "TestSomeText";
1651 IRichEditOle *reOle = NULL;
1652 ITextDocument *doc = NULL;
1653 ITextRange *range = NULL;
1654 ITextPara *para, *para2;
1655 HRESULT hr;
1656 HWND hwnd;
1658 create_interfaces(&hwnd, &reOle, &doc, NULL);
1659 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
1661 EXPECT_REF(reOle, 3);
1662 EXPECT_REF(doc, 3);
1664 hr = ITextDocument_Range(doc, 0, 4, &range);
1665 ok(hr == S_OK, "got 0x%08x\n", hr);
1667 EXPECT_REF(reOle, 3);
1668 EXPECT_REF(doc, 3);
1669 EXPECT_REF(range, 1);
1671 hr = ITextRange_GetPara(range, NULL);
1672 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1674 hr = ITextRange_GetPara(range, &para);
1675 ok(hr == S_OK, "got 0x%08x\n", hr);
1677 EXPECT_REF(reOle, 3);
1678 EXPECT_REF(doc, 3);
1679 EXPECT_REF(range, 2);
1680 EXPECT_REF(para, 1);
1682 hr = ITextRange_GetPara(range, &para2);
1683 ok(hr == S_OK, "got 0x%08x\n", hr);
1684 ok(para != para2, "got %p, %p\n", para, para2);
1686 EXPECT_REF(reOle, 3);
1687 EXPECT_REF(doc, 3);
1688 EXPECT_REF(range, 3);
1689 EXPECT_REF(para, 1);
1690 EXPECT_REF(para2, 1);
1692 ITextPara_Release(para);
1693 ITextPara_Release(para2);
1694 ITextRange_Release(range);
1695 release_interfaces(&hwnd, &reOle, &doc, NULL);
1698 static void test_dispatch(void)
1700 static const WCHAR testnameW[] = {'G','e','t','T','e','x','t',0};
1701 static const WCHAR testname2W[] = {'T','e','x','t',0};
1702 IRichEditOle *reOle = NULL;
1703 ITextDocument *doc = NULL;
1704 ITextRange *range = NULL;
1705 WCHAR *nameW;
1706 DISPID dispid;
1707 HRESULT hr;
1708 UINT count;
1709 HWND hwnd;
1711 create_interfaces(&hwnd, &reOle, &doc, NULL);
1713 range = NULL;
1714 hr = ITextDocument_Range(doc, 0, 0, &range);
1715 ok(hr == S_OK, "got 0x%08x\n", hr);
1716 ok(range != NULL, "got %p\n", range);
1718 dispid = 123;
1719 nameW = (WCHAR*)testnameW;
1720 hr = ITextRange_GetIDsOfNames(range, &IID_NULL, &nameW, 1, LOCALE_USER_DEFAULT, &dispid);
1721 ok(hr == DISP_E_UNKNOWNNAME, "got 0x%08x\n", hr);
1722 ok(dispid == DISPID_UNKNOWN, "got %d\n", dispid);
1724 dispid = 123;
1725 nameW = (WCHAR*)testname2W;
1726 hr = ITextRange_GetIDsOfNames(range, &IID_NULL, &nameW, 1, LOCALE_USER_DEFAULT, &dispid);
1727 ok(hr == S_OK, "got 0x%08x\n", hr);
1728 ok(dispid == DISPID_VALUE, "got %d\n", dispid);
1730 release_interfaces(&hwnd, &reOle, &doc, NULL);
1732 /* try dispatch methods on detached range */
1733 hr = ITextRange_GetTypeInfoCount(range, &count);
1734 ok(hr == S_OK, "got 0x%08x\n", hr);
1736 dispid = 123;
1737 nameW = (WCHAR*)testname2W;
1738 hr = ITextRange_GetIDsOfNames(range, &IID_NULL, &nameW, 1, LOCALE_USER_DEFAULT, &dispid);
1739 ok(hr == S_OK, "got 0x%08x\n", hr);
1740 ok(dispid == DISPID_VALUE, "got %d\n", dispid);
1742 ITextRange_Release(range);
1745 static void test_detached_font_getters(ITextFont *font, BOOL duplicate)
1747 HRESULT hr, hrexp = duplicate ? S_OK : CO_E_RELEASED;
1748 LONG value;
1749 float size;
1750 BSTR str;
1752 hr = ITextFont_GetBold(font, NULL);
1753 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1755 hr = ITextFont_GetBold(font, &value);
1756 ok(hr == hrexp, "got 0x%08x\n", hr);
1758 hr = ITextFont_GetForeColor(font, NULL);
1759 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1761 hr = ITextFont_GetForeColor(font, &value);
1762 ok(hr == hrexp, "got 0x%08x\n", hr);
1764 hr = ITextFont_GetItalic(font, NULL);
1765 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1767 hr = ITextFont_GetItalic(font, &value);
1768 ok(hr == hrexp, "got 0x%08x\n", hr);
1770 hr = ITextFont_GetLanguageID(font, NULL);
1771 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1773 hr = ITextFont_GetLanguageID(font, &value);
1774 ok(hr == hrexp, "got 0x%08x\n", hr);
1776 hr = ITextFont_GetName(font, NULL);
1777 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1779 hr = ITextFont_GetName(font, &str);
1780 ok(hr == hrexp, "got 0x%08x\n", hr);
1782 hr = ITextFont_GetSize(font, NULL);
1783 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1785 hr = ITextFont_GetSize(font, &size);
1786 ok(hr == hrexp, "got 0x%08x\n", hr);
1788 hr = ITextFont_GetStrikeThrough(font, NULL);
1789 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1791 hr = ITextFont_GetStrikeThrough(font, &value);
1792 ok(hr == hrexp, "got 0x%08x\n", hr);
1794 hr = ITextFont_GetSubscript(font, NULL);
1795 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1797 hr = ITextFont_GetSubscript(font, &value);
1798 ok(hr == hrexp, "got 0x%08x\n", hr);
1800 hr = ITextFont_GetSuperscript(font, NULL);
1801 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1803 hr = ITextFont_GetSuperscript(font, &value);
1804 ok(hr == hrexp, "got 0x%08x\n", hr);
1806 hr = ITextFont_GetUnderline(font, NULL);
1807 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1809 hr = ITextFont_GetUnderline(font, &value);
1810 ok(hr == hrexp, "got 0x%08x\n", hr);
1813 static void test_textfont_global_defaults(ITextFont *font)
1815 float valuef;
1816 LONG value;
1817 HRESULT hr;
1818 BSTR str;
1820 value = tomUndefined;
1821 hr = ITextFont_GetAllCaps(font, &value);
1822 ok(hr == S_OK, "got 0x%08x\n", hr);
1823 ok(value == tomFalse, "got %d\n", value);
1825 value = tomUndefined;
1826 hr = ITextFont_GetAnimation(font, &value);
1827 ok(hr == S_OK, "got 0x%08x\n", hr);
1828 ok(value == tomFalse, "got %d\n", value);
1830 value = tomUndefined;
1831 hr = ITextFont_GetBackColor(font, &value);
1832 ok(hr == S_OK, "got 0x%08x\n", hr);
1833 ok(value == tomAutoColor, "got %d\n", value);
1835 value = tomUndefined;
1836 hr = ITextFont_GetBold(font, &value);
1837 ok(hr == S_OK, "got 0x%08x\n", hr);
1838 ok(value == tomFalse || value == tomTrue, "got %d\n", value);
1840 value = tomUndefined;
1841 hr = ITextFont_GetEmboss(font, &value);
1842 ok(hr == S_OK, "got 0x%08x\n", hr);
1843 ok(value == tomFalse, "got %d\n", value);
1845 value = tomUndefined;
1846 hr = ITextFont_GetForeColor(font, &value);
1847 ok(hr == S_OK, "got 0x%08x\n", hr);
1848 ok(value == tomAutoColor, "got %d\n", value);
1850 value = tomUndefined;
1851 hr = ITextFont_GetHidden(font, &value);
1852 ok(hr == S_OK, "got 0x%08x\n", hr);
1853 ok(value == tomFalse, "got %d\n", value);
1855 value = tomUndefined;
1856 hr = ITextFont_GetEngrave(font, &value);
1857 ok(hr == S_OK, "got 0x%08x\n", hr);
1858 ok(value == tomFalse, "got %d\n", value);
1860 value = tomUndefined;
1861 hr = ITextFont_GetItalic(font, &value);
1862 ok(hr == S_OK, "got 0x%08x\n", hr);
1863 ok(value == tomFalse, "got %d\n", value);
1865 valuef = 1.0;
1866 hr = ITextFont_GetKerning(font, &valuef);
1867 ok(hr == S_OK, "got 0x%08x\n", hr);
1868 ok(valuef == 0.0, "got %.2f\n", valuef);
1870 value = tomUndefined;
1871 hr = ITextFont_GetLanguageID(font, &value);
1872 ok(hr == S_OK, "got 0x%08x\n", hr);
1873 ok(value == GetSystemDefaultLCID(), "got %d\n", value);
1875 str = NULL;
1876 hr = ITextFont_GetName(font, &str);
1877 ok(hr == S_OK, "got 0x%08x\n", hr);
1878 ok(!lstrcmpW(sysW, str), "%s\n", wine_dbgstr_w(str));
1879 SysFreeString(str);
1881 value = tomUndefined;
1882 hr = ITextFont_GetOutline(font, &value);
1883 ok(hr == S_OK, "got 0x%08x\n", hr);
1884 ok(value == tomFalse, "got %d\n", value);
1886 valuef = 1.0;
1887 hr = ITextFont_GetPosition(font, &valuef);
1888 ok(hr == S_OK, "got 0x%08x\n", hr);
1889 ok(valuef == 0.0, "got %.2f\n", valuef);
1891 value = tomUndefined;
1892 hr = ITextFont_GetProtected(font, &value);
1893 ok(hr == S_OK, "got 0x%08x\n", hr);
1894 ok(value == tomFalse, "got %d\n", value);
1896 value = tomUndefined;
1897 hr = ITextFont_GetShadow(font, &value);
1898 ok(hr == S_OK, "got 0x%08x\n", hr);
1899 ok(value == tomFalse, "got %d\n", value);
1901 valuef = 0.0;
1902 hr = ITextFont_GetSize(font, &valuef);
1903 ok(hr == S_OK, "got 0x%08x\n", hr);
1904 ok(valuef >= 0.0, "got %.2f\n", valuef);
1906 value = tomUndefined;
1907 hr = ITextFont_GetSmallCaps(font, &value);
1908 ok(hr == S_OK, "got 0x%08x\n", hr);
1909 ok(value == tomFalse, "got %d\n", value);
1911 valuef = 1.0;
1912 hr = ITextFont_GetSpacing(font, &valuef);
1913 ok(hr == S_OK, "got 0x%08x\n", hr);
1914 ok(valuef == 0.0, "got %.2f\n", valuef);
1916 value = tomUndefined;
1917 hr = ITextFont_GetStrikeThrough(font, &value);
1918 ok(hr == S_OK, "got 0x%08x\n", hr);
1919 ok(value == tomFalse, "got %d\n", value);
1921 value = tomUndefined;
1922 hr = ITextFont_GetSubscript(font, &value);
1923 ok(hr == S_OK, "got 0x%08x\n", hr);
1924 ok(value == tomFalse, "got %d\n", value);
1926 value = tomUndefined;
1927 hr = ITextFont_GetSuperscript(font, &value);
1928 ok(hr == S_OK, "got 0x%08x\n", hr);
1929 ok(value == tomFalse, "got %d\n", value);
1931 value = tomUndefined;
1932 hr = ITextFont_GetUnderline(font, &value);
1933 ok(hr == S_OK, "got 0x%08x\n", hr);
1934 ok(value == tomFalse, "got %d\n", value);
1936 value = tomUndefined;
1937 hr = ITextFont_GetWeight(font, &value);
1938 ok(hr == S_OK, "got 0x%08x\n", hr);
1939 ok(value == FW_NORMAL || value == FW_BOLD, "got %d\n", value);
1942 static void test_textfont_undefined(ITextFont *font)
1944 float valuef;
1945 LONG value;
1946 HRESULT hr;
1948 value = tomFalse;
1949 hr = ITextFont_GetAllCaps(font, &value);
1950 ok(hr == S_OK, "got 0x%08x\n", hr);
1951 ok(value == tomUndefined, "got %d\n", value);
1953 value = tomFalse;
1954 hr = ITextFont_GetAnimation(font, &value);
1955 ok(hr == S_OK, "got 0x%08x\n", hr);
1956 ok(value == tomUndefined, "got %d\n", value);
1958 value = tomFalse;
1959 hr = ITextFont_GetBackColor(font, &value);
1960 ok(hr == S_OK, "got 0x%08x\n", hr);
1961 ok(value == tomUndefined, "got %d\n", value);
1963 value = tomFalse;
1964 hr = ITextFont_GetBold(font, &value);
1965 ok(hr == S_OK, "got 0x%08x\n", hr);
1966 ok(value == tomUndefined, "got %d\n", value);
1968 value = tomFalse;
1969 hr = ITextFont_GetEmboss(font, &value);
1970 ok(hr == S_OK, "got 0x%08x\n", hr);
1971 ok(value == tomUndefined, "got %d\n", value);
1973 value = tomFalse;
1974 hr = ITextFont_GetForeColor(font, &value);
1975 ok(hr == S_OK, "got 0x%08x\n", hr);
1976 ok(value == tomUndefined, "got %d\n", value);
1978 value = tomFalse;
1979 hr = ITextFont_GetHidden(font, &value);
1980 ok(hr == S_OK, "got 0x%08x\n", hr);
1981 ok(value == tomUndefined, "got %d\n", value);
1983 value = tomFalse;
1984 hr = ITextFont_GetEngrave(font, &value);
1985 ok(hr == S_OK, "got 0x%08x\n", hr);
1986 ok(value == tomUndefined, "got %d\n", value);
1988 value = tomFalse;
1989 hr = ITextFont_GetItalic(font, &value);
1990 ok(hr == S_OK, "got 0x%08x\n", hr);
1991 ok(value == tomUndefined, "got %d\n", value);
1993 valuef = 0.0;
1994 hr = ITextFont_GetKerning(font, &valuef);
1995 ok(hr == S_OK, "got 0x%08x\n", hr);
1996 ok(valuef == tomUndefined, "got %.2f\n", valuef);
1998 value = tomFalse;
1999 hr = ITextFont_GetLanguageID(font, &value);
2000 ok(hr == S_OK, "got 0x%08x\n", hr);
2001 ok(value == tomUndefined, "got %d\n", value);
2003 value = tomFalse;
2004 hr = ITextFont_GetOutline(font, &value);
2005 ok(hr == S_OK, "got 0x%08x\n", hr);
2006 ok(value == tomUndefined, "got %d\n", value);
2008 valuef = 0.0;
2009 hr = ITextFont_GetPosition(font, &valuef);
2010 ok(hr == S_OK, "got 0x%08x\n", hr);
2011 ok(valuef == tomUndefined, "got %.2f\n", valuef);
2013 value = tomFalse;
2014 hr = ITextFont_GetProtected(font, &value);
2015 ok(hr == S_OK, "got 0x%08x\n", hr);
2016 ok(value == tomUndefined, "got %d\n", value);
2018 value = tomFalse;
2019 hr = ITextFont_GetShadow(font, &value);
2020 ok(hr == S_OK, "got 0x%08x\n", hr);
2021 ok(value == tomUndefined, "got %d\n", value);
2023 valuef = 0.0;
2024 hr = ITextFont_GetSize(font, &valuef);
2025 ok(hr == S_OK, "got 0x%08x\n", hr);
2026 ok(valuef == tomUndefined, "got %.2f\n", valuef);
2028 value = tomFalse;
2029 hr = ITextFont_GetSmallCaps(font, &value);
2030 ok(hr == S_OK, "got 0x%08x\n", hr);
2031 ok(value == tomUndefined, "got %d\n", value);
2033 valuef = 0.0;
2034 hr = ITextFont_GetSpacing(font, &valuef);
2035 ok(hr == S_OK, "got 0x%08x\n", hr);
2036 ok(valuef == tomUndefined, "got %.2f\n", valuef);
2038 value = tomFalse;
2039 hr = ITextFont_GetStrikeThrough(font, &value);
2040 ok(hr == S_OK, "got 0x%08x\n", hr);
2041 ok(value == tomUndefined, "got %d\n", value);
2043 value = tomFalse;
2044 hr = ITextFont_GetSubscript(font, &value);
2045 ok(hr == S_OK, "got 0x%08x\n", hr);
2046 ok(value == tomUndefined, "got %d\n", value);
2048 value = tomFalse;
2049 hr = ITextFont_GetSuperscript(font, &value);
2050 ok(hr == S_OK, "got 0x%08x\n", hr);
2051 ok(value == tomUndefined, "got %d\n", value);
2053 value = tomFalse;
2054 hr = ITextFont_GetUnderline(font, &value);
2055 ok(hr == S_OK, "got 0x%08x\n", hr);
2056 ok(value == tomUndefined, "got %d\n", value);
2058 value = tomFalse;
2059 hr = ITextFont_GetWeight(font, &value);
2060 ok(hr == S_OK, "got 0x%08x\n", hr);
2061 ok(value == tomUndefined, "got %d\n", value);
2064 static void test_ITextFont(void)
2066 static const WCHAR arialW[] = {'A','r','i','a','l',0};
2067 static const CHAR test_text1[] = "TestSomeText";
2068 ITextFont *font, *font2, *font3;
2069 IRichEditOle *reOle = NULL;
2070 ITextDocument *doc = NULL;
2071 ITextRange *range = NULL;
2072 CHARFORMAT2A cf;
2073 LONG value;
2074 HRESULT hr;
2075 HWND hwnd;
2076 BOOL ret;
2077 BSTR str;
2079 create_interfaces(&hwnd, &reOle, &doc, NULL);
2080 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2082 hr = ITextDocument_Range(doc, 0, 10, &range);
2083 ok(hr == S_OK, "got 0x%08x\n", hr);
2085 hr = ITextRange_GetFont(range, &font);
2086 ok(hr == S_OK, "got 0x%08x\n", hr);
2088 hr = ITextFont_GetName(font, NULL);
2089 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2091 /* default font name */
2092 str = NULL;
2093 hr = ITextFont_GetName(font, &str);
2094 ok(hr == S_OK, "got 0x%08x\n", hr);
2095 ok(!lstrcmpW(str, sysW), "got %s\n", wine_dbgstr_w(str));
2096 SysFreeString(str);
2098 /* change font name for an inner subrange */
2099 memset(&cf, 0, sizeof(cf));
2100 cf.cbSize = sizeof(cf);
2101 cf.dwMask = CFM_FACE;
2102 strcpy(cf.szFaceName, "Arial");
2104 SendMessageA(hwnd, EM_SETSEL, 3, 4);
2105 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2106 ok(ret, "got %d\n", ret);
2108 /* still original name */
2109 str = NULL;
2110 hr = ITextFont_GetName(font, &str);
2111 ok(hr == S_OK, "got 0x%08x\n", hr);
2112 ok(!lstrcmpW(str, sysW), "got %s\n", wine_dbgstr_w(str));
2113 SysFreeString(str);
2115 SendMessageA(hwnd, EM_SETSEL, 1, 2);
2116 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2117 ok(ret, "got %d\n", ret);
2119 str = NULL;
2120 hr = ITextFont_GetName(font, &str);
2121 ok(hr == S_OK, "got 0x%08x\n", hr);
2122 ok(!lstrcmpW(str, sysW), "got %s\n", wine_dbgstr_w(str));
2123 SysFreeString(str);
2125 /* name is returned for first position within a range */
2126 SendMessageA(hwnd, EM_SETSEL, 0, 1);
2127 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2128 ok(ret, "got %d\n", ret);
2130 str = NULL;
2131 hr = ITextFont_GetName(font, &str);
2132 ok(hr == S_OK, "got 0x%08x\n", hr);
2133 ok(!lstrcmpW(str, arialW), "got %s\n", wine_dbgstr_w(str));
2134 SysFreeString(str);
2136 /* GetDuplicate() */
2137 hr = ITextFont_GetDuplicate(font, NULL);
2138 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2140 EXPECT_REF(range, 2);
2141 font2 = NULL;
2142 hr = ITextFont_GetDuplicate(font, &font2);
2143 ok(hr == S_OK, "got 0x%08x\n", hr);
2144 EXPECT_REF(range, 2);
2146 /* set whole range to italic */
2147 cf.cbSize = sizeof(CHARFORMAT2A);
2148 cf.dwMask = CFM_ITALIC;
2149 cf.dwEffects = CFE_ITALIC;
2151 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2152 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2153 ok(ret, "got %d\n", ret);
2155 value = tomFalse;
2156 hr = ITextFont_GetItalic(font, &value);
2157 ok(hr == S_OK, "got 0x%08x\n", hr);
2158 ok(value == tomTrue, "got %d\n", value);
2160 /* duplicate retains original value */
2161 value = tomTrue;
2162 hr = ITextFont_GetItalic(font2, &value);
2163 ok(hr == S_OK, "got 0x%08x\n", hr);
2164 ok(value == tomFalse, "got %d\n", value);
2166 /* get a duplicate from a cloned font */
2167 hr = ITextFont_GetDuplicate(font2, &font3);
2168 ok(hr == S_OK, "got 0x%08x\n", hr);
2169 ITextFont_Release(font3);
2171 ITextRange_Release(range);
2172 release_interfaces(&hwnd, &reOle, &doc, NULL);
2174 hr = ITextFont_GetDuplicate(font, NULL);
2175 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2177 test_detached_font_getters(font, FALSE);
2178 test_detached_font_getters(font2, TRUE);
2180 /* get a duplicate of detached font */
2181 hr = ITextFont_GetDuplicate(font2, &font3);
2182 ok(hr == S_OK, "got 0x%08x\n", hr);
2183 ITextFont_Release(font3);
2185 /* reset detached font to undefined */
2186 value = tomUndefined;
2187 hr = ITextFont_GetBold(font2, &value);
2188 ok(hr == S_OK, "got 0x%08x\n", hr);
2189 ok(value != tomUndefined, "got %d\n", value);
2191 /* reset to undefined for deatached font */
2192 hr = ITextFont_Reset(font2, tomUndefined);
2193 ok(hr == S_OK, "got 0x%08x\n", hr);
2194 test_textfont_undefined(font2);
2196 /* font is detached, default means global TOM defaults */
2197 hr = ITextFont_Reset(font2, tomDefault);
2198 ok(hr == S_OK, "got 0x%08x\n", hr);
2199 test_textfont_global_defaults(font2);
2201 hr = ITextFont_GetDuplicate(font2, &font3);
2202 ok(hr == S_OK, "got 0x%08x\n", hr);
2203 test_textfont_global_defaults(font2);
2205 hr = ITextFont_Reset(font2, tomApplyNow);
2206 ok(hr == S_OK, "got 0x%08x\n", hr);
2207 test_textfont_global_defaults(font2);
2209 hr = ITextFont_Reset(font2, tomApplyLater);
2210 ok(hr == S_OK, "got 0x%08x\n", hr);
2211 test_textfont_global_defaults(font2);
2213 hr = ITextFont_Reset(font2, tomTrackParms);
2214 ok(hr == S_OK, "got 0x%08x\n", hr);
2215 test_textfont_global_defaults(font2);
2217 hr = ITextFont_SetItalic(font2, tomUndefined);
2218 ok(hr == S_OK, "got 0x%08x\n", hr);
2220 hr = ITextFont_GetItalic(font2, &value);
2221 ok(hr == S_OK, "got 0x%08x\n", hr);
2222 ok(value == tomFalse, "got %d\n", value);
2224 hr = ITextFont_Reset(font2, tomCacheParms);
2225 ok(hr == S_OK, "got 0x%08x\n", hr);
2226 test_textfont_global_defaults(font2);
2228 ITextFont_Release(font3);
2229 ITextFont_Release(font2);
2231 font2 = (void*)0xdeadbeef;
2232 hr = ITextFont_GetDuplicate(font, &font2);
2233 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2234 ok(font2 == NULL, "got %p\n", font2);
2236 hr = ITextFont_Reset(font, tomDefault);
2237 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2239 ITextFont_Release(font);
2241 /* Reset() */
2242 create_interfaces(&hwnd, &reOle, &doc, NULL);
2243 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2245 hr = ITextDocument_Range(doc, 0, 10, &range);
2246 ok(hr == S_OK, "got 0x%08x\n", hr);
2248 hr = ITextRange_GetFont(range, &font);
2249 ok(hr == S_OK, "got 0x%08x\n", hr);
2251 value = tomUndefined;
2252 hr = ITextFont_GetBold(font, &value);
2253 ok(hr == S_OK, "got 0x%08x\n", hr);
2254 ok(value != tomUndefined, "got %d\n", value);
2256 /* reset to undefined for attached font */
2257 hr = ITextFont_Reset(font, tomUndefined);
2258 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2260 value = tomUndefined;
2261 hr = ITextFont_GetBold(font, &value);
2262 ok(hr == S_OK, "got 0x%08x\n", hr);
2263 ok(value != tomUndefined, "got %d\n", value);
2265 /* tomCacheParms/tomTrackParms */
2266 hr = ITextFont_Reset(font, tomCacheParms);
2267 ok(hr == S_OK, "got 0x%08x\n", hr);
2269 hr = ITextFont_GetItalic(font, &value);
2270 ok(hr == S_OK, "got 0x%08x\n", hr);
2271 ok(value == tomFalse, "got %d\n", value);
2273 memset(&cf, 0, sizeof(cf));
2274 cf.cbSize = sizeof(CHARFORMAT2A);
2275 cf.dwMask = CFM_ITALIC;
2277 cf.dwEffects = CFE_ITALIC;
2278 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2279 ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2280 ok(ret, "got %d\n", ret);
2282 /* still cached value */
2283 hr = ITextFont_GetItalic(font, &value);
2284 ok(hr == S_OK, "got 0x%08x\n", hr);
2285 ok(value == tomFalse, "got %d\n", value);
2287 hr = ITextFont_Reset(font, tomTrackParms);
2288 ok(hr == S_OK, "got 0x%08x\n", hr);
2290 hr = ITextFont_GetItalic(font, &value);
2291 ok(hr == S_OK, "got 0x%08x\n", hr);
2292 ok(value == tomTrue, "got %d\n", value);
2294 /* switch back to cache - value retained */
2295 hr = ITextFont_Reset(font, tomCacheParms);
2296 ok(hr == S_OK, "got 0x%08x\n", hr);
2298 hr = ITextFont_GetItalic(font, &value);
2299 ok(hr == S_OK, "got 0x%08x\n", hr);
2300 ok(value == tomTrue, "got %d\n", value);
2302 /* tomApplyLater */
2303 hr = ITextFont_Reset(font, tomApplyLater);
2304 ok(hr == S_OK, "got 0x%08x\n", hr);
2306 hr = ITextFont_SetItalic(font, tomFalse);
2307 ok(hr == S_OK, "got 0x%08x\n", hr);
2309 hr = ITextFont_GetItalic(font, &value);
2310 ok(hr == S_OK, "got 0x%08x\n", hr);
2311 ok(value == tomFalse, "got %d\n", value);
2313 cf.dwEffects = 0;
2314 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2315 ret = SendMessageA(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2316 ok(ret, "got %d\n", ret);
2317 ok((cf.dwEffects & CFE_ITALIC) == CFE_ITALIC, "got 0x%08x\n", cf.dwEffects);
2319 hr = ITextFont_Reset(font, tomApplyNow);
2320 ok(hr == S_OK, "got 0x%08x\n", hr);
2322 cf.dwEffects = 0;
2323 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2324 ret = SendMessageA(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2325 ok(ret, "got %d\n", ret);
2326 ok((cf.dwEffects & CFE_ITALIC) == 0, "got 0x%08x\n", cf.dwEffects);
2328 hr = ITextFont_SetItalic(font, tomUndefined);
2329 ok(hr == S_OK, "got 0x%08x\n", hr);
2331 hr = ITextFont_GetItalic(font, &value);
2332 ok(hr == S_OK, "got 0x%08x\n", hr);
2333 ok(value == tomFalse, "got %d\n", value);
2335 hr = ITextFont_SetItalic(font, tomAutoColor);
2336 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2338 cf.dwEffects = 0;
2339 SendMessageA(hwnd, EM_SETSEL, 0, 10);
2340 ret = SendMessageA(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
2341 ok(ret, "got %d\n", ret);
2342 ok((cf.dwEffects & CFE_ITALIC) == 0, "got 0x%08x\n", cf.dwEffects);
2344 ITextRange_Release(range);
2345 ITextFont_Release(font);
2346 release_interfaces(&hwnd, &reOle, &doc, NULL);
2349 static void test_Delete(void)
2351 static const CHAR test_text1[] = "TestSomeText";
2352 IRichEditOle *reOle = NULL;
2353 ITextDocument *doc = NULL;
2354 ITextRange *range, *range2;
2355 LONG value;
2356 HRESULT hr;
2357 HWND hwnd;
2359 create_interfaces(&hwnd, &reOle, &doc, NULL);
2360 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2362 hr = ITextDocument_Range(doc, 0, 4, &range);
2363 ok(hr == S_OK, "got 0x%08x\n", hr);
2365 hr = ITextDocument_Range(doc, 1, 2, &range2);
2366 ok(hr == S_OK, "got 0x%08x\n", hr);
2368 hr = ITextRange_GetEnd(range, &value);
2369 ok(hr == S_OK, "got 0x%08x\n", hr);
2370 ok(value == 4, "got %d\n", value);
2372 /* unit type doesn't matter is count is 0 */
2373 value = 0;
2374 hr = ITextRange_Delete(range2, tomSentence, 0, &value);
2375 todo_wine {
2376 ok(hr == S_OK, "got 0x%08x\n", hr);
2377 ok(value == 1, "got %d\n", value);
2379 value = 1;
2380 hr = ITextRange_Delete(range2, tomCharacter, 0, &value);
2381 todo_wine {
2382 ok(hr == S_FALSE, "got 0x%08x\n", hr);
2383 ok(value == 0, "got %d\n", value);
2385 hr = ITextRange_GetEnd(range, &value);
2386 ok(hr == S_OK, "got 0x%08x\n", hr);
2387 todo_wine
2388 ok(value == 3, "got %d\n", value);
2390 hr = ITextRange_GetStart(range2, &value);
2391 ok(hr == S_OK, "got 0x%08x\n", hr);
2392 ok(value == 1, "got %d\n", value);
2394 hr = ITextRange_GetEnd(range2, &value);
2395 ok(hr == S_OK, "got 0x%08x\n", hr);
2396 todo_wine
2397 ok(value == 1, "got %d\n", value);
2399 ITextRange_Release(range);
2400 ITextRange_Release(range2);
2401 release_interfaces(&hwnd, &reOle, &doc, NULL);
2404 static void test_SetText(void)
2406 static const CHAR test_text1[] = "TestSomeText";
2407 static const WCHAR textW[] = {'a','b','c','d','e','f','g','h','i',0};
2408 IRichEditOle *reOle = NULL;
2409 ITextDocument *doc = NULL;
2410 ITextRange *range, *range2;
2411 LONG value;
2412 HRESULT hr;
2413 HWND hwnd;
2414 BSTR str;
2416 create_interfaces(&hwnd, &reOle, &doc, NULL);
2417 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
2419 hr = ITextDocument_Range(doc, 0, 4, &range);
2420 ok(hr == S_OK, "got 0x%08x\n", hr);
2422 hr = ITextDocument_Range(doc, 0, 4, &range2);
2423 ok(hr == S_OK, "got 0x%08x\n", hr);
2425 value = 1;
2426 hr = ITextRange_GetStart(range2, &value);
2427 ok(hr == S_OK, "got 0x%08x\n", hr);
2428 ok(value == 0, "got %d\n", value);
2430 value = 0;
2431 hr = ITextRange_GetEnd(range2, &value);
2432 ok(hr == S_OK, "got 0x%08x\n", hr);
2433 ok(value == 4, "got %d\n", value);
2435 hr = ITextRange_SetText(range, NULL);
2436 ok(hr == S_OK, "got 0x%08x\n", hr);
2438 value = 1;
2439 hr = ITextRange_GetEnd(range2, &value);
2440 ok(hr == S_OK, "got 0x%08x\n", hr);
2441 ok(value == 0, "got %d\n", value);
2443 str = SysAllocString(textW);
2444 hr = ITextRange_SetText(range, str);
2445 ok(hr == S_OK, "got 0x%08x\n", hr);
2447 value = 1;
2448 hr = ITextRange_GetStart(range, &value);
2449 ok(hr == S_OK, "got 0x%08x\n", hr);
2450 ok(value == 0, "got %d\n", value);
2452 value = 0;
2453 hr = ITextRange_GetEnd(range, &value);
2454 ok(hr == S_OK, "got 0x%08x\n", hr);
2455 ok(value == 9, "got %d\n", value);
2457 value = 1;
2458 hr = ITextRange_GetStart(range2, &value);
2459 ok(hr == S_OK, "got 0x%08x\n", hr);
2460 ok(value == 0, "got %d\n", value);
2462 value = 0;
2463 hr = ITextRange_GetEnd(range2, &value);
2464 ok(hr == S_OK, "got 0x%08x\n", hr);
2465 ok(value == 0, "got %d\n", value);
2467 str = SysAllocStringLen(NULL, 0);
2468 hr = ITextRange_SetText(range, str);
2469 ok(hr == S_OK, "got 0x%08x\n", hr);
2470 value = 1;
2471 hr = ITextRange_GetEnd(range, &value);
2472 ok(hr == S_OK, "got 0x%08x\n", hr);
2473 ok(value == 0, "got %d\n", value);
2474 SysFreeString(str);
2476 ITextRange_Release(range2);
2477 release_interfaces(&hwnd, &reOle, &doc, NULL);
2479 hr = ITextRange_SetText(range, NULL);
2480 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2482 str = SysAllocStringLen(NULL, 0);
2483 hr = ITextRange_SetText(range, str);
2484 ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
2485 SysFreeString(str);
2487 ITextRange_Release(range);
2490 START_TEST(richole)
2492 /* Must explicitly LoadLibrary(). The test has no references to functions in
2493 * RICHED20.DLL, so the linker doesn't actually link to it. */
2494 hmoduleRichEdit = LoadLibraryA("riched20.dll");
2495 ok(hmoduleRichEdit != NULL, "error: %d\n", (int) GetLastError());
2497 test_Interfaces();
2498 test_ITextDocument_Open();
2499 test_GetText();
2500 test_ITextSelection_GetChar();
2501 test_ITextSelection_GetStart_GetEnd();
2502 test_ITextSelection_Collapse();
2503 test_ITextDocument_Range();
2504 test_ITextRange_GetChar();
2505 test_ITextRange_GetStart_GetEnd();
2506 test_ITextRange_GetDuplicate();
2507 test_ITextRange_Collapse();
2508 test_IOleClientSite_QueryInterface();
2509 test_IOleWindow_GetWindow();
2510 test_IOleInPlaceSite_GetWindow();
2511 test_GetFont();
2512 test_GetPara();
2513 test_dispatch();
2514 test_ITextFont();
2515 test_Delete();
2516 test_SetText();